稼働中

マイクロビット(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 の行をコメントアウトして測定しています)

sin波

のこぎり波

波形のデータを変更してのこぎり波、のこぎり波にしてみました。

スクリプト(変更部分)


# 波形のデータ
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変換による任意波形の出力ができるようになったように思います。