-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Standardize I2C initialization for libraries that use it. #340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@caternuson would you mind providing numbered options for people to weigh in on? Thanks! |
OPTION 1CODE from adafruit_bus_device.i2c_device import I2CDevice
DEVICE_DEFAULT_I2C_ADDR = 0x42
class Some_Device():
def __init__(self, i2c, address=DEVICE_DEFAULT_I2C_ADDR):
self._device = I2CDevice(i2c, address) USAGE import board
import busio
import adafruit_some_device
i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_some_device.Some_Device(i2c) EXAMPLE OPTION 2CODE from adafruit_bus_device.i2c_device import I2CDevice
DEVICE_DEFAULT_I2C_ADDR = 0x42
class Some_Device():
def __init__(self, i2c=None, address=DEVICE_DEFAULT_I2C_ADDR, **kwargs):
if i2c is None:
import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)
self.i2c_device = I2CDevice(i2c, address) USAGE import adafruit_some_device
sensor = adafruit_some_device.Some_Device() EXAMPLE OPTION 3CODE from adafruit_bus_device.i2c_device import I2CDevice
DEVICE_DEFAULT_I2C_ADDR = 0x42
class Some_Device():
def __init__(self, i2c=None, address=DEVICE_DEFAULT_I2C_ADDR):
self._device = I2CDevice(i2c, address) USAGE import adafruit_some_device
sensor = adafruit_some_device.Some_Device() EXAMPLE OPTION 4CODE from adafruit_bus_device.i2c_device import I2CDevice
DEVICE_DEFAULT_I2C_ADDR = 0x42
class Some_Device():
def __init__(self, address=DEVICE_DEFAULT_I2C_ADDR, i2c=None, **kwargs):
if i2c is None:
import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)
self.i2c_device = I2CDevice(i2c, address) USAGE import adafruit_some_device
sensor = adafruit_some_device.Some_Device() EXAMPLE OPTION 5CODE from adafruit_bus_device.i2c_device import I2CDevice
class Some_Device():
def __init__(self, i2c):
self.i2c_device = I2CDevice(i2c, 0x42) USAGE import board
import busio
import adafruit_some_device
i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_some_device.Some_Device(i2c) EXAMPLE |
I like an option that would allow the simple usage syntax of Options 2-4 without all the boiler plate imports and setup. |
i think the issue with #2 is if the sensor has no args and thus creates an i2c device, then if they use that syntax to make another sensor, it will error out because the pins are in use. so id prefer requiring passing in an i2c device |
That is an issue (same for #4) :( import adafruit_this_device
import adafruit_that_device
this_sensor = adafruit_this_device.This_Device()
that_sensor = adafruit_that_device.That_Device() Looks nice, but second sensor would error out. |
For options 2-4 you are forcing it to use SDA,SCL - this is fine for boards that have hardware I2C and SCL/SDA are fixed, but what about boards like the ESP8266 where it is not fixed to these pins. Would be possible to allow for optional arguments to set the pins in all options? |
some boards have fixed i2c, some you can change, so i like the idea of a kwargs for the address. also some, rare devices require another initializer when creating (since we do not use begin()) so kwargs seems best? |
I'm curious is there an issue with the current state of the world (option 1, passing in an explicit I2C bus)? If the issues is reducing boilerplate IMHO I'd push that complexity to another layer and not into the drivers (where they might have to make tradeoffs like picking to use busio vs. bitbangio for ESP8266, etc.). IMHO something nice would be in the board module add functions that give you the default I2C bus for the board and can know if they should be bitbangio, busio, etc. For example:
Then for each board they can choose how they implement default_I2C_bus(), perhaps returning a busio.I2C for the default SCL, SDA, etc. or returning a bitbangio.I2C on ESP8266, etc. You could even extend it further and just have explicit buses on the board module (board.I2C_0, board.I2C_1, etc.) |
That's it really. Just thinking of target audience, it'd be nice if it could be as simple as: import thing
thingee = thing.Thing() |
@tdicola I think what you are suggesting is similar to what @tannewt mentioned, but bury it in I2CDevice, i.e. Option 3. I think this would also cover the case of software I2C like ESP8266 as @jerryneedell has pointed out. Summarizing thoughts to date: |
There is also option 6, make from adafruit_bus_device.i2c_device import I2CDevice
DEVICE_DEFAULT_I2C_ADDR = 0x42
class Some_Device():
def __init__(self, i2c_device):
self._device = i2c_device
i2c_device.set_default_address(DEVICE_DEFAULT_I2C_ADDR) The nice thing about this is that the |
My preference would be @tdicola's suggestion because its just explicit enough in my mind. @deshipu's options 6 and 7 feel like they hide too much by hiding board. So, how about @caternuson's Option 1 for drivers and an issue to support default i2c busses through |
I'll take the silence to mean we're ok with my proposal. Would someone mind:
|
Done and done. |
Thanks @caternuson ! |
For libraries that are for I2C devices, come up with a standard
__init__
to use for all of them.The text was updated successfully, but these errors were encountered: