It's bad practice to do I/O inside __init__ which should only initialize the class instance.
|
self._card_rev_major = self.bus.read_byte_data(self._hw_address_, I2C_MEM.REVISION_HW_MAJOR_ADD) |
class SM16uout:
"""Python class to control the Sixteen 0-10V Analog Outputs
Args:
stack (int): Stack level/device number.
i2c (int): i2c bus number
"""
def __init__(self, stack=0, i2c=1):
if stack < 0 or stack > data.STACK_LEVEL_MAX:
raise ValueError("Invalid stack level!")
self._hw_address_ = data.SLAVE_OWN_ADDRESS_BASE + stack
self._i2c_bus_no = i2c
self.bus = SMBus(self._i2c_bus_no)
try:
self._card_rev_major = self.bus.read_byte_data(self._hw_address_, I2C_MEM.REVISION_HW_MAJOR_ADD)
self._card_rev_minor = self.bus.read_byte_data(self._hw_address_, I2C_MEM.REVISION_HW_MINOR_ADD)
except Exception:
print("{} not detected!".format(data.CARD_NAME))
raise
This creates a real problem with the hardware, this program doesn't work:
from SM16uout import SM16uout
m = SM16uout()
m.set_led(0, 1)
Traceback (most recent call last):
File "/home/pi/script.py", line 8, in <module>
m.set_led(0, 1)
File "/home/pi/venv/lib/python3.11/site-packages/SM16uout/__init__.py", line 165, in set_led
self._set_byte(I2C_MEM.LED_SET, led)
File "/home/pi/venv/lib/python3.11/site-packages/SM16uout/__init__.py", line 56, in _set_byte
self.bus.write_byte_data(self._hw_address_, address, int(value))
File "/home/pi/venv/lib/python3.11/site-packages/smbus2/smbus2.py", line 457, in write_byte_data
ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 5] Input/output error
It seems that your embedded controller doesn't accept new commands quickly after reading the card rev data, so it's necessary to add a time.sleep(0.1) after creating the SM16uout class.
self._card_rev_major and self._card_rev_minor are not used, I recommend removing them. Or, make a property:
@property
def card_rev(self):
major = self.bus.read_byte_data(self._hw_address_, I2C_MEM.REVISION_HW_MAJOR_ADD)
minor = self.bus.read_byte_data(self._hw_address_, I2C_MEM.REVISION_HW_MINOR_ADD)
return (major, minor)
This way you won't do any I/O unless the user asks for it.
It's bad practice to do I/O inside
__init__which should only initialize the class instance.16uout-rpi/python/SM16uout/__init__.py
Line 26 in 79b443d
This creates a real problem with the hardware, this program doesn't work:
It seems that your embedded controller doesn't accept new commands quickly after reading the card rev data, so it's necessary to add a
time.sleep(0.1)after creating theSM16uoutclass.self._card_rev_majorandself._card_rev_minorare not used, I recommend removing them. Or, make a property:This way you won't do any I/O unless the user asks for it.