稼働中

マイクロビット(e_53)MCP4725 D/A変換(1)

MCP4725 D/A (I2C)

Microchip社のMCP4725をmicro:bitで使ってみました。※thonny-microbitのMicroPythonを使っています。
「MCP4725」は分解能12bitのD/Aコンバータです。I2C通信で制御します。EEPROMも内臓しています。
I2Cの周波数は標準100kHz、Fast400kHz、High-Speed3.4MHzとあります。micro:bitで使うので標準100kHzになります。(micro:bitに搭載されているI2Cデバイスの地磁気センサーMAG3110、加速度センサMMA865が100kHzで動作しているため)

外観

MCP4725モジュールHW-315の外観写真です。右はピンヘッダを半田付けした状態です。(以後はMCP4725と記載します)

MCP4725外観MCP4725-HW-315

接続例

MCP4725の電源電圧は2.7V~5.5Vなのでmicro:bitと接続できます。その際のD/A変換出力は3.3Vが最大になります。
D/A変換出力をmicro:bitで測定するために、MCP4725の出力端子からmicro:bitのpin0に接続しています。pin0のモードはアナログ入力にします。
接続例
※micro:bitのピン配置図は「https://tech.microbit.org/hardware/edgeconnector/」からの引用です。

実体接続した写真です。

実体配線図

ちなみにI2Cデバイスのスレーブアドレスは簡単にわかります。96(0x60)がMCP4725のアドレスになります。

i2c.scan()


>>> from microbit import *
>>> i2c.scan()
[14, 29, 96]
>>> hex(96)
'0x60'

ちなみに、14(0xe)がMAG3110(地磁気センサー)、29(0x1d)がMMA8653(加速度センサー)です。

READ COMMAND

DAC registerとEEPROMのデータを読込んでみようと思います。

データは下図のように格納されています。読込むデータは2nd~6th byteの5バイトです。
2nd byteは現在の設定値です。RDY/BSY(ready/busy/Write EEPROM status)やPOR(power on reset)、PD1、PD0(power down mode)が分かります。
3-4th byteはDACレジスタ値です。
5-6th byteはEEPROMの値です。PDモードも含んでいます。
※詳細はMCP4725のデーターシートを参照ください。

micro:bitで読込むには
i2c.read(MCP4725のアドレス,5)
で読込みます。これが下図の1st byte(Read Command)です。

Read Command
※ Microchip Technology MCP4725のデータシートから抜粋

スクリプト

データ読み込みのスクリプトは以下のようにしました。


mcp4725_read_b0.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from microbit import *
# i2c.init(freq=100000, sda=pin20, scl=pin19)
# MCP4725 slave-add hex(96)='0x60'
adr_dac=0x60

def r_digit(dat):   # int
    dat=bin(dat)    # str  
    value='0'*(8-len(dat[2:])) + dat[2:] # str
    return value

def read_DAC():
    # read 5bytes
    r_dat=i2c.read(adr_dac,5)
    # 2nd byte r_dat[0]
    by2_rdpo=r_digit(r_dat[0])[0:2] #RDY/BSY POR   str
    by2_pd10=r_digit(r_dat[0])[5:7] #PD1 PD2       str
    print('<2nd byte>')
    print('RDY/BSY POR=',by2_rdpo, 'PD1 PD0=', by2_pd10)

    # 3nd byte r_dat[1] 4nd byte r_dat[2]
    by3_da=r_digit(r_dat[1])
    by4_da=r_digit(r_dat[2])[0:4]
    reg_dat='0b'+by3_da + by4_da    # DAC Resister 12bit Data str

    print('<3,4nd byte 8+4bit>')
    print('Register Data=', reg_dat,hex(int(reg_dat)) )

    # 5nd byte r_dat[3] 6nd byte r_dat[4]
    by5_pd10=r_digit(r_dat[3])[1:3]
    by5_da=r_digit(r_dat[3])[4:8]
    by6_da=r_digit(r_dat[4])
    rom_dat='0b'+by5_da + by6_da    # DAC EEPROM 12bit Data str

    print('<5-6nd byte PD, 4+8bit>')
    print('PD1 PD0=', by5_pd10, 'EEPROM Data=', rom_dat, hex(int(rom_dat)) )

read_DAC()

関数
r_digit(dat)はdat(int)値を’0’で埋めた8文字にしています。例えば以下のようになります。


>>> r_digit(0x06)
'00000110'
>>> r_digit(0b0110)
'00000110'

読込だ各byteをr_digit()に送って8文字データに変更して必要な部分をスライスして抜き出しています。
必要に応じて文字を加算しています。

実行結果


%Run mcp4725_read_b0.py
<2nd byte>
RDY/BSY POR= 11 PD1 PD0= 00
<3,4nd byte 8+4bit>
Register Data= 0b100000000000 0x800
<5-6nd byte PD, 4+8bit>
PD1 PD0= 00 EEPROM Data= 0b100000000000 0x800
>>> 

出荷時にはEEPROM Dataは0b100000000000(0x800)になっています。そのため電源電圧の1/2(Vcc/2)が出力されます。

Write Commands

D/A変換するデータを書込んでその出力値をmicro:bitのpin0で読込んでみます。
MCP4725の書込みは下図のようになっています。

