from time import sleep_ms class ChipSelect: def __init__(self, pin): pin.value(1) self._pin = pin def __enter__(self): self._pin.value(0) def __exit__(self, exc_type, exc_obj, exc_tb): self._pin.value(1) class MCP3208: WIDTH = 2**12 def __init__(self, spi, cs, ref_voltage=3.3): """ Create MCP3208 instance Args: spi: configured SPI bus cs: pin to use for chip select ref_voltage: reference voltage """ self.cs = ChipSelect(cs) self._spi = spi self._buffer_in = bytearray(3) self._buffer_out = bytearray(3) self._ref_voltage = ref_voltage @property def reference_voltage(self) -> float: """Returns the MCP3xxx's reference voltage as a float.""" return self._ref_voltage def read_raw(self, channel, is_differential=False): """ read a voltage or voltage difference using the MCP3208. Args: pin: the pin to use is_differential: if true, return the potential difference between two pins, Returns: voltage in range [0, 4095] where 4095 = VREF (3V3) """ # self._out_buf[0] = 1 << 7 | (not is_differential) << 6 | channel << 3 self._buffer_out = bytearray( [ 1 << 2 | (not is_differential) << 1 | (channel & 0x04) >> 2, (channel & 0x03) << 6, 0, ] ) # print(self._buffer_out) with self.cs: self._spi.write_readinto(self._buffer_out, self._buffer_in) # self._spi.write(self._buffer_out) # self._spi.readinto(self._buffer_in) return (self._buffer_in[1] & 0x0F) << 8 | self._buffer_in[2] def read(self, channel, is_differential=False): return ( self.read_raw(channel, is_differential) / (self.WIDTH - 1) * self.reference_voltage )