|
|
@@ -1,27 +1,46 @@
|
|
|
import smbus2 as smbus
|
|
|
-from ..vendor.mcp3428 import MCP3428, MCP3428_DEFAULT_ADDRESS
|
|
|
+from abc import ABC, abstractmethod
|
|
|
from time import sleep
|
|
|
+import asyncio
|
|
|
+
|
|
|
+class I2CDevice(ABC):
|
|
|
+ @abstractmethod
|
|
|
+ def initialize(self, bus: smbus.SMBus, address: int):
|
|
|
+ pass
|
|
|
+
|
|
|
+ @abstractmethod
|
|
|
+ def config_channel(self, channel: int, **kwargs):
|
|
|
+ pass
|
|
|
+
|
|
|
+ @abstractmethod
|
|
|
+ def read_value(self) -> float:
|
|
|
+ pass
|
|
|
|
|
|
class I2C:
|
|
|
- def __init__(self, channels, gain = 1, resolution = 12):
|
|
|
- self.channels = channels if isinstance(channels, list) else [channels]
|
|
|
- self.gain = gain
|
|
|
- self.resolution = resolution
|
|
|
- self.mcp = None
|
|
|
+ def __init__(self, device_class:I2CDevice, address=None, **kwargs):
|
|
|
+ self.device_class = device_class
|
|
|
+ self.address = address if address is not None else device_class.default_address
|
|
|
+ assert self.address is not None, "I2C address must be provided"
|
|
|
+ self.kwargs = kwargs
|
|
|
+ self.device = None
|
|
|
|
|
|
def initialize(self):
|
|
|
bus = smbus.SMBus(1)
|
|
|
- self.mcp = MCP3428(bus, MCP3428_DEFAULT_ADDRESS)
|
|
|
+ self.device:I2CDevice = self.device_class()
|
|
|
+ self.device.initialize(bus, self.address)
|
|
|
|
|
|
- def read_channel(self, channel):
|
|
|
- if self.mcp is None:
|
|
|
+ async def read_channel(self, channel):
|
|
|
+ if self.device is None:
|
|
|
raise RuntimeError("I2C not initialized")
|
|
|
- self.mcp.config_command(channel, self.gain, self.resolution)
|
|
|
- sleep(0.01)
|
|
|
- return self.mcp.read_adc()
|
|
|
+ self.device.config_channel(channel, **self.kwargs)
|
|
|
+ await asyncio.sleep(0.01)
|
|
|
+ return self.device.read_value()
|
|
|
|
|
|
- def read(self):
|
|
|
- return {channel: self.read_channel(channel) for channel in self.channels}
|
|
|
+ async def read_channels(self, channels):
|
|
|
+ self.channels = channels if isinstance(channels, list) else [channels]
|
|
|
+
|
|
|
+ # Needs to be sequential otherwise readings will be mixedup
|
|
|
+ return {channel: await self.read_channel(channel) for channel in self.channels}
|
|
|
|
|
|
|
|
|
|