From 08d2495bf8844ad2dfbdb465c673c003152da8be Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Fri, 28 Jun 2024 17:25:07 +0200
Subject: [PATCH 01/30] ModulinoDistance: add available() API

available() returns true is the distance is retrieved and is valid; get() returns now the last value read.
---
 src/Modulino.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/Modulino.h b/src/Modulino.h
index 95a406e..0aacfbc 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -412,10 +412,11 @@ class ModulinoDistance : public Module {
   operator bool() {
     return (tof_sensor != nullptr);
   }
-  float get() {
+  bool available() {
     if (tof_sensor == nullptr) {
-      return NAN;
+      return false;
     }
+    float ret = internal;
     uint8_t NewDataReady = 0;
     tof_sensor->VL53L4CD_CheckForDataReady(&NewDataReady);
     if (NewDataReady) {
@@ -423,15 +424,17 @@ class ModulinoDistance : public Module {
       tof_sensor->VL53L4CD_GetResult(&results);
     }
     if (results.range_status == 0) {
-      return results.distance_mm;
+      internal = results.distance_mm;
     } else {
-      return NAN;
+      internal = NAN;
     }
+    return !isnan(internal);
   }
-  bool isValid(float distance) {
-    return !isnan(distance);
+  float get() {
+    return internal;
   }
 private:
   VL53L4CD* tof_sensor = nullptr;
   VL53L4CD_Result_t results;
+  float internal = NAN;
 };
\ No newline at end of file

From 4f15175f16bd4b4f067fdea8cb75f76bd8760c44 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Mon, 8 Jul 2024 09:55:06 +0200
Subject: [PATCH 02/30] ModulinoDistance: fix examples for new API

---
 examples/Modulino_Distance/Basic/Basic.ino                  | 6 ++++--
 .../Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino     | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/examples/Modulino_Distance/Basic/Basic.ino b/examples/Modulino_Distance/Basic/Basic.ino
index 6d4d3e1..eed3bbf 100644
--- a/examples/Modulino_Distance/Basic/Basic.ino
+++ b/examples/Modulino_Distance/Basic/Basic.ino
@@ -9,7 +9,9 @@ void setup() {
 }
 
 void loop() {
-  int measure = distance.get();
-  Serial.println(measure);
+  if (distance.available()) {
+    int measure = distance.get();
+    Serial.println(measure);
+  }
   delay(10);
 }
\ No newline at end of file
diff --git a/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino b/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
index 792c170..bf9ba8d 100644
--- a/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
+++ b/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
@@ -40,7 +40,7 @@ void loop() {
     skip = (skip + 1) % 5;
   }
 
-  pitch = encoder.get() + distance.get();
+  pitch = encoder.get() + (distance.available() ? distance.get() : 0);
 
   if (Serial.available() && Serial.read() == 's') {
     imu.update();

From 3772433d9b119441b7d9801b48fefa6c07524d85 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Mon, 8 Jul 2024 17:07:05 +0200
Subject: [PATCH 03/30] Release 0.4.0

---
 library.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library.properties b/library.properties
index d0cfb87..8d0b1b0 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=Modulino
-version=0.3.0
+version=0.4.0
 author=Arduino
 maintainer=Arduino <info@arduino.cc>
 sentence=Arduino Library for Modulinos

From 25b4c35ba4922f156e7aeab01b65e74c65d5e316 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Tue, 9 Jul 2024 10:41:26 +0200
Subject: [PATCH 04/30] Increase I2C priority if LED Matrix is used

The distance sensor doesn't like to be interrupted in the middle of a transaction.
Changing the priority of the IIC peripheral to be higher than the timer one will prevent it from getting stuck
---
 src/Modulino.cpp | 17 ++++++++++++++++-
 src/Modulino.h   |  7 +++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/Modulino.cpp b/src/Modulino.cpp
index fc74b38..8a2b7e0 100644
--- a/src/Modulino.cpp
+++ b/src/Modulino.cpp
@@ -11,4 +11,19 @@ ModulinoColor RED(255, 0, 0);
 ModulinoColor BLUE(0, 0, 255);
 ModulinoColor GREEN(0, 255, 0);
 ModulinoColor VIOLET(255, 0, 255);
-ModulinoColor WHITE(255, 255, 255);
\ No newline at end of file
+ModulinoColor WHITE(255, 255, 255);
+
+#if __has_include("Arduino_LED_Matrix.h")
+void __increaseI2CPriority() {
+    for (int i = 0; i < 96; i++) {
+        if (R_ICU->IELSR[i] == BSP_PRV_IELS_ENUM(EVENT_IIC0_TXI)) {
+            NVIC_SetPriority(IRQn_Type(i), 6);
+            NVIC_SetPriority(IRQn_Type(i+1), 6);
+            NVIC_SetPriority(IRQn_Type(i+2), 6);
+            NVIC_SetPriority(IRQn_Type(i+3), 6);
+        }
+    }
+}
+#else
+void __increaseI2CPriority() {}
+#endif
\ No newline at end of file
diff --git a/src/Modulino.h b/src/Modulino.h
index 0aacfbc..ee29261 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -14,6 +14,8 @@
 #define HardwareI2C   TwoWire
 #endif
 
+void __increaseI2CPriority();
+
 class ModulinoClass {
 public:
 #ifdef ARDUINO_UNOR4_WIFI
@@ -33,6 +35,7 @@ class ModulinoClass {
     _wire = &wire;
     _wire->begin();
     _wire->setClock(100000);
+    __increaseI2CPriority();
   }
   friend class Module;
 protected:
@@ -298,6 +301,7 @@ class ModulinoMovement : public Module {
       _imu = new LSM6DSOXClass(*((TwoWire*)getWire()), 0x6A);
     }
     initialized = _imu->begin();
+    __increaseI2CPriority();
     return initialized != 0;
   }
   operator bool() {
@@ -331,6 +335,7 @@ class ModulinoThermo: public Module {
       _sensor = new HS300xClass(*((TwoWire*)getWire()));
     }
     initialized = _sensor->begin();
+    __increaseI2CPriority();
     return initialized;
   }
   operator bool() {
@@ -364,6 +369,7 @@ class ModulinoPressure : public Module {
       // unfortunately LPS22HBClass calles Wire.end() on failure, restart it
       getWire()->begin();
     }
+    __increaseI2CPriority();
     return initialized != 0;
   }
   operator bool() {
@@ -400,6 +406,7 @@ class ModulinoDistance : public Module {
     }
     tof_sensor = new VL53L4CD((TwoWire*)getWire(), -1);
     auto ret = tof_sensor->InitSensor();
+    __increaseI2CPriority();
     if (ret == VL53L4CD_ERROR_NONE) {
       tof_sensor->VL53L4CD_SetRangeTiming(20, 0);
       tof_sensor->VL53L4CD_StartRanging();

From f698330b84564bbfe4b7456dca3ee240054649d7 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Tue, 9 Jul 2024 15:50:38 +0200
Subject: [PATCH 05/30] Release 0.4.1

---
 library.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library.properties b/library.properties
index 8d0b1b0..6234a79 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=Modulino
-version=0.4.0
+version=0.4.1
 author=Arduino
 maintainer=Arduino <info@arduino.cc>
 sentence=Arduino Library for Modulinos

From a978cd6f90df29c743598d2ff9dcf055af68939b Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Fri, 19 Jul 2024 12:55:23 +0200
Subject: [PATCH 06/30] Replace vectors in discover() with simple arrays

---
 src/Modulino.h | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/Modulino.h b/src/Modulino.h
index ee29261..565d314 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: MPL-2.0
 
 #include "Wire.h"
-#include <vector>
 #include <vl53l4cd_class.h>  // from stm32duino
 #include "Arduino_LSM6DSOX.h"
 #include <Arduino_LPS22HB.h>
@@ -141,7 +140,7 @@ class ModulinoButtons : public Module {
     return;
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < match.size(); i++) {
+    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -151,7 +150,7 @@ class ModulinoButtons : public Module {
 private:
   bool last_status[3];
 protected:
-  std::vector<uint8_t> match = { 0x7C };  // same as fw main.c
+  uint8_t match[1] = { 0x7C };  // same as fw main.c
 };
 
 class ModulinoBuzzer : public Module {
@@ -170,7 +169,7 @@ class ModulinoBuzzer : public Module {
     write(buf, 8);
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < match.size(); i++) {
+    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -178,7 +177,7 @@ class ModulinoBuzzer : public Module {
     return 0xFF;
   }
 protected:
-  std::vector<uint8_t> match = { 0x3C };  // same as fw main.c
+  uint8_t match[1] = { 0x3C };  // same as fw main.c
 };
 
 class ModulinoColor {
@@ -217,7 +216,7 @@ class ModulinoPixels : public Module {
     write((uint8_t*)data, NUMLEDS * 4);
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < match.size(); i++) {
+    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -228,7 +227,7 @@ class ModulinoPixels : public Module {
   static const int NUMLEDS = 8;
   uint32_t data[NUMLEDS];
 protected:
-  std::vector<uint8_t> match = { 0x6C };
+  uint8_t match[1] = { 0x6C };
 };
 
 
@@ -274,7 +273,7 @@ class ModulinoKnob : public Module {
     return _pressed;
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < match.size(); i++) {
+    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -285,7 +284,7 @@ class ModulinoKnob : public Module {
   bool _pressed = false;
   bool _bug_on_set = false;
 protected:
-  std::vector<uint8_t> match = { 0x74, 0x76 };
+  uint8_t match[2] = { 0x74, 0x76 };
 };
 
 extern ModulinoColor RED;

From fd803c4b1166e75f88625c435693fb56d4a00c7f Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Tue, 3 Sep 2024 13:22:49 +0200
Subject: [PATCH 07/30] distance: allow both VL53L4CD and VL53L4ED

---
 src/Modulino.h | 85 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 12 deletions(-)

diff --git a/src/Modulino.h b/src/Modulino.h
index ee29261..f790346 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -4,6 +4,7 @@
 #include "Wire.h"
 #include <vector>
 #include <vl53l4cd_class.h>  // from stm32duino
+#include <vl53l4ed_class.h>  // from stm32duino
 #include "Arduino_LSM6DSOX.h"
 #include <Arduino_LPS22HB.h>
 #include <Arduino_HS300x.h>
@@ -396,6 +397,52 @@ class ModulinoLight : public Module {
 
 };
 
+class _distance_api {
+public:
+  _distance_api(VL53L4CD* sensor) : sensor(sensor) {
+    isVL53L4CD = true;
+  };
+  _distance_api(VL53L4ED* sensor) : sensor(sensor) {};
+  uint8_t setRangeTiming(uint32_t timing_budget_ms, uint32_t inter_measurement_ms) {
+    if (isVL53L4CD) {
+      return ((VL53L4CD*)sensor)->VL53L4CD_SetRangeTiming(timing_budget_ms, inter_measurement_ms);
+    } else {
+      return ((VL53L4ED*)sensor)->VL53L4ED_SetRangeTiming(timing_budget_ms, inter_measurement_ms);
+    }
+  }
+  uint8_t startRanging() {
+    if (isVL53L4CD) {
+      return ((VL53L4CD*)sensor)->VL53L4CD_StartRanging();
+    } else {
+      return ((VL53L4ED*)sensor)->VL53L4ED_StartRanging();
+    }
+  }
+  uint8_t checkForDataReady(uint8_t* p_is_data_ready) {
+    if (isVL53L4CD) {
+      return ((VL53L4CD*)sensor)->VL53L4CD_CheckForDataReady(p_is_data_ready);
+    } else {
+      return ((VL53L4ED*)sensor)->VL53L4ED_CheckForDataReady(p_is_data_ready);
+    }
+  }
+  uint8_t clearInterrupt() {
+    if (isVL53L4CD) {
+      return ((VL53L4CD*)sensor)->VL53L4CD_ClearInterrupt();
+    } else {
+      return ((VL53L4ED*)sensor)->VL53L4ED_ClearInterrupt();
+    }
+  }
+  uint8_t getResult(void* result) {
+    if (isVL53L4CD) {
+      return ((VL53L4CD*)sensor)->VL53L4CD_GetResult((VL53L4CD_Result_t*)result);
+    } else {
+      return ((VL53L4ED*)sensor)->VL53L4ED_GetResult((VL53L4ED_ResultsData_t*)result);
+    }
+  }
+private:
+  void* sensor;
+  bool isVL53L4CD = false;
+};
+
 class ModulinoDistance : public Module {
 public:
   bool begin() {
@@ -406,29 +453,40 @@ class ModulinoDistance : public Module {
     }
     tof_sensor = new VL53L4CD((TwoWire*)getWire(), -1);
     auto ret = tof_sensor->InitSensor();
-    __increaseI2CPriority();
-    if (ret == VL53L4CD_ERROR_NONE) {
-      tof_sensor->VL53L4CD_SetRangeTiming(20, 0);
-      tof_sensor->VL53L4CD_StartRanging();
-      return true;
-    } else {
+    if (ret != VL53L4CD_ERROR_NONE) {
+      delete tof_sensor;
       tof_sensor = nullptr;
-      return false;
+      tof_sensor_alt = new VL53L4ED((TwoWire*)getWire(), -1);
+      ret = tof_sensor_alt->InitSensor();
+      if (ret == VL53L4ED_ERROR_NONE) {
+        api = new _distance_api(tof_sensor_alt);
+      } else {
+        delete tof_sensor_alt;
+        tof_sensor_alt = nullptr;
+        return false;
+      }
+    } else {
+      api = new _distance_api(tof_sensor);
     }
+
+    __increaseI2CPriority();
+    api->setRangeTiming(20, 0);
+    api->startRanging();
+    return true;
   }
   operator bool() {
-    return (tof_sensor != nullptr);
+    return (api != nullptr);
   }
   bool available() {
-    if (tof_sensor == nullptr) {
+    if (api == nullptr) {
       return false;
     }
     float ret = internal;
     uint8_t NewDataReady = 0;
-    tof_sensor->VL53L4CD_CheckForDataReady(&NewDataReady);
+    api->checkForDataReady(&NewDataReady);
     if (NewDataReady) {
-      tof_sensor->VL53L4CD_ClearInterrupt();
-      tof_sensor->VL53L4CD_GetResult(&results);
+      api->clearInterrupt();
+      api->getResult(&results);
     }
     if (results.range_status == 0) {
       internal = results.distance_mm;
@@ -442,6 +500,9 @@ class ModulinoDistance : public Module {
   }
 private:
   VL53L4CD* tof_sensor = nullptr;
+  VL53L4ED* tof_sensor_alt = nullptr;
   VL53L4CD_Result_t results;
+  //VL53L4ED_ResultsData_t results;
   float internal = NAN;
+  _distance_api* api = nullptr;
 };
\ No newline at end of file

From b7a2d495a2b3ed1061f9b588eb8d0329caa08d95 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Tue, 3 Sep 2024 14:35:42 +0200
Subject: [PATCH 08/30] gh: add new dependency

---
 .github/workflows/compile-examples.yml | 1 +
 library.properties                     | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 7c9ed7c..c058661 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -47,6 +47,7 @@ jobs:
             - source-path: ./
             # Install library dependencies.
             - name: STM32duino VL53L4CD
+            - name: STM32duino VL53L4ED
             - name: Arduino_LSM6DSOX
             - name: Arduino_LPS22HB
             - name: Arduino_HS300x
diff --git a/library.properties b/library.properties
index 6234a79..3141f03 100644
--- a/library.properties
+++ b/library.properties
@@ -8,4 +8,4 @@ category=Communication
 url=https://github.com/arduino-libraries/Modulino
 architectures=*
 includes=Modulino.h
-depends=STM32duino VL53L4CD,Arduino_LSM6DSOX,Arduino_LPS22HB,Arduino_HS300x
+depends=STM32duino VL53L4CD,STM32duino VL53L4ED,Arduino_LSM6DSOX,Arduino_LPS22HB,Arduino_HS300x

From a61a49188120213a78577ca254fdc296bff37f94 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Tue, 3 Sep 2024 17:47:38 +0200
Subject: [PATCH 09/30] Release 0.4.2

---
 library.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library.properties b/library.properties
index 3141f03..5ba88fa 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=Modulino
-version=0.4.1
+version=0.4.2
 author=Arduino
 maintainer=Arduino <info@arduino.cc>
 sentence=Arduino Library for Modulinos

From 47828b2100a013bafca01153672434c5844a1090 Mon Sep 17 00:00:00 2001
From: maidnl <d.aimo@arduino.cc>
Date: Thu, 3 Oct 2024 12:16:04 +0200
Subject: [PATCH 10/30] removed compilation warnings

---
 src/Modulino.h | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/Modulino.h b/src/Modulino.h
index fbda065..cfe420b 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -46,8 +46,9 @@ extern ModulinoClass Modulino;
 
 class Module : public Printable {
 public:
-  Module(uint8_t address = 0xFF, char* name = "")
-    : address(address), name(name) {}
+  Module(uint8_t address = 0xFF, const char* name = "")
+    : address(address), name((char *)name) {}
+  virtual ~Module() {}  
   bool begin() {
     if (address == 0xFF) {
       address = discover() / 2;  // divide by 2 to match address in fw main.c
@@ -141,7 +142,7 @@ class ModulinoButtons : public Module {
     return;
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
+    for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -170,7 +171,7 @@ class ModulinoBuzzer : public Module {
     write(buf, 8);
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
+    for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -217,7 +218,7 @@ class ModulinoPixels : public Module {
     write((uint8_t*)data, NUMLEDS * 4);
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
+    for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -274,7 +275,7 @@ class ModulinoKnob : public Module {
     return _pressed;
   }
   virtual uint8_t discover() {
-    for (int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
+    for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
         return match[i];
       }
@@ -480,7 +481,7 @@ class ModulinoDistance : public Module {
     if (api == nullptr) {
       return false;
     }
-    float ret = internal;
+    
     uint8_t NewDataReady = 0;
     api->checkForDataReady(&NewDataReady);
     if (NewDataReady) {
@@ -504,4 +505,4 @@ class ModulinoDistance : public Module {
   //VL53L4ED_ResultsData_t results;
   float internal = NAN;
   _distance_api* api = nullptr;
-};
\ No newline at end of file
+};

From 8bf849563d4144ea3e5829533a3de9541ec05319 Mon Sep 17 00:00:00 2001
From: seaxwi <71350948+seaxwi@users.noreply.github.com>
Date: Mon, 4 Nov 2024 13:58:17 +0100
Subject: [PATCH 11/30] Add ArduinoGraphics as a library dependency

---
 library.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library.properties b/library.properties
index 5ba88fa..aa67d58 100644
--- a/library.properties
+++ b/library.properties
@@ -8,4 +8,4 @@ category=Communication
 url=https://github.com/arduino-libraries/Modulino
 architectures=*
 includes=Modulino.h
-depends=STM32duino VL53L4CD,STM32duino VL53L4ED,Arduino_LSM6DSOX,Arduino_LPS22HB,Arduino_HS300x
+depends=STM32duino VL53L4CD,STM32duino VL53L4ED,Arduino_LSM6DSOX,Arduino_LPS22HB,Arduino_HS300x,ArduinoGraphics

From e5f48a6502e4a8f0b7617bf3cf353f266f55a5c1 Mon Sep 17 00:00:00 2001
From: Eli Tayrien <EliTayrien@users.noreply.github.com>
Date: Tue, 12 Nov 2024 15:34:15 -0800
Subject: [PATCH 12/30] Add #include guard around Modulino.h

My project currently cannot include modulino.h from two source files. An include guard could resolve this issue.
---
 src/Modulino.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/Modulino.h b/src/Modulino.h
index cfe420b..c4aa73c 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -1,3 +1,6 @@
+#ifndef ARDUINO_LIBRARIES_MODULINO_H
+#define ARDUINO_LIBRARIES_MODULINO_H
+
 // Copyright (c) 2024 Arduino SA
 // SPDX-License-Identifier: MPL-2.0
 
@@ -506,3 +509,5 @@ class ModulinoDistance : public Module {
   float internal = NAN;
   _distance_api* api = nullptr;
 };
+
+#endif

From f3ce8fdb3077ec5cd90a5ae1dbf94b241f7b3f66 Mon Sep 17 00:00:00 2001
From: d-le0 <113344476+d-le0@users.noreply.github.com>
Date: Thu, 6 Feb 2025 12:59:41 +0100
Subject: [PATCH 13/30] Fix on begin() addr check Modulino.h

---
 src/Modulino.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Modulino.h b/src/Modulino.h
index cfe420b..da4dedf 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -50,7 +50,7 @@ class Module : public Printable {
     : address(address), name((char *)name) {}
   virtual ~Module() {}  
   bool begin() {
-    if (address == 0xFF) {
+    if (address >= 0x7F) {
       address = discover() / 2;  // divide by 2 to match address in fw main.c
     }
     return (address < 0x7F);

From feef4264ef12fe9e54a89c5f3893a9a113b91f6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Marqu=C3=ADnez=20Ferr=C3=A1ndiz?=
 <11246294+marqdevx@users.noreply.github.com>
Date: Mon, 17 Feb 2025 15:21:38 +0100
Subject: [PATCH 14/30] Firmware updater: use led matrix only on UNO R4 (#23)

---
 examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino b/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino
index 166d44b..0cabe5d 100644
--- a/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino
+++ b/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino
@@ -1,5 +1,7 @@
+#if defined(ARDUINO_UNOWIFIR4) 
 #include "ArduinoGraphics.h"
 #include "Arduino_LED_Matrix.h"
+#endif
 
 #include "Modulino.h"
 #include "Wire.h"
@@ -20,11 +22,14 @@ void setup() {
   }
 
   auto result = flash(node_base_bin, node_base_bin_len);
+  
+  #if defined(ARDUINO_UNOWIFIR4)
   if (result) {
     matrixInitAndDraw("PASS");
   } else {
     matrixInitAndDraw("FAIL");
   }
+  #endif
 }
 
 void loop() {
@@ -53,6 +58,7 @@ class SerialVerbose {
     bool _verbose;
 };
 
+#if defined(ARDUINO_UNOWIFIR4)
 ArduinoLEDMatrix matrix;
 
 void matrixInitAndDraw(char* text) {
@@ -67,6 +73,7 @@ void matrixInitAndDraw(char* text) {
 
   matrix.endDraw();
 }
+#endif
 
 bool flash(const uint8_t* binary, size_t lenght, bool verbose) {
 

From 610427b80041ab860d5a62e4197c45572af32867 Mon Sep 17 00:00:00 2001
From: Leonardo Cavagnis <l.cavagnis@arduino.cc>
Date: Thu, 20 Feb 2025 15:05:02 +0100
Subject: [PATCH 15/30] add available() function for Modulino Movement (query
 if new acceleration data from the modulino is available)

---
 src/Modulino.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/Modulino.h b/src/Modulino.h
index 41fa945..128c46d 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -317,6 +317,12 @@ class ModulinoMovement : public Module {
     }
     return 0;
   }
+  int available() {
+    if (initialized) {
+      return _imu->accelerationAvailable();
+    }
+    return 0;
+  }
   float getX() {
     return x;
   }

From d5de8d9b6c7e85140d5b3a9bfe68e9d071cab44d Mon Sep 17 00:00:00 2001
From: Leonardo Cavagnis <45899760+leonardocavagnis@users.noreply.github.com>
Date: Tue, 4 Mar 2025 12:06:41 +0100
Subject: [PATCH 16/30] Bump the library version to 0.4.3

---
 library.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library.properties b/library.properties
index aa67d58..7e1d04b 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=Modulino
-version=0.4.2
+version=0.4.3
 author=Arduino
 maintainer=Arduino <info@arduino.cc>
 sentence=Arduino Library for Modulinos

From abfb36326713aa203ef3faff27bc5f83d1795437 Mon Sep 17 00:00:00 2001
From: Leonardo Cavagnis <l.cavagnis@arduino.cc>
Date: Mon, 17 Mar 2025 11:54:44 +0100
Subject: [PATCH 17/30] add documentation: readme.md, docs/readme.md,
 docs/api.md

---
 README.md                                     |  13 ++
 docs/api.md                                   | 177 +++++++++++++++++
 docs/images/modulino-buttons.jpeg             | Bin 0 -> 187508 bytes
 docs/images/modulino-buzzer.jpg               | Bin 0 -> 171601 bytes
 docs/images/modulino-distance.jpg             | Bin 0 -> 139900 bytes
 docs/images/modulino-knob.jpg                 | Bin 0 -> 160236 bytes
 docs/images/modulino-movement.jpg             | Bin 0 -> 162278 bytes
 docs/images/modulino-pixels.jpg               | Bin 0 -> 179368 bytes
 docs/images/modulino-thermo.jpg               | Bin 0 -> 147692 bytes
 docs/readme.md                                | 181 ++++++++++++++++++
 examples/Modulino_Buttons/Basic/Basic.ino     |   8 +
 .../Button2Integration/Button2Integration.ino |   9 +-
 examples/Modulino_Buzzer/Basic/Basic.ino      |   8 +
 .../Simple_melody/Simple_melody.ino           |   8 +
 examples/Modulino_Distance/Basic/Basic.ino    |   8 +
 examples/Modulino_Knob/Basic/Basic.ino        |   8 +
 .../EncoderSetter/EncoderSetter.ino           |   8 +
 examples/Modulino_Movement/Basic/Basic.ino    |   8 +
 examples/Modulino_Pixels/Basic/Basic.ino      |   8 +
 .../Simple_Animation/Simple_Animation.ino     |   8 +
 examples/Modulino_Thermo/Basic/Basic.ino      |   8 +
 .../TemperatureHumidityMatrix.ino             |   8 +
 .../AddressChanger/AddressChanger.ino         |   8 +
 .../FirmwareUpdater/FirmwareUpdater.ino       |   8 +
 .../Modulino_PlugNPlay/Modulino_PlugNPlay.ino |   8 +
 src/Modulino.cpp                              |   2 +-
 src/Modulino.h                                |   6 +-
 27 files changed, 495 insertions(+), 5 deletions(-)
 create mode 100644 README.md
 create mode 100644 docs/api.md
 create mode 100644 docs/images/modulino-buttons.jpeg
 create mode 100644 docs/images/modulino-buzzer.jpg
 create mode 100644 docs/images/modulino-distance.jpg
 create mode 100644 docs/images/modulino-knob.jpg
 create mode 100644 docs/images/modulino-movement.jpg
 create mode 100644 docs/images/modulino-pixels.jpg
 create mode 100644 docs/images/modulino-thermo.jpg
 create mode 100644 docs/readme.md

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..45f68f1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# 🧩 Arduino Modulino® Library
+
+The Arduino Modulino® Library simplifies the integration and management of Modulino® modules on Arduino boards. 
+
+A Modulino® is a compact, modular electronic device that connects easily to Arduino via the Qwiic connector and communicates using the I2C (`Wire`) protocol. These modules include sensors, actuators, and more.
+
+📖 For more information about this library please read the documentation [here](./docs/).
+
+## Hardware Compatibility
+This library is compatible with all Arduino boards that feature an I2C interface (`Wire`).
+
+## Support and Contributions
+If you find this library helpful, consider supporting us through [donations](https://www.arduino.cc/en/donate/), [sponsorship](https://github.com/sponsors/arduino) or check out our [store](https://store.arduino.cc/).
\ No newline at end of file
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 0000000..5ced974
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,177 @@
+# Arduino Modulino Library API
+
+## Summary
+
+ Members                                    | Descriptions
+--------------------------------------------|------------------------------------------
+| `class` [`ModulinoClass`](#modulinoclass) | The base class for all Modulino components, providing essential functionality and structure for all subsequent Modulino modules.                                  |
+| `class` [`ModulinoButtons`](#modulinobuttons) | Handles the functionality of Modulino Buttons, enabling detection of presses and handling input events.                                                |
+| `class` [`ModulinoBuzzer`](#modulinobuttons) |Handles the functionality of Modulino Buzzer, enabling the sound generation for feedback or alerts.                                                    |
+| `class` [`ModulinoPixels`](#modulinopixels) | Handles the functionality of Modulino Pixels, managing LEDs strip color, status and brightness.                                          |
+| `class` [`ModulinoKnob`](#modulinoknob) | Handles the functionality of Modulino Knob, interfacing with the rotary knob position.                                                     |
+| `class` [`ModulinoMovement`](#modulinomovement) | Handles the functionality of Modulino Movement,interfacing with the IMU sensor to get acceleration readings. |
+| `class` [`ModulinoThermo`](#modulinothermo) | Handles the functionality of Modulino Thermo, managing temperature sensors to provide real-time temperature and humidity readings.                                |
+| `class` [`ModulinoDistance`](#modulinodistance) | Handles the functionality of Modulino Distance, enabling distance measurement using ToF (Time-of-Flight) sensors for precise range detection. |
+
+### ModulinoClass
+
+The `ModulinoClass` is the main class that handles the initialization of the I2C communication bus.
+
+#### Methods
+
+- **`void begin(HardwareI2C& wire = Wire)`**  
+  Initializes the I2C communication. The default I2C bus is `Wire`, but you can specify another one (e.g., `Wire1`).
+
+---
+
+### ModulinoButtons
+
+Represents a Modulino Buttons module.
+
+#### Methods
+
+- **`PinStatus isPressed(int index)`**  
+  Returns the press status (HIGH/LOW) of the button at the specified index (_0-A, 1-B, 2-C_).
+
+- **`bool update()`**  
+  Updates the button status. Returns `true` if the status has changed, `false` otherwise.
+
+- **`void setLeds(bool a, bool b, bool c)`**  
+  Sets the LED states. Each argument corresponds to one LED's state (on/off).
+
+---
+
+### ModulinoBuzzer
+
+Represents a Modulino Buzzer module.
+
+#### Methods
+
+- **`void tone(size_t freq, size_t len_ms)`**  
+  Plays a tone at the specified frequency (`freq`) and duration (`len_ms`).
+
+- **`void noTone()`**  
+  Stops any tone currently playing.
+
+---
+
+### ModulinoPixels
+
+Represents a Modulino Pixels module.
+
+#### Methods
+
+- **`void set(int idx, ModulinoColor rgb, uint8_t brightness = 25)`**  
+  Sets the color of the LED at the specified index.
+
+- **`void set(int idx, uint8_t r, uint8_t g, uint8_t b, uint8_t brightness = 5)`**  
+  Sets the color of the LED at the specified index using RGB values.
+
+- **`void clear(int idx)`**  
+  Clears the LED at the specified index (turns it off).
+
+- **`void clear()`**  
+  Clears all LEDs (turns them all off).
+
+- **`void show()`**  
+  Updates the LEDs to display the current color data.
+
+---
+
+### ModulinoKnob
+
+Represents a Modulino Knob module.
+
+#### Methods
+
+- **`int16_t get()`**  
+  Gets the current value of the knob.
+
+- **`bool isPressed()`**  
+  Returns `true` if the button on the knob is pressed, `false` otherwise.
+
+- **`void set(int16_t value)`**  
+  Sets the knob value.
+
+---
+
+### ModulinoMovement
+
+Represents a Modulino Movement module.
+
+#### Methods
+
+- **`int update()`**  
+  Updates the sensor data and reads the acceleration values.
+
+- **`int available()`**  
+  Returns `true` if acceleration data is available.
+
+- **`float getX()`**  
+  Returns the X-axis acceleration.
+
+- **`float getY()`**  
+  Returns the Y-axis acceleration.
+
+- **`float getZ()`**  
+  Returns the Z-axis acceleration.
+
+---
+
+### ModulinoThermo
+
+Represents a Modulino Thermo module.
+
+#### Methods
+
+- **`float getHumidity()`**  
+  Returns the humidity reading.
+
+- **`float getTemperature()`**  
+  Returns the temperature reading.
+
+---
+
+### ModulinoDistance
+
+Represents a Modulino Distance module.
+
+#### Methods
+
+- **`available()`**  
+  Checks if new distance data is available from the sensor. If data is ready, it reads the data and updates the distance value.  
+  `true` if distance data is available, `false` if distance data is not available.
+
+- **`float get()`**  
+  Returns the distance measured by the sensor in millimeters.  
+  The measured distance in millimeters if available, `NAN` if the distance reading is invalid.
+
+## Constants
+
+- **`ModulinoColor RED`**  
+  Represents the color red for Modulino Pixels modules.
+
+- **`ModulinoColor BLUE`**  
+  Represents the color blue for Modulino Pixels modules.
+
+- **`ModulinoColor GREEN`**  
+  Represents the color green for Modulino Pixels modules.
+
+- **`ModulinoColor VIOLET`**  
+  Represents the color violet for Modulino Pixels modules.
+
+- **`ModulinoColor WHITE`**  
+  Represents the color white for Modulino Pixels modules.
+
+### ModulinoColor
+
+Represents a color for Modulino Pixels modules.
+
+#### Constructor
+
+- **`ModulinoColor(uint8_t r, uint8_t g, uint8_t b)`**  
+  Creates a color with the specified red (`r`), green (`g`), and blue (`b`) components.
+
+## License
+
+This library is released under the [MPL-2.0 license](../LICENSE).
\ No newline at end of file
diff --git a/docs/images/modulino-buttons.jpeg b/docs/images/modulino-buttons.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..229e68c86b0260589eb4ad9e42827278de0e55db
GIT binary patch
diff --git a/docs/images/modulino-buzzer.jpg b/docs/images/modulino-buzzer.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fb9a730567042fa3afbc0b3f1d55e0ba28fbd712
GIT binary patch
diff --git a/docs/images/modulino-distance.jpg b/docs/images/modulino-distance.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..806734a9da0c25ced8705caa882b047ee4e702a4
GIT binary patch
diff --git a/docs/images/modulino-knob.jpg b/docs/images/modulino-knob.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6c68a16b4dce06bdfadc94518e43846e3b78a148
GIT binary patch
diff --git a/docs/images/modulino-movement.jpg b/docs/images/modulino-movement.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..97d0d2dd9bb4082b3429672b2cc1708a5b2046b0
GIT binary patch
diff --git a/docs/images/modulino-pixels.jpg b/docs/images/modulino-pixels.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..8140a101065495054b93989a7b7bb23d843789e8
GIT binary patch
diff --git a/docs/images/modulino-thermo.jpg b/docs/images/modulino-thermo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b5158d6e6b59cd7a78c883e6d0e50b269a21e7aa
GIT binary patch
diff --git a/docs/readme.md b/docs/readme.md
new file mode 100644
index 0000000..9c59418
--- /dev/null
+++ b/docs/readme.md
@@ -0,0 +1,181 @@
+# Arduino Modulino® Library
+
+The **Modulino** library is designed to simplify integration with various Modulino. It supports a variety of modules, such as motion sensors, buttons, buzzers, LED displays, and more, all through an I2C (`Wire`) interface.
+
+## Hardware Compatibility
+
+The library is compatible with Arduino boards that support I2C (`Wire`) communication.
+
+Each Modulino has a fixed I2C address assigned by default. If you wish to change the I2C address, you can refer to the [Utilities](#utilities) section.
+
+## Main Features
+
+The **Modulino** library supports the following hardware modules:
+
+- **Buttons (`ModulinoButtons`)**: Read the state of buttons and control the associated LEDs.
+- **Buzzer (`ModulinoBuzzer`)**: Activate and deactivate the buzzer and set its frequency.
+- **LEDs (`ModulinoPixels`)**: Control RGB LEDs with customizable display modes.
+- **Knob (`ModulinoKnob`)**: Read the value of a rotary encoder.
+- **Motion (`ModulinoMovement`)**: Interface with the LSM6DSOX IMU sensor to get acceleration values.
+- **Temperature & Humidity (`ModulinoThermo`)**: Get temperature and humidity readings from the HS300x sensor.
+- **Distance (`ModulinoDistance`)**: Measures distance using a Time-of-Flight (ToF) sensor (VL53L0x).
+
+## Library Initialization
+
+To initialize the **Modulino** library, include the header file and call the `begin()` method. This will set up the I2C communication and prepare the library for use with the modules.
+
+```cpp
+#include <Modulino.h>
+Modulino.begin();  // Initialize the Modulino library
+```
+
+## Supported Modules
+
+You can initialize a Modulino board easily. The basic setup requires just a call to the `begin()` method for each module. For example:
+
+```cpp
+ModulinoType modulino_name;
+modulino_name.begin();  // Initialize the ModulinoType module
+```
+
+### ModulinoButtons
+Manages the state of three buttons and controls their associated LED states. You can read the state of each button and send commands to turn the LEDs on/off.
+
+![Modulino Buttons](./images/modulino-buttons.jpg)
+
+```cpp
+ModulinoButtons buttons;
+buttons.begin();
+buttons.setLeds(true, false, true);  // Turn on LED 1 and LED 3
+```
+
+### ModulinoBuzzer
+Allows you to emit sounds through the buzzer. You can set the frequency and duration of the sound.
+
+![Modulino Buzzer](./images/modulino-buzzer.jpg)
+
+```cpp
+ModulinoBuzzer buzzer;
+buzzer.begin();
+buzzer.tone(440, 1000);  // 440Hz frequency for 1000ms
+```
+
+### ModulinoPixels
+Controls an array of 8 RGB LEDs, allowing you to set the colors and brightness. You can also clear individual LEDs or the entire array.
+
+![Modulino Pixels](./images/modulino-pixels.jpg)
+
+```cpp
+ModulinoPixels leds;
+leds.set(0, ModulinoColor(255, 0, 0));  // Set the first LED (Position: 0) to red
+leds.show();  // Display the LEDs
+```
+
+### ModulinoKnob
+Manages a rotary encoder, allowing you to read the potentiometer value and check if the knob is pressed.
+
+![Modulino Knob](./images/modulino-knob.jpg)
+
+```cpp
+ModulinoKnob knob;
+knob.begin();
+int16_t value = knob.get();  // Get the value of the encoder
+```
+
+###  ModulinoMovement
+Interfaces with the LSM6DSOX IMU sensor to get acceleration readings.
+
+![Modulino Movement](./images/modulino-movement.jpg)
+
+```cpp
+ModulinoMovement movement;
+movement.begin();
+float x = movement.getX();
+```
+
+### ModulinoThermo
+Reads temperature and humidity data from the HS300x sensor.
+
+![Modulino Thermo](./images/modulino-thermo.jpg)
+
+```cpp
+ModulinoThermo thermo;
+thermo.begin();
+float temperature = thermo.getTemperature();
+float humidity = thermo.getHumidity();
+```
+
+### ModulinoDistance
+Measures distance using a ToF (Time-of-Flight) sensor.
+
+![Modulino Distance](./images/modulino-distance.jpg)
+
+```cpp
+ModulinoDistance distance;
+distance.begin();
+float distanceValue = distance.get();
+```
+
+## Example Usage
+
+Here’s an example of how to use some Modulino in a program:
+
+```cpp
+// This sketch demonstrates how to use the Modulino library to control buttons, LEDs, and a buzzer.
+// It listens for a button press (Button A), turns on the LED 0, and plays a sound through the buzzer when pressed.
+
+#include <Modulino.h>
+
+ModulinoButtons buttons;  // Declare a Buttons Modulino
+ModulinoPixels leds;      // Declare a Pixels Modulino
+ModulinoBuzzer buzzer;    // Declare a Buzzer Modulino
+
+int frequency = 440;      // Set frequency to 440Hz
+int duration = 1000;      // Set duration to 1000ms
+
+void setup() {
+  Serial.begin(9600);
+
+  Modulino.begin();        // Initialize the Modulino library
+
+  buttons.begin();         // Initialize the Buttons module
+  leds.begin();            // Initialize the Pixels module
+  buzzer.begin();          // Initialize the Buzzer module
+}
+
+void loop() {
+  if (buttons.update()) {  // Update the button states
+    if (buttons.isPressed(0)) {  // Check if Button A (button 0) is pressed
+      Serial.println("Button A pressed!");
+      leds.set(0, RED);  // Turn on LED 0 to red
+      leds.show();
+
+      buzzer.tone(frequency, duration);  // Play buzzer sound with the specified frequency and duration
+      delay(duration);
+    } else {
+      leds.clear(0); // Turn off LED 0
+      leds.show();
+    }
+  }
+}
+```
+
+## Examples
+
+The examples folder is organized by Modulino type. Each module has its own folder with example sketches that demonstrate both basic and advanced usage (where applicable).
+
+You can explore the examples [here](../examples).
+
+### Utilities
+
+In the [Utilities](../examples/Utilities) folder, you will find programs designed to help you manage and manipulate the Modulino:
+
+- [AddressChanger](../examples/Utilities/AddressChanger/): This program allows you to change the I2C address of a Modulino module. It’s helpful when you need to reassign addresses to avoid conflicts or organize your I2C network.
+
+## API
+
+The API documentation can be found [here](./api.md).
+
+## License
+
+This library is released under the [MPL-2.0 license](../LICENSE).
\ No newline at end of file
diff --git a/examples/Modulino_Buttons/Basic/Basic.ino b/examples/Modulino_Buttons/Basic/Basic.ino
index c40209b..5145f02 100644
--- a/examples/Modulino_Buttons/Basic/Basic.ino
+++ b/examples/Modulino_Buttons/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Buttons - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 ModulinoButtons buttons;
diff --git a/examples/Modulino_Buttons/Button2Integration/Button2Integration.ino b/examples/Modulino_Buttons/Button2Integration/Button2Integration.ino
index 883bb6c..9f092c0 100644
--- a/examples/Modulino_Buttons/Button2Integration/Button2Integration.ino
+++ b/examples/Modulino_Buttons/Button2Integration/Button2Integration.ino
@@ -1,4 +1,11 @@
-// Integration with https://github.com/LennartHennigs/Button2
+/*
+ * Modulino Buttons - Button2 Integration
+ * Integration with https://github.com/LennartHennigs/Button2
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
 
 #include "Modulino.h"
 #include "Button2.h"
diff --git a/examples/Modulino_Buzzer/Basic/Basic.ino b/examples/Modulino_Buzzer/Basic/Basic.ino
index b66e419..a254115 100644
--- a/examples/Modulino_Buzzer/Basic/Basic.ino
+++ b/examples/Modulino_Buzzer/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Buzzer - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 ModulinoBuzzer buzzer;
diff --git a/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino b/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino
index 25c01cf..fbff626 100644
--- a/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino
+++ b/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Buzzer - Simple melody
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 ModulinoBuzzer buzzer;
diff --git a/examples/Modulino_Distance/Basic/Basic.ino b/examples/Modulino_Distance/Basic/Basic.ino
index eed3bbf..a9622bd 100644
--- a/examples/Modulino_Distance/Basic/Basic.ino
+++ b/examples/Modulino_Distance/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Distance - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include "Modulino.h"
 
 ModulinoDistance distance;
diff --git a/examples/Modulino_Knob/Basic/Basic.ino b/examples/Modulino_Knob/Basic/Basic.ino
index 879c940..1272a60 100644
--- a/examples/Modulino_Knob/Basic/Basic.ino
+++ b/examples/Modulino_Knob/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Knob - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 ModulinoKnob knob;
diff --git a/examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino b/examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino
index f130a63..8d6299b 100644
--- a/examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino
+++ b/examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Knob - Encoder Setter
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include "Modulino.h"
 
 ModulinoKnob encoder;
diff --git a/examples/Modulino_Movement/Basic/Basic.ino b/examples/Modulino_Movement/Basic/Basic.ino
index 956ae54..4b0c06e 100644
--- a/examples/Modulino_Movement/Basic/Basic.ino
+++ b/examples/Modulino_Movement/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Movement - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include "Modulino.h"
 
 ModulinoMovement movement;
diff --git a/examples/Modulino_Pixels/Basic/Basic.ino b/examples/Modulino_Pixels/Basic/Basic.ino
index 88099a5..63b2fc6 100644
--- a/examples/Modulino_Pixels/Basic/Basic.ino
+++ b/examples/Modulino_Pixels/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Pixels - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 ModulinoPixels leds;
diff --git a/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino b/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino
index addec14..39d7ede 100644
--- a/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino
+++ b/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Pixels - Simple Animation
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 ModulinoPixels leds;
diff --git a/examples/Modulino_Thermo/Basic/Basic.ino b/examples/Modulino_Thermo/Basic/Basic.ino
index 74894c2..e98afd5 100644
--- a/examples/Modulino_Thermo/Basic/Basic.ino
+++ b/examples/Modulino_Thermo/Basic/Basic.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Thermo - Basic
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include <Modulino.h>
 
 // Create object instance
diff --git a/examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino b/examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino
index 20335f3..eab6001 100644
--- a/examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino
+++ b/examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino Thermo - Temperature Humidity Matrix
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include "Modulino.h"
 #include "ArduinoGraphics.h"
 #include "Arduino_LED_Matrix.h"
diff --git a/examples/Utilities/AddressChanger/AddressChanger.ino b/examples/Utilities/AddressChanger/AddressChanger.ino
index 3081be1..abe4181 100644
--- a/examples/Utilities/AddressChanger/AddressChanger.ino
+++ b/examples/Utilities/AddressChanger/AddressChanger.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino - Address Changer
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include "Wire.h"
 
 // Setting new_address to 0 means that the module will get back its original address
diff --git a/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino b/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino
index 0cabe5d..3d6068a 100644
--- a/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino
+++ b/examples/Utilities/FirmwareUpdater/FirmwareUpdater.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino - Firmware Updater
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #if defined(ARDUINO_UNOWIFIR4) 
 #include "ArduinoGraphics.h"
 #include "Arduino_LED_Matrix.h"
diff --git a/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino b/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
index bf9ba8d..60368a3 100644
--- a/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
+++ b/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
@@ -1,3 +1,11 @@
+/*
+ * Modulino - Plug and Play
+ *
+ * This example code is in the public domain. 
+ * Copyright (c) 2025 Arduino
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
 #include "Modulino.h"
 
 ModulinoButtons buttons;
diff --git a/src/Modulino.cpp b/src/Modulino.cpp
index 8a2b7e0..9c3ef2c 100644
--- a/src/Modulino.cpp
+++ b/src/Modulino.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 Arduino SA
+// Copyright (c) 2025 Arduino SA
 // SPDX-License-Identifier: MPL-2.0
 
 #include "Modulino.h"
diff --git a/src/Modulino.h b/src/Modulino.h
index 128c46d..aa259da 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -1,9 +1,9 @@
+// Copyright (c) 2025 Arduino SA
+// SPDX-License-Identifier: MPL-2.0
+
 #ifndef ARDUINO_LIBRARIES_MODULINO_H
 #define ARDUINO_LIBRARIES_MODULINO_H
 
-// Copyright (c) 2024 Arduino SA
-// SPDX-License-Identifier: MPL-2.0
-
 #include "Wire.h"
 #include <vl53l4cd_class.h>  // from stm32duino
 #include <vl53l4ed_class.h>  // from stm32duino

From 5c5ecc322b97a419231c047454cb83e8471f5f66 Mon Sep 17 00:00:00 2001
From: Leonardo Cavagnis <45899760+leonardocavagnis@users.noreply.github.com>
Date: Wed, 19 Mar 2025 10:35:08 +0100
Subject: [PATCH 18/30] Update readme.md: fix modulino buttons img

---
 docs/readme.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/readme.md b/docs/readme.md
index 9c59418..de7bc45 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -41,7 +41,7 @@ modulino_name.begin();  // Initialize the ModulinoType module
 ### ModulinoButtons
 Manages the state of three buttons and controls their associated LED states. You can read the state of each button and send commands to turn the LEDs on/off.
 
-![Modulino Buttons](./images/modulino-buttons.jpg)
+![Modulino Buttons](./images/modulino-buttons.jpeg)
 
 ```cpp
 ModulinoButtons buttons;
@@ -178,4 +178,4 @@ The API documentation can be found [here](./api.md).
 
 ## License
 
-This library is released under the [MPL-2.0 license](../LICENSE).
\ No newline at end of file
+This library is released under the [MPL-2.0 license](../LICENSE).

From 711d2868cb977aa15f712e1b7e912742038e59d0 Mon Sep 17 00:00:00 2001
From: pedromsousalima <32345730+pedromsousalima@users.noreply.github.com>
Date: Wed, 16 Apr 2025 11:12:18 +0200
Subject: [PATCH 19/30] [PXCT-843] Renamed examples + Added comments (#28)

---
 .../Buttons_Basic.ino}                          |  9 ++++++---
 .../Basic.ino => Buzzer_Basic/Buzzer_Basic.ino} |  5 +++++
 .../Simple_melody/Simple_melody.ino             |  9 +++++++--
 .../Distance_Basic.ino}                         |  5 +++++
 .../Encoder_Setter.ino}                         | 16 ++++++++++++++--
 .../Basic.ino => Knob_Basic/Knob_Basic.ino}     |  5 +++++
 .../Movement_Basic.ino}                         |  5 +++++
 .../Basic.ino => Pixels_Basic/Pixels_Basic.ino} |  8 +++++++-
 .../Simple_Animation/Simple_Animation.ino       | 10 ++++++++--
 .../Temperature_Humidity_Matrix.ino}            |  5 +++++
 .../Basic.ino => Thermo_Basic/Thermo_Basic.ino} |  7 +++++--
 .../Modulino_PlugNPlay/Modulino_PlugNPlay.ino   | 17 +++++++++++++----
 12 files changed, 85 insertions(+), 16 deletions(-)
 rename examples/Modulino_Buttons/{Basic/Basic.ino => Buttons_Basic/Buttons_Basic.ino} (69%)
 rename examples/Modulino_Buzzer/{Basic/Basic.ino => Buzzer_Basic/Buzzer_Basic.ino} (66%)
 rename examples/Modulino_Distance/{Basic/Basic.ino => Distance_Basic/Distance_Basic.ino} (63%)
 rename examples/Modulino_Knob/{EncoderSetter/EncoderSetter.ino => Encoder_Setter/Encoder_Setter.ino} (60%)
 rename examples/Modulino_Knob/{Basic/Basic.ino => Knob_Basic/Knob_Basic.ino} (68%)
 rename examples/Modulino_Movement/{Basic/Basic.ino => Movement_Basic/Movement_Basic.ino} (72%)
 rename examples/Modulino_Pixels/{Basic/Basic.ino => Pixels_Basic/Pixels_Basic.ino} (54%)
 rename examples/Modulino_Thermo/{TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino => Temperature_Humidity_Matrix/Temperature_Humidity_Matrix.ino} (85%)
 rename examples/Modulino_Thermo/{Basic/Basic.ino => Thermo_Basic/Thermo_Basic.ino} (73%)

diff --git a/examples/Modulino_Buttons/Basic/Basic.ino b/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
similarity index 69%
rename from examples/Modulino_Buttons/Basic/Basic.ino
rename to examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
index 5145f02..d69f13f 100644
--- a/examples/Modulino_Buttons/Basic/Basic.ino
+++ b/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
@@ -8,6 +8,7 @@
 
 #include <Modulino.h>
 
+// Create a ModulinoButtons object
 ModulinoButtons buttons;
 
 bool button_a = false;
@@ -16,15 +17,17 @@ bool button_c = false;
 
 void setup() {
   Serial.begin(9600);
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to buttons module
   buttons.begin();
-  //function to control the LEDs on top of each button
+  // Turn on the LEDs above buttons A, B, and C
   buttons.setLeds(true, true, true);
 }
 void loop() {
-  //request new data from the Modulino buttons
+  // Check for new button events, returns true when button state changes
   if (buttons.update()) {
-    //Check if the buttons has been pressed
+    // Check which button was pressed (0=A, 1=B, 2=C)
     if (buttons.isPressed(0)) {
       Serial.println("Button A pressed!");
     } else if (buttons.isPressed(1)) {
diff --git a/examples/Modulino_Buzzer/Basic/Basic.ino b/examples/Modulino_Buzzer/Buzzer_Basic/Buzzer_Basic.ino
similarity index 66%
rename from examples/Modulino_Buzzer/Basic/Basic.ino
rename to examples/Modulino_Buzzer/Buzzer_Basic/Buzzer_Basic.ino
index a254115..47ebcf9 100644
--- a/examples/Modulino_Buzzer/Basic/Basic.ino
+++ b/examples/Modulino_Buzzer/Buzzer_Basic/Buzzer_Basic.ino
@@ -8,20 +8,25 @@
 
 #include <Modulino.h>
 
+// Create a ModulinoBuzzer object
 ModulinoBuzzer buzzer;
 
 int frequency = 440;
 int duration = 1000;
 
 void setup(){
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to buzzer module
   buzzer.begin();
 }
 
 void loop(){
 
+  // Play tone at specified frequency and duration
   buzzer.tone(frequency, duration);
   delay(1000);
+  // Stop the tone (0 frequency)
   buzzer.tone(0, duration);
   delay(1000);
 
diff --git a/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino b/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino
index fbff626..ba27151 100644
--- a/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino
+++ b/examples/Modulino_Buzzer/Simple_melody/Simple_melody.ino
@@ -8,20 +8,25 @@
 
 #include <Modulino.h>
 
+// Create a ModulinoBuzzer object
 ModulinoBuzzer buzzer;
 
+// Define melody notes in Hz (C4, G3, G3, A3, G3, rest, B3, C4)
 int melody[] = { 262, 196, 196, 220, 196, 0, 247, 262 };
 
 void setup() {
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to buzzer module
   buzzer.begin();
 }
 
 void loop() {
-
+  // Play each note in the melody
   for (int i = 0; i < 8; i++) {
+    // Get current note frequency
     int note = melody[i];
-
+    // Play the note for 250ms
     buzzer.tone(note, 250);
     delay(250);
 
diff --git a/examples/Modulino_Distance/Basic/Basic.ino b/examples/Modulino_Distance/Distance_Basic/Distance_Basic.ino
similarity index 63%
rename from examples/Modulino_Distance/Basic/Basic.ino
rename to examples/Modulino_Distance/Distance_Basic/Distance_Basic.ino
index a9622bd..08e298e 100644
--- a/examples/Modulino_Distance/Basic/Basic.ino
+++ b/examples/Modulino_Distance/Distance_Basic/Distance_Basic.ino
@@ -8,16 +8,21 @@
 
 #include "Modulino.h"
 
+// Create a ModulinoDistance object
 ModulinoDistance distance;
 
 void setup() {
   Serial.begin(9600);
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to distance sensor module
   distance.begin();
 }
 
 void loop() {
+  // Check if new distance measurement is available
   if (distance.available()) {
+    // Get the latest distance measurement in millimeters
     int measure = distance.get();
     Serial.println(measure);
   }
diff --git a/examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino b/examples/Modulino_Knob/Encoder_Setter/Encoder_Setter.ino
similarity index 60%
rename from examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino
rename to examples/Modulino_Knob/Encoder_Setter/Encoder_Setter.ino
index 8d6299b..9f91112 100644
--- a/examples/Modulino_Knob/EncoderSetter/EncoderSetter.ino
+++ b/examples/Modulino_Knob/Encoder_Setter/Encoder_Setter.ino
@@ -8,31 +8,43 @@
 
 #include "Modulino.h"
 
+// Create objects for the modules
 ModulinoKnob encoder;
 ModulinoPixels leds;
 ModulinoButtons buttons;
 
 void setup() {
-  // put your setup code here, to run once:
   Serial.begin(115200);
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to modules
   encoder.begin();
   leds.begin();
   buttons.begin();
 }
 
 void loop() {
+  // Get current encoder position value
   int value = encoder.get();
-  //Reset the position of the encoder with the set function
+  // Reset encoder position if out of range (0-100)
   if (value > 100 || value < 0) {
     encoder.set(0);
   }
+
+  // Get updated encoder value after possible reset
   value = encoder.get();
+
   Serial.println(value);
+
+  // Set LED brightness based on encoder value (0-100)
+  // Available colors: RED, BLUE, GREEN, VIOLET, WHITE
   leds.set(1, RED, value);
   leds.set(2, GREEN, value);
   leds.set(3, BLUE, value);
+  // Update LEDs with new settings
   leds.show();
+  // Check button states
   buttons.update();
+  // Set button LEDs to match button press states
   buttons.setLeds(buttons.isPressed(0), buttons.isPressed(1), buttons.isPressed(2));
 }
diff --git a/examples/Modulino_Knob/Basic/Basic.ino b/examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino
similarity index 68%
rename from examples/Modulino_Knob/Basic/Basic.ino
rename to examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino
index 1272a60..b933002 100644
--- a/examples/Modulino_Knob/Basic/Basic.ino
+++ b/examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino
@@ -8,16 +8,21 @@
 
 #include <Modulino.h>
 
+// Create a ModulinoKnob object
 ModulinoKnob knob;
 
 void setup() {
   Serial.begin(9600);
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to knob module
   knob.begin();
 }
 
 void loop(){
+  // Get the current position value of the knob
   int position = knob.get();
+  // Check if the knob has been pressed (clicked)
   bool click = knob.isPressed();
 
   Serial.print("Current position is: ");
diff --git a/examples/Modulino_Movement/Basic/Basic.ino b/examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino
similarity index 72%
rename from examples/Modulino_Movement/Basic/Basic.ino
rename to examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino
index 4b0c06e..8de9a97 100644
--- a/examples/Modulino_Movement/Basic/Basic.ino
+++ b/examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino
@@ -8,6 +8,7 @@
 
 #include "Modulino.h"
 
+// Create a ModulinoMovement
 ModulinoMovement movement;
 
 float x;
@@ -16,13 +17,17 @@ float z;
 
 void setup() {
   Serial.begin(9600);
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to movement sensor module
   movement.begin();
 }
 
 void loop() {
+  // Read new acceleration data from the sensor
   movement.update();
 
+  // Get the acceleration values for each axis (in Gs)
   x = movement.getX();
   y = movement.getY();
   z = movement.getZ();
diff --git a/examples/Modulino_Pixels/Basic/Basic.ino b/examples/Modulino_Pixels/Pixels_Basic/Pixels_Basic.ino
similarity index 54%
rename from examples/Modulino_Pixels/Basic/Basic.ino
rename to examples/Modulino_Pixels/Pixels_Basic/Pixels_Basic.ino
index 63b2fc6..69be734 100644
--- a/examples/Modulino_Pixels/Basic/Basic.ino
+++ b/examples/Modulino_Pixels/Pixels_Basic/Pixels_Basic.ino
@@ -8,19 +8,25 @@
 
 #include <Modulino.h>
 
+// Create a ModulinoPixels object
 ModulinoPixels leds;
 
 int brightness = 25;
 
 void setup(){
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to pixels module
   leds.begin();
 }
 
 void loop(){
-  //Set all LEDs blue
+  // Set all 8 LEDs to blue color
   for (int i = 0; i < 8; i++) {
+    // Set each LED (index, color, brightness)
+    // Available colors: RED, BLUE, GREEN, VIOLET, WHITE
     leds.set(i, BLUE, brightness);
+    // Update the physical LEDs with new settings
     leds.show();
   }
 }
\ No newline at end of file
diff --git a/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino b/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino
index 39d7ede..40c1c26 100644
--- a/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino
+++ b/examples/Modulino_Pixels/Simple_Animation/Simple_Animation.ino
@@ -8,19 +8,24 @@
 
 #include <Modulino.h>
 
+// Create a ModulinoPixels object for the LED array
 ModulinoPixels leds;
 
+// Define a custom color for turning off LEDs
 ModulinoColor OFF(0, 0, 0);
 
 int brightness = 25;
 
 void setup() {
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to pixels module
   leds.begin();
 }
 
 void loop() {
-
+  // Light up LEDs in different colors
+  // Available colors: RED, BLUE, GREEN, VIOLET, WHITE
   for (int i = 0; i < 8; i++) {
     if (i == 0 || i == 1) {
       setPixel(i, RED);
@@ -37,7 +42,8 @@ void loop() {
   delay(25);
 
   }
-  
+
+  // Turn off all LEDs one by one
   for (int i = 0; i < 8; i++) {
     setPixel(i, OFF);
     delay(25);
diff --git a/examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino b/examples/Modulino_Thermo/Temperature_Humidity_Matrix/Temperature_Humidity_Matrix.ino
similarity index 85%
rename from examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino
rename to examples/Modulino_Thermo/Temperature_Humidity_Matrix/Temperature_Humidity_Matrix.ino
index eab6001..57de8de 100644
--- a/examples/Modulino_Thermo/TemperatureHumidityMatrix/TemperatureHumidityMatrix.ino
+++ b/examples/Modulino_Thermo/Temperature_Humidity_Matrix/Temperature_Humidity_Matrix.ino
@@ -10,7 +10,9 @@
 #include "ArduinoGraphics.h"
 #include "Arduino_LED_Matrix.h"
 
+// Create a ModulinoThermo object
 ModulinoThermo thermo;
+// Create an object to control the LED matrix on UNO R4 WiFi
 ArduinoLEDMatrix matrix;
 
 float temperature = -273.15;
@@ -19,9 +21,12 @@ float humidity = 0.0;
 void setup() {
   Serial.begin(9600);
 
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to temperature/humidity sensor module
   thermo.begin();
 
+  // Initialize the LED matrix
   matrix.begin();
   delay(100);
 }
diff --git a/examples/Modulino_Thermo/Basic/Basic.ino b/examples/Modulino_Thermo/Thermo_Basic/Thermo_Basic.ino
similarity index 73%
rename from examples/Modulino_Thermo/Basic/Basic.ino
rename to examples/Modulino_Thermo/Thermo_Basic/Thermo_Basic.ino
index e98afd5..d219fce 100644
--- a/examples/Modulino_Thermo/Basic/Basic.ino
+++ b/examples/Modulino_Thermo/Thermo_Basic/Thermo_Basic.ino
@@ -14,17 +14,20 @@ ModulinoThermo thermo;
 void setup(){
   Serial.begin(9600);
 
-  // Call all necessary .begin() function
+  // Initialize Modulino I2C communication
   Modulino.begin();
+  // Detect and connect to temperature/humidity sensor module
   thermo.begin();
 }
 
 void loop(){
-
+  // Read temperature in Celsius from the sensor
   float celsius = thermo.getTemperature();
 
+  // Convert Celsius to Fahrenheit
   float fahrenheit = (celsius * 9 / 5) + 32;
 
+  // Read humidity percentage from the sensor
   float humidity = thermo.getHumidity();
 
   Serial.print("Temperature (C) is: ");
diff --git a/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino b/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
index 60368a3..5fcc7cf 100644
--- a/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
+++ b/examples/Utilities/Modulino_PlugNPlay/Modulino_PlugNPlay.ino
@@ -8,6 +8,7 @@
 
 #include "Modulino.h"
 
+// Create objects for all Modulino modules
 ModulinoButtons buttons;
 ModulinoBuzzer buzzer;
 ModulinoPixels leds;
@@ -19,15 +20,14 @@ ModulinoThermo thermo;
 void setup() {
 
   Serial.begin(115200);
+  // Initialize Modulino I2C communication
   Modulino.begin();
-
+  // Detect and connect to all modules
   distance.begin();
-
   buttons.begin();
   encoder.begin();
   buzzer.begin();
   leds.begin();
-
   imu.begin();
   thermo.begin();
 }
@@ -43,14 +43,17 @@ void loop() {
   float x;
   float y;
   float z;
-
+  // Cycle through LED patterns when encoder is pressed
   if (encoder.isPressed()) {
     skip = (skip + 1) % 5;
   }
 
+  // Calculate pitch by combining encoder position and distance sensor value
   pitch = encoder.get() + (distance.available() ? distance.get() : 0);
 
+  // When 's' is received over serial, report sensor data
   if (Serial.available() && Serial.read() == 's') {
+    // Update and report accelerometer values
     imu.update();
     Serial.print("IMU: x ");
     Serial.print(imu.getX(), 3);
@@ -59,29 +62,35 @@ void loop() {
     Serial.print("\tz ");
     Serial.println(imu.getZ(), 3);
 
+    // Report temperature and humidity values
     Serial.print("Humidity: " + String(thermo.getHumidity()));
     Serial.println("\tTemperature: " + String(thermo.getTemperature()));
   }
 
+  // Check for button presses
   if (buttons.update()) {
+    // Button A: Red LED and 440Hz tone
     if (buttons.isPressed(0)) {
       leds.set(1 + skip, RED, 100);
       buzzer.tone(440 + pitch, 1000);
     } else {
       leds.clear(1 + skip);
     }
+    // Button B: Blue LED and 880Hz tone
     if (buttons.isPressed(1)) {
       leds.set(2 + skip, BLUE, 100);
       buzzer.tone(880 + pitch, 1000);
     } else {
       leds.clear(2 + skip);
     }
+    // Button C: Green LED and 1240Hz tone
     if (buttons.isPressed(2)) {
       leds.set(3 + skip, GREEN, 100);
       buzzer.tone(1240 + pitch, 1000);
     } else {
       leds.clear(3 + skip);
     }
+    // Update the LEDs
     leds.show();
   }
 }

From 8441dd9cb2e5872d0cd46ff28d0c999d978810df Mon Sep 17 00:00:00 2001
From: Giulio <pilotto.giulio@gmail.com>
Date: Wed, 16 Apr 2025 11:34:38 +0200
Subject: [PATCH 20/30] Theremin example (#8)

* Encoder and distance as theremin
---
 .../Modulino_Buzzer/Theremin/Theremin.ino     | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 examples/Modulino_Buzzer/Theremin/Theremin.ino

diff --git a/examples/Modulino_Buzzer/Theremin/Theremin.ino b/examples/Modulino_Buzzer/Theremin/Theremin.ino
new file mode 100644
index 0000000..fd79184
--- /dev/null
+++ b/examples/Modulino_Buzzer/Theremin/Theremin.ino
@@ -0,0 +1,32 @@
+#include "Modulino.h"
+
+ModulinoBuzzer buzzer;
+ModulinoDistance distance;
+ModulinoKnob encoder;
+
+
+void setup() {
+
+  Modulino.begin();
+  encoder.begin();
+  distance.begin();
+  buzzer.begin();
+}
+
+int pitch = 0;
+int noteIndex = 0;
+
+//Notes from C to B with #
+int note[] = {262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494};
+
+void loop() {
+  pitch = distance.get();
+  noteIndex = encoder.get();
+
+  noteIndex = noteIndex % 11;
+  if (noteIndex < 0){
+      noteIndex = 0;
+  }
+
+  buzzer.tone(note[noteIndex] + pitch, 1000);
+}
\ No newline at end of file

From 08a4fe1d85b8fd9426c468c6a0d91c0bb43ead4d Mon Sep 17 00:00:00 2001
From: pedromsousalima <32345730+pedromsousalima@users.noreply.github.com>
Date: Thu, 24 Apr 2025 15:13:37 +0200
Subject: [PATCH 21/30] [PXCT-768] Modulino Movement Gyroscope readings (#29)

* AddedGyro

* Added Gyro to Basic

* Added more accurate terminology

roll, pitch, yaw

* Update api.md

Added info on the movement modulino for angular velocity
---
 docs/api.md                                   |  9 +++++
 .../Movement_Basic/Movement_Basic.ino         | 36 +++++++++++++------
 src/Modulino.h                                | 16 +++++++--
 3 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/docs/api.md b/docs/api.md
index 5ced974..7c463c0 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -116,6 +116,15 @@ Represents a Modulino Movement module.
 - **`float getZ()`**  
   Returns the Z-axis acceleration.
 
+- **`float getRoll()`**
+  Returns the angular velocity around X-axis.
+
+- **`float getPitch()`**
+  Returns the angular velocity around Y-axis.
+
+- **`float getYaw()`**
+  Returns the angular velocity around Z-axis.
+
 ---
 
 ### ModulinoThermo
diff --git a/examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino b/examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino
index 8de9a97..4868dca 100644
--- a/examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino
+++ b/examples/Modulino_Movement/Movement_Basic/Movement_Basic.ino
@@ -11,9 +11,10 @@
 // Create a ModulinoMovement
 ModulinoMovement movement;
 
-float x;
-float y;
-float z;
+
+float x, y, z;
+float roll, pitch, yaw;
+
 
 void setup() {
   Serial.begin(9600);
@@ -24,19 +25,34 @@ void setup() {
 }
 
 void loop() {
-  // Read new acceleration data from the sensor
+  // Read new movement data from the sensor
   movement.update();
 
-  // Get the acceleration values for each axis (in Gs)
+  // Get acceleration and gyroscope values
   x = movement.getX();
   y = movement.getY();
   z = movement.getZ();
+  roll = movement.getRoll();
+  pitch = movement.getPitch();
+  yaw = movement.getYaw();
 
-  Serial.print("Movement data: ");
-  Serial.print("x ");
+  // Print acceleration values
+  Serial.print("A: ");
   Serial.print(x, 3);
-  Serial.print("	y ");
+  Serial.print(", ");
   Serial.print(y, 3);
-  Serial.print("	z ");
-  Serial.println(z, 3);
+  Serial.print(", ");
+  Serial.print(z, 3);
+  
+  // Print divider between acceleration and gyroscope
+  Serial.print(" | G: ");
+  
+  // Print gyroscope values
+  Serial.print(roll, 1);
+  Serial.print(", ");
+  Serial.print(pitch, 1);
+  Serial.print(", ");
+  Serial.println(yaw, 1);
+  
+  delay(200);
 }
\ No newline at end of file
diff --git a/src/Modulino.h b/src/Modulino.h
index aa259da..6f62aaf 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -313,13 +313,15 @@ class ModulinoMovement : public Module {
   }
   int update() {
     if (initialized) {
-      return _imu->readAcceleration(x, y, z);
+      int accel = _imu->readAcceleration(x, y, z);
+      int gyro = _imu->readGyroscope(roll, pitch, yaw);
+      return accel && gyro;
     }
     return 0;
   }
   int available() {
     if (initialized) {
-      return _imu->accelerationAvailable();
+      return _imu->accelerationAvailable() && _imu->gyroscopeAvailable();
     }
     return 0;
   }
@@ -332,9 +334,19 @@ class ModulinoMovement : public Module {
   float getZ() {
     return z;
   }
+  float getRoll() {
+    return roll;
+  }
+  float getPitch() {
+    return pitch;
+  }
+  float getYaw() {
+    return yaw;
+  }
 private:
   LSM6DSOXClass* _imu = nullptr;
   float x,y,z;
+  float roll,pitch,yaw; //gx, gy, gz
   int initialized = 0;
 };
 

From d0c12de9db8b9a4b081551c5e0670be16426751f Mon Sep 17 00:00:00 2001
From: Leonardo Cavagnis <45899760+leonardocavagnis@users.noreply.github.com>
Date: Thu, 24 Apr 2025 15:49:57 +0200
Subject: [PATCH 22/30] Bump the library version to 0.5.0

---
 library.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library.properties b/library.properties
index 7e1d04b..8989efb 100644
--- a/library.properties
+++ b/library.properties
@@ -1,9 +1,9 @@
 name=Modulino
-version=0.4.3
+version=0.5.0
 author=Arduino
 maintainer=Arduino <info@arduino.cc>
 sentence=Arduino Library for Modulinos
-paragraph=
+paragraph=The Arduino Modulino® Library simplifies the integration of Modulino®, compact devices that connect via Qwiic and communicate over I2C. It provides an easy-to-use interface for working with sensors, actuators, and other modules on Arduino boards.
 category=Communication
 url=https://github.com/arduino-libraries/Modulino
 architectures=*

From b57e5d6a23004773c39396a5ab788e3520e5f6fd Mon Sep 17 00:00:00 2001
From: Xayton <30591904+Xayton@users.noreply.github.com>
Date: Sun, 27 Apr 2025 21:23:07 +0200
Subject: [PATCH 23/30] Toggle leds when pushing buttons

---
 .../Buttons_Basic/Buttons_Basic.ino                 | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino b/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
index d69f13f..f29f96b 100644
--- a/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
+++ b/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
@@ -11,9 +11,9 @@
 // Create a ModulinoButtons object
 ModulinoButtons buttons;
 
-bool button_a = false;
-bool button_b = false;
-bool button_c = false;
+bool button_a = true;
+bool button_b = true;
+bool button_c = true;
 
 void setup() {
   Serial.begin(9600);
@@ -28,12 +28,19 @@ void loop() {
   // Check for new button events, returns true when button state changes
   if (buttons.update()) {
     // Check which button was pressed (0=A, 1=B, 2=C)
+    // Also toggle the corresponding LED, for each of the three buttons
     if (buttons.isPressed(0)) {
       Serial.println("Button A pressed!");
+      button_a = !button_a;
     } else if (buttons.isPressed(1)) {
       Serial.println("Button B pressed!");
+      button_b = !button_b;
     } else if (buttons.isPressed(2)) {
       Serial.println("Button C pressed!");
+      button_c = !button_c;
     }
+    
+    // Update the LEDs above buttons, depending on the variables value
+    buttons.setLeds(button_a, button_b, button_c);
   }
 }
\ No newline at end of file

From 3c3673277049c6d2247ee45e09bb3cf750b391a7 Mon Sep 17 00:00:00 2001
From: Antonio Bernardini <60107274+AntonioBerna@users.noreply.github.com>
Date: Fri, 9 May 2025 12:18:16 +0200
Subject: [PATCH 24/30] Add `getDirection()` support to `ModulinoKnob` and
 example :zap: (#34)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* feat(buttons): allow isPressed() to accept 'A', 'B', 'C' as input

Added support for character and string-based input to `isPressed()` in `ModulinoButtons`,
so it now accepts both index (0–2) and letter identifiers (`'A'`, `'B'`, `'C'`) matching
the physical button labeling.

Closes #3

* Update example to document support for both numeric and letter indices :recycle:

* Add getDirection() support to ModulinoKnob and example :zap:

* Fix: :fire:

* Fix: restore files :fire:

* Minor fixes :recycle:

* Update API docs :recycle:

* Update API docs :recycle:

* Update examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino

---------

Co-authored-by: Leonardo Cavagnis <45899760+leonardocavagnis@users.noreply.github.com>
---
 docs/api.md                                   |  6 +++++
 .../Modulino_Knob/Knob_Basic/Knob_Basic.ino   | 11 ++++++++-
 src/Modulino.h                                | 24 ++++++++++++++++++-
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/docs/api.md b/docs/api.md
index 7c463c0..225181b 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -90,6 +90,12 @@ Represents a Modulino Knob module.
 - **`bool isPressed()`**  
   Returns `true` if the button on the knob is pressed, `false` otherwise.
 
+- **`int8_t getDirection()`**
+  Returns the direction of the knob rotation.  
+  - `1` for clockwise
+  - `-1` for counter-clockwise
+  - `0` if no movement is detected
+
 - **`void set(int16_t value)`**  
   Sets the knob value.
 
diff --git a/examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino b/examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino
index b933002..60dc248 100644
--- a/examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino
+++ b/examples/Modulino_Knob/Knob_Basic/Knob_Basic.ino
@@ -24,6 +24,8 @@ void loop(){
   int position = knob.get();
   // Check if the knob has been pressed (clicked)
   bool click = knob.isPressed();
+  // Get the rotation direction
+  int8_t direction = knob.getDirection();
 
   Serial.print("Current position is: ");
   Serial.println(position);
@@ -32,4 +34,11 @@ void loop(){
     Serial.println("Clicked!");
   }
 
-}
\ No newline at end of file
+  if (direction == 1) {
+    Serial.println("Rotated clockwise");
+  } else if (direction == -1) {
+    Serial.println("Rotated counter-clockwise");
+  }
+
+  delay(10); // optional small delay to reduce serial spam
+} 
\ No newline at end of file
diff --git a/src/Modulino.h b/src/Modulino.h
index 6f62aaf..365d3c1 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -243,8 +243,9 @@ class ModulinoKnob : public Module {
   bool begin() {
     auto ret = Module::begin();
     if (ret) {
-      // check for set() bug
       auto _val = get();
+      _lastPosition = _val;
+      _lastDebounceTime = millis();
       set(100);
       if (get() != 100) {
         _bug_on_set = true;
@@ -277,6 +278,24 @@ class ModulinoKnob : public Module {
     get();
     return _pressed;
   }
+  int8_t getDirection() {
+    unsigned long now = millis();
+    if (now - _lastDebounceTime < DEBOUNCE_DELAY) {
+      return 0;
+    }
+    int16_t current = get();
+    int8_t direction = 0;
+    if (current > _lastPosition) {
+      direction = 1;
+    } else if (current < _lastPosition) {
+      direction = -1;
+    }
+    if (direction != 0) {
+      _lastDebounceTime = now;
+      _lastPosition = current;
+    }
+    return direction;
+  }
   virtual uint8_t discover() {
     for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
       if (scan(match[i])) {
@@ -288,6 +307,9 @@ class ModulinoKnob : public Module {
 private:
   bool _pressed = false;
   bool _bug_on_set = false;
+  int16_t _lastPosition = 0;
+  unsigned long _lastDebounceTime = 0;
+  static constexpr unsigned long DEBOUNCE_DELAY = 30;
 protected:
   uint8_t match[2] = { 0x74, 0x76 };
 };

From 9c948fefc0de011add921fb36a4cf06687dc4871 Mon Sep 17 00:00:00 2001
From: Antonio Bernardini <60107274+AntonioBerna@users.noreply.github.com>
Date: Fri, 9 May 2025 12:29:09 +0200
Subject: [PATCH 25/30] Add support for character input (`'A'`, `'B'`, `'C'`)
 in `isPressed()` (#33)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* feat(buttons): allow isPressed() to accept 'A', 'B', 'C' as input

Added support for character and string-based input to `isPressed()` in `ModulinoButtons`,
so it now accepts both index (0–2) and letter identifiers (`'A'`, `'B'`, `'C'`) matching
the physical button labeling.

Closes #3

* Update example to document support for both numeric and letter indices :recycle:

* Update API docs :recycle:

* Delete .gitignore

* Update examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino

---------

Co-authored-by: Leonardo Cavagnis <45899760+leonardocavagnis@users.noreply.github.com>
---
 docs/api.md                                   |  6 ++++++
 .../Buttons_Basic/Buttons_Basic.ino           | 14 ++++++++------
 src/Modulino.h                                | 19 +++++++++++++++++++
 3 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/docs/api.md b/docs/api.md
index 225181b..f52c482 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -33,6 +33,12 @@ Represents a Modulino Buttons module.
 - **`PinStatus isPressed(int index)`**  
   Returns the press status (HIGH/LOW) of the button at the specified index (_0-A, 1-B, 2-C_).
 
+- **`PinStatus isPressed(char button)`**  
+  Returns the press status (HIGH/LOW) of the button specified by its character ('A', 'B', 'C').
+
+- **`PinStatus isPressed(const char *button)`**
+  Returns the press status (HIGH/LOW) of the button specified by its string ("A", "B", "C").
+
 - **`bool update()`**  
   Updates the button status. Returns `true` if the status has changed, `false` otherwise.
 
diff --git a/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino b/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
index f29f96b..9d5e4da 100644
--- a/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
+++ b/examples/Modulino_Buttons/Buttons_Basic/Buttons_Basic.ino
@@ -24,22 +24,24 @@ void setup() {
   // Turn on the LEDs above buttons A, B, and C
   buttons.setLeds(true, true, true);
 }
+
 void loop() {
   // Check for new button events, returns true when button state changes
   if (buttons.update()) {
-    // Check which button was pressed (0=A, 1=B, 2=C)
-    // Also toggle the corresponding LED, for each of the three buttons
-    if (buttons.isPressed(0)) {
+    // You can use either index (0=A, 1=B, 2=C) or letter ('A', 'B', 'C') to check buttons
+    // Below we use the letter-based method for better readability
+
+    if (buttons.isPressed('A')) {
       Serial.println("Button A pressed!");
       button_a = !button_a;
-    } else if (buttons.isPressed(1)) {
+    } else if (buttons.isPressed("B")) {
       Serial.println("Button B pressed!");
       button_b = !button_b;
-    } else if (buttons.isPressed(2)) {
+    } else if (buttons.isPressed('C')) {
       Serial.println("Button C pressed!");
       button_c = !button_c;
     }
-    
+
     // Update the LEDs above buttons, depending on the variables value
     buttons.setLeds(button_a, button_b, button_c);
   }
diff --git a/src/Modulino.h b/src/Modulino.h
index 365d3c1..f723e24 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -127,6 +127,17 @@ class ModulinoButtons : public Module {
   PinStatus isPressed(int index) {
     return last_status[index] ? HIGH : LOW;
   }
+  PinStatus isPressed(char button) {
+    int index = buttonToIndex(button);
+    if (index < 0) return LOW;
+    return isPressed(index);
+  }
+  PinStatus isPressed(const char *button) {
+    if (button == nullptr || button[0] == '\0' || button[1] != '\0') {
+      return LOW;
+    }
+    return isPressed(button[0]);
+  }
   bool update() {
     uint8_t buf[3];
     auto res = read((uint8_t*)buf, 3);
@@ -154,6 +165,14 @@ class ModulinoButtons : public Module {
   }
 private:
   bool last_status[3];
+  int buttonToIndex(char button) {
+    switch (toupper(button)) {
+      case 'A': return 0;
+      case 'B': return 1;
+      case 'C': return 2;
+      default:  return -1;
+    }
+  }
 protected:
   uint8_t match[1] = { 0x7C };  // same as fw main.c
 };

From 71ca9fb84b097af1fa82f3058dcae7b21c6fc56d Mon Sep 17 00:00:00 2001
From: Giovanni Bruno <g.bruno@arduino.cc>
Date: Tue, 1 Jul 2025 15:42:22 +0200
Subject: [PATCH 26/30] fix: error if nano esp32 and selected Arduino pin
 number

---
 src/Modulino.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/Modulino.h b/src/Modulino.h
index f723e24..a79d4b5 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -4,6 +4,11 @@
 #ifndef ARDUINO_LIBRARIES_MODULINO_H
 #define ARDUINO_LIBRARIES_MODULINO_H
 
+#if defined(ESP32) && defined(BOARD_HAS_PIN_REMAP) && defined(tone)
+  #error "The current configuration is unsupported, switch Pin Numbering to "By GPIO number" or #undef tone and #undef noTone in the beginning of your sketch."
+  #error "Learn more at: https://support.arduino.cc/hc/en-us/articles/10483225565980-Select-pin-numbering-for-Nano-ESP32-in-Arduino-IDE"
+#endif
+
 #include "Wire.h"
 #include <vl53l4cd_class.h>  // from stm32duino
 #include <vl53l4ed_class.h>  // from stm32duino

From 10bda6d6d3139c505bbd65b8025b1a0502664bae Mon Sep 17 00:00:00 2001
From: kunningKing11 <150028328+kunningKing11@users.noreply.github.com>
Date: Wed, 16 Jul 2025 11:22:29 +0200
Subject: [PATCH 27/30] Update AddressChanger.ino spelling (#37)

Corrected a minor typo
---
 examples/Utilities/AddressChanger/AddressChanger.ino | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/Utilities/AddressChanger/AddressChanger.ino b/examples/Utilities/AddressChanger/AddressChanger.ino
index abe4181..4005574 100644
--- a/examples/Utilities/AddressChanger/AddressChanger.ino
+++ b/examples/Utilities/AddressChanger/AddressChanger.ino
@@ -29,7 +29,7 @@ void setup() {
       Serial.print("Found device at ");
       Serial.println(i);
       address = i;
-      Serial.println("Press 'c' to configure te new address");
+      Serial.println("Press 'c' to configure the new address");
     }
   }
 }

From 2f3a683c7411bcfa20ac6ccc7b2d065e319fbecf Mon Sep 17 00:00:00 2001
From: Xayton <30591904+Xayton@users.noreply.github.com>
Date: Thu, 24 Jul 2025 09:51:05 +0200
Subject: [PATCH 28/30] Make AddressChanger interactive

---
 .../AddressChanger/AddressChanger.ino         | 264 +++++++++++++++---
 1 file changed, 230 insertions(+), 34 deletions(-)

diff --git a/examples/Utilities/AddressChanger/AddressChanger.ino b/examples/Utilities/AddressChanger/AddressChanger.ino
index 4005574..d6fe0a9 100644
--- a/examples/Utilities/AddressChanger/AddressChanger.ino
+++ b/examples/Utilities/AddressChanger/AddressChanger.ino
@@ -8,60 +8,256 @@
 
 #include "Wire.h"
 
-// Setting new_address to 0 means that the module will get back its original address
-const uint8_t new_address = 0;
+struct DetectedModulino {
+  uint8_t addr;
+  String modulinoType;
+  String pinstrap;
+  String defaultAddr;
+};
+
+#define MAX_DEVICES 16
+DetectedModulino rows[MAX_DEVICES];
+int numRows = 0;
 
-uint8_t address;
 
 void setup() {
   Wire1.begin();
   Serial.begin(115200);
-  delay(1000);
-  if (new_address != 0 && (new_address < 8 || new_address > 0x77)) {
-    Serial.println("Address outside valid range");
-    while (1);
+
+  delay(600);
+  discoverDevices();
+}
+
+bool waitingInput = false;
+void loop() {
+  if (numRows == 0) return;
+  if (Serial.available() == 0 && waitingInput) return;
+
+  if (Serial.available() > 0) {
+    String hex1 = Serial.readStringUntil(' ');   // Read until space (or other delimiter)
+    String hex2 = Serial.readStringUntil('\n');  // Read until newline
+    Serial.println("> " + hex1 + " " + hex2);    // Print what the user inserted.
+
+    int num1 = parseHex(hex1);  // Parse the first hex number
+    int num2 = parseHex(hex2);  // Parse the second hex number
+    if (num1 == -1 || num2 == -1) {
+      Serial.println("Error: Incomplete or invalid input. Please enter two hexadecimal numbers");
+      return;
+    }
+
+    bool success = updateI2cAddress(num1, num2);
+    if (!success) return;  // If the update failed, skip discovery and messages, and wait for input again.
+
+    discoverDevices();
+    waitingInput = false;
+  }
+
+  Serial.println("Enter the current address, space, and new address (ex. \"0x20 0x30\" or \"20 2A\"):");
+  Serial.println("  - Enter \"<addr> 0\" to reset the device at <addr> to its default address.");
+  Serial.println("  - Enter \"0 0\" to reset all devices to the default address.");
+  waitingInput = true;
+}
+
+// Updates the device at current address to new address. Supports broadcasting and setting default address (0).
+// Returns true if the update was successful, false otherwise.
+bool updateI2cAddress(int curAddress, int newAddress) {
+  uint8_t data[40] = { 'C', 'F', newAddress * 2 };
+  memset(data + 3, 0, sizeof(data) - 3);  // Zero the rest of the buffer.
+
+  // Validate the current address, it must match a detected device.
+  if (curAddress != 0 && !findRow(curAddress)) {
+    Serial.println("Error: current address 0x" + String(curAddress, HEX) + " not found in the devices list\n");
+    return false;
+  }
+
+  if (curAddress != 0 && isFixedAddrDevice(curAddress)) {
+    Serial.println("Error: address 0x" + String(curAddress, HEX) + " is a non configurable device\n");
+    return false;
+  }
+
+  // Validate the new address.
+  if (newAddress != 0 && (newAddress < 8 || newAddress > 0x77)) {
+    Serial.println("Error: new address 0x" + String(newAddress, HEX) + " must be from 0x08 to 0x77\n");
+    return false;
+  }
+
+  if (curAddress == 0) {
+    Serial.print("Updating all devices (broadcast 0x00) to 0x" + String(newAddress, HEX));
+  } else {
+    Serial.print("Updating the device address from 0x" + String(curAddress, HEX) + " to 0x" + String(newAddress, HEX));
+  }
+  if (newAddress == 0) Serial.print(" (default address)");
+  Serial.print("...");
+
+  Wire1.beginTransmission(curAddress);
+  Wire1.write(data, 40);
+  Wire1.endTransmission();
+
+  delay(500);
+
+  if (newAddress == 0) {
+    Serial.println(" done\n");
+    return true;
+  } else {
+    Wire1.requestFrom(newAddress, 1);
+    if (Wire1.available()) {
+      Serial.println(" done\n");
+      return true;
+    } else {
+      Serial.println(" error\n");
+      return false;
+    }
+  }
+}
+
+// Function to parse hex number (with or without 0x prefix)
+int parseHex(String hexStr) {
+  hexStr.trim();
+
+  if (hexStr.length() == 0) {
+    return -1;
+  }
+
+  if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
+    hexStr = hexStr.substring(2);  // Remove the "0x" prefix
   }
-  // Search for devices and wait for user confirmation
-  for (int i = 8; i < 128; i++) {
-    Wire1.beginTransmission(i);
-    auto err = Wire1.endTransmission();
-    if (err == 0) {
-      Serial.print("Found device at ");
-      Serial.println(i);
-      address = i;
-      Serial.println("Press 'c' to configure the new address");
+
+  // Validate that the remaining string contains only valid hexadecimal characters (0-9, A-F, a-f)
+  for (int i = 0; i < hexStr.length(); i++) {
+    if (!isHexDigit(hexStr.charAt(i))) {
+      return -1;
+    }
+  }
+
+  return strtol(hexStr.c_str(), NULL, 16);
+}
+
+bool isHexDigit(char c) {
+  return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
+}
+
+void discoverDevices() {
+  char buffer[64];
+  Serial.println("ADDR\tMODULINO\tPINSTRAP\tDEFAULT ADDR");  // Table heading.
+
+  numRows = 0;
+
+  // Discover all modulino devices connected to the I2C bus.
+  for (int addr = 8; addr < 128; addr++) {
+    Wire1.beginTransmission(addr);
+    if (Wire1.endTransmission() != 0) continue;
+
+    if (numRows >= MAX_DEVICES) {
+      Serial.println("Too many devices connected, maximum supported is" + String(MAX_DEVICES));
+      return;
+    }
+
+    // Some addresses represent non configurable devices (no MCU on it). Handle them as a special case.
+    if (isFixedAddrDevice(addr)) {
+      snprintf(buffer, 64, "0x%02X (cannot change)", addr);
+      addRow(addr, fixedAddrToName(addr), "-", String(buffer));
+
+      continue;  // Stop here, do not try to communicate with this device.
     }
+
+    {
+      uint8_t pinstrap = 0;           // Variable to store the pinstrap (device type)
+      Wire1.beginTransmission(addr);  // Begin I2C transmission to the current address
+      Wire1.write(0x00);              // Send a request to the device (assuming 0x00 is the register for device type)
+      Wire1.endTransmission();        // End transmission
+
+      delay(50);  // Delay to allow for the device to respond
+
+      Wire1.requestFrom(addr, 1);  // Request 1 byte from the device at the current address
+      if (Wire1.available()) {
+        pinstrap = Wire1.read();  // Read the device type (pinstrap)
+      } else {
+        // If an error happens in the range 0x78 to 0x7F, ignore it.
+        if (addr >= 0x78) continue;
+        Serial.println("Failed to read device type at address 0x" + String(addr, HEX));
+      }
+
+      snprintf(buffer, 64, "0x%02X", pinstrap);
+      auto hexPinstrap = String(buffer);
+
+      snprintf(buffer, 64, "0x%02X", pinstrap / 2);  // Default address is half pinstrap.
+      auto defaultAddr = String(buffer);
+      if (addr != pinstrap / 2) defaultAddr += " *";  // Mark devices with modified address.
+
+      addRow(addr, pinstrapToName(pinstrap), hexPinstrap, defaultAddr);
+    }
+  }
+
+  // Print the results.
+  for (int i = 0; i < numRows; i++) {
+    char buffer[16];
+    snprintf(buffer, 16, "0x%02X", rows[i].addr);
+
+    Serial.print(fixedWidth(buffer, 8));
+    Serial.print(fixedWidth(rows[i].modulinoType, 16));
+    Serial.print(fixedWidth(rows[i].pinstrap, 16));
+    Serial.println(fixedWidth(rows[i].defaultAddr, 12));
   }
 }
 
+void addRow(uint8_t address, String modulinoType, String pinstrap, String defaultAddr) {
+  if (numRows >= MAX_DEVICES) return;
+
+  rows[numRows].addr = address;
+  rows[numRows].modulinoType = modulinoType;
+  rows[numRows].pinstrap = pinstrap;
+  rows[numRows].defaultAddr = defaultAddr;
+  numRows++;  // Increment the row counter
+}
+
+bool findRow(uint8_t address) {
+  for (int i = 0; i < numRows; i++) {
+    if (rows[i].addr == address) return true;
+  }
+  return false;
+}
+
+
+// Function to add padding to the right to ensure each field has a fixed width
+String fixedWidth(String str, int width) {
+  for (int i = str.length(); i < width; i++) str += ' ';
+  return str;
+}
+
 String pinstrapToName(uint8_t pinstrap) {
   switch (pinstrap) {
     case 0x3C:
-      return "BUZZER";
+      return "Buzzer";
     case 0x7C:
-      return "BUTTONS";
+      return "Buttons";
     case 0x76:
     case 0x74:
-      return "ENCODER";
+      return "Encoder";
     case 0x6C:
-      return "SMARTLEDS";
+      return "Smartleds";
   }
   return "UNKNOWN";
 }
 
-void loop() {
-  // put your main code here, to run repeatedly:
-  if (Serial.available()) {
-    if (Serial.read() == 'c') {
-      Serial.print("Assigning new address to ");
-      Serial.println(address);
-      uint8_t data[40] = { 'C', 'F', new_address * 2 };
-      Wire1.beginTransmission(address);
-      Wire1.write(data, 40);
-      Wire1.endTransmission();
-      delay(1000);
-      Wire1.requestFrom(new_address, 1);
-      Serial.println("Device type " + pinstrapToName(Wire1.read()) + " at new address " + String(new_address));
-    }
+String fixedAddrToName(uint8_t address) {
+  switch (address) {
+    case 0x29:
+      return "Distance";
+    case 0x44:
+      return "Thermo";
+    case 0x6A:
+    case 0x6B:
+      return "Movement";
+  }
+  return "UNKNOWN";
+}
+
+bool isFixedAddrDevice(uint8_t addr) {
+  // List of non-configurable devices, recognized by their fixed I2C address.
+  const uint8_t fixedAddr[] = { 0x29, 0x44, 0x6A, 0x6B };
+
+  for (int i = 0; i < sizeof(fixedAddr) / sizeof(fixedAddr[0]); i++) {
+    if (addr == fixedAddr[i]) return true;
   }
+  return false;
 }

From 532ead92da1ea7fab89c034e415a017c25b6f271 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Thu, 24 Jul 2025 09:56:49 +0200
Subject: [PATCH 29/30] Assign Wire1 as default for NanoR4

---
 src/Modulino.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Modulino.h b/src/Modulino.h
index a79d4b5..745061f 100644
--- a/src/Modulino.h
+++ b/src/Modulino.h
@@ -26,7 +26,7 @@ void __increaseI2CPriority();
 
 class ModulinoClass {
 public:
-#ifdef ARDUINO_UNOR4_WIFI
+#if defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_NANO_R4)
   void begin(HardwareI2C& wire = Wire1) {
 #else
   void begin(HardwareI2C& wire = Wire) {

From e9e816a0b41b44718cef522058e3ab3ecea44411 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Thu, 24 Jul 2025 16:45:10 +0200
Subject: [PATCH 30/30] Update library version to 0.5.1

---
 library.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library.properties b/library.properties
index 8989efb..e78f90c 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=Modulino
-version=0.5.0
+version=0.5.1
 author=Arduino
 maintainer=Arduino <info@arduino.cc>
 sentence=Arduino Library for Modulinos
