以前書いたADコンバータを動かすやつの使い勝手が悪かったので直すついでにChatGPTに添削してもらいました。
書いたやつ
SX8725C.py
import machine,math,utime
class SX8725C:
def __init__(self, i2c_addr=0x48, i2c_id=0, sda_pin=0, scl_pin=1, freq=100000):
self.id = i2c_id
self.sda = sda_pin
self.scl = scl_pin
self.i2c = machine.I2C(id=i2c_id, sda=machine.Pin(sda_pin), scl=machine.Pin(scl_pin), freq=freq)
self.addr = i2c_addr
self.reg_map = [0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x70]
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
# Default settings
self.set_adc = "on"
self.set_pga1 = "on"
self.set_pga2 = "on"
self.set_pga3 = "off"
self.set_pga1_gain = 10 # 1, 10
self.set_pga2_gain = 5 # 1, 2, 5, 10
self.set_pga3_gain = 12 # 0/12 to 32/12
self.analog_input_VinP = "AC2"
self.analog_input_VinN = "AC3"
self.sampling_param_fs = 500
self.sampling_param_osr = 1024
self.sampling_param_nelconv = 8
self.reg_mode_chopper = "Nelconv"
self.reg_mode_MultForceOn = "off"
self.reg_mode_MultForceOff = "off"
self.vref_Vmux = "Vbgd1"
self.vref_VrefD0Out = "off"
self.vref_VrefD1In = "off"
self.vref_vref = 1.22
self.start_cont_start = 1
self.start_cont_cont = 1
self.o2_zero = 0.0
self.o2_span_air = 0.0
self.o2_span_o2 = 0.0
# Initialize
self._load_calibration_values()
self._initialize_device()
def _load_calibration_values(self):
self.o2_zero = self._read_calibration_file('o2_zero.txt', self.o2_zero)
self.o2_span_air = self._read_calibration_file('o2_span_air.txt', self.o2_span_air)
self.o2_span_o2 = self._read_calibration_file('o2_span_o2.txt', self.o2_span_o2)
@staticmethod
def _read_calibration_file(filename, default):
try:
with open(filename) as f:
return float(f.read())
except:
return default
def _initialize_device(self):
self.enable_adc_pga(adc=self.set_adc, pga1=self.set_pga1, pga2=self.set_pga2, pga3=self.set_pga3)
self.set_analog_input(VinP=self.analog_input_VinP, VinN=self.analog_input_VinN)
self.set_pga_gain(pga1=self.set_pga1_gain, pga2=self.set_pga2_gain, pga3=self.set_pga3_gain)
self.set_sampling_params(fs=self.sampling_param_fs, osr=self.sampling_param_osr, nelconv=self.sampling_param_nelconv)
self.set_reg_mode(chopper=self.reg_mode_chopper, MultForceOn=self.reg_mode_MultForceOn, MultForceOff=self.reg_mode_MultForceOff)
self.set_vref(Vmux=self.vref_Vmux, VrefD0Out=self.vref_VrefD0Out, VrefD1In=self.vref_VrefD1In, Vref=self.vref_vref)
self.set_start_cont(start=self.start_cont_start, cont=self.start_cont_cont)
def load_reg_params(self):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
dict_str = {hex(reg):'{:08b}'.format(value[0]) for reg, value in sx8725c.reg_params.items()}
return dict_str
@staticmethod
def view_8bit(value_bytes):
value_bytes = int.from_bytes(value, "big")
print("raw: ",value, type(value))
value = '{:08b}'.format(value)
print("8bit: ",value, type(value))
@staticmethod
def set_bit(byte_value, bit_position, bit_value):#e.g. self.set_bit(RegACCfg1, 0, 1)
byte_list = bytearray(byte_value)
if bit_value:
byte_list[0] |= (1 << bit_position)
else:
byte_list[0] &= ~(1 << bit_position)
return bytes(byte_list)
@staticmethod
def set_bit_range(byte_value, start_bit, end_bit, new_value):#e.g. self.set_bit_range(RegACCfg5,1,5,0b10001)
mask = ((1 << (end_bit - start_bit + 1)) - 1) << start_bit
new_value &= ((1 << (end_bit - start_bit + 1)) - 1)
return bytes([(byte_value[0] & ~mask) | (new_value << start_bit)])
def enable_adc_pga(self, adc="on", pga1="off", pga2="off", pga3="off"):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegACCfg1 = self.reg_params[0x53]
if adc == "on":
RegACCfg1 = self.set_bit(RegACCfg1, 0, 1)
elif adc == "off":
RegACCfg1 = self.set_bit(RegACCfg1, 0, 0)
if pga1 == "on":
RegACCfg1 = self.set_bit(RegACCfg1, 1, 1)
elif pga1 == "off":
RegACCfg1 = self.set_bit(RegACCfg1, 1, 0)
if pga2 == "on":
RegACCfg1 = self.set_bit(RegACCfg1, 2, 1)
elif pga2 == "off":
RegACCfg1 = self.set_bit(RegACCfg1, 2, 0)
if pga3 == "on":
RegACCfg1 = self.set_bit(RegACCfg1, 3, 1)
elif pga3 == "off":
RegACCfg1 = self.set_bit(RegACCfg1, 3, 0)
self.i2c.writeto_mem(self.addr, 0x53, RegACCfg1)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
self.set_adc = adc
self.set_pga1 = pga1
self.set_pga2 = pga2
self.set_pga3 = pga3
def set_pga_gain(self,pga1=1,pga2=1,pga3=12):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegACCfg2 = self.reg_params[0x54]
RegACCfg3 = self.reg_params[0x55]
if pga1 == 1:
RegACCfg3 = self.set_bit(RegACCfg3, 7, 0)
self.pga1_gain = 1
elif pga1 == 10:
RegACCfg3 = self.set_bit(RegACCfg3, 7, 1)
self.pga1_gain = 10
if pga2 == 1:
RegACCfg2 = self.set_bit_range(RegACCfg2,4,5,0b00)
self.pga2_gain = 1
elif pga2 == 2:
RegACCfg2 = self.set_bit_range(RegACCfg2,4,5,0b01)
self.pga2_gain = 2
elif pga2 == 5:
RegACCfg2 = self.set_bit_range(RegACCfg2,4,5,0b10)
self.pga2_gain = 5
elif pga2 == 10:
RegACCfg2 = self.set_bit_range(RegACCfg2,4,5,0b11)
self.pga2_gain = 10
if 0 <= pga3 <= 32:
RegACCfg3 = self.set_bit_range(RegACCfg3,0,6,pga3)
self.pga3_gain = pga3
self.i2c.writeto_mem(self.addr, 0x54, RegACCfg2)
self.i2c.writeto_mem(self.addr, 0x55, RegACCfg3)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
self.set_pga1_gain = pga1
self.set_pga2_gain = pga2
self.set_pga3_gain = pga3
def set_analog_input(self,VinP="AC3",VinN="AC2"):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegACCfg5 = self.reg_params[0x57]
if VinP == "AC3":
if VinN == "AC2":
RegACCfg5 = self.set_bit_range(RegACCfg5,1,5,0b00001)
elif VinN == "AC0":
RegACCfg5 = self.set_bit_range(RegACCfg5,1,5,0b10011)
elif VinP == "AC2":
if VinN == "AC3":
RegACCfg5 = self.set_bit_range(RegACCfg5,1,5,0b01001)
elif VinP == "AC0":
RegACCfg5 = self.set_bit_range(RegACCfg5,1,5,0b10010)
elif VinP == "AC1":
if VinN == "AC0":
RegACCfg5 = self.set_bit_range(RegACCfg5,1,5,0b10001)
self.i2c.writeto_mem(self.addr, 0x57, RegACCfg5)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
self.analog_input_VinP = VinP
self.analog_input_VinN = VinN
def set_sampling_params(self,fs=62.5,osr=32,nelconv=2):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegACCfg0 = self.reg_params[0x52]
RegACCfg2 = self.reg_params[0x54]
if fs == 62.5:
RegACCfg2 = self.set_bit_range(RegACCfg2,6,7,0b00)
elif fs == 125:
RegACCfg2 = self.set_bit_range(RegACCfg2,6,7,0b01)
elif fs == 250:
RegACCfg2 = self.set_bit_range(RegACCfg2,6,7,0b10)
elif fs == 500:
RegACCfg2 = self.set_bit_range(RegACCfg2,6,7,0b11)
if isinstance(osr, int) and 0 < osr and (osr & (osr - 1)) == 0:
if 8 <= osr <= 1024:
reg = int(math.log2(osr))-3
RegACCfg0 = self.set_bit_range(RegACCfg0,2,4,reg)
if isinstance(nelconv, int) and 0 < nelconv and (nelconv & (nelconv - 1)) == 0:
if 1 <= nelconv <= 8:
reg = int(math.log2(nelconv))
RegACCfg0 = self.set_bit_range(RegACCfg0,5,6,reg)
self.i2c.writeto_mem(self.addr, 0x52, RegACCfg0)
self.i2c.writeto_mem(self.addr, 0x54, RegACCfg2)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
self.sampling_param_fs = fs
self.sampling_param_osr = osr
self.sampling_param_nelconv = nelconv
def set_reg_mode(self,chopper="state1",MultForceOn="off",MultForceOff="off"):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegMode = self.reg_params[0x70]
if chopper == "state0":
RegMode = self.set_bit_range(RegMode,4,5,0b00)
elif chopper == "state1":
RegMode = self.set_bit_range(RegMode,4,5,0b01)
elif chopper == "Nelconv":
RegMode = self.set_bit_range(RegMode,4,5,0b10)
elif chopper == "Nelconv/2":
RegMode = self.set_bit_range(RegMode,4,5,0b11)
if MultForceOn == "off":
RegMode = self.set_bit(RegMode,3,0)
elif MultForceOn == "on":
RegMode = self.set_bit(RegMode,3,1)
if MultForceOff == "off":
RegMode = self.set_bit(RegMode,2,0)
elif MultForceOff == "on":
RegMode = self.set_bit(RegMode,2,1)
self.i2c.writeto_mem(self.addr, 0x70, RegMode)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
self.reg_mode_chopper = chopper
self.reg_mode_MultForceOn = MultForceOn
self.reg_mode_MultForceOff = MultForceOff
def set_vref(self,Vmux="Vbgd1",VrefD0Out="off",VrefD1In="off",Vref=1.22):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegACCfg5 = self.reg_params[0x57]
RegMode = self.reg_params[0x70]
if Vmux == "Vbgd1":
RegACCfg5 = self.set_bit(RegACCfg5,0,1)
elif Vmux == "Vbatt":
RegACCfg5 = self.set_bit(RegACCfg5,0,0)
if VrefD0Out == "off":
RegMode = self.set_bit(RegMode,1,0)
elif VrefD0Out == "on":
RegMode = self.set_bit(RegMode,1,1)
if VrefD1In == "off":
RegMode = self.set_bit(RegMode,0,0)
elif VrefD1In == "on":
RegMode = self.set_bit(RegMode,0,1)
self.i2c.writeto_mem(self.addr, 0x57, RegACCfg5)
self.i2c.writeto_mem(self.addr, 0x70, RegMode)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
self.vref_Vmux = Vmux
self.vref_VrefD0Out = VrefD0Out
self.vref_VrefD1In = VrefD1In
self.vref_vref = Vref
def set_start_cont(self,start=1,cont=1):
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
RegACCfg0 = self.reg_params[0x52]
if start == 0:
RegACCfg0 = self.set_bit(RegACCfg0,7,0)
elif start == 1:
RegACCfg0 = self.set_bit(RegACCfg0,7,1)
if cont == 0:
RegACCfg0 = self.set_bit(RegACCfg0,1,0)
elif cont == 1:
RegACCfg0 = self.set_bit(RegACCfg0,1,1)
self.i2c.writeto_mem(self.addr, 0x52, RegACCfg0)
self.reg_params = {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
def read_raw(self):
lsb = self.i2c.readfrom_mem(self.addr,0x50,1)
msb = self.i2c.readfrom_mem(self.addr,0x51,1)
x = (msb[0]<<8)|lsb[0]
x = (-(x&32768)|(x&32767))
return x
def read(self):
# convert to mV
val = self.read_raw()
val = val * 1000 * (self.vref_vref/65535)
if self.set_pga1 == "on":
val = val/self.set_pga1_gain
if self.set_pga2 == "on":
val = val/self.set_pga2_gain
if self.set_pga3 == "on":
val = val/(self.set_pga3_gain/12)
return val
# convert value
def conv_o2_val(self,buf):
if self.o2_span_air > buf:
val = round(((20.95-0)/(self.o2_span_air-self.o2_zero))*(buf-self.o2_zero)+0,2)
else:
val = round(((100-20.95)/(self.o2_span_o2-self.o2_span_air))*(buf-self.o2_span_air)+20.95,2)
return val
def read_o2(self):
buf = self.read()
val = self.conv_o2_val(buf)
return val
### TEST CODE ###
# SX8725Cのインスタンス化
sx8725c = SX8725C(i2c_id=1, sda_pin=18, scl_pin=19)
print("Register parameters:")
[print(hex(reg), ":", '{:08b}'.format(value[0])) for reg, value in sx8725c.reg_params.items()]
print("_______________________________________________________________")
print("start test roop")
try:
raw = 0
val = 0
conv = 0
while True:
raw = sx8725c.read_raw()
val = sx8725c.read()
conv = sx8725c.read_o2()
print(raw,val,conv)
utime.sleep(2)
except KeyboardInterrupt:
pass
ChatGPTによる指摘が以下
問題点
- デフォルト設定の論理:
- self.set_adc, self.set_pga1, self.set_pga2, self.set_pga3 などの変数が設定されているが、実際にこれらの変数がどのように使用されるかが曖昧です。
- デフォルトの設定が enable_adc_pga メソッドで初期化されていますが、インスタンスの生成時にこれが実際に適用されることが保証されていないように見えます。
- メソッドの一貫性:
- メソッドの名前や引数が一貫していないため、理解しにくくなっています。
- 例えば、set_pga_gain メソッドで self.pga1_gain と self.set_pga1_gain が混在しています。
- I2C通信のエラーハンドリング:
- I2C通信時のエラーハンドリングが不足しているため、エラーが発生した場合に適切に対応できません。
- 計算ロジックの一貫性:
- read メソッドの計算ロジックが複雑で、一貫していないように見えます。
- 例えば、PGAの設定に応じて計算が異なるが、その処理が明確でない。
改善点
- デフォルト設定の適用:
- インスタンス生成時にデフォルト設定が確実に適用されるように、初期化メソッドで呼び出す。
- メソッドの一貫性と明確化:
- メソッドの名前や引数を一貫させ、コードの可読性を向上させる。
- I2C通信のエラーハンドリング追加:
- I2C通信時のエラーハンドリングを追加し、エラー発生時に適切に対応できるようにする。
- 計算ロジックの明確化:
- 計算ロジックを明確にし、コメントを追加して処理内容を理解しやすくする。
以下は、改善されたコードです:
SX8725C.py

import machine, math, utime
class SX8725C:
def __init__(self, i2c_addr=0x48, i2c_id=0, sda_pin=0, scl_pin=1, freq=100000):
self.id = i2c_id
self.sda = sda_pin
self.scl = scl_pin
self.i2c = machine.I2C(id=i2c_id, sda=machine.Pin(sda_pin), scl=machine.Pin(scl_pin), freq=freq)
self.addr = i2c_addr
self.reg_map = [0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x70]
self.reg_params = self._load_reg_params()
# Default settings
self.adc_enabled = "on"
self.pga1_enabled = "on"
self.pga2_enabled = "on"
self.pga3_enabled = "off"
self.pga1_gain = 10 # 1, 10
self.pga2_gain = 5 # 1, 2, 5, 10
self.pga3_gain = 12 # 0/12 to 32/12
self.analog_input_vinp = "AC2"
self.analog_input_vinn = "AC3"
self.sampling_fs = 500
self.sampling_osr = 1024
self.sampling_nelconv = 8
self.reg_mode_chopper = "Nelconv"
self.reg_mode_multforceon = "off"
self.reg_mode_multforceoff = "off"
self.vref_vmux = "Vbgd1"
self.vref_vrefd0out = "off"
self.vref_vrefd1in = "off"
self.vref_value = 1.22
self.start_continuous = 1
self.start_enabled = 1
self.o2_zero = 0.0
self.o2_span_air = 0.0
self.o2_span_o2 = 0.0
# Initialize
self._load_calibration_values()
self._initialize_device()
def _load_calibration_values(self):
self.o2_zero = self._read_calibration_file('o2_zero.txt', self.o2_zero)
self.o2_span_air = self._read_calibration_file('o2_span_air.txt', self.o2_span_air)
self.o2_span_o2 = self._read_calibration_file('o2_span_o2.txt', self.o2_span_o2)
@staticmethod
def _read_calibration_file(filename, default):
try:
with open(filename) as f:
return float(f.read())
except Exception as e:
print(f"Error reading {filename}: {e}")
return default
def _initialize_device(self):
self.enable_adc_pga(adc=self.adc_enabled, pga1=self.pga1_enabled, pga2=self.pga2_enabled, pga3=self.pga3_enabled)
self.set_analog_input(vinp=self.analog_input_vinp, vinn=self.analog_input_vinn)
self.set_pga_gain(pga1=self.pga1_gain, pga2=self.pga2_gain, pga3=self.pga3_gain)
self.set_sampling_params(fs=self.sampling_fs, osr=self.sampling_osr, nelconv=self.sampling_nelconv)
self.set_reg_mode(chopper=self.reg_mode_chopper, multforceon=self.reg_mode_multforceon, multforceoff=self.reg_mode_multforceoff)
self.set_vref(vmux=self.vref_vmux, vrefd0out=self.vref_vrefd0out, vrefd1in=self.vref_vrefd1in, vref=self.vref_value)
self.set_start_continuous(start=self.start_enabled, cont=self.start_continuous)
def _load_reg_params(self):
try:
return {reg: self.i2c.readfrom_mem(self.addr, reg, 1) for reg in self.reg_map}
except Exception as e:
print(f"Failed to load register parameters: {e}")
return {reg: bytes([0]) for reg in self.reg_map}
def load_reg_params(self):
self.reg_params = self._load_reg_params()
dict_str = {hex(reg): '{:08b}'.format(value[0]) for reg, value in self.reg_params.items()}
return dict_str
@staticmethod
def set_bit(byte_value, bit_position, bit_value):
byte_list = bytearray(byte_value)
if bit_value:
byte_list[0] |= (1 << bit_position)
else:
byte_list[0] &= ~(1 << bit_position)
return bytes(byte_list)
@staticmethod
def set_bit_range(byte_value, start_bit, end_bit, new_value):
mask = ((1 << (end_bit - start_bit + 1)) - 1) << start_bit
new_value &= ((1 << (end_bit - start_bit + 1)) - 1)
return bytes([(byte_value[0] & ~mask) | (new_value << start_bit)])
def enable_adc_pga(self, adc="on", pga1="off", pga2="off", pga3="off"):
self.reg_params = self._load_reg_params()
reg_accfg1 = self.reg_params[0x53]
reg_accfg1 = self.set_bit(reg_accfg1, 0, adc == "on")
reg_accfg1 = self.set_bit(reg_accfg1, 1, pga1 == "on")
reg_accfg1 = self.set_bit(reg_accfg1, 2, pga2 == "on")
reg_accfg1 = self.set_bit(reg_accfg1, 3, pga3 == "on")
self.i2c.writeto_mem(self.addr, 0x53, reg_accfg1)
self.reg_params = self._load_reg_params()
self.adc_enabled = adc
self.pga1_enabled = pga1
self.pga2_enabled = pga2
self.pga3_enabled = pga3
def set_pga_gain(self, pga1=1, pga2=1, pga3=12):
self.reg_params = self._load_reg_params()
reg_accfg2 = self.reg_params[0x54]
reg_accfg3 = self.reg_params[0x55]
reg_accfg3 = self.set_bit(reg_accfg3, 7, pga1 == 10)
self.pga1_gain = 10 if pga1 == 10 else 1
reg_accfg2 = self.set_bit_range(reg_accfg2, 4, 5, self._gain_to_bits(pga2))
self.pga2_gain = pga2
if 0 <= pga3 <= 32:
reg_accfg3 = self.set_bit_range(reg_accfg3, 0, 6, pga3)
self.pga3_gain = pga3
self.i2c.writeto_mem(self.addr, 0x54, reg_accfg2)
self.i2c.writeto_mem(self.addr, 0x55, reg_accfg3)
self.reg_params = self._load_reg_params()
self.pga1_gain = pga1
self.pga2_gain = pga2
self.pga3_gain = pga3
def set_analog_input(self, vinp="AC3", vinn="AC2"):
self.reg_params = self._load_reg_params()
reg_accfg5 = self.reg_params[0x57]
reg_accfg5 = self.set_bit_range(reg_accfg5, 1, 5, self._analog_input_to_bits(vinp, vinn))
self.i2c.writeto_mem(self.addr, 0x57, reg_accfg5)
self.reg_params = self._load_reg_params()
self.analog_input_vinp = vinp
self.analog_input_vinn = vinn
def set_sampling_params(self, fs=62.5, osr=32, nelconv=2):
self.reg_params = self._load_reg_params()
reg_accfg0 = self.reg_params[0x52]
reg_accfg2 = self.reg_params[0x54]
reg_accfg2 = self.set_bit_range(reg_accfg2, 6, 7, self._fs_to_bits(fs))
reg_accfg0 = self.set_bit_range(reg_accfg0, 2, 4, self._osr_to_bits(osr))
reg_accfg0 = self.set_bit_range(reg_accfg0, 5, 6, self._nelconv_to_bits(nelconv))
self.i2c.writeto_mem(self.addr, 0x52, reg_accfg0)
self.i2c.writeto_mem(self.addr, 0x54, reg_accfg2)
self.reg_params = self._load_reg_params()
self.sampling_fs = fs
self.sampling_osr = osr
self.sampling_nelconv = nelconv
def set_reg_mode(self, chopper="state1", multforceon="off", multforceoff="off"):
self.reg_params = self._load_reg_params()
reg_mode = self.reg_params[0x70]
reg_mode = self.set_bit_range(reg_mode, 4, 5, self._chopper_to_bits(chopper))
reg_mode = self.set_bit(reg_mode, 3, multforceon == "on")
reg_mode = self.set_bit(reg_mode, 2, multforceoff == "on")
self.i2c.writeto_mem(self.addr, 0x70, reg_mode)
self.reg_params = self._load_reg_params()
self.reg_mode_chopper = chopper
self.reg_mode_multforceon = multforceon
self.reg_mode_multforceoff = multforceoff
def set_vref(self, vmux="Vbgd1", vrefd0out="off", vrefd1in="off", vref=1.22):
self.reg_params = self._load_reg_params()
reg_accfg5 = self.reg_params[0x57]
reg_mode = self.reg_params[0x70]
reg_accfg5 = self.set_bit(reg_accfg5, 0, vmux == "Vbgd1")
reg_mode = self.set_bit(reg_mode, 1, vrefd0out == "on")
reg_mode = self.set_bit(reg_mode, 0, vrefd1in == "on")
self.i2c.writeto_mem(self.addr, 0x57, reg_accfg5)
self.i2c.writeto_mem(self.addr, 0x70, reg_mode)
self.reg_params = self._load_reg_params()
self.vref_vmux = vmux
self.vref_vrefd0out = vrefd0out
self.vref_vrefd1in = vrefd1in
self.vref_value = vref
def set_start_continuous(self, start=1, cont=1):
self.reg_params = self._load_reg_params()
reg_accfg0 = self.reg_params[0x52]
reg_accfg0 = self.set_bit(reg_accfg0, 7, start)
reg_accfg0 = self.set_bit(reg_accfg0, 1, cont)
self.i2c.writeto_mem(self.addr, 0x52, reg_accfg0)
self.reg_params = self._load_reg_params()
self.start_enabled = start
self.start_continuous = cont
def read_raw(self):
try:
lsb = self.i2c.readfrom_mem(self.addr, 0x50, 1)
msb = self.i2c.readfrom_mem(self.addr, 0x51, 1)
x = (msb[0] << 8) | lsb[0]
x = (-(x & 32768) | (x & 32767))
return x
except Exception as e:
print(f"Failed to read raw value: {e}")
return 0
def read(self):
val = self.read_raw()
val = val * 1000 * (self.vref_value / 65535)
if self.pga1_enabled == "on":
val /= self.pga1_gain
if self.pga2_enabled == "on":
val /= self.pga2_gain
if self.pga3_enabled == "on":
val /= (self.pga3_gain / 12)
return val
def conv_o2_val(self, buf):
if self.o2_span_air > buf:
val = round(((20.95 - 0) / (self.o2_span_air - self.o2_zero)) * (buf - self.o2_zero) + 0, 2)
else:
val = round(((100 - 20.95) / (self.o2_span_o2 - self.o2_span_air)) * (buf - self.o2_span_air) + 20.95, 2)
return val
def read_o2(self):
buf = self.read()
val = self.conv_o2_val(buf)
return val
@staticmethod
def _gain_to_bits(gain):
return {
1: 0b00,
2: 0b01,
5: 0b10,
10: 0b11,
}.get(gain, 0b00)
@staticmethod
def _analog_input_to_bits(vinp, vinn):
return {
("AC3", "AC2"): 0b00001,
("AC3", "AC0"): 0b10011,
("AC2", "AC3"): 0b01001,
("AC2", "AC0"): 0b10010,
("AC1", "AC0"): 0b10001,
}.get((vinp, vinn), 0b00001)
@staticmethod
def _fs_to_bits(fs):
return {
62.5: 0b00,
125: 0b01,
250: 0b10,
500: 0b11,
}.get(fs, 0b00)
@staticmethod
def _osr_to_bits(osr):
if isinstance(osr, int) and osr & (osr - 1) == 0 and 8 <= osr <= 1024:
return int(math.log2(osr)) - 3
return 0
@staticmethod
def _nelconv_to_bits(nelconv):
if isinstance(nelconv, int) and nelconv & (nelconv - 1) == 0 and 1 <= nelconv <= 8:
return int(math.log2(nelconv))
return 0
@staticmethod
def _chopper_to_bits(chopper):
return {
"state0": 0b00,
"state1": 0b01,
"Nelconv": 0b10,
"Nelconv/2": 0b11,
}.get(chopper, 0b01)
# # ### TEST CODE ###
# sx8725c = SX8725C(i2c_id=1, sda_pin=18, scl_pin=19)
# print("Register parameters:")
# [print(hex(reg), ":", '{:08b}'.format(value[0])) for reg, value in sx8725c.reg_params.items()]
# print("_______________________________________________________________")
#
# print("Start test loop")
# try:
# while True:
# raw = sx8725c.read_raw()
# val = sx8725c.read()
# conv = sx8725c.read_o2()
# print(raw, val, conv)
# utime.sleep(2)
# except KeyboardInterrupt:
# pass
編集画面がやたら重いのでここまで。