kplindegaard / smbus2

A drop-in replacement for smbus-cffi/smbus-python in pure Python
MIT License
243 stars 68 forks source link

Multiple instances of the SMBus class #75

Closed mglowinski93 closed 2 years ago

mglowinski93 commented 3 years ago

Hi, I have a question about creating several instances of an SMBus object. I have a system that uses several sensors that communicate over I2C.

I noticed that the library for each of them creates its own instance of SMBus in __init__.

Example:

class Sensor1:
    def __init__(self):
        self.bus = SMBus(1)

class Sensor2:
    def __init__(self):
        self.bus = SMBus(1)

Can I have two SMBus objects? They will not impact each other?

Additionally, I noticed that often the connection in such libraries is not closed (method close in not invoked). How might this affect the application?

Wouldn't it be a better idea to pass the SMBus instance to the __init__ and manage it outside of a class?

class SmBusWrapper:
    def __init__(self):
        self.bus = SMBus(1)

    def __del__(self):
        self.bus.close()

class Sensor1:
    def __init__(self, smbus: SMBus):
        self.bus = smbus

class Sensor2:
    def __init__(self, smbus: SMBus):
        self.bus = smbus

Thanks for answers :) !

kplindegaard commented 3 years ago
  1. It's generally not a good idea to create two instances of the SMBus class accessing the same physical bus. See here
  2. As long as you don't use the with clause, you are responsible for closing the bus yourself. See the difference between Example 1a and 1b in the readme.
mglowinski93 commented 2 years ago

I've crated below class to manage access to I2C Bus:

class SMBusWrapper(metaclass=Singleton):
    def __init__(self):
        self._smbus = SMBus(1)
        atexit.register(self.close_smbus)

    @property
    def smbus(self):
        return self._smbus

    @smbus.setter
    def smbus(self, value):
        self._smbus = value

    def close_smbus(self):
        self._smbus.close()

And getting access to I2CBus:

def get_smbus() -> SMBus:
    """
    Returns
    -------
    SMBus
        Return a new SMBus object that is connected to the specified I2C device interface.
    """

    return SMBusWrapper().smbus