2nd byteのC2,C1,C0でレジスタだけ、EEPROMと両方に書込みを設定できます。まだPD1,PD0でPower のモードが設定できます。通常(0,0)で出力します。(0,1)なら1.0kΩ、(1,0)なら100kΩ、(1,1)なら500kΩで接地します。待機電力が軽減されるようです。

micro:bitで書込むには
書込むデータを
buf=bytearray(3)として
i2c.write(MCP4725のアドレス,buf)
で書込みます。これが下図の1st byte(Device Addressing)です。

繰返しての書込みは2nd-4byteを繰返します。
例えばbuf=bytearray(3の倍数)として、相当のデータを与えて書込みます。
※詳細はMCP4725のデーターシートを参照ください。
Write Command
※ Microchip Technology MCP4725のデータシートから抜粋

スクリプト

データ書込みのスクリプトは以下のようにしました。


mcp4725_write_b0.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from microbit import *
# i2c.init(freq=100000, sda=pin20, scl=pin19)
# MCP4725 100kHz:standard_mode
adr_dac=0x60   # MCP4725 address hex(96)='0x60'
VDD=3200       # mV micro:bitの電源電圧をテスターで測定すると3200mVでした

def w_digt(dat):   # int
    dat=bin(dat)   # str
    value='0'*(12-len(dat[2:])) + dat[2:] # str '0'で埋めた12文字
    return value

def write_DAC(value,cmd='010', pd='00'):# value 出力mV
    # 設定できるのは4095/4096*VDD まで hex(4095)'0xfff' 12bit(4096)
    s_dat=int(value/VDD*4096)   # 出力したい電圧に応じたデジタル値に
    print('set mv =',value)
    
    w_dat=w_digt(s_dat)         # str w_digtへ送って'0'で埋めた12文字にする

    buf=bytearray(3)                     # I2C write bytedata
    buf[0]=int('0b'+ cmd +'00'+pd +'0')  # command PowerDown
    # DAC no Data wo 8bit 4bit ni bunkai site set suru
    buf[1]=int('0b'+ w_dat[0:8])               # D11-D4 8bit
    buf[2]=int('0b'+ w_dat[8:12]) << 4   # D3-D0 4bit 4 shift-up   
    i2c.write(adr_dac,buf)                     # bufを送信
    return buf

write_DAC(1500,cmd='010', pd='00') # 出力したい電圧 1500mv,コマンドモード,パワーダウンモード

pin0.set_pull(pin0.NO_PULL)         # pin0をNO_PULLにしておく
r_out=pin0.read_analog()*VDD/1024   # pin0でアナログ値を読む 分解能8bit
print('pin0 mv=',int(r_out))        # micro:bit測定値

関数
write_DAC(value,cmd=’010′, pd=’00’)
value:アナログ出力電圧値(mV)、cmd=’010′:書込むモード(’010’ならレジスタだけ、’011’ならEEPROMと両方)、パワーダウンモードを設定します。

実行結果(1)


>>> %Run mcp4725_write_b0.py
set mv = 1500
pin0 mv= 1525

micro:bitビットで測定した値は少しズレました。分解能の差異かも知れません。ちなみに、テスターで測定した出力は1515mVでした。

Power Down モード以下のように’01’で実行して見ます。
write_DAC(1500,cmd=’010′, pd=’01’)

実行結果(2)


>>> %Run mcp4725_write_b0.py
set mv = 1500
w_dat= 100000000000
write_buf_data= bytearray(b'b\x80\x00')
pin0 mv= 11                     # power down動作されている

先の読込み(mcp4725_read_b0.py)を確認して見ます。分かりやすいように、VDD=750mVにしました。
mcp4725_write_b0.py
write_DAC(750,cmd=’010′, pd=’00’)で実行した後、設定を読込みしてみます。

実行結果(3)


>>> %Run mcp4725_write_b0.py
set mv = 750
w_dat= 010000000000
write_buf_data= bytearray(b'@@\x00')
pin0 mv= 773

>>> %Run mcp4725_read_b0.py
<2nd byte>
RDY/BSY POR= 11 PD1 PD0= 00
<3,4nd byte 8+4bit>
Register Data= 0b010000000000 0x400            #レジスタに書込まれた
<5-6nd byte PD, 4+8bit>
PD1 PD0= 00 EEPROM Data= 0b100000000000 0x800  #EEPROMには書込みされてない

write_DAC(750,cmd=’011′, pd=’00’)で実行した後、設定を読込みしてみます。

実行結果(4)


>>> %Run mcp4725_write_b0.py
set mv = 750
w_dat= 010000000000
write_buf_data= bytearray(b'`@\x00')
pin0 mv= 773

>>> %Run mcp4725_read_b0.py
<2nd byte>
RDY/BSY POR= 11 PD1 PD0= 00
<3,4nd byte 8+4bit>
Register Data= 0b010000000000 0x400             #レジスタに書込まれた
<5-6nd byte PD, 4+8bit>
PD1 PD0= 00 EEPROM Data= 0b010000000000 0x400   #EEPROMに書込まれた

<h3<まとめ

micro:bitでMCP4725モジュールHW-315を使ったD/A変換を確認しました。Read Command、Write Commandの動作を確認しました。