From bdff8b093aa5e4eccb2f64072aff9f9fec49d1dd Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 24 Oct 2024 13:54:44 +0200 Subject: [PATCH 1/3] Better error handling if I2C device is not found --- src/modulino/modulino.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/modulino/modulino.py b/src/modulino/modulino.py index ecc17ad..0368398 100644 --- a/src/modulino/modulino.py +++ b/src/modulino/modulino.py @@ -104,10 +104,13 @@ def __init__(self, i2c_bus=None, address=None, name=None): else: self.i2c_bus = i2c_bus - self.address = address self.name = name + self.address = address - if self.address == None and len(self.default_addresses) > 0: + if self.address == None: + if len(self.default_addresses) == 0: + raise RuntimeError(f"No default addresses defined for the {self.name} device.") + if self.convert_default_addresses: # Need to convert the 8-bit address to 7-bit actual_addresses = list(map(lambda addr: addr >> 1, self.default_addresses)) @@ -115,6 +118,11 @@ def __init__(self, i2c_bus=None, address=None, name=None): else: self.address = self.discover(self.default_addresses) + if self.address == None: + raise RuntimeError(f"Couldn't find the {self.name} device on the bus. Try resetting the board.") + elif not self.connected: + raise RuntimeError(f"Couldn't find a {self.name} device with address {hex(self.address)} on the bus. Try resetting the board.") + def discover(self, default_addresses): """ Tries to find the given modulino device in the device chain From 387a5b665bca7857365ab692a9a3fdd469969b83 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 24 Oct 2024 13:55:15 +0200 Subject: [PATCH 2/3] Fix pydoc configuration --- pyproject.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index df362e5..c82de07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,12 @@ [[tool.pydoc-markdown.loaders]] type = "python" search_path = [ "./src" ] -packages = ["arduino_nicla_sense_env"] +packages = ["modulino"] + +[[tool.pydoc-markdown.processors]] +type = "filter" +skip_empty_modules = true +expression = "not \"modulino.lib\" in name and default()" [tool.pydoc-markdown.renderer] type = "markdown" From 414d0e88ae01e97f2c3fe646f183839d446dcda8 Mon Sep 17 00:00:00 2001 From: sebromero Date: Thu, 24 Oct 2024 15:05:18 +0000 Subject: [PATCH 3/3] Update documentation --- docs/api.md | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/docs/api.md b/docs/api.md index df6f151..4c55c8f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,3 +1,268 @@ # Summary +* [buttons](#modulino.buttons) + * [ModulinoButtons](#modulino.buttons.ModulinoButtons) + * [default\_long\_press\_duration](#modulino.buttons.ModulinoButtons.default_long_press_duration) + * [update](#modulino.buttons.ModulinoButtons.update) +* [modulino](#modulino.modulino) + * [I2CHelper](#modulino.modulino.I2CHelper) + * [frequency](#modulino.modulino.I2CHelper.frequency) + * [reset\_bus](#modulino.modulino.I2CHelper.reset_bus) + * [find\_interface](#modulino.modulino.I2CHelper.find_interface) + * [Modulino](#modulino.modulino.Modulino) + * [discover](#modulino.modulino.Modulino.discover) + * [\_\_bool\_\_](#modulino.modulino.Modulino.__bool__) + * [connected](#modulino.modulino.Modulino.connected) + * [pin\_strap\_address](#modulino.modulino.Modulino.pin_strap_address) + * [read](#modulino.modulino.Modulino.read) + * [write](#modulino.modulino.Modulino.write) + * [has\_default\_address](#modulino.modulino.Modulino.has_default_address) + * [reset\_bus](#modulino.modulino.Modulino.reset_bus) +* [pixels](#modulino.pixels) + * [ModulinoColor](#modulino.pixels.ModulinoColor) + * [\_\_int\_\_](#modulino.pixels.ModulinoColor.__int__) +* [thermo](#modulino.thermo) + * [ModulinoThermo](#modulino.thermo.ModulinoThermo) + * [measurements](#modulino.thermo.ModulinoThermo.measurements) + * [relative\_humidity](#modulino.thermo.ModulinoThermo.relative_humidity) + * [temperature](#modulino.thermo.ModulinoThermo.temperature) + + + +## class `ModulinoButtons` + +```python +class ModulinoButtons(Modulino) +``` + + + +### `default_long_press_duration` + +1 second + + + +### `update` + +```python +def update() +``` + +Update the button status and call the corresponding callbacks. +Returns True if any of the buttons has changed its state. + + + +## class `I2CHelper` + +```python +class I2CHelper() +``` + +A helper class for interacting with I2C devices on supported boards. + + + +### `frequency` + +Modulinos operate at 100kHz + + + +### `reset_bus` + +```python +@staticmethod +def reset_bus(i2c_bus) +``` + +Resets the I2C bus in case it got stuck. To unblock the bus the SDA line is kept high for 20 clock cycles +Which causes the triggering of a NAK message. + + + +### `find_interface` + +```python +@staticmethod +def find_interface() -> I2C +``` + +Returns an instance of the I2C interface for the current board. + +Raises: + RuntimeError: If the current board is not supported. + +Returns: + I2C: An instance of the I2C interface. + + + +## class `Modulino` + +```python +class Modulino() +``` + + + +### `discover` + +```python +def discover(default_addresses) +``` + +Tries to find the given modulino device in the device chain +based on the pre-defined default addresses. +If the address has been changed to a custom one it won't be found with this function. + + + +### `__bool__` + +```python +def __bool__() +``` + +Boolean cast operator to determine if the given i2c device has a correct address +and if the bus is defined. +In case of auto discovery this also means that the device was found on the bus +because otherwise the address would be None. + + + +### `connected` + +```python +@property +def connected() +``` + +Determines if the given modulino is connected to the i2c bus. + + + +### `pin_strap_address` + +```python +@property +def pin_strap_address() +``` + +Returns the pin strap i2c address of the modulino. +This address is set via resistors on the modulino board. +Since all modulinos generally use the same firmware, the pinstrap address +is needed to determine the type of the modulino at boot time, so it know what to do. +At boot it checks the internal flash in case its address has been overridden by the user +which would take precedence. + + + +### `read` + +```python +def read(amount_of_bytes) +``` + +Reads the given amount of bytes from the i2c device and returns the data. +It skips the first byte which is the pinstrap address. + + + +### `write` + +```python +def write(data_buffer) +``` + +Writes the given buffer to the i2c device. + + + +### `has_default_address` + +```python +@property +def has_default_address() +``` + +Determines if the given modulino has a default address +or if a custom one was set. + + + +### `reset_bus` + +```python +@staticmethod +def reset_bus(i2c_bus) +``` + +Resets the i2c bus. This is useful when the bus is in an unknown state. +The modulinos that are equipped with a micro controller use DMA operations. +If the host board does a reset during such operation it can make the bus get stuck. + +Returns + ---- + I2C: A new i2c bus object after resetting the bus. + + + +## class `ModulinoColor` + +```python +class ModulinoColor() +``` + + + +### `__int__` + +```python +def __int__() +``` + +Return the 32-bit integer representation of the color. + + + +## class `ModulinoThermo` + +```python +class ModulinoThermo(Modulino) +``` + + + +### `measurements` + +```python +@property +def measurements() -> Measurement +``` + +Return Temperature and Relative Humidity or None if the data is stalled + + + +### `relative_humidity` + +```python +@property +def relative_humidity() -> float +``` + +The current relative humidity in % rH + + + +### `temperature` + +```python +@property +def temperature() -> float +``` + +The current temperature in Celsius