diff --git a/cnc/sensors/ads111x.py b/cnc/sensors/ads111x.py index 0831abe..f30db55 100644 --- a/cnc/sensors/ads111x.py +++ b/cnc/sensors/ads111x.py @@ -8,26 +8,36 @@ import threading ADS111x_ADDRESS = 0x48 I2C_SLAVE = 0x0703 -# Initialize i2c interface and register it for closing on exit. -__i2c_dev = os.open("/dev/i2c-1", os.O_SYNC | os.O_RDWR) + +class __I2CDev(object): + def __init__(self): + self._os_close = os.close + # Initialize i2c interface and register it for closing on exit. + self._dev = os.open("/dev/i2c-1", os.O_SYNC | os.O_RDWR) + if self._dev < 0: + raise ImportError("i2c device not found") + else: + if fcntl.ioctl(self._dev, I2C_SLAVE, ADS111x_ADDRESS) < 0: + self._close() + raise ImportError("Failed to set up i2c address") + else: + atexit.register(self._close) + + def _close(self): + self._os_close(self._dev) + + def write(self, data): + os.write(self._dev, data) + + def read(self, n): + os.read(self._dev, n) + +i2c = __I2CDev() # mutex for multi threading requests lock = threading.Lock() -def __close(): - os.close(__i2c_dev) - -if __i2c_dev < 0: - raise ImportError("i2c device not found") -else: - if fcntl.ioctl(__i2c_dev, I2C_SLAVE, ADS111x_ADDRESS) < 0: - __close() - raise ImportError("Failed to set up i2c address") - else: - atexit.register(__close) - - def measure(channel): """ Measure voltage on chip input. @@ -36,7 +46,7 @@ def measure(channel): :param channel: chip channel to use. :return: Voltage in Volts. """ - global __i2c_dev + global i2c if channel < 0 or channel > 3: raise ValueError("Wrong channel") lock.acquire() @@ -46,16 +56,16 @@ def measure(channel): # single shot mode, +-4.096V, AINN = GND ((0b100 | channel) << 12) | 0x8380 ) - os.write(__i2c_dev, data) + i2c.write(data) # wait for conversion while True: - os.write(__i2c_dev, struct.pack("B", 0x01)) - if struct.unpack(">H", os.read(__i2c_dev, 2))[0] & 0x8000 != 0: + i2c.write(data, struct.pack("B", 0x01)) + if struct.unpack(">H", i2c.read(data, 2))[0] & 0x8000 != 0: break time.sleep(0.0001) # read result - os.write(__i2c_dev, struct.pack("B", 0x00)) # conversion register - v = struct.unpack(">h", os.read(__i2c_dev, 2))[0] + i2c.write(data, struct.pack("B", 0x00)) # conversion register + v = struct.unpack(">h", i2c.read(data, 2))[0] lock.release() return v / 8000.0 # / 32768.0 * 4.096 according to specified range