# I2C address of the device MCP3428_DEFAULT_ADDRESS = 0x68 # MCP3428 Configuration Command Set MCP3428_CMD_NEW_CNVRSN = 0x80 # Initiate a new conversion(One-Shot Conversion mode only) CHANNEL = { 1: 0x00, # Channel-1 Selected 2: 0x20, # Channel-2 Selected 3: 0x40, # Channel-3 Selected 4: 0x60 # Channel-4 Selected } MCP3428_CMD_MODE_CONT = 0x10 # Continuous Conversion Mode MCP3428_CMD_MODE_ONESHOT = 0x00 # One-Shot Conversion Mode RESOLUTION = { 12: 0x00, # 240 SPS (12-bit) 14: 0x04, # 60 SPS (14-bit) 16: 0x08 # 15 SPS (16-bit) } GAIN = { 1: 0x00, # PGA Gain = 1V/V 2: 0x01, # PGA Gain = 2V/V 4: 0x02, # PGA Gain = 4V/V 8: 0x03 # PGA Gain = 8V/V } MCP3428_CMD_READ_CNVRSN = 0x00 # Read Conversion Result Data import smbus2 as smbus from ..api.i2c_handler import I2CDevice class MCP3428(I2CDevice): default_address = MCP3428_DEFAULT_ADDRESS def initialize(self, address: int): self.bus = smbus.SMBus(1) self.address = address def config_channel(self, channel: int, gain=1, resolution=12): """Select the Configuration Command from the given provided values""" self.gain = gain self.resolution = resolution CONFIG_CMD = (MCP3428_CMD_MODE_CONT | RESOLUTION[resolution] | GAIN[gain] | CHANNEL[channel]) self.bus.write_byte(self.address, CONFIG_CMD) def read_value(self) -> float: raw_adc = self._read_adc() res_per_bit = 2.048/2**(self.resolution-1) return raw_adc*res_per_bit/self.gain def _read_adc(self): """Read data back from MCP3428_CMD_READ_CNVRSN(0x00), 2 bytes raw_adc MSB, raw_adc LSB""" read = smbus.i2c_msg.read(self.address, 2) self.bus.i2c_rdwr(read) data = list(read) # Convert the data to 12-bits raw_adc = ((data[0] & 0x0F) * 256) + data[1] if raw_adc > 2047: raw_adc -= 4095 return raw_adc