@@ -133,7 +133,7 @@ class Modulino:
133133 This class variable needs to be overridden in derived classes.
134134 """
135135
136- def __init__ (self , i2c_bus : I2C = None , address : int = None , name : str = None ) :
136+ def __init__ (self , i2c_bus : I2C = None , address : int = None , name : str = None , check_connection : bool = True ) -> None :
137137 """
138138 Initializes the Modulino object with the given i2c bus and address.
139139 If the address is not provided, the device will try to auto discover it.
@@ -145,6 +145,7 @@ def __init__(self, i2c_bus: I2C = None, address: int = None, name: str = None):
145145 i2c_bus (I2C): The I2C bus to use. If not provided, the default I2C bus will be used.
146146 address (int): The address of the device. If not provided, the device will try to auto discover it.
147147 name (str): The name of the device.
148+ check_connection (bool): Whether to check if the device is connected to the bus.
148149 """
149150
150151 if i2c_bus is None :
@@ -168,7 +169,7 @@ def __init__(self, i2c_bus: I2C = None, address: int = None, name: str = None):
168169
169170 if self .address is None :
170171 raise RuntimeError (f"Couldn't find the { self .name } device on the bus. Try resetting the board." )
171- elif not self .connected :
172+ elif check_connection and not self .connected :
172173 raise RuntimeError (f"Couldn't find a { self .name } device with address { hex (self .address )} on the bus. Try resetting the board." )
173174
174175 def discover (self , default_addresses : list [int ]) -> int | None :
@@ -183,11 +184,9 @@ def discover(self, default_addresses: list[int]) -> int | None:
183184 if len (default_addresses ) == 0 :
184185 return None
185186
186- devices_on_bus = Modulino .scan (self .i2c_bus )
187- for addr in default_addresses :
188- if addr in devices_on_bus :
189- return addr
190-
187+ devices_on_bus = Modulino .scan (self .i2c_bus , default_addresses )
188+ if len (devices_on_bus ) > 0 :
189+ return devices_on_bus [0 ]
191190 return None
192191
193192 def __bool__ (self ) -> bool :
@@ -207,7 +206,12 @@ def connected(self) -> bool:
207206 """
208207 if not bool (self ):
209208 return False
210- return self .address in Modulino .scan (self .i2c_bus )
209+
210+ try :
211+ self .i2c_bus .writeto (self .address , b'' )
212+ return True
213+ except OSError :
214+ return False
211215
212216 @property
213217 def pin_strap_address (self ) -> int | None :
@@ -315,10 +319,12 @@ def has_default_address(self) -> bool:
315319 return self .address in self .default_addresses
316320
317321 @staticmethod
318- def scan (bus : I2C ) -> list [int ]:
322+ def scan (bus : I2C , target_addresses = None ) -> list [int ]:
319323 addresses = bytearray () # Use 8bit data type
320- # Skip general call address (0x00)
321- for address in range (1 ,128 ):
324+ # General call address (0x00) is skipped in default range
325+ candidates = target_addresses if target_addresses is not None else range (1 ,128 )
326+
327+ for address in candidates :
322328 try :
323329 bus .writeto (address , b'' )
324330 addresses .append (address )
@@ -345,7 +351,7 @@ def available_devices(bus: I2C = None) -> list[Modulino]:
345351 if address == _BOOTLOADER_ADDRESS :
346352 # Skip bootloader address
347353 continue
348- device = Modulino (i2c_bus = bus , address = address )
354+ device = Modulino (i2c_bus = bus , address = address , check_connection = False )
349355 devices .append (device )
350356 return devices
351357
0 commit comments