マイクロビット(e_54)MCP4725 D/A変換(2)
MCP4725 波形出力
前回はmicro:bitでMicrochip社のMCP4725を使ってD/A変換の動作を確認しました。
今回はMCP4725でsin波形を生成してみたいと思います。※thonny-microbitのMicroPythonを使っています。
前回に作成した mcp4725_write_b0.py を改良して波形を生成しました。スクリプトと結果だけ記載します。
sin波形のスクリプト
sin波形出力のスクリプトは以下のようにしました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from microbit import *
import math
import utime
# MCP4725 add hex(96)='0x60'
adr_dac=0x60 # MCP4725
VDD=3000 # mV
def write_DAC(value,cmd='010', pd='00'): # 前回を参照
s_dat=int(value/VDD*4096)
# 12moji '0'の穴埋め 0bは付いてない
dat=bin(s_dat) # str
w_dat='0'*(12-len(dat[2:])) + dat[2:] # str
#print('12bit w_data str=',w_dat)
buf=bytearray(3) # I2C write data
buf[0]=int('0b'+ cmd +'00'+pd +'0') # command power down
# 8bitと4bitに
buf[1]=int('0b'+ w_dat[0:8]) # D11-D4 8bit
buf[2]=int('0b'+ w_dat[8:12]) << 4 # D3-D0 4bit +'0000' 8bit
#print('write_buf_data=',buf)
return buf
# 波形のデータ
A=1500 # 振れ幅
div=256 # 分解値
base_set=1500 # オフセット
# 全データをバイト
sum_buf=bytearray()
for i in range(div):
deg=360/div*i
a=math.sin(deg/180*math.pi)
dat= int(a*A)+base_set # OF_SET(+/-)sin T=180°
buf=write_DAC(dat,cmd='010', pd='00') # 3 bytes
# 3bytes x 256 =768 波形のbytearrayデータ
sum_buf=sum_buf+buf
print('sum_buf=',sum_buf) # sum_buf
# 3バイトづづ送信する
buf=bytearray(3)
while True:
sta_time=running_time() # start time
for i in range(div):
buf[0]=sum_buf[i*3]
buf[1]=sum_buf[i*3+1]
buf[2]=sum_buf[i*3+2]
#print(i,buf,buf)
i2c.write(adr_dac,buf)
#utime.sleep_us(300) # 時間調整
dur_time=running_time()-sta_time # cycle time
#print(dur_time)
実行結果
#print(‘sum_buf=’,sum_buf)、#print(dur_time)を有効にして実行しました。
波形のbytearrayデータ 768ケのデータと大まかな周期は303msecにました。
>>> %Run mcp4725_test20-1b.py
sum_buf= bytearray(b'@v\xe0@y\xb0@|\xa0@\x7f\x90@\x82\x80@\x85`@\x88P@\x8b @\x8e\x00@\
x90\xe0@\x93\xb0@\x96\x90@\・・(省略)・・\xc0@I`@L @N\xd0@Q\xa0@T`@W @Z\x00@\\\xe0@_\
xb0@b\x90@ep@h`@k0@n @q\x10@t\x00') #print('sum_buf=',sum_buf)
358 #print(dur_time) 周期
303
302
303
・・
省略
ちなみに、時間調整のutime.sleep_us(300)を有効にすると大まかな周期は401msecになりました。
波形写真
古いブラウン管のOSCで確認しました。ストレージが無いので上手く記録できませんでした。
画像はつぎ足しをしています。
周期はだいたい合っているようです。1500mVを軸に振れ幅1500mVのsin波になっています。
( # sum_buf, # start time, # cycle time の行をコメントアウトして測定しています)
のこぎり波
波形のデータを変更してのこぎり波、のこぎり波にしてみました。
スクリプト(変更部分)
# 波形のデータ
A=1500 # 振れ幅
div=256 # 分解値
base_set=0 # オフセット
# 全データをバイト
sum_buf=bytearray()
for i in range(div):
# T=180deg nokogiri 180°まで単調増加 のこぎり
deg=(360/(div))*i
#dat=A*(deg/360-deg//360)
dat=deg/360
#print(i,dat)
dat= int(A*dat)+base_set # OF_SET
buf=write_DAC(dat,cmd='010', pd='00')
# 3bytes x 256 =768 波形のbytearrayデータ
sum_buf=sum_buf+buf
#print('sum_buf=',sum_buf)
実行結果
>>> %Run mcp4725_test20-2b.py
354 #print(dur_time) 周期
355
354
354
354
355
・・
省略
波形写真
三角波
波形のデータを変更して三角波にしてみました。
スクリプト(変更部分)
# 波形のデータ
A=1500 # 振れ幅
div=256 # 分解値
base_set=0 # オフセット
# 全データをバイト
sum_buf=bytearray()
# T=180deg 90degまで単調増加、180degまで単調減少
for i in range(div):
deg=(360/div)*i
#b=deg/180-deg//180
dat=deg/180
if dat>1:
dat=2-dat
#print(i,b)
dat= int(A*dat)+base_set # OF_SET(+/-)
buf=write_DAC(dat,cmd='010', pd='00')
# 3bytes x 256 =768 波形のbytearrayデータ
sum_buf=sum_buf+buf
#print('sum_buf=',sum_buf)
実行結果
>>> %Run mcp4725_test20-3.py
354 #print(dur_time) 周期
355
354
354
355
・・
省略
波形写真
まとめ
micro:bitでMCP4725を使って波形を出力することができました。かなり遅い周期の波形しか生成できませんでした。他にもっと良い方法があるのかも知れません。とりあえず、micro:bitでD/A変換による任意波形の出力ができるようになったように思います。