Raspberry Pi Pico(s_07)MCP4725 用モジュール
MCP4725 MCP4725c.py
MCP4725は分解能12bitのD/Aコンバータです。I2C通信で制御します。※詳細はMCP4725のデータシートを参照ください。
MCP4725 HW-315モジュールで使う自作の’MCP4725c.py’を作成しました。記事d_09を元に作成しています。使い方だけを記載します。’MCP4725c.py’は末尾にあります。
使い方
■ファイル転送
Raspberry Pi Picoへ’MCP4725c.py’を送った後でimportして使います。
※MCP4725c.pyの末尾に、使用例(MCP4725_ex.py)の## example以降をコピペ追加しても動作確認できます。
■メソッド
‘MCP4725c’をimportすると「read_DAC、write_DAC、read_ADC」のメソッドが使えるようになります。
MCP4725(i2c_num=0,sda_num=8,Adr=0x60,Vdd=3300)で初期化します。
i2c_num:I2C0、I2C1の番号、デフォルトは0(I2C0)
sda_num:SDAのGPIO番号、デフォルトは8(GP8)
Adr:スレーブアドレス、デフォルトは0x60
Vdd:基準電圧、デフォルトは3300(mV)
※freq=100_000
(01)read_DAC()
MCP4725のレジスタ、EEPROMデータを読みます。以下のようにThonnyのShellに表示します。
<2 byte>
|RDY/BSY|POR|= 11 |PD1|PD0|= 00
<3-4 byte 12bit>
Register_Data= 0b100000000000 0x800
<5-6 byte PD, 12bit>
|PD1|PD0|= 00
EEPROM_Data= 0b100000000000 0x800
(02)write_DAC(value,cmd=’010′, pd=’00’)
value:出力したい電圧値(mV)
cmd:データ書込みモード、レジスタのみ’010’、EEPROMにも書込む’011′
※Fastモード’00’は設定できません。
pd:Power Down mode 通常DAC(’00’)、接地1kΩ(’01’)、100kΩ(’10’)、500kΩ(’10’)
(03)read_ADC(num_pin=28)
num_pin:GPIO番号
ADC変換値を返します。ADC0(GP26),ADC1(GP27),ADC2(GP28)が使えます。
使用例
MCP4725で設定した電圧値を出力し、その値をADC2(GPIO28)で測定をして確認します。
接続図は記事d_09を参照ください。
MCP4725_ex.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
#from machine import I2C,SoftI2C,Pin,ADC
#import time
from MCP4725c import MCP4725
# MCP4725 12-Bit Digital-to-Analog Converter with EEPROM Memory
## example
a=MCP4725(1,10) #初期化 I2C1,SDA=GP10 (address=0x60 VDD=3300mv)
# MCP4725 Write Data
Vset=3300/2 # 出力設定 1650mV
a.write_DAC(Vset,cmd='010', pd='00') # MCP4725設定 EEPROM書込み無し、DACモード
print('Vset mv =',Vset)
val=a.read_ADC() # ADC2 GP28
print('Vout mv =',val)
print("")
# MCP4725 Read Data
print("MCP4725 Read Regi-EEPROM Data ---")
a.read_DAC() # MCP4725のデータ読出し
print("---")
実行結果
実行すると以下のようになりました。※Thonnyのshellに表示されます。
>>> %Run -c $EDITOR_CONTENT
Vset mv = 1650.0 # MC4725設定値
Vout mv = 1639.879 # ADC2値(MC4725出力値)
MCP4725 Read Regi-EEPROM Data ---
<2 byte> # MCP4725の各データ読出し
|RDY/BSY|POR|= 11 |PD1|PD0|= 00
<3-4 byte 12bit>
Register_Data= 0b100000000000 0x800
<5-6 byte PD, 12bit>
|PD1|PD0|= 00
EEPROM_Data= 0b100000000000 0x800
---
>>>
MCP4725用モジュール
MCP4725c.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import I2C,SoftI2C,Pin,ADC
import time
# MCP4725 12-Bit Digital-to-Analog Converter with EEPROM Memory
class MCP4725:
def __init__(self,i2c_num=0,sda_num=8,Adr=0x60,Vdd=3300):
self.i2c = I2C(i2c_num, scl=Pin(sda_num+1), sda=Pin(sda_num), freq=100_000)
self.adr=Adr # slave address hex(96)='0x60'
self.VDD=Vdd # 3300mV
def r_digit(self,dat): # int
dat=bin(dat) # str
value='0'*(8-len(dat[2:])) + dat[2:] # str
return value
def read_DAC(self):
# read 5bytes
r_dat=self.i2c.readfrom(self.adr,5)
# 2 byte r_dat[0]
by2_rdpo=self.r_digit(r_dat[0])[0:2] #RDY/BSY POR str
by2_pd10=self.r_digit(r_dat[0])[5:7] #PD1 PD0 str
print('<2 byte>')
print('|RDY/BSY|POR|=',by2_rdpo, '|PD1|PD0|=', by2_pd10)
# 3 byte r_dat[1] 4nd byte r_dat[2]
by3_da=self.r_digit(r_dat[1])
by4_da=self.r_digit(r_dat[2])[0:4]
reg_dat='0b'+by3_da + by4_da # DAC Resister 12bit Data str
print('<3-4 byte 12bit>')
print('Register_Data=', reg_dat,hex(int(reg_dat)) )
# 5 byte r_dat[3] 6nd byte r_dat[4] EEPROM Data
by5_pd10=self.r_digit(r_dat[3])[1:3] #PD1 PD0
by5_da=self.r_digit(r_dat[3])[4:8]
by6_da=self.r_digit(r_dat[4])
rom_dat='0b'+by5_da + by6_da # DAC EEPROM 12bit Data str
print('<5-6 byte PD, 12bit>')
print('|PD1|PD0|=', by5_pd10)
print('EEPROM_Data=', rom_dat, hex(int(rom_dat)))
return #r_dat
def w_digt(self,dat): # int
dat=bin(dat) # str
value='0'*(12-len(dat[2:])) + dat[2:] # str '0'埋12文字
return value
def write_DAC(self,value,cmd='010', pd='00'):
# write cmd '010' DAC-Regi '011'DAC-Regi+EEPROM
# 設定できるのは4095/4096*VDD まで hex(4095)'0xfff'
s_dat=int(value/self.VDD*4096)
w_dat=self.w_digt(s_dat) #str
#print('w_dat=',w_dat)
buf=bytearray(3) # I2C write data
buf[0]=int('0b'+ cmd +'00'+pd +'0') # command PowerDown
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
self.i2c.writeto(self.adr,buf)
#EEPROM Write Time typ 25msec max 50msec
if cmd == '011':
time.sleep_ms(50)
return
def read_ADC(self,num_pin=28):
# MCP4725 OUT Data >> ADC Read
adc=ADC(Pin(num_pin))
val=adc.read_u16()*(self.VDD/2**16)
return val