diff --git a/content/arduino-cloud/02.hardware/06.device-provisioning/content.md b/content/arduino-cloud/02.hardware/06.device-provisioning/content.md
index 88b73593f8..4b4e24b599 100644
--- a/content/arduino-cloud/02.hardware/06.device-provisioning/content.md
+++ b/content/arduino-cloud/02.hardware/06.device-provisioning/content.md
@@ -146,7 +146,7 @@ During this process you will be asked to wipe out the current network configurat
3. Click on the device you want to update the network settings for.
4. Click on the "change" button by the network section.
5. If you are using the Arduino Cloud webpage, select the Bluetooth method.
-6. Reset the board using the method of your board. Have a look at the [How to set up the Reconfiguration Procedure](#how-to-set-up-the-reconfiguration-procedure) section of this article to find the default board reset pin. If you have changed the reset pin from the default one, please use that.
+6. Reset the board using the method of your board. Have a look at the [How to set up the Reconfiguration Procedure](https://docs.arduino.cc/arduino-cloud/cloud-interface/sketches/#how-to-set-up-the-reconfiguration-procedure) article to find the default board reset pin. If you have changed the reset pin from the default one, please use that.
7. The board will reboot, and you will see the LED pulsing.
8. Connect to the board on the Arduino Cloud.
9. Input the new network configuration.
@@ -173,7 +173,7 @@ If you want to delete the stored network configuration without updating it, ther
To proceed with the next steps, the Cloud-generated sketch must be uploaded to the board.
-Reset the board using the method of your board. Have a look at the [How to set up the Reconfiguration Procedure](#how-to-set-up-the-reconfiguration-procedure) section of this article to find the default board reset pin. If you have changed the reset pin from the default one, please use that.
+Reset the board using the method of your board. Have a look at the [How to set up the Reconfiguration Procedure](https://docs.arduino.cc/arduino-cloud/cloud-interface/sketches/#how-to-set-up-the-reconfiguration-procedure) article to find the default board reset pin. If you have changed the reset pin from the default one, please use that.
### Using the DeleteConfiguration Sketch
@@ -181,19 +181,3 @@ Open Arduino IDE and on the left side open the **Library Manager**. Search for *
The sketch can also be found [here](https://github.com/arduino-libraries/Arduino_NetworkConfigurator/blob/main/examples/utility/DeleteConfiguration/DeleteConfiguration.ino).
-### How to set up the Reconfiguration Procedure
-
-As the Provisioning 2.0 ends, the Bluetooth LE interface is turned off.
-
-To restart the Bluetooth LE interface to update the network settings, the [**Arduino_NetworkConfigurator**](https://github.com/arduino-libraries/Arduino_NetworkConfigurator?tab=readme-ov-file) library provides a procedure called "Reconfiguration Procedure". This procedure is based on the shorting of two pins of the board.
-
-The library provides a default implementation according to the board type.
-
-- `Arduino Opta`: Press and hold the user button (BTN_USER) until the led (LED_USER) turns off
-- `Arduino MKR WiFi 1010`: Short pin 7 to GND until the led turns off
-- `Arduino GIGA R1 WiFi`: Short pin 7 to GND until the led turns off
-- `Arduino Nano RP2040 Connect`: Short pin 2 to 3.3V until the led turns off
-- `Arduino Portenta H7`: Short pin 0 to GND until the led turns off
-- `Arduino Portenta C33`: Short pin 0 to GND until the led turns off
-- `Other boards`: Short pin 2 to GND until the led turns off
-- `Portenta Machine Control`: Currently the reset procedure is not available
\ No newline at end of file
diff --git a/content/arduino-cloud/03.cloud-interface/00.sketches/sketches.md b/content/arduino-cloud/03.cloud-interface/00.sketches/sketches.md
index b8d61cd065..ba2e700978 100644
--- a/content/arduino-cloud/03.cloud-interface/00.sketches/sketches.md
+++ b/content/arduino-cloud/03.cloud-interface/00.sketches/sketches.md
@@ -311,6 +311,57 @@ void initProperties(){
ArduinoCloud.addProperty(variable, READWRITE, ON_CHANGE, onVariableChange);
}
```
+### How to set up the Reconfiguration Procedure
+
+As the Provisioning 2.0 ends, the Bluetooth LE interface is turned off.
+
+To restart the Bluetooth LE interface to update the network settings, the [**Arduino_NetworkConfigurator**](https://github.com/arduino-libraries/Arduino_NetworkConfigurator?tab=readme-ov-file) library provides a procedure called "Reconfiguration Procedure". This procedure is based on the shorting of two pins of the board.
+
+The library provides a default implementation according to the board type.
+
+- `Arduino Opta`: Press and hold the user button (BTN_USER) until the led (LED_USER) turns off
+- `Arduino MKR WiFi 1010`: Short pin 7 to GND until the led turns off
+- `Arduino GIGA R1 WiFi`: Short pin 7 to GND until the led turns off
+- `Nicla Vision`: Short the pin PA_13 to GND until the led turns off
+- `Arduino Portenta H7`: Short pin 0 to GND until the led turns off
+- `Arduino Portenta C33`: Short pin 0 to GND until the led turns off
+- `Other boards`: Short pin 2 to GND until the led turns off
+- `Portenta Machine Control`: Currently the reset procedure is not available
+
+***Internally, the pin designated for the procedure is set as INPUT_PULLUP (except for Arduino Opta ), and it's attached to an ISR fired on every change of the pin's status.***
+
+#### How to use the Reconfiguration pin in your sketch
+
+If you want to use the Reconfiguration pin in your sketch, you can add a custom callback function to be fired every time the pin’s state changes.
+
+1. Define a function having this signature: `void func(void)`
+Example:
+```
+void onReconfigurationPinInterrupt()
+```
+2. Pass the callback function to the `NetworkConfigurator`, adding this line in the `initProperties()` function of the `thingProperties.h`
+```
+NetworkConfigurator.addReconfigurePinCallback(onReconfigurationPinInterrupt);
+```
+
+#### Change the Reconfiguration pin
+
+Despite the default reconfiguration pin, you can change it using the following code:
+```
+NetworkConfigurator.setReconfigurePin(your_pin);
+```
+in the `initProperties()` function of the `thingProperties.h`
+
+The new pin must be in the list of digital pins usable for interrupts.
+Please refer to the Arduino documentation for more [details](https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/).
+
+#### Disable the Reconfiguration feature
+
+To disable the reconfiguration procedure, use the following function:
+```
+NetworkConfigurator.setReconfigurePin(DISABLE_PIN);
+```
+in the `initProperties()` function of the `thingProperties.h`
## Offline Sketches
diff --git a/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-bool-trigger.png b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-bool-trigger.png
new file mode 100644
index 0000000000..aeddcadd2a
Binary files /dev/null and b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-bool-trigger.png differ
diff --git a/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-int-trigger.png b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-int-trigger.png
new file mode 100644
index 0000000000..20753a5f11
Binary files /dev/null and b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-int-trigger.png differ
diff --git a/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-markers.png b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-markers.png
new file mode 100644
index 0000000000..0a73806ad0
Binary files /dev/null and b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map-markers.png differ
diff --git a/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map.png b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map.png
new file mode 100644
index 0000000000..ad847a1a72
Binary files /dev/null and b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/assets/image-map.png differ
diff --git a/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/dashboard-widgets.md b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/dashboard-widgets.md
index a243696e0b..dc13e9b0ba 100644
--- a/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/dashboard-widgets.md
+++ b/content/arduino-cloud/03.cloud-interface/03.dashboard-widgets/dashboard-widgets.md
@@ -198,6 +198,26 @@ gaugeVariable = analogRead(A0);
Use the image widget to put a JPG, PNG or WEBP image on your dashboard! If you instead want to use an image URL, then chose the URL option under image source. Keep in mind the URL needs to be a HTTPS URL and not a HTTP URL. It is also possible to use local addresses. If you are using the URL option you can add a refresh frequency to the image widget, enabling the widget to function as a video or moving image. The image will then update The image can be made to fill the widget frame or to fit within the widget frame. A grey background can be added to the widget to help with visibility issues for PNGs with transparent backgrounds.
+### Image Map
+
+
+
+Monitor your environment at a glance by placing markers on a map of your space. It could be a map of your house, warehouse, plant, etc. Enabling you to see real-time data from your devices.
+
+Upload or link an image of the space you want to monitor. You can then add `markers` that you can customize the look and placement of while also linking to any public URL.
+
+
+
+You can also add `triggers` and set their label, unit, position and looks. Link any `int`, `float`, `String`, `bool` or any Specialized types based on them to the triggers on the image map.
+
+Depending on the variable that you link you will get different options. With a `boolean` you can decide if the style should be `On/Off`, `True/False` or `Icons`. Then change the color of the trigger depending on the state if you check the `Custom style` option.
+
+
+
+With a `int` or `float` you can change the color of the trigger depending on the threshold if you check the `Customize color` option.
+
+
+
### LED

diff --git a/content/hardware/02.uno/boards/uno-q/certifications/Arduino_ABX00162-DoC_CE.pdf b/content/hardware/02.uno/boards/uno-q/certifications/Arduino_ABX00162-DoC_CE.pdf
new file mode 100644
index 0000000000..29764951f3
Binary files /dev/null and b/content/hardware/02.uno/boards/uno-q/certifications/Arduino_ABX00162-DoC_CE.pdf differ
diff --git a/content/hardware/02.uno/boards/uno-q/certifications/Arduino_ABX00162-DoC_UKCA.pdf b/content/hardware/02.uno/boards/uno-q/certifications/Arduino_ABX00162-DoC_UKCA.pdf
new file mode 100644
index 0000000000..5f5a05783b
Binary files /dev/null and b/content/hardware/02.uno/boards/uno-q/certifications/Arduino_ABX00162-DoC_UKCA.pdf differ
diff --git a/content/hardware/02.uno/boards/uno-q/datasheet/datasheet.md b/content/hardware/02.uno/boards/uno-q/datasheet/datasheet.md
index a861ed0056..abe37c9ad1 100644
--- a/content/hardware/02.uno/boards/uno-q/datasheet/datasheet.md
+++ b/content/hardware/02.uno/boards/uno-q/datasheet/datasheet.md
@@ -707,14 +707,6 @@ This equipment should be installed and operated with a minimum distance of 20 cm
French:
Lors de l’ installation et de l’ exploitation de ce dispositif, la distance entre le radiateur et le corps est d ’au moins 20 cm.
-**Important:** The operating temperature of the EUT can’t exceed 85℃ and shouldn’t be lower than -40℃.
-
-Hereby, Arduino S.r.l. declares that this product is in compliance with essential requirements and other relevant provisions of Directive 201453/EU. This product is allowed to be used in all EU member states.
-
-| Frequency bands | Maximum output power (ERP) |
-|----------------------|----------------------------|
-| 2.4 GHz, 40 channels | TBD |
-
# Company Information
| Company name | Arduino S.r.l. |
@@ -733,8 +725,9 @@ Hereby, Arduino S.r.l. declares that this product is in compliance with essentia
# Document Revision History
-| **Date** | **Revision** | **Changes** |
-|:----------:|:------------:|-------------------------------------------------|
-| 27/10/2025 | 2 | Mechanical drawing and RTC power detail update |
-| 01/10/2025 | 1 | First release |
+| **Date** | **Revision** | **Changes** |
+| :--------: | :----------: | ---------------------------------------------- |
+| 05/11/2025 | 3 | Update operational information |
+| 27/10/2025 | 2 | Mechanical drawing and RTC power detail update |
+| 01/10/2025 | 1 | First release |
diff --git a/content/hardware/02.uno/boards/uno-q/downloads/ABX00162-datasheet.pdf b/content/hardware/02.uno/boards/uno-q/downloads/ABX00162-datasheet.pdf
index f9c458304f..234ce96f47 100644
Binary files a/content/hardware/02.uno/boards/uno-q/downloads/ABX00162-datasheet.pdf and b/content/hardware/02.uno/boards/uno-q/downloads/ABX00162-datasheet.pdf differ
diff --git a/content/hardware/02.uno/boards/uno-q/downloads/ABX00173-datasheet.pdf b/content/hardware/02.uno/boards/uno-q/downloads/ABX00173-datasheet.pdf
index f9c458304f..4eef4e21f6 100644
Binary files a/content/hardware/02.uno/boards/uno-q/downloads/ABX00173-datasheet.pdf and b/content/hardware/02.uno/boards/uno-q/downloads/ABX00173-datasheet.pdf differ
diff --git a/content/hardware/02.uno/boards/uno-q/tutorials/01.user-manual/content.md b/content/hardware/02.uno/boards/uno-q/tutorials/01.user-manual/content.md
index bc46225680..921cbd32bd 100644
--- a/content/hardware/02.uno/boards/uno-q/tutorials/01.user-manual/content.md
+++ b/content/hardware/02.uno/boards/uno-q/tutorials/01.user-manual/content.md
@@ -287,8 +287,8 @@ LEDs #1 and #2 are controlled by the MPU.
There is a dedicated LED interface in our Linux OS for controlling these LEDs, they can be controlled via `/sys/class/leds` from the **Command Line**, using **SSH**, an **ADB** connection from your PC terminal or by using the Linux built-in terminal application when used in single-board computer mode:
```bash
-echo 1 | sudo tee /sys/class/leds/red:user/brightness # set HIGH/ON
-echo 0 | sudo tee /sys/class/leds/red:user/brightness # set LOW/OFF
+echo 1 | tee /sys/class/leds/red:user/brightness # set HIGH/ON
+echo 0 | tee /sys/class/leds/red:user/brightness # set LOW/OFF
```

diff --git a/content/hardware/02.uno/boards/uno-q/tutorials/04.update-image/update-image.md b/content/hardware/02.uno/boards/uno-q/tutorials/04.update-image/update-image.md
index 0882107ed1..ff5437eeb8 100644
--- a/content/hardware/02.uno/boards/uno-q/tutorials/04.update-image/update-image.md
+++ b/content/hardware/02.uno/boards/uno-q/tutorials/04.update-image/update-image.md
@@ -23,16 +23,19 @@ However, if we want to hard-reset the board and perform a fresh installation, it
### Software Requirements
+- [Arduino Flasher CLI](https://www.arduino.cc/en/software/#flasher-tool)
+- At least 10 GB of free disk space
+
To re-flash the board, we will use the **Arduino Flasher CLI** tool:
- Download the [Arduino Flasher CLI](https://www.arduino.cc/en/software/#flasher-tool)
-***Note that this tool will download an image with a size that exceeds 1 GB. A stable Internet connection is recommended.***
+***Note that this tool will download an image with a size that exceeds 1 GB. A stable Internet connection and at least 10 GB of free disk space is recommended.***
## Download & Install CLI Tool
1. Download the [Arduino Flasher CLI](https://www.arduino.cc/en/software/#flasher-tool) for your OS (MacOS / Linux / Windows)
-2. Unzip the downloaded file, (you will receive a executable binary named `arduino-flasher-cli`)
+2. Unzip the downloaded file, (you will receive an executable binary named `arduino-flasher-cli`)
### Verify Tool Is Installed
@@ -50,13 +53,13 @@ You should see something like:

-This means it is working, and we can proceed to [flashing the board](#flash-image-to-the-board).
+This means it is working, and we can proceed to [preparing the hardware](#preparing-the-hardware).
**Important Note:** Do not run the file directly from Finder, you will receive a prompt window akin to:

-As the tool is ran from the command line with specific flags (explained further below), there is no reason to run it from Finder.
+As the tool is run from the command line with specific flags (explained further below), there is no reason to run it from Finder.
#### Windows
@@ -70,7 +73,7 @@ A new window should appear, prompting you to install the driver. Install it, and

-This means it is working, and we can proceed to [flashing the board](#flash-image-to-the-board).
+This means it is working, and we can proceed to [preparing the hardware](#preparing-the-hardware).
#### Linux
@@ -84,7 +87,7 @@ You should see something like:

-This means it is working, and we can proceed to [flashing the board](#flash-image-to-the-board).
+This means it is working, and we can proceed to [preparing the hardware](#preparing-the-hardware).
***Note: in some Linux systems, the `arduino-flasher-cli` could exit with an error right before flashing. This may occur if the kernel module `qcserial` is loaded. A workaround solution to fix this is in place (see section below).***
diff --git a/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/adb.md b/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/adb.md
new file mode 100644
index 0000000000..a536186ac2
--- /dev/null
+++ b/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/adb.md
@@ -0,0 +1,80 @@
+---
+title: Connect to UNO Q via ADB
+description: Learn how to connect to the UNO Q's shell via ADB.
+author: Karl Söderby
+tags: [UNO Q, ADB, Linux]
+---
+
+The Linux OS running on the [Arduino UNO Q](https://store.arduino.cc/products/uno-q) can be accessed over USB, using a tool called Android Debug Bridge (ADB).
+
+ADB is a tool that you install on your computer, where you can access the board's shell and run operations on the system.
+
+## Requirements
+
+The following hardware is required:
+- [Arduino UNO Q](https://store.arduino.cc/products/uno-q)
+- [USB-C® type cable](https://store.arduino.cc/products/usb-cable2in1-type-c)
+
+You will also need to have the following software installed on your OS:
+- [Android Debug Bridge](https://developer.android.com/tools/releases/platform-tools)
+
+## Installing ADB (Host Computer)
+
+The ADB command line tool is supported on MacOS, Windows & Linux. For more specific instructions for your OS, see the sections below.
+
+***You can find more information and download the latest version for the tool for all operating systems directly from the [Android SDK Platform Tools](https://developer.android.com/tools/releases/platform-tools#downloads) page.***
+
+### MacOS
+
+To install the ADB tools on **MacOS**, we can use `homebrew`. Open the terminal and run the following command:
+
+```bash
+brew install android-platform-tools
+```
+
+To verify the tool is installed, run `adb version`.
+
+### Windows
+
+To install the ADB tools on **Windows**, we can use `winget`, supported on Windows 11 and on some earlier Windows 10 versions.
+
+Open a terminal and run the following:
+
+```bash
+winget install Google.PlatformTools
+```
+
+To verify the tool is installed, run `adb version`.
+
+### Linux
+
+To install ADB tools on a **Debian/Ubuntu Linux distribution**, open a terminal and run the following command:
+
+```bash
+sudo apt-get install android-sdk-platform-tools
+```
+
+To verify the tool is installed, run `adb version`.
+
+## Connect via ADB
+
+1. Connect the UNO Q board to your computer via USB-C®.
+2. Run `adb devices` in the terminal. This should list the connected devices.
+
+ 
+
+>Note that it may take up to a minute for the device to appear after connecting it.
+
+3. Run `adb shell`. If you have not set up your board prior to this via the Arduino App Lab, you may be required to provide a password, which is `arduino`.
+4. You should now be inside your board's terminal.
+
+ 
+
+5. You are now able to run commands via the terminal on your board! To exit from the terminal, simply type `exit`.
+
+## Summary
+
+Connecting via ADB is an easy way to gain access to your board's shell, allowing you to perform actions such as installing packages, editing files and running scripts.
+
+The `arduino-app-cli` can also be used directly via the shell, allowing you to launch Apps directly from the command line. You can read more about that in the link below:
+- [Arduino App CLI: Manage Apps from the Command Line](/software/app-lab/tutorials/cli/)
\ No newline at end of file
diff --git a/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/assets/board-terminal.png b/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/assets/board-terminal.png
new file mode 100644
index 0000000000..3a83ffa5ee
Binary files /dev/null and b/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/assets/board-terminal.png differ
diff --git a/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/assets/connected-devices.png b/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/assets/connected-devices.png
new file mode 100644
index 0000000000..ed27cffab4
Binary files /dev/null and b/content/hardware/02.uno/boards/uno-q/tutorials/06.adb/assets/connected-devices.png differ
diff --git a/content/hardware/02.uno/shields/4-relays-shield/product.md b/content/hardware/02.uno/shields/4-relays-shield/product.md
index 6218de704d..65e407f525 100644
--- a/content/hardware/02.uno/shields/4-relays-shield/product.md
+++ b/content/hardware/02.uno/shields/4-relays-shield/product.md
@@ -8,4 +8,5 @@ forumCategorySlug: '/hardware/12'
sku: [A000110]
---
-The Arduino 4 Relays Shield allows your Arduino driving high power loads.
\ No newline at end of file
+The Arduino 4 Relays Shield allows your Arduino to drive high power loads.
+
diff --git a/content/hardware/03.nano/boards/nano-r4/certifications/Arduino_ABX00142-DoC_CE.pdf b/content/hardware/03.nano/boards/nano-r4/certifications/Arduino_ABX00142-DoC_CE.pdf
new file mode 100644
index 0000000000..02df18594a
Binary files /dev/null and b/content/hardware/03.nano/boards/nano-r4/certifications/Arduino_ABX00142-DoC_CE.pdf differ
diff --git a/content/hardware/03.nano/boards/nano-r4/certifications/Arduino_ABX00142-DoC_UKCA.pdf b/content/hardware/03.nano/boards/nano-r4/certifications/Arduino_ABX00142-DoC_UKCA.pdf
new file mode 100644
index 0000000000..87a4b25413
Binary files /dev/null and b/content/hardware/03.nano/boards/nano-r4/certifications/Arduino_ABX00142-DoC_UKCA.pdf differ
diff --git a/content/hardware/03.nano/carriers/nano-connector-carrier/tutorials/getting-started-nano-connector-carrier/content.md b/content/hardware/03.nano/carriers/nano-connector-carrier/tutorials/getting-started-nano-connector-carrier/content.md
index b30444f240..44b9f28ada 100644
--- a/content/hardware/03.nano/carriers/nano-connector-carrier/tutorials/getting-started-nano-connector-carrier/content.md
+++ b/content/hardware/03.nano/carriers/nano-connector-carrier/tutorials/getting-started-nano-connector-carrier/content.md
@@ -46,7 +46,7 @@ The Qwiic connector uses a 4-pin JST SH connector (P/N: SM04B-SRSS-TB(LF)(SN)) w
| Pin | Connection |
|-----|------------------------------------------|
| GND | Ground |
-| VCC | +3.3 VDC/ +5 VDC (selected by the input selector switch) |
+| VCC | +3.3 VDC |
| SDA | I²C Data (connected to the A4 pin of the Nano board) |
| SCL | I²C Clock (connected to the A5 pin of the Nano board) |
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/user-manual-4.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/boards-manager.png
similarity index 100%
rename from content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/user-manual-4.png
rename to content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/boards-manager.png
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/library-installation.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/library-installation.png
new file mode 100644
index 0000000000..d126a054d3
Binary files /dev/null and b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/library-installation.png differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/library-repository.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/library-repository.png
new file mode 100644
index 0000000000..92b1796d06
Binary files /dev/null and b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/library-repository.png differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/nearbydemo-serial-monitor.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/nearbydemo-serial-monitor.png
new file mode 100644
index 0000000000..e7ea5f0377
Binary files /dev/null and b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/nearbydemo-serial-monitor.png differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-portenta-serial.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-portenta-serial.png
new file mode 100644
index 0000000000..f832d2aa9f
Binary files /dev/null and b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-portenta-serial.png differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-serial-plotter.gif b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-serial-plotter.gif
new file mode 100644
index 0000000000..3c1dbcc200
Binary files /dev/null and b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-serial-plotter.gif differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-stella-serial.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-stella-serial.png
new file mode 100644
index 0000000000..a0669bee84
Binary files /dev/null and b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/twr-stella-serial.png differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/user-manual-3.png b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/user-manual-3.png
deleted file mode 100644
index 4ff31b5393..0000000000
Binary files a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/assets/user-manual-3.png and /dev/null differ
diff --git a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/content.md b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/content.md
index fa806f8cdb..ff7b294996 100644
--- a/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/content.md
+++ b/content/hardware/04.pro/shields/portenta-uwb-shield/tutorials/01.user-manual/content.md
@@ -26,22 +26,24 @@ This user manual provides a comprehensive overview of the Portenta UWB Shield, h
- [Portenta UWB Shield (SKU: ASX00074)](https://store.arduino.cc/products/portenta-uwb-shield) (x1)
- [Portenta C33 (SKU: ABX00074)](https://store.arduino.cc/products/portenta-c33) (x1)
-- [Arduino Stella (SKU: ABX00131)](https://store.arduino.cc/products/stella) (x1)
+- [Arduino Stella (SKU: ABX00131)](https://store.arduino.cc/products/stella) (x1) (optional, for Two-Way Ranging examples)
- [USB-C® cable (SKU: TPX00094)](https://store.arduino.cc/products/usb-cable2in1-type-c) (x2)
+- External antenna (x1) (optional, for Bluetooth® Low Energy functionality)
### Software Requirements
-- [Arduino IDE 2.0+](https://www.arduino.cc/en/software)
+- [Arduino IDE](https://www.arduino.cc/en/software)
- [`PortentaUWBShield` library](https://github.com/Truesense-it/PortentaUWBShield) (designed for the Portenta UWB Shield)
-- [`StellaUWB` library](https://github.com/Truesense-it/StellaUWB) (designed for the Arduino Stella)
-- [`ArduinoBLE` library](https://github.com/arduino/ArduinoBLE)
-- [Arduino Renesas Portenta Boards core](https://github.com/arduino/ArduinoCore-renesas) (required to work with the Portenta C33 board)
+- [`StellaUWB` library](https://github.com/Truesense-it/StellaUWB) (optional, for Two-Way Ranging with Arduino Stella)
+- [`ArduinoBLE` library](https://github.com/arduino-libraries/ArduinoBLE) (for Bluetooth® Low Energy examples)
+- [Arduino Renesas Portenta Boards core](https://github.com/arduino/ArduinoCore-renesas) (required for the Portenta C33 microcontroller)
+- [Arduino Mbed OS Stella Boards core](https://github.com/arduino/ArduinoCore-mbed) (optional, for Arduino Stella in Two-Way Ranging examples)
-***The Portenta UWB Shield is not intended as a standalone device but as a shield to work alongside a Portenta family board. In this user manual, we will use the Portenta C33 as the main board and show how to use the Portenta UWB Shield with it.***
+***The Portenta UWB Shield is not intended as a standalone device but as a shield to work alongside a Portenta family board. In this user manual, we will use the Portenta C33 as the host board and demonstrate how to implement UWB functionality for real-time location services and precise ranging applications.***
## Portenta UWB Shield Overview
-Enhance your positioning and real-time location capabilities with the Portenta UWB Shield. Based on the Truesense DCU150 module, this versatile Ultra-Wideband (UWB) communication solution integrates with the Portenta C33 board via its High-Density connectors and functions as a base station for two-way ranging and real-time location services (RTLS).
+Enhance your positioning and real-time location capabilities with the Portenta UWB Shield. Based on the Truesense [DCU150](https://ultrawideband.truesense.it/wp-content/uploads/2022/07/TRUESENSE-DCU150_Datasheet.pdf) Ultra-Wide Band (UWB) module, this versatile Ultra-Wideband (UWB) communication solution integrates with the Portenta C33 board via its High-Density connectors and functions as a base station for two-way ranging and real-time location services (RTLS).

@@ -108,7 +110,7 @@ In an UWB positioning system, devices typically operate in one of two roles:
- **Anchors**: Fixed-position devices (like the Portenta UWB Shield with a Portenta C33) that provide reference points for the positioning system. A minimum of three anchors is typically needed for 2D positioning and four for 3D positioning.
- **Tags**: Mobile devices that communicate with anchors to determine their position in space. Tags can be standalone devices like the Arduino Stella or integrated into smartphones, wearables, or other IoT devices.
-#### Applications of UWB Technology
+#### Applications of the Portenta UWB Shield with UWB Technology
UWB's unique combination of precision, low latency, and security opens up numerous applications:
@@ -150,7 +152,7 @@ Here's an overview of the shield's main components shown in the images:
### Board Libraries
-The Portenta UWB Shield and the Arduino Stella use different libraries and board cores due to their different microcontrollers and onboard UWB modules:
+The Portenta UWB Shield and Arduino Stella use different libraries and board cores due to their different microcontrollers and onboard UWB modules:
#### Portenta UWB Shield Library
@@ -160,37 +162,58 @@ The [`PortentaUWBShield` library](https://github.com/Truesense-it/PortentaUWBShi
- Angle of Arrival (AoA) measurement for 2D and 3D positioning.
- SPI and GPIO communication with the host board through dedicated level translators.
-***The [Arduino Renesas Portenta Boards core](https://github.com/arduino/ArduinoCore-renesas) is required to work with the Portenta C33 board that hosts the UWB Shield in this User Manual.***
+***The [Arduino Renesas Portenta Boards core](https://github.com/arduino/ArduinoCore-renesas) is required to work with the Portenta C33 board that hosts the UWB Shield.***
#### Arduino Stella Library
-For two-way ranging experiments between the Portenta UWB Shield and Arduino Stella, you'll also need the [`StellaUWB` library](https://github.com/Truesense-it/StellaUWB). This library provides similar functionality but is specifically optimized for the DCU040 module in the Stella board.
+If you plan to use the Portenta UWB Shield with an Arduino Stella for two-way ranging, you will also need the [`StellaUWB` library](https://github.com/Truesense-it/StellaUWB) for the Arduino Stella. This library is specifically designed for the DCU040 module used in the Stella board.
-***The Arduino mbed OS Boards core is required to work with Stella's nRF52840 microcontroller.***
+***The [Arduino Mbed OS Stella Boards core](https://github.com/arduino/ArduinoCore-mbed) is required to work with the Arduino Stella's nRF52840 microcontroller.***
#### Bluetooth® Communication
-For examples that use Bluetooth® Low Energy communication (like the Nearby Demo), you'll also need the [`ArduinoBLE` library](https://github.com/arduino/ArduinoBLE). This library enables Bluetooth Low Energy communication functionality for device discovery and initial connection setup before UWB ranging begins.
+For examples that use Bluetooth® Low Energy communication, you'll also need the [`ArduinoBLE` library](https://github.com/arduino/ArduinoBLE). This library enables Bluetooth® Low Energy functionality for device discovery and initial connection setup before UWB ranging begins.
-#### Installing the Libraries and Board Cores
+#### Installing the Libraries
-To install the required libraries:
+To install the required libraries, follow these steps:
-1. Navigate to `Tools > Manage libraries...` or click the **Library Manager** icon in the left tab of the Arduino IDE.
-2. In the Library Manager tab, search for the library name (`PortentaUWBShield`, `StellaUWB`, or `ArduinoBLE`).
-3. Click "Install" to install the latest version of each library.
+**Step 1: Download the library ZIP file**
-
+- Visit the library's GitHub repository using the links provided above
+- Click the green Code button
+- Select Download ZIP from the dropdown menu
+- Save the ZIP file to your computer
+
+
+
+**Step 2: Install the library in Arduino IDE**
+
+- Open the Arduino IDE
+- Navigate to `Sketch > Include Library > Add .ZIP Library...`
+- Browse to the location where you saved the ZIP file
+- Select the ZIP file and click Open
+- The library will be automatically installed and ready to use
+
+
+
+**Step 3: Verify the library installation**
+
+- Go to `Sketch > Include Library`
+- Scroll down to see if the library appears in the `Contributed libraries` list
+- You can also check `File > Examples` to see if example sketches from the library are available
+
+#### Installing the Board Cores
To install the required board cores:
-1. Navigate to `Tools > Board > Boards Manager...`
-2. For the Portenta C33: Search for "Arduino Renesas Boards" and install the latest version.
-3. For the Arduino Stella (if using two-way ranging examples): Search for `Arduino mbed OS Boards` and install the latest version.
+- Navigate to `Tools > Board > Boards Manager...`
+- For the Portenta C33, search for `Arduino Renesas Portenta Boards` and install the latest version
+- For the Arduino Stella (if using two-way ranging examples), search for `Arduino Mbed OS Stella Boards` and install the latest version
-
+
-***Important note: Make sure to install both the appropriate library and board core for your specific hardware. The Portenta UWB Shield with Portenta C33 requires the `PortentaUWBShield` library and Arduino Renesas Boards core. For examples involving Arduino Stella, you'll need the `StellaUWB` library and Arduino mbed OS Boards core. For examples involving Bluetooth® Low Energy communication, both devices will need the `ArduinoBLE` library installed.***
+***Important note: Make sure to install both the appropriate library and board core for your specific hardware. The Portenta UWB Shield with Portenta C33 requires the `PortentaUWBShield` library and `Arduino Renesas Portenta Boards` core, while the Arduino Stella requires the `StellaUWB` library and `Arduino Mbed OS Stella Boards` core.***
### Pinout
@@ -259,26 +282,39 @@ The `Nearby World` example demonstrates the core functionality of UWB technology
1. **Bluetooth® Low Energy connection setup**: The Portenta UWB Shield establishes a Bluetooth Low Energy connection with a compatible smartphone app.
2. **Configuration exchange**: The Bluetooth Low Energy connection is used to exchange necessary UWB configuration parameters.
3. **UWB ranging**: Once configured, the actual UWB ranging session begins, providing precise distance measurements.
-4. **Real-time feedback**: Distance data is continuously updated and can be viewed on the IDE's Serial Monitor and the smartphone app.
+4. **Real-time updates**: The system continuously calculates and displays distance measurements between the devices.
-This process demonstrates the working principle of many UWB applications, where Bluetooth Low Energy is used primarily for discovery and configuration, while UWB handles the precise ranging.
+This process demonstrates the working principle of many UWB applications, where Bluetooth® Low Energy is used primarily for discovery and configuration, while UWB handles the precise ranging.
#### Uploading the Sketch
-First, connect the Portenta UWB Shield to the Portenta C33 as described in the [Connecting the Shield section](#connecting-the-shield). Now, connect the Portenta C33 to your computer using a USB-C cable, open the Arduino IDE and connect the board to it.
+**Step 1: Verify Board Selection**
-***If you are new to the Portenta C33, please refer to the board's [user manual](https://docs.arduino.cc/tutorials/portenta-c33/user-manual/) for more detailed information.***
+Before uploading any code to the Arduino Stella, ensure you have selected the correct board:
+
+1. Connect the Portenta C33 to your computer using a USB-C cable
+2. Open the Arduino IDE
+3. **Critical**: Navigate to `Tools > Board > Arduino Renesas Portenta Boards > Portenta C33`
+4. Verify the correct port is selected in `Tools > Port`
+
+**Step 2: Upload the Sketch**
Copy and paste the example sketch below into a new sketch in the Arduino IDE:
-```arduino
+```arduino
/**
- Nearby Demo Example for Portenta UWB Shield
- Name: portenta_uwb_nearby.ino
+ Nearby World Example for the Portenta UWB Shield
+ Name: portenta_uwb_shield_nearby_world.ino
Purpose: This sketch demonstrates how to use the Portenta UWB Shield
- to measure distance between the shield and a UWB-enabled smartphone.
+ to measure distance between the board and a UWB-enabled smartphone.
+
+ Compatible with:
+ - NXP Trimensions AR (iOS)
+ - Qorvo Nearby Interaction (iOS)
+ - NXP Android demo
+ - Truesense Android demo
- @author Pierpaolo Lento from Truesense, modified by the Arduino Product Experience Team
+ @author Arduino Product Experience Team
@version 1.0 15/04/25
*/
@@ -286,7 +322,7 @@ Copy and paste the example sketch below into a new sketch in the Arduino IDE:
#include
#include
-// Track the number of connected Bluetooth® Low Energy clients
+// Track the number of connected Bluetooth Low Energy clients
uint16_t numConnected = 0;
/**
@@ -296,57 +332,55 @@ uint16_t numConnected = 0;
void rangingHandler(UWBRangingData &rangingData) {
Serial.print("- GOT RANGING DATA - Type: ");
Serial.println(rangingData.measureType());
-
+
// Nearby interaction uses Double-sided Two-way Ranging method
- if(rangingData.measureType()==(uint8_t)uwb::MeasurementType::TWO_WAY) {
+ if(rangingData.measureType() == (uint8_t)uwb::MeasurementType::TWO_WAY) {
// Get the TWR (Two-Way Ranging) measurements
RangingMeasures twr = rangingData.twoWayRangingMeasure();
// Loop through all available measurements
- for(int j=0; jImportant note for Android devices: If Developer Mode is currently enabled on your Android device, please ensure all radio-related options remain at their default settings. We recommend keeping Developer Mode disabled for optimal UWB functionality. If you previously enabled it, consider disabling it for the most stable device operation.***
+***__Important note for Android devices:__ If Developer Options is currently enabled on your Android device, please ensure all radio-related options remain at their default settings. We recommend keeping Developer Options disabled for optimal UWB functionality. If you previously enabled it, consider disabling it for the most stable device operation.***
Install one of these apps on your smartphone and follow these steps:
-1. Open the app on your smartphone.
-2. Look for a device named `Portenta UWB Shield` in the app's device list.
-3. Connect to the device.
-4. Once connected, the app will begin an UWB ranging session.
-5. Move your phone closer to and further from the Portenta UWB Shield.
+1. Open the app on your smartphone
+2. Look for a device named `Portenta UWB Shield` in the app's device list
+3. Connect to the device
+4. Once connected, the app will initiate a UWB ranging session
+5. Move your phone closer to and further from the Portenta UWB Shield
+
+The smartphone app shows the connection status and continuously updates the distance measurement as you move the phone. Both the app and the Serial Monitor display synchronized measurements in millimeters.
-You should see the distance measurements updating in real-time both on your smartphone app and in the IDE's Serial Monitor. The distances are shown in millimeters, providing centimeter-level accuracy characteristic of the UWB technology.
+You should see the distance measurements updating in real-time both on your smartphone app and in the IDE's Serial Monitor. The distances are shown in millimeters, providing centimeter-level accuracy characteristic of UWB technology.
## NearbyDemo Example
### About the NearbyDemo Example
-The NearbyDemo example sketch is a fundamental demonstration of the Portenta UWB Shield's core capabilities. This example showcases how to implement a direct distance measurement system between a stationary UWB device (the Portenta UWB Shield, acting as an UWB anchor) and a mobile UWB device (the UWB-enabled smartphone, acting as an UWB tag).
+***__Before you begin__: Ensure you have selected `Tools > Board > Arduino Renesas Portenta Boards > Portenta C33` in the Arduino IDE.***
-This example sketch demonstrates the following:
+The `NearbyDemo` example sketch demonstrates how to implement distance measurement between the Portenta UWB Shield with the Portenta C33 board and UWB-enabled smartphones using Apple's Nearby Interaction protocol or compatible Android implementations. This example showcases how Bluetooth® Low Energy is used for initial device discovery and configuration exchange, while UWB handles the precise distance measurements.
-- **Hybrid communication protocol:** It shows the integration of Bluetooth® Low Energy for device discovery and configuration with UWB for precise distance measurements, a common pattern in production UWB applications.
-- **Standards compatibility:** The implementation is compatible with Apple's Nearby Interaction API and similar Android standards, demonstrating how the Arduino ecosystem can interact with mainstream consumer devices.
-- **Foundation for advanced applications:**: The ranging capability demonstrated is the building block for more sophisticated applications such as indoor positioning systems, geofencing, secure access and proximity-based automation.
+This example demonstrates the following:
-Some of the real-life applications for this example sketch are the following:
+- **Hybrid communication protocol**: Integration of Bluetooth® Low Energy for device discovery and configuration with UWB for precise distance measurements
+- **Standards compatibility**: Compatible with Apple's Nearby Interaction API and Android UWB implementations
+- **Power-efficient design**: UWB subsystem only activates when a client connects, conserving battery life
+- **Multi-client support**: Can handle connections from multiple smartphones simultaneously
-- **Industrial automation:** Creating safety zones around machinery that can detect when workers approach with centimeter precision.
-- **Smart buildings:** Enabling location-aware services within facilities where GPS is unavailable.
-- **Healthcare:** Tracking the movement of patients, staff and equipment with high accuracy.
-- **Retail:** Implementing contactless payment systems with a higher degree of security than current NFC solutions.
-- **Consumer electronics:** Enabling precise "Find My Device" features and spatial awareness between gadgets.
+Real-world applications for this example include:
-Now, let's take a closer look at the sketch:
+- **Asset tracking**: Precisely locate Portenta UWB Shield-based devices attached to valuable items using smartphones
+- **Smart building automation**: Implement room-level presence detection for environmental control
+- **Healthcare**: Track movement of equipment and personnel with smartphone-based monitoring
+- **Retail analytics**: Analyze customer movement patterns using their smartphones
+- **Consumer item finding**: Create smartphone-compatible tags for locating misplaced items
+
+Here's the complete code for the `NearbyDemo` example sketch:
```arduino
/**
- Nearby Demo Example for Portenta UWB Shield
- Name: portenta_uwb_nearby.ino
+ Nearby World Example for the Portenta UWB Shield
+ Name: portenta_uwb_shield_nearby_world.ino
Purpose: This sketch demonstrates how to use the Portenta UWB Shield
- to measure distance between the shield and an UWB-enabled smartphone.
+ to measure distance between the board and a UWB-enabled smartphone.
+
+ Compatible with:
+ - NXP Trimensions AR (iOS)
+ - Qorvo Nearby Interaction (iOS)
+ - NXP Android demo
+ - Truesense Android demo
- @author Pierpaolo Lento from Truesense, modified by the Arduino Product Experience Team
+ @author Arduino Product Experience Team
@version 1.0 15/04/25
*/
@@ -459,7 +504,7 @@ Now, let's take a closer look at the sketch:
#include
#include
-// Track the number of connected BLE clients
+// Track the number of connected Bluetooth Low Energy clients
uint16_t numConnected = 0;
/**
@@ -469,57 +514,55 @@ uint16_t numConnected = 0;
void rangingHandler(UWBRangingData &rangingData) {
Serial.print("- GOT RANGING DATA - Type: ");
Serial.println(rangingData.measureType());
-
+
// Nearby interaction uses Double-sided Two-way Ranging method
- if(rangingData.measureType()==(uint8_t)uwb::MeasurementType::TWO_WAY) {
+ if(rangingData.measureType() == (uint8_t)uwb::MeasurementType::TWO_WAY) {
// Get the TWR (Two-Way Ranging) measurements
RangingMeasures twr = rangingData.twoWayRangingMeasure();
// Loop through all available measurements
- for(int j=0; j
@@ -578,37 +627,31 @@ The `NearbyDemo` code follows an event-driven architecture that employs callback
uint16_t numConnected = 0;
```
-The code includes two essential libraries:
+The example sketch uses two important libraries for its operation:
- `ArduinoBLE`: Provides Bluetooth® Low Energy functionality for device discovery and initial connection.
-- `PortentaUWBShield`: The core library that enables interaction with the UWB hardware on the Portenta UWB Shield.
+- `PortentaUWBShield`: The core library that enables interaction with the onboard UWB module of the Portenta UWB Shield.
+
+The `numConnected` variable tracks how many Bluetooth® Low Energy clients are currently connected to the Portenta UWB Shield.
-The `numConnected` variable tracks how many Bluetooth Low Energy clients are currently connected to the Portenta UWB Shield.
+- **Ranging Data Handler**
-1. **Ranging Data Handler**
+The heart of the UWB functionality resides in the ranging callback:
```arduino
void rangingHandler(UWBRangingData &rangingData) {
- // ...
- if(rangingData.measureType()==(uint8_t)uwb::MeasurementType::TWO_WAY) {
+ if(rangingData.measureType() == (uint8_t)uwb::MeasurementType::TWO_WAY) {
RangingMeasures twr = rangingData.twoWayRangingMeasure();
- // ...
- if(twr[j].status==0 && twr[j].distance!=0xFFFF) {
- Serial.print("Distance: ");
- Serial.println(twr[j].distance);
- }
+ // Process measurements...
}
}
```
-This callback function is the heart of the UWB functionality:
+This function processes incoming distance measurements, validates the data integrity, and outputs results to the IDE's Serial Monitor. The validation checks ensure only valid measurements are displayed (`status = 0` and `distance ≠ 0xFFFF`).
-- It's triggered whenever new ranging data is received from the UWB subsystem.
-- It checks if the measurement type is *Two-Way Ranging (TWR)*.
-- It validates the measurement (`status = 0` indicates a valid measurement, while `distance = 0xFFFF` is a reserved value indicating an invalid distance).
-- It extracts the distance measurements in millimeters and prints them to the IDE's Serial Monitor.
+- **Connection Management**
-1. **Connection Management**
+The connection callbacks manage the UWB subsystem lifecycle efficiently:
```arduino
void clientConnected(BLEDevice dev) {
@@ -617,62 +660,41 @@ void clientConnected(BLEDevice dev) {
}
numConnected++;
}
-
-void clientDisconnected(BLEDevice dev) {
- UWBSession sess = UWBNearbySessionManager.find(dev);
- sess.stop();
- numConnected--;
- if(numConnected==0) {
- UWB.end();
- }
-}
```
-These functions handle Bluetooth® Low Energy connection events:
+This power-saving approach ensures the UWB hardware only activates when needed, extending battery life in portable applications.
-- `clientConnected` initializes the UWB subsystem when the first client connects.
-- `clientDisconnected` shuts down the UWB subsystem when no clients are connected.
-
-This approach saves power by only running the shield's UWB hardware when it's needed.
-
-4. **Session Management**
+- **Session Management**
```arduino
void sessionStarted(BLEDevice dev) {
- Serial.println("Session started!");
-}
-
-void sessionStopped(BLEDevice dev) {
- Serial.println("Session stopped!");
+ Serial.println("- Session started!");
}
```
-These callbacks track the UWB session state:
+These functions provide feedback about the session lifecycle, helping developers understand the connection state during debugging.
-- A session begins after the Bluetooth® Low Energy connection is established and the UWB configuration is exchanged.
-- A session ends when the UWB communication is terminated, either by the client disconnecting or other factors.
+- **Setup and Initialization**
-5. **Setup and Initialization**
+The setup function registers all callbacks and starts Bluetooth® Low Energy advertising:
```arduino
void setup() {
- // ...
+ // Register all callbacks
UWB.registerRangingCallback(rangingHandler);
UWBNearbySessionManager.onConnect(clientConnected);
- UWBNearbySessionManager.onDisconnect(clientDisconnected);
- UWBNearbySessionManager.onSessionStart(sessionStarted);
- UWBNearbySessionManager.onSessionStop(sessionStopped);
+ // ... other callbacks
- UWBNearbySessionManager.begin("Portenta UWB Shield");
+ // Start advertising with device name
+ UWBNearbySessionManager.begin("TS_DCU150");
}
```
-The setup function:
+The device name `TS_DCU150` appears in smartphone apps when scanning for available UWB devices.
-- Registers all the callback functions with the UWB subsystem.
-- Initializes the Bluetooth® Low Energy advertising with the name `Portenta UWB Shield`. This name is what will appear in the smartphone app's device list.
+- **Main Loop**
-1. **Main Loop**
+The main loop maintains the Bluetooth® Low Energy connection:
```arduino
void loop() {
@@ -681,81 +703,135 @@ void loop() {
}
```
-The main loop is quite simple:
+The `poll()` function processes Bluetooth® Low Energy events while the actual UWB ranging occurs asynchronously through callbacks.
-- It calls the `UWBNearbySessionManager.poll()` function to process Bluetooth® Low Energy events.
-- The actual UWB ranging happens asynchronously through the callback system.
-
-This event-driven architecture allows the system to respond quickly to UWB and Bluetooth Low Energy events without blocking the main program flow.
+### Testing with Smartphones
+
+To test this example with a UWB-enabled smartphone:
+
+1. Upload the sketch to your Portenta C33
+2. Open the IDE's Serial Monitor at 115200 baud
+3. Install a compatible app on your smartphone:
+
+- **For iOS**: NXP® Trimensions AR or Qorvo Nearby Interaction
+- **For Android**: Truesense or NXP® UWB demo apps
+
+4. Connect to the device named "Portenta UWB Shield" in the app
+5. Move your phone to see distance measurements update in real-time
+
+The smartphone app displays the connection status and real-time distance to the Portenta UWB Shield. Once connected, both the app and the IDE's Serial Monitor will show synchronized distance measurements as you move the phone. The distance measurements are displayed in millimeters, providing centimeter-level accuracy. For example, a reading of "Distance: 80" indicates approximately 8 cm between devices.
+
+***__Important note__: If the connection fails or no measurements appear, verify that your smartphone has UWB enabled and that the Portenta C33 is powered on and running the sketch.***
### Extending the Example Sketch
-The `NearbyDemo` example sketch provides a great foundation that you can build upon for more complex projects. Some possible extensions of this sketch include the following:
+The `NearbyDemo` example sketch provides a great foundation that you can build upon for more complex projects. Some possible extensions of this example sketch include the following:
-- **Adding visual feedback:** Using LEDs or displays to indicate distance ranges.
-- **Implementing proximity alerts:** Triggering actions when devices come within a certain distance.
-- **Data logging:** Recording distance measurements for analysis and visualization.
-- **Integrating with other sensors:** Combining UWB data with other environmental sensors for context-aware applications.
+- **Visual feedback**: Add LED patterns based on distance thresholds
+- **Audio alerts**: Implement buzzer feedback for proximity warnings
+- **Motion detection**: Combine accelerometer data with ranging for activity monitoring
+- **Data logging**: Record distance measurements for analysis
+- **Custom device names**: Modify the advertising name for multiple device deployments
-***Note: If you want to try this example yourself, please follow the same steps described in the [Nearby World Example](#nearby-world-example) section. The process for uploading the sketch and testing it with a smartphone is the same.***
+The event-driven architecture makes it easy to add features without disrupting the core ranging functionality.
## Two-Way Ranging Example
### About the Two-Way Ranging Example
-The Two-Way Ranging example demonstrates direct UWB communication between two Arduino devices: the Portenta UWB Shield (acting as a Controlee/Responder) and the Arduino Stella (acting as a Controller/Initiator). This example showcases the fundamental distance measurement capabilities of UWB technology in a dedicated device-to-device setup without requiring external UWB-enabled consumer devices such as smartphones.
+**📋 Hardware Setup Reminder:**
-***Note: In UWB communication, the terms "Controller" and "Controlee" refer to specific roles within a ranging session. A __Controller__ (also called an Initiator) is the device that initiates and controls the ranging process, sending the initial signal and managing the timing of exchanges. A __Controlee__ (also called a Responder) is the device that responds to the Controller's signals. These terms are used interchangeably in UWB documentation: Controller/Initiator and Controlee/Responder refer to the same roles. In positioning systems, Controllers/Initiators often correspond to mobile "tags" while Controlees/Responders often serve as stationary "anchors".***
+- **For the Arduino Stella:** Select `Tools > Board > Arduino Mbed OS Stella Boards > Arduino Stella` on the Arduino IDE
+- **For the Portenta C33 board and the UWB Shield:** Select `Tools > Board > Arduino Renesas Portenta Boards > Portenta C33` on the Arduino IDE
+
+The Two-Way Ranging example demonstrates direct UWB communication between two Arduino devices: the Arduino Stella (acting as a Controller/Initiator) and the Portenta UWB Shield (acting as a Controlee/Responder). This example showcases the fundamental distance measurement capabilities of UWB technology in a dedicated device-to-device setup without requiring external UWB-enabled consumer devices such as smartphones.
+
+***__Important note__: In UWB communication, the terms "Controller" and "Controlee" refer to specific roles within a ranging session. A __Controller__ (also called an Initiator) is the device that initiates and controls the ranging process, sending the initial signal and managing the timing of exchanges. A __Controlee__ (also called a Responder) is the device that responds to the Controller's signals. These terms are used interchangeably in UWB documentation: Controller/Initiator and Controlee/Responder refer to the same roles. In positioning systems, Controllers/Initiators often correspond to mobile "tags" while Controlees/Responders often serve as stationary "anchors".***
This example demonstrates the following:
- **Direct device-to-device communication:** Unlike the `NearbyDemo` example, which requires a smartphone, this example establishes direct UWB communication between two UWB-enabled Arduino devices.
- **Controller-Controlee architecture:** It shows how to configure one device as a Controller (initiator of the ranging) and another as a Controlee (responder).
- **Double-Sided Two-Way Ranging (DS-TWR):** This technique provides higher accuracy in distance measurements by accounting for clock drift between devices.
-- **Simple MAC addressing:** The implementation shows how to use short MAC addresses for device identification in UWB networks.
+- **Visual feedback system**: Both devices provide LED feedback to indicate connection status and distance measurements.
+- **Real-time distance visualization**: The Portenta C33 displays both raw measurements and smoothed moving average for analysis.
Some of the real-life applications for this example include:
-- **Multi-node positioning systems:** Creating networks of UWB nodes for advanced indoor positioning.
-- **Robot navigation:** Enabling precise distance measurements between robots or between robots and fixed stations.
-- **Asset tracking:** Building custom tracking solutions with multiple Arduino-based UWB anchors.
-- **Proximity detection systems:** Creating safety systems that can detect precise distances between industrial equipment and personnel.
-- **Interactive installations:** Enabling position-based interactive exhibits in museums or public spaces.
+- **Multi-node positioning systems**: Creating networks of UWB nodes for advanced indoor positioning.
+- **Robot navigation**: Enabling precise distance measurements between robots or between robots and fixed stations.
+- **Asset tracking**: Building custom tracking solutions with multiple Arduino-based UWB anchors.
+- **Proximity detection systems**: Creating safety systems that can detect precise distances between industrial equipment and personnel.
+- **Access control systems**: Implementing secure entry systems based on precise proximity detection.
+- **Interactive installations**: Enabling position-based interactive exhibits in museums or public spaces
-Here's the code for the Portenta UWB Shield, which acts as the Controlee (Responder) in this Two-Way Ranging scenario:
+Here's the code for the Arduino Stella, which acts as the Controller (Initiator) in this Two-Way Ranging scenario.
+
+**📋 Board Selection Check:** Ensure `Arduino Stella` is selected in the Arduino IDE before uploading this code.
```arduino
/**
- Two-Way Ranging Controlee Example for Portenta UWB Shield
- Name: portenta_uwb_twr_controlee.ino
- Purpose: This sketch configures the Portenta UWB Shield as a Controlee (Responder)
- for Two-Way Ranging with an Arduino Stella configured as Controller.
+ Two-Way Ranging Controller Example for Arduino Stella
+ Name: stella_uwb_twr_controller.ino
+ Purpose: This sketch configures the Arduino Stella as a Controller (Initiator)
+ for Two-Way Ranging with a Portenta UWB Shield configured as Controlee.
+ The LED provides visual feedback based on measured distance.
- @author Pierpaolo Lento from Truesense, modified by the Arduino Product Experience Team
+ @author Arduino Product Experience Team
@version 1.0 15/04/25
*/
// Include required UWB library
-#include
+#include
+
+// Pin definitions
+#define LED_PIN p37 // Stella's built-in LED for status indication
+
+// Distance and timing parameters
+#define MAX_DISTANCE 300 // Maximum distance to consider (cm)
+#define MIN_BLINK_TIME 50 // Fastest blink rate (ms)
+#define MAX_BLINK_TIME 1000 // Slowest blink rate (ms)
+#define TIMEOUT_MS 2000 // Connection timeout (ms)
+
+// System state variables
+unsigned long lastBlink = 0;
+unsigned long lastMeasurement = 0;
+bool ledState = false;
+int currentBlinkInterval = MAX_BLINK_TIME;
+long lastDistance = MAX_DISTANCE;
/**
Processes ranging data received from UWB communication.
+ Updates LED feedback based on measured distance.
@param rangingData Reference to UWB ranging data object.
*/
void rangingHandler(UWBRangingData &rangingData) {
- Serial.print("- GOT RANGING DATA - Type: ");
- Serial.println(rangingData.measureType());
- if(rangingData.measureType()==(uint8_t)uwb::MeasurementType::TWO_WAY) {
+ if (rangingData.measureType() == (uint8_t)uwb::MeasurementType::TWO_WAY) {
// Get the TWR (Two-Way Ranging) measurements
- RangingMeasures twr=rangingData.twoWayRangingMeasure();
-
+ RangingMeasures twr = rangingData.twoWayRangingMeasure();
+
// Loop through all available measurements
- for(int j=0;j MAX_DISTANCE) {
+ currentBlinkInterval = MAX_BLINK_TIME;
+ } else {
+ // Map distance to blink interval
+ currentBlinkInterval = map(lastDistance,
+ 0, MAX_DISTANCE,
+ MIN_BLINK_TIME, MAX_BLINK_TIME);
+ }
+
+ // Display the distance measurement in centimeters
+ Serial.print("- Distance (cm): ");
+ Serial.println(lastDistance);
}
}
}
@@ -765,106 +841,147 @@ void setup() {
// Initialize serial communication at 115200 bits per second
Serial.begin(115200);
- #if defined(ARDUINO_PORTENTA_C33)
- // Only the Portenta C33 has an RGB LED
- pinMode(LEDR, OUTPUT);
- digitalWrite(LEDR, LOW);
- #endif
+ // Configure LED pin
+ pinMode(LED_PIN, OUTPUT);
+ digitalWrite(LED_PIN, HIGH); // Start with LED off
- // Define MAC addresses for this device and the target
- // This device (Controlee) has address 0x2222
- // Target device (Controller) has address 0x1111
- uint8_t devAddr[]={0x22,0x22};
- uint8_t destination[]={0x11,0x11};
- UWBMacAddress srcAddr(UWBMacAddress::Size::SHORT,devAddr);
- UWBMacAddress dstAddr(UWBMacAddress::Size::SHORT,destination);
+ Serial.println("- Arduino Stella - Two-Way Ranging Controller started...");
+ // Define MAC addresses for this device and the target
+ // This device (Controller) has address 0x2222
+ // Target device (Controlee) has address 0x1111
+ uint8_t devAddr[] = {0x22, 0x22};
+ uint8_t destination[] = {0x11, 0x11};
+ UWBMacAddress srcAddr(UWBMacAddress::Size::SHORT, devAddr);
+ UWBMacAddress dstAddr(UWBMacAddress::Size::SHORT, destination);
+
// Register the callback and start UWB
UWB.registerRangingCallback(rangingHandler);
UWB.begin();
- Serial.println("- Starting UWB ...");
-
+
+ Serial.println("- Starting UWB...");
+
// Wait until UWB stack is initialized
- while(UWB.state()!=0)
+ while (UWB.state() != 0) {
delay(10);
+ }
- // Configure the UWB session
- Serial.println("- Starting session ...");
- UWBSession session1;
- session1.sessionID(0x11223344);
- session1.sessionType(uwb::SessionType::RANGING);
-
- // Set application parameters
- if(!session1.appParams.addOrUpdateParam(AppConfigId::NO_OF_CONTROLEES,1))
- Serial.println("- Could not add to app params!");
- if(!session1.appParams.destinationMacAddr(dstAddr))
- Serial.println("- Could not add to app params!");
-
- // Apply default values for measurement repetition rate and antenna config
- session1.applyDefaults();
-
- // Configure ranging parameters
- session1.rangingParams.deviceMacAddr(srcAddr);
- session1.rangingParams.deviceRole(uwb::DeviceRole::RESPONDER);
- session1.rangingParams.deviceType(uwb::DeviceType::Controlee);
- session1.rangingParams.multiNodeMode(uwb::MultiNodeMode::UNICAST);
- session1.rangingParams.rangingRoundUsage(uwb::RangingMethod::DS_TWR);
- session1.rangingParams.scheduledMode(uwb::ScheduledMode::TIME_SCHEDULED);
-
- // Add the session to the manager and start it
- UWBSessionManager.addSession(session1);
- session1.init();
- session1.start();
+ // Setup and start the UWB session using simplified UWBTracker
+ Serial.println("- Starting session...");
+ UWBTracker myTracker(0x11223344, srcAddr, dstAddr);
+ UWBSessionManager.addSession(myTracker);
+ myTracker.init();
+ myTracker.start();
+
+ // Signal initialization complete with triple LED flash
+ Serial.println("- Initialization complete!");
+ for (int i = 0; i < 3; i++) {
+ digitalWrite(LED_PIN, LOW); // LED ON
+ delay(100);
+ digitalWrite(LED_PIN, HIGH); // LED OFF
+ delay(100);
+ }
}
void loop() {
- // Toggle the LED to show the system is running
- #if defined(ARDUINO_PORTENTA_C33)
- // Only the Portenta C33 has an RGB LED
- digitalWrite(LEDR, !digitalRead(LEDR));
- #else
- Serial.println(millis());
- #endif
-
- // Small delay using FreeRTOS scheduler
- vTaskDelay(configTICK_RATE_HZ/4);
+ unsigned long currentTime = millis();
+
+ // Handle LED feedback based on connection status and distance
+ if (currentTime - lastMeasurement > TIMEOUT_MS) {
+ // No connection detected - rapid blink warning
+ if (currentTime - lastBlink >= 100) {
+ lastBlink = currentTime;
+ ledState = !ledState;
+ digitalWrite(LED_PIN, ledState ? LOW : HIGH);
+ }
+ } else {
+ // Normal operation - distance-based blink rate
+ if (currentTime - lastBlink >= currentBlinkInterval) {
+ lastBlink = currentTime;
+ ledState = !ledState;
+ digitalWrite(LED_PIN, ledState ? LOW : HIGH);
+ }
+ }
+
+ // Small delay to prevent CPU overload
+ delay(10);
}
```
-Here's the code for the Arduino Stella, which acts as the Controller (Initiator) in this Two-Way Ranging scenario:
+Here's the code for the Portenta UWB Shield, which acts as the Controlee (Responder) in this Two-Way Ranging scenario:
+
+**📋 Board Selection Check:** Ensure `Portenta C33` is selected in the Arduino IDE before uploading this code.
```arduino
/**
- Two-Way Ranging Controller Example for Arduino Stella
- Name: stella_uwb_twr_controller.ino
- Purpose: This sketch configures the Arduino Stella as a Controller (Initiator)
- for Two-Way Ranging with a Portenta UWB Shield configured as Controlee.
+ Two-Way Ranging Controlee Example for Portenta UWB Shield
+ Name: portenta_uwb_twr_controlee.ino
+ Purpose: This sketch configures the Portenta UWB Shield as a Controlee (Responder)
+ for Two-Way Ranging with an Arduino Stella configured as Controller.
+ Includes distance visualization and moving average calculation.
- @author Pierpaolo Lento from Truesense, modified by the Arduino Product Experience Team
+ @author Arduino Product Experience Team
@version 1.0 15/04/25
*/
// Include required UWB library
-#include
+#include
+
+// Moving average configuration
+#define SAMPLES 10 // Number of samples for moving average
+long distances[SAMPLES] = {0}; // Circular buffer for distance measurements
+int sample_index = 0; // Current position in circular buffer
+
+// LED and status configuration
+#define NEARBY_THRESHOLD 300 // Distance threshold for green LED (cm)
+#define CONNECTION_TIMEOUT 2000 // Time before considering tag lost (ms)
+#define LED_BLINK_INTERVAL 500 // Red LED blink interval (ms)
+
+// System state variables
+unsigned long lastMeasurement = 0;
+unsigned long lastLedBlink = 0;
+bool ledState = false;
/**
Processes ranging data received from UWB communication.
+ Calculates moving average and provides visual feedback.
@param rangingData Reference to UWB ranging data object.
*/
void rangingHandler(UWBRangingData &rangingData) {
- Serial.print("- GOT RANGING DATA - Type: ");
- Serial.println(rangingData.measureType());
- if(rangingData.measureType()==(uint8_t)uwb::MeasurementType::TWO_WAY) {
+ if (rangingData.measureType() == (uint8_t)uwb::MeasurementType::TWO_WAY) {
// Get the TWR (Two-Way Ranging) measurements
- RangingMeasures twr=rangingData.twoWayRangingMeasure();
-
+ RangingMeasures twr = rangingData.twoWayRangingMeasure();
+
// Loop through all available measurements
- for(int j=0;j CONNECTION_TIMEOUT) ? LOW : HIGH);
+
+ // Blink red LED to show system is running
+ if (currentTime - lastLedBlink >= LED_BLINK_INTERVAL) {
+ lastLedBlink = currentTime;
+ ledState = !ledState;
+ digitalWrite(LEDR, ledState ? HIGH : LOW);
+ }
+ #else
+ // For boards without RGB LED, print heartbeat
+ if (currentTime - lastLedBlink >= LED_BLINK_INTERVAL) {
+ lastLedBlink = currentTime;
+ Serial.println("- System running...");
+ }
+ #endif
+
+ // Small delay to prevent CPU overload
+ delay(10);
}
```
+***__Important note:__ Both devices must be programmed and powered on before you will see any distance measurements. The ranging session only begins when both the Controller (Arduino Stella) and Controlee (Portenta UWB Shield) are running their respective sketches.***
+
+Once both devices are running, the Arduino Stella's Serial Monitor will display the distance measurements:
+
+
+
+Similarly, the Portenta UWB Shield's Serial Monitor will show both raw and averaged distance measurements:
+
+
+
+The output format from the Portenta C33 board is optimized for visualization, showing both the immediate distance readings and the calculated moving average.
+
### Key Components of the Example Sketch
-The Two-Way Ranging example demonstrates a more direct approach to UWB communication compared to the `NearbyDemo`. Let's analyze the key components of both example sketches:
+The Two-Way Ranging example uses simplified helper classes (`UWBTracker` and `UWBRangingControlee`) that make device configuration easier while maintaining the same functionality. Let's analyze the key components:
-1. **Libraries and MAC Addressing**
+- **Libraries and MAC Addressing**
Both devices use their respective UWB libraries:
+- The Arduino Stella uses `StellaUWB.h` (for the DCU040 module)
- The Portenta UWB Shield uses `PortentaUWBShield.h` (for the DCU150 module)
-- The Stella uses `StellaUWB.h` (for the DCU040 module)
-Both sketches configure MAC addresses for identification:
+MAC address configuration remains critical for communication:
```arduino
-// On Portenta UWB Shield
-uint8_t devAddr[]={0x22,0x22};
-uint8_t destination[]={0x11,0x11};
+// On Arduino Stella (Controller)
+uint8_t devAddr[] = {0x22, 0x22}; // This device
+uint8_t destination[] = {0x11, 0x11}; // Target device
-// On Arduino Stella
-uint8_t devAddr[]={0x11,0x11};
-uint8_t destination[]={0x22,0x22};
+// On Portenta UWB Shield (Controlee)
+uint8_t devAddr[] = {0x11, 0x11}; // This device
+uint8_t destination[] = {0x22, 0x22}; // Target device
```
-***Important note: Notice how the MAC addresses are reversed between the two devices; this is critical for proper communication. In UWB communication, each device must know both its own address (`devAddr`) and the address of the device it is communicating with (`destination`). The Portenta UWB Shield identifies itself as `0x2222` and expects to communicate with `0x1111`, while the Arduino Stella identifies itself as `0x1111` and expects to communicate with `0x2222`. If these addresses don't match correctly, the devices won't be able to establish a ranging session. The prefix `0x` indicates these are hexadecimal values, which is a common notation in programming for representing memory addresses and identifiers.***
-
-The MAC addresses used in this example are short (2-byte) addresses for simplicity, but UWB also supports extended (8-byte) addresses for larger networks where unique identification is required. For basic two-device setups, these short addresses are enough, but for multi-node positioning systems, you may want to use extended addressing to avoid conflicts.
+***__Important note:__ The MAC addresses are reversed between the two devices. The Arduino Stella identifies itself as `0x2222`and expects to communicate with `0x1111`, while the Portenta UWB Shield identifies itself as `0x1111` and expects to communicate with `0x2222`. Both devices must use the same session ID (`0x11223344`) to establish communication.***
-2. **Setup and Initialization**
+- **Simplified Session Setup**
-The setup process for UWB communication differs between the two devices due to their different roles in the ranging session:
+The new code uses helper classes that simplify the UWB session configuration:
-**Portenta UWB Shield (Controlee/Responder):**
+**Arduino Stella (Controller/Initiator):**
```arduino
-// Configure the UWB session
-UWBSession session1;
-session1.sessionID(0x11223344); // Unique identifier for this session
-session1.sessionType(uwb::SessionType::RANGING);
-
-// Set application parameters
-if(!session1.appParams.addOrUpdateParam(AppConfigId::NO_OF_CONTROLEES,1))
- Serial.println("could not add to app params");
-if(!session1.appParams.destinationMacAddr(dstAddr))
- Serial.println("could not add to app params");
-
-// Apply default values for measurement repetition rate and antenna config
-session1.applyDefaults();
-
-// Configure ranging parameters
-session1.rangingParams.deviceMacAddr(srcAddr);
-session1.rangingParams.deviceRole(uwb::DeviceRole::RESPONDER);
-session1.rangingParams.deviceType(uwb::DeviceType::Controlee);
-session1.rangingParams.multiNodeMode(uwb::MultiNodeMode::UNICAST);
-session1.rangingParams.rangingRoundUsage(uwb::RangingMethod::DS_TWR);
-session1.rangingParams.scheduledMode(uwb::ScheduledMode::TIME_SCHEDULED);
-
-// Add the session to the manager and start it
-UWBSessionManager.addSession(session1);
-session1.init();
-session1.start();
+UWBTracker myTracker(0x11223344, srcAddr, dstAddr);
+UWBSessionManager.addSession(myTracker);
+myTracker.init();
+myTracker.start();
```
-**Arduino Stella (Controller/Initiator):**
+**Portenta UWB Shield (Controlee/Responder):**
```arduino
-// Configure the UWB session
-UWBSession session1;
-session1.sessionID(0x11223344);
-session1.sessionType(UWBD_RANGING_SESSION);
-
-// Set application parameters
-if(!session1.appParams.addOrUpdateParam(UWB_SET_APP_PARAM_VALUE(NO_OF_CONTROLEES,1)))
- Serial.println("could not add to app params");
-if(!session1.appParams.destinationMacAddr(dstAddr))
- Serial.println("could not add to app params");
-
-// Apply default values for measurement repetition rate and antenna config
-session1.applyDefaults();
-
-// Configure ranging parameters
-session1.rangingParams.deviceMacAddr(srcAddr);
-session1.rangingParams.deviceRole(kUWB_DeviceRole_Initiator);
-session1.rangingParams.deviceType(kUWB_DeviceType_Controller);
-session1.rangingParams.multiNodeMode(kUWB_MultiNodeMode_UniCast);
-session1.rangingParams.rangingRoundUsage(kUWB_RangingRoundUsage_DS_TWR);
-session1.rangingParams.scheduledMode(kUWB_ScheduledMode_TimeScheduled);
-
-// Add the session to the manager and start it
-UWBSessionManager.addSession(session1);
-session1.init();
-session1.start();
+UWBRangingControlee myControlee(0x11223344, srcAddr, dstAddr);
+UWBSessionManager.addSession(myControlee);
+myControlee.init();
+myControlee.start();
```
-***Important note: The session configuration is more detailed for the Portenta UWB Shield because it explicitly defines all the ranging parameters. The Arduino Stella uses the simplified `UWBTracker` class, which automatically sets up the device as a Controller/Initiator with appropriate defaults. However, both devices must use the same session ID (`0x11223344` in this example) to communicate with each other. This session ID is a shared identifier for the ranging session between these devices.***
+These helper classes automatically configure the appropriate ranging parameters for their respective roles, making the setup process more straightforward.
-Let's examine some of the key configuration parameters:
+- **Enhanced Visual Feedback**
-- `sessionID`: A unique 32-bit identifier (`0x11223344`) must match between devices in the same session.
-- `deviceRole`: Defines whether the device is a Responder (Controlee) or Initiator (Controller).
-- `multiNodeMode`: Set to UniCast for direct device-to-device communication.
-- `rangingRoundUsage`: Set to DS_TWR (Double-Sided Two-Way Ranging) for the highest accuracy.
-- `scheduledMode`: `TimeScheduled` mode allows the Controller to manage the timing of ranging exchanges.
+Both devices in this example provide visual feedback to help users understand the system status and distance measurements at a glance. Each device uses its LED capabilities to indicate different operational states.
-The initialization follows a specific sequence on both devices:
+**Arduino Stella LED Behavior:**
-- Register the ranging callback.
-- Start the UWB subsystem.
-- Configure the session parameters.
-- Initialize the session (apply the configuration).
-- Start the session (begin the ranging process).
+The Arduino Stella uses its built-in LED to provide distance-based feedback through variable blink rates:
-This process ensures both devices are properly configured before ranging begins, establishing a synchronized communication channel for precise distance measurements.
+- **Close range (0 to 50 cm)**: Very fast blinking for immediate proximity alert
+- **Medium range (50 to 150 cm)**: Medium blinking for moderate distances
+- **Far range (150 to 300 cm)**: Slow blinking indicating increasing distance
+- **Very far (>300 cm)**: Very slow blinking for maximum range
+- **No connection**: Rapid blinking (100 ms intervals) as a warning signal
+- **Startup**: Triple flash to indicate successful initialization
-1. **Ranging Data Handler**
+This variable blink rate creates an intuitive feedback system where users can gauge distance without looking at the serial output.
-Both devices use nearly identical callback functions to process ranging data:
+**Portenta C33 RGB LED Behavior:**
-```arduino
-void rangingHandler(UWBRangingData &rangingData) {
- // ...
- if(rangingData.measureType()==(uint8_t)uwb::MeasurementType::TWO_WAY) {
- RangingMeasures twr=rangingData.twoWayRangingMeasure();
- for(int j=0;j Board > Arduino Renesas Portenta Boards > Portenta C33`
+- Upload the Controlee/Responder sketch to the Portenta C33 board
-You should see distance measurements on both Serial Monitors. Try moving the devices closer together and further apart to see the distance values change in real time.
+2. **For the Arduino Stella:**
-**Tips for optimal performance:**
+- Select `Tools > Board > Arduino Mbed OS Stella Boards > Arduino Stella`
+- Upload the Controller/Initiator sketch to the Arduino Stella
-- For best results, position the devices so their antennas have a clear line-of-sight to each other.
-- Keep the devices at least 20 cm away from large metal objects, as these can reflect UWB signals and interfere with measurements.
-- Maintain the devices in a similar orientation (parallel to each other) for more consistent results, as antenna positioning affects signal strength.
-- Start testing at distances between 0.5 to 3 meters, as extremely close or far distances might produce less reliable measurements.
+***__Important note__: If you encounter compilation errors, verify that you have selected the correct board for each device before uploading.***
-The distances are reported in millimeters, providing centimeter-level accuracy. For example, a reading of `- Distance: 1234` indicates the devices are approximately 1.234 meters apart.
+**Testing:**
+
+Once both devices are programmed, you can begin testing the ranging system:
+
+1. Open the IDE's Serial Monitor for the Portenta C33 board at 115200 baud
+2. For best visualization, use `Tools > Serial Plotter` instead of the `Serial Monitor`
+3. Move the devices closer and further apart
+4. Observe the LED feedback on both devices
+
+***If you don't see any measurements, verify that both devices are powered on and running their respective sketches. The system requires both the Controller and Controlee to be active for ranging to occur.***
+
+**Visual Feedback During Operation:**
+
+When the system is working correctly, both devices provide LED feedback:
+
+- **Arduino Stella LED:** Blinks faster as devices get closer (fast at 50 cm, slow at 300 cm)
+- **Portenta C33 Red LED:** Blinks continuously to show system is active
+- **Portenta C33 Blue LED:** OFF when connected, ON when connection is lost
+- **Portenta C33 Green LED:** ON when Stella is within 300 cm, OFF when further away
+
+**Serial Output Visualization:**
+
+The Serial Plotter provides real-time visualization of the distance measurements:
+
+
+
+The graph shows two lines:
+
+- **Blue line:** Raw distance measurements in centimeters
+- **Red line:** Smoothed moving average for trend analysis
+
+Example readings: `Distance(cm):125,Average(cm):123` indicates the devices are approximately 1.25 meters apart.
### Extending the Two-Way Ranging Example
-This basic example can be extended in several ways for more advanced applications:
+This enhanced example provides a foundation for more advanced applications:
+
+- **Access control systems**: Use the distance threshold to trigger door locks or security systems
+- **Safety zones**: Create multiple distance thresholds for industrial safety applications
+- **Data logging**: Add SD card storage to record distance measurements over time
+- **Multi-node networks**: Extend to support multiple tags communicating with one base station
+- **Position calculation**: Combine multiple base stations for 2D/3D positioning through triangulation
+- **Alert systems**: Add buzzer or additional LEDs for specific distance-based alerts
-- **Adding multiple nodes:** Modify the example sketch to support multiple anchors or tags for triangulation and full positioning.
-- **Integrating additional sensors:** Combine UWB ranging with IMU data for more robust positioning.
-- **Implementing position calculation:** Add algorithms to convert distance measurements to coordinates.
-- **Creating a visualization interface:** Develop a graphical interface to display the relative positions of devices.
-- **Adding data communication:** Use UWB not just for ranging but also for data exchange between devices.
+The visual feedback and data processing capabilities demonstrated in this example can be adapted to various real-world applications requiring precise distance measurement and proximity detection.
## Support
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_CE_IC.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_CE_IC.pdf
new file mode 100644
index 0000000000..33e4fc7468
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_CE_IC.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_CE_RED.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_CE_RED.pdf
new file mode 100644
index 0000000000..7931950640
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_CE_RED.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_FCC_DSS.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_FCC_DSS.pdf
new file mode 100644
index 0000000000..dd612308bf
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_FCC_DSS.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_FCC_DTS.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_FCC_DTS.pdf
new file mode 100644
index 0000000000..c5ff483e5a
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_FCC_DTS.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_MIC.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_MIC.pdf
new file mode 100644
index 0000000000..63366e407b
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_MIC.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_RoHS.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_RoHS.pdf
new file mode 100644
index 0000000000..71cee580f1
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_RoHS.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_UKCA.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_UKCA.pdf
new file mode 100644
index 0000000000..fee127f08d
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-CERT_UKCA.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_CE.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_CE.pdf
new file mode 100644
index 0000000000..97ea0d696a
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_CE.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_FCC.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_FCC.pdf
new file mode 100644
index 0000000000..cacdff744c
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_FCC.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_UKCA.pdf b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_UKCA.pdf
new file mode 100644
index 0000000000..e39353fb3f
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/certifications/Arduino_TPX00227-DoC_UKCA.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/compatibility.yml b/content/hardware/09.kits/maker/nesso-n1/compatibility.yml
new file mode 100644
index 0000000000..f7e3920efd
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/compatibility.yml
@@ -0,0 +1,18 @@
+software:
+ - arduino-ide
+ - arduino-cli
+ - cloud-editor
+hardware:
+ boards: ~
+ carriers: ~
+ shields: ~
+ accessories:
+ - modulino-buttons
+ - modulino-buzzer
+ - modulino-distance
+ - modulino-knob
+ - modulino-movement
+ - modulino-pixels
+ - modulino-thermo
+
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/TPX00227-pinout.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/TPX00227-pinout.png
new file mode 100644
index 0000000000..e631bd7f71
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/TPX00227-pinout.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/featured.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/featured.png
new file mode 100644
index 0000000000..41a14eee33
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/featured.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_display.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_display.png
new file mode 100644
index 0000000000..ea31dbc4a8
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_display.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_grove_qwiic.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_grove_qwiic.png
new file mode 100644
index 0000000000..19c57aa7b9
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_grove_qwiic.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_hat.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_hat.png
new file mode 100644
index 0000000000..56b70183be
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_hat.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_lora_antenna.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_lora_antenna.png
new file mode 100644
index 0000000000..4a21e124ab
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_lora_antenna.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_overview.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_overview.png
new file mode 100644
index 0000000000..a3f24861ff
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_overview.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_power_options.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_power_options.png
new file mode 100644
index 0000000000..6ca7839ea1
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_power_options.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_ui.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_ui.png
new file mode 100644
index 0000000000..79e75438f3
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/n1_ui.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_antenna_md.svg b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_antenna_md.svg
new file mode 100644
index 0000000000..2943277c2e
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_antenna_md.svg
@@ -0,0 +1,3731 @@
+
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_block_diagram.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_block_diagram.png
new file mode 100644
index 0000000000..f988b8535e
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_block_diagram.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_deviceStorage_md.svg b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_deviceStorage_md.svg
new file mode 100644
index 0000000000..f16e7dda3a
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_deviceStorage_md.svg
@@ -0,0 +1,4217 @@
+
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_device_md.svg b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_device_md.svg
new file mode 100644
index 0000000000..b8ed8aa695
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_device_md.svg
@@ -0,0 +1,4577 @@
+
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_power_tree.png b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_power_tree.png
new file mode 100644
index 0000000000..51051ad910
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/datasheet/assets/nesso_n1_power_tree.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/datasheet/datasheet.md b/content/hardware/09.kits/maker/nesso-n1/datasheet/datasheet.md
new file mode 100644
index 0000000000..8dc9d3f64b
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/datasheet/datasheet.md
@@ -0,0 +1,505 @@
+---
+identifier: TPX00227
+title: Arduino® Nesso N1
+type: maker
+---
+
+
+
+# Description
+
+
Arduino® Nesso N1 (hereafter Nesso N1) is a compact, all-in-one IoT development kit powered by the ESP32-C6 microcontroller, a single-core 32-bit RISC-V CPU running at up to 160 MHz. Designed for remote monitoring and automation applications, Nesso N1 combines multiple wireless protocols, such as Wi-Fi® 6, Bluetooth® 5.3, Thread®, and LoRa® into a sleek, portable form factor with an integrated 1.14" touch display and rechargeable 250 mAh battery. Built-in sensors include a 6-axis IMU, passive buzzer, and infrared transmitter, with expansion capabilities through Grove, Qwiic, and M5StickC HAT-compatible connectors.
+
+
Nesso N1 can be programmed using Arduino IDE, MicroPython, or UIFlow, and integrates seamlessly with Arduino Cloud for remote device management and data visualization. With comprehensive documentation, ready-to-use examples, and compatibility with Arduino Modulino® nodes and third-party accessories, Nesso N1 accelerates the development of connected devices for smart homes, industrial automation, and environmental monitoring.
Nesso N1 combines multi-protocol wireless connectivity (Wi-Fi® 6, Bluetooth® 5.3, Thread, LoRa®) with integrated sensors, a touch display, and battery operation, making it a versatile platform for IoT applications. Alongside expansion via Grove, Qwiic, and HAT connectors, it supports Arduino Modulino® nodes and third-party Qwiic, Grove, and M5StickC HAT accessories for diverse connected device projects.
+
+**Smart Home Hub:** Central control hub for smart home devices, integrating with platforms like Home Assistant via Wi-Fi®, Thread, or LoRa® connectivity.
+
+- **IR to IoT Gateway:** Transforms traditional infrared remote-controlled devices (TVs, air conditioners, fans) into smart, connected appliances controllable via Wi-Fi® or cloud platforms.
+
+- **Environmental Monitoring:** Remote weather stations and sensor nodes monitoring temperature, humidity, and air quality with external sensors, logging data to Arduino Cloud via LoRa®.
+
+- **Industrial IoT Edge Node:** Aggregates sensor data from factory equipment using multiple wireless protocols, transmitting real-time machine status and predictive maintenance alerts to cloud platforms.
+
+- **Asset Tracking:** Monitors equipment location and status in warehouses, construction sites, or logistics operations using integrated IMU and wireless connectivity.
+
+- **Agriculture Monitoring:** Connects soil moisture, weather, and irrigation sensors via LoRa® or Thread to optimize resource usage in precision agriculture applications.
+
+- **Education and Prototyping:** Hands-on learning platform for IoT protocols (Wi-Fi® 6, Bluetooth® 5.3, Thread, LoRa®) and rapid development of connected device proof-of-concepts with pre-configured hardware.
+
+- **Home Automation:** Custom automation systems including automated lighting, security systems, and environmental controls when combined with Modulino nodes or Grove sensors.
+
+
+
+## Features
+
+### General Specifications Overview
+
+
+
+#### Processing and Memory
+
+| **Component** | **Details** |
+|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Microcontroller | - ESP32-C6 RISC-V 32-bit single-core CPU @ 160 MHz - Wi-Fi® 6 (802.11ax), Bluetooth® 5.3, 802.15.4 (Thread/Zigbee®) - 16 MB external Flash (GD25Q128/W25Q128) |
+| System Memory | - 1536 kB on-chip Flash - 512 kB on-chip SRAM - 16 MB external Flash for application storage |
+
+#### Connectivity and Wireless
+
+| **Component** | **Details** |
+|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Wireless (ESP32-C6) | - 2.4 GHz Wi-Fi® 6 (802.11ax) - Bluetooth® 5.3 LE - 802.15.4 Thread/Zigbee® - Dedicated FPC antenna |
+| LoRa® Module | - SX1262 transceiver (850-960 MHz) - Detachable external IPEX4 antenna - FM8625H LNA for receive path - SGM13005L4 amplifier for transmit path - Antenna storage within enclosure |
+| USB Interface | - USB-C connector - 5V DC input for charging and programming - USB 3.0 data interface |
+
+#### Display and User Interface
+
+| **Component** | **Details** |
+|------------------|-------------------------------------------------------------------------------------------------------------------------|
+| Display | - 1.14" IPS LCD - ST7789P3 driver @ SPI communication - Resolution: 135 × 240 pixels - 262K colors (18-bit) |
+| Touch Controller | - FT6336U capacitive touch controller - I²C communication |
+| User Buttons | - 2× programmable buttons (KEY1, KEY2) - 1× power button (long-press reset function) |
+| LEDs | - 1× green user programmable LED - 1× blue power/status LED |
+| Audio Feedback | - Passive buzzer (4 kHz) - GPIO-controlled |
+| Infrared | - IR LED transmitter - Remote control and signal transmission capability |
+
+#### Sensors and Expansion
+
+| **Component** | **Details** |
+|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| IMU Sensor | - BMI270 6-axis IMU - 3-axis accelerometer + 3-axis gyroscope - I²C communication - Motion and orientation detection |
+| Expansion Ports | - Grove connector (HY2.0-4P): I²C, GPIO, power - Qwiic connector (PH1.0-4P): I²C interface - 8-pin HAT port: M5StickC HAT-compatible (GPIO, ADC, power) |
+
+#### Power System
+
+| **Component** | **Details** |
+|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Battery | - 250 mAh lithium polymer battery (3.7 - 4.2 V) - Integrated within enclosure |
+| Power Management | - AW32001ECSR charge controller with power path management - BQ27220YZFR battery fuel gauge (real-time capacity, voltage, current monitoring) - Over-current and over-voltage protection |
+| Voltage Regulation | - JW5712 DC-DC buck converter (battery to 3.3V system rail) - SGM6603 boost converter (3.3V to 5V output for peripherals) |
+| Input Voltage | - USB-C®: 5V DC input - Battery nominal: 3.7 V (3.7 - 4.2 V range) |
+
+### Related Products
+
+- Arduino Modulino® Family
+- Grove sensors and actuators (I²C, GPIO)
+- Qwiic ecosystem modules
+- M5StickC HAT accessories
+- LoRa® antennas (850-960 MHz, IPEX4 connector)
+
+
+
+## Ratings
+
+### Input Power
+
+
+
+| **Source** | **Voltage Range** | **Maximum Current** | **Connector** |
+|----------------|------------------:|--------------------:|------------------|
+| USB-C® | 5 V | up to 1 A | USB-C® connector |
+| Battery (LiPo) | 3.7 - 4.2 V | 250 mAh | Internal |
+
+
Nesso N1 is powered via a USB-C® connector accepting 5 V DC input for charging and operation, or through the integrated 250 mAh lithium polymer battery. The AW32001 power management IC handles charge control and power path management, allowing simultaneous charging and operation. Use a USB power source rated for at least 5 V at 1 A to ensure proper charging and operation during peak power consumption (e.g., Wi-Fi® transmission, display backlight at maximum, LoRa® transmission).
+
+Two main power functions are performed as follows:
+
+-
Battery charging: The AW32001 provides intelligent charge management with over-current and over-voltage protection. Charge current is automatically regulated based on input power availability and battery state.
+
+-
Battery monitoring: The BQ27220 fuel gauge continuously monitors battery voltage, current, and remaining capacity. Battery status data is accessible via I²C interface for real-time reporting.
+
+### Recommended Operating Conditions
+
+Use the limits below to define the operating environment, thermal margins, and power source specifications:
+
+| **Parameter** | **Symbol** | **Minimum** | **Typical** | **Maximum** | **Unit** |
+|-----------------------|-----------------|:-----------:|:-----------:|:-----------:|:--------:|
+| USB-C® input | `V_USB` | 4.75 | 5.0 | 5.25 | V |
+| Battery voltage | `V_BAT` | 3.0 | 3.7 | 4.2 | V |
+| 3.3V system rail | `V_SYS` | 3.1 | 3.3 | 3.5 | V |
+| Operating temperature | `T_OP` | 0 | - | 40 | °C |
+
+
+
Operating Conditions:Minimum values represent the lowest continuous operating point. Brief drops below these levels may cause a brownout or reset. Typical represents nominal design conditions. Maximum must not be exceeded to prevent damage. For battery voltage, 3.0 V represents the low-battery cutoff threshold, and 4.2 V is the fully charged state. The operating temperature range refers to the ambient air temperature near the device.
Nesso N1 uses a power management architecture optimized for battery-powered IoT applications. The system takes 5 V DC input via the USB-C® connector, which provides the AW32001ECSR power management IC. This IC manages charge control for the 250 mAh lithium polymer battery (3.7 - 4.2 V nominal) and provides power path management, allowing simultaneous charging and operation.
+
+
The JW5712 DC-DC buck converter steps down the battery voltage to generate the main 3.3 V system rail (SYS_3.3V), which powers the ESP32-C6 microcontroller, sensors, display controller, and most system peripherals. For peripherals requiring 5 V operation (such as certain HAT accessories), the SGM6603 boost converter steps up the 3.3 V rail to provide a regulated 5V output (INT_5VOUT).
+
+
The BQ27220YZFR fuel gauge IC continuously monitors battery voltage, current, and state of charge through dedicated sense connections to the battery. Real-time battery status information is accessible via the I²C interface. The system includes comprehensive protection circuitry against over-current, over-voltage, and reverse polarity conditions.
+
+
When USB power is disconnected, the device operates entirely from battery power. The power management system automatically transitions between power sources without disrupting operations.
+
+
+
+
The integrated 250 mAh lithium polymer battery (3.7 - 4.2 V nominal) provides portable operation for remote and mobile applications. The BQ27220 fuel gauge continuously monitors battery voltage, current, and remaining capacity in real-time, with status data accessible via I²C interface for integration into user applications. Typical runtime varies based on wireless activity (Wi-Fi®, Bluetooth®, LoRa® transmission frequency), display brightness settings, and connected peripheral power consumption.
+
+
To maximize battery life, leverage the ESP32-C6's deep sleep modes when inactive, reducing power consumption to minimal levels. Display backlight brightness can be reduced or disabled entirely when visual feedback is not required. Unused wireless radios (Wi-Fi®, Bluetooth®, or LoRa®) should be disabled to conserve power.
+
+
The BMI270 IMU's interrupt outputs enable motion-triggered wake-up, allowing the system to remain in low-power mode until physical movement is detected. For LoRa® applications, Class A operation provides the lowest power consumption profile, which is ideal for battery-powered sensor nodes with infrequent uplink transmissions.
+
+**Power Button Behavior:**
+- **Single press:** Turns on the device if powered down or resets if done while operating
+- **Double press:** Turns off the device
+- **Long press:** Enters Download/Bootloader mode while operating
+
+
+
+## UI & Indicators
+
+
+
+- **Green User LED (LED1):** Programmable user LED controlled by ESP32-C6 GPIO. Available for custom application feedback and status indication.
+
+- **Blue Power LED (LED3):** Indicates power status. Illuminated when the device is powered on (tied to VBUS rail via current-limiting resistor).
+
+- **Programmable Buttons:**
+ - **KEY1 (S1):** User-programmable button connected to I/O expander P0
+ - **KEY2 (S2):** User-programmable button connected to I/O expander P1
+
+- **Power Button (SW_PWR):** Controls device power state. Single-press turns on the device if powered down or resets if done while operating. Double-press turns off the device.
+
+- **Buzzer (BZ1):** 4 kHz passive buzzer driven by `GPIO11` through transistor driver circuit. Provides audio feedback for alarms, notifications, and user interactions.
+
+- **Infrared Transmitter (LED4):** IR LED driven by `GPIO9` through transistor driver circuit. Enables remote control of IR-compatible devices (TVs, air conditioners, etc.).
+
+## Microcontroller and Processing
+
+### ESP32-C6 Microcontroller
+
+
The ESP32-C6 is a single-core 32-bit RISC-V microcontroller running at up to 160 MHz, designed specifically for IoT applications requiring multiple wireless protocols. It integrates 2.4 GHz Wi-Fi® 6 (802.11ax), Bluetooth® 5.3 LE, and IEEE 802.15.4 (Thread/Zigbee®) radios on a single chip, reducing component count and system complexity.
+
+**Key specifications:**
+- 32-bit RISC-V single-core processor @ 160 MHz maximum
+- 1536 kB on-chip Flash, 512 kB on-chip SRAM
+- 16 MB external Flash (GD25Q128 / W25Q128) via SPI interface for application storage
+- Hardware cryptographic accelerators (AES, SHA, RSA)
+- Low-power modes for battery-operated applications
+
+**Wireless capabilities:**
+- **Wi-Fi® 6 (802.11ax):** 2.4 GHz band, supports target wake time (TWT) for power savings
+- **Bluetooth® 5.3 LE:** Low energy mode for peripheral and beacon applications
+- **802.15.4 (Thread/Zigbee®):** Mesh networking capability for smart home and industrial applications
+
+
+ Note: The Wi-Fi® and Bluetooth® connectivity uses a dedicated FPC antenna integrated into the device. Removing or modifying the FPC antenna may cause wireless connectivity to stop working.
+
+
+**Peripheral interfaces:**
+- Multiple GPIO pins with configurable functions
+- I²C, SPI, UART communication interfaces
+- PWM outputs for LED control, servo motors
+- ADC inputs for analog sensor reading
+- Touch sensor support on select GPIO
+
+
+
+### LoRa® Configuration
+
+
The SX1262 LoRa® transceiver provides long-range, low-power wireless connectivity in the 850–960 MHz frequency range. It connects to the ESP32-C6 via SPI interface and includes a dedicated low-noise amplifier (SGM13005L4) on the receive path and RF switch (FM8625H) for antenna path selection. The module supports both LoRa® and FSK modulation with a detachable IPEX4 antenna that can be stored within the device enclosure when not in use.
+
+| **Parameter** | **Specification** |
+|---------------------|-----------------------------------------|
+| Maximum TX power | +22 dBm |
+| RX sensitivity | -147 dBm @ SF12 (low data rate mode) |
+| Frequency range | 850-960 MHz (region-dependent) |
+| Modulation | LoRa® and FSK |
+
+
To use the LoRa® module, connect the detachable antenna to the IPEX4 connector on the device. For compact storage when the antenna is not needed, it can be detached and inserted into the dedicated storage slot within the enclosure, maintaining the device's sleek form factor.
+ Important: Always attach the LoRa® antenna before transmitting. Operating the LoRa® transmitter without an antenna can damage the SX1262 module due to reflected RF power.
+
+
+
The SX1262 operates in region-specific frequency bands: 868 MHz for Europe (863–870 MHz), 915 MHz for North America and Australia (902–928 MHz), and 923 MHz for Asia (920–925 MHz). Proper frequency configuration is required based on your deployment region to comply with local regulations.
+
+
For LoRa® network connectivity, configure the appropriate frequency, spreading factor (SF7–SF12), bandwidth, and coding rate based on your application requirements. Software libraries are available for configuring and using the LoRa® transceiver with the SX1262 module.
+
+### I/O Expansion
+
+
Two PI4IOE5V6408 I²C I/O expanders provide additional GPIO pins for the system. These devices operate on the shared I²C bus with configurable addresses, allowing control of a wider range of peripherals while keeping the ESP32-C6's native GPIO resources for other functions.
+
+
The first expander manages display control signals, status indicators, and power monitoring functions. The second expander handles user interface elements such as programmable buttons, manages LoRa® transceiver control signals, and provides GPIO for external expansion connectors. The I/O expanders also offer interrupt capability for event detection.
+
+
+
+## Peripherals
+
+### Grove Connector (J2)
+
+
+
+**Grove HY2.0-4P Connector** connects Grove ecosystem sensors and actuators with a custom pinout.
+
+| **Pin** | **Signal** | **Description** |
+|--------:|------------|---------------------------------|
+| 1 | GND | Ground |
+| 2 | 5VOUT | 5 V output from boost converter |
+| 3 | GROVE_IO_0 | GPIO 5 |
+| 4 | GROVE_IO_1 | GPIO 4 |
+
+
The Grove connector provides both power (5V from boost converter) and signal connections. IO_0 and IO_1 are controlled through the GPIO 5 and 4, accessible via I²C commands. Use this connector for Grove modules requiring 5V operation or GPIO control.
+
+
+ Note: This connector uses a custom pinout that differs from standard Grove connectors. Verify pin compatibility before connecting standard Grove modules.
+
The Qwiic connector shares the main I²C bus with internal peripherals (BMI270 IMU, BQ27220 fuel gauge, touch controller, I/O expander). I²C pull-up resistors are provided on the SDA and SCL lines. Maximum I²C bus speed is 400 kHz (Fast Mode).
+
+
+ I²C Bus Considerations: Multiple devices share the same I²C bus. Ensure connected modules use unique I²C addresses to avoid conflicts. The system I²C addresses include: BMI270 (0x68/0x69), BQ27220 (0x55), FT6336U (0x38), PI4IOE5V6408 (0x20/0x21 selectable).
+
+
+### HAT Connector (J4)
+
+**8-Pin HAT Connector** compatible with M5StickC HAT accessory ecosystem. Provides GPIO, ADC, and power connections for stackable expansion modules.
+
+
+
+| **Pin** | **Signal** | **Function** |
+|--------:|------------|-----------------------------------------------------------|
+| 1 | GND | Ground |
+| 2 | 5VOUT | 5V boost converter output (INT_5VOUT) |
+| 3 | D1 | GPIO7 (ADC capable, HAT_IO3) |
+| 4 | D3 | GPIO6 (ADC capable, HAT_IO2) |
+| 5 | D2 | GPIO2 (ADC capable, HAT_IO1) |
+| 6 | VBAT | Battery voltage (SYS_VBAT) |
+| 7 | 3V3 | 3.3V system power output (SYS_3.3V) |
+| 8 | 5VIN | Input voltage from external source (SYS_VIN) |
+
+
The HAT connector provides access to battery voltage, regulated power rails, and GPIO/ADC capable pins for connecting M5StickC-compatible accessories. GPIO2, GPIO6, and GPIO7 are ESP32-C6 pins capable of analog-to-digital conversion for sensor applications.
+
+### Display and Touch Interface
+
+
+
+
The integrated 1.14" IPS LCD features a 135 × 240 pixel resolution with 262K color depth (18-bit color), driven by the ST7789P3 controller. The display connects via SPI interface, which is shared with external Flash memory and the LoRa® module. Dedicated control signals include LCD_CS (chip select), LCD_RS (register select), and LCD_BL (backlight enable). The backlight is GPIO-controlled and supports PWM dimming for adjustable brightness levels.
+
+
The FT6336U capacitive touch controller allows single-point touch detection on the display. It communicates via the shared I²C bus alongside other internal peripherals. It provides an interrupt output (INT_LINE) for touch event notification, allowing power management through event-driven wake-up.
+
+
+ SPI Bus Sharing: The display controller shares the SPI bus with external Flash memory and LoRa® module. Chip select lines ensure only one device communicates at a time. Use appropriate delays and CS control in firmware to prevent bus conflicts.
+
+
+### IMU Sensor
+
+
The BMI270 enables motion and orientation detection, gesture recognition, and activity tracking applications. Interrupt outputs can wake the ESP32-C6 from sleep mode when motion events occur, enabling ultra-low-power monitoring applications. Its characteristics are:
+
+- 3-axis accelerometer (±2 g, ±4 g, ±8 g, ±16 g ranges)
+- 3-axis gyroscope (±125°/s to ±2000°/s ranges)
+- I²C interface (address 0x68 or 0x69 selectable)
+- Interrupt outputs (INT1, INT2) for motion detection, tap detection, orientation change
+- Low-power modes for battery conservation
+- Motion-triggered wake-up capability
+
+### Audio and Infrared
+
+
The onboard passive buzzer operates at 4 kHz and is GPIO-controlled via a transistor driver circuit. It provides audible feedback for notifications, alarms, and user interactions, allowing applications that require audio alerts or confirmation tones.
+
+
An infrared LED transmitter enables remote control applications for IR-compatible consumer devices such as TVs, air conditioners, and fans. The IR transmitter is GPIO-controlled via a transistor driver. It supports standard infrared remote control protocols, allowing the Nesso N1 to function as a universal remote or IoT gateway for traditional IR-based devices.
+
+
+
+## Device Operation
+
+### Getting Started - IDE
+
+If you want to program your Nesso N1 while offline you need to install the Arduino® Desktop IDE **[1]**. To connect the Nesso N1 to your computer, you will need a Type-C® USB cable, which can also provide power to the board, as indicated by the green power LED (LED1).
+
+### Getting Started - Arduino Cloud Editor
+
+All Arduino boards, including this one, work out-of-the-box on the Arduino® Cloud Editor **[2]**, by just installing a simple plugin.
+
+The Arduino Cloud Editor is hosted online, therefore it will always be up-to-date with the latest features and support for all boards. Follow **[2]** to start coding on the browser and upload your sketches onto your board.
+
+### Getting Started - Arduino Cloud
+
+All Arduino IoT enabled products are supported on Arduino Cloud which allows you to log, graph and analyze sensor data, trigger events, and automate your home or business.
+
+### Online Resources
+
+Now that you have gone through the basics of what you can do with the board you can explore the endless possibilities it provides by checking existing projects on Arduino Project Hub **[4]**, the Arduino Library Reference **[5]**, and the online store **[6]**; where you will be able to complement your board with sensors, actuators and more.
+
+
+
+## Mechanical Information
+
+
Nesso N1 features a compact, ergonomic design optimized for portable IoT applications. The device measures 48 mm × 24 mm × 14 mm (without antenna storage) or 48 mm × 24 mm × 21.1 mm (with antenna stored in integrated slot). The pre-assembled enclosure eliminates the need for additional mechanical design, allowing immediate deployment in prototypes and final products.
+
+**Device Dimensions (without antenna storage):**
+- Length: 48 mm
+- Width: 24 mm
+- Height: 14 mm
+
+
+
+
+
+**Device Dimensions (with antenna storage):**
+- Length: 48 mm
+- Width: 24 mm
+- Height: 21.1 mm
+
+
+
+
+
+**LoRa® Antenna Dimensions (detachable):**
+- Length: 45.5 mm
+- Width: 10.8 mm
+- Height: 4.8 mm
+- Connector: IPEX4 standard
+
+
+
+
+
+## Certifications
+
+### Declaration of Conformity CE DoC (EU)
+
+English: We declare under our sole responsibility that the products above are in conformity with the essential requirements of the following EU Directives and therefore qualify for free movement within markets comprising the European Union (EU) and European Economic Area (EEA).
+
+French: Nous déclarons sous notre seule responsabilité que les produits indiqués ci-dessus sont conformes aux exigences essentielles des directives de l'Union européenne mentionnées ci-après, et qu'ils remplissent à ce titre les conditions permettant la libre circulation sur les marchés de l'Union européenne (UE) et de l'Espace économique européen (EEE).
+
+### Declaration of Conformity to EU RoHS & REACH
+
+
Arduino boards are in compliance with Directive 2011/65/EU of the European Parliament and Directive 2015/863/EU of the Council of 4 June 2015 on the restriction of the use of certain hazardous substances in electrical and electronic equipment.
Arduino boards are fully compliant with the related requirements of European Union Regulation (EC) 1907/2006 concerning the Registration, Evaluation, Authorization and Restriction of Chemicals (REACH). We declare none of the SVHCs (https://echa.europa.eu/web/guest/candidate-list-table), the Candidate List of Substances of Very High Concern for authorization currently released by ECHA, is present in all products (and also package) in quantities totaling in a concentration equal or above 0.1%. To the best of our knowledge, we also declare that our products do not contain any of the substances listed on the "Authorization List" (Annex XIV of the REACH regulations) and Substances of Very High Concern (SVHC) in any significant amounts as specified by the Annex XVII of Candidate list published by ECHA (European Chemical Agency) 1907/2006/EC.
+
+### Conflict Minerals Declaration
+
+
As a global supplier of electronic and electrical components, Arduino is aware of our obligations with regards to laws and regulations regarding Conflict Minerals, specifically the Dodd-Frank Wall Street Reform and Consumer Protection Act, Section 1502. Arduino does not directly source or process conflict minerals such as Tin, Tantalum, Tungsten, or Gold. Conflict minerals are contained in our products in the form of solder, or as a component in metal alloys. As part of our reasonable due diligence Arduino has contacted component suppliers within our supply chain to verify their continued compliance with the regulations. Based on the information received thus far we declare that our products contain Conflict Minerals sourced from conflict-free areas.
+
+## FCC Caution
+
+Any Changes or modifications not expressly approved by the party responsible for compliance could void the user's authority to operate the equipment.
+
+This device complies with part 15 of the FCC Rules. Operation is subject to the following two conditions:
+
+(1) This device may not cause harmful interference
+
+(2) this device must accept any interference received, including interference that may cause undesired operation.
+
+**FCC RF Radiation Exposure Statement:**
+
+1. This Transmitter must not be co-located or operating in conjunction with any other antenna or transmitter.
+
+2. This equipment complies with RF radiation exposure limits set forth for an uncontrolled environment.
+
+3. This equipment should be installed and operated with a minimum distance of 20 cm between the radiator & your body.
+
+English:
+
User manuals for licence-exempt radio apparatus shall contain the following or equivalent notice in a conspicuous location in the user manual or alternatively on the device or both. This device complies with Industry Canada licence-exempt RSS standard(s). Operation is subject to the following two conditions:
+
+(1) this device may not cause interference
+
+(2) this device must accept any interference, including interference that may cause undesired operation of the device.
+
+French:
+
Le présent appareil est conforme aux CNR d'Industrie Canada applicables aux appareils radio exempts de licence. L'exploitation est autorisée aux deux conditions suivantes:
+
+(1) l'appareil ne doit pas produire de brouillage
+
+(2) l'utilisateur de l'appareil doit accepter tout brouillage radioélectrique subi, même si le brouillage est susceptible d'en compromettre le fonctionnement.
+
+**IC SAR Warning:**
+
+English:
+This equipment should be installed and operated with a minimum distance of 20 cm between the radiator and your body.
+
+French:
+Lors de l'installation et de l'exploitation de ce dispositif, la distance entre le radiateur et le corps est d'au moins 20 cm.
+
+**Important:** The operating temperature of the EUT can't exceed 40°C and shouldn't be lower than 0°C.
+
+Hereby, Arduino S.r.l. declares that this product is in compliance with essential requirements and other relevant provisions of Directive 2014/53/EU. This product is allowed to be used in all EU member states.
+
+## Company Information
+
+| Company name | Arduino S.r.l. |
+|--------------|--------------------------------------------|
+| Address | Via Andrea Appiani 25, 20900 Monza (Italy) |
+
+## Documentation Reference
+
+| No. | Reference | Link |
+|:---:|--------------------------------|------------------------------------------------------------------------------------------|
+| 1 | Arduino IDE (Desktop) | [https://www.arduino.cc/en/Main/Software](https://www.arduino.cc/en/Main/Software) |
+| 2 | Arduino IDE (Cloud) | [https://create.arduino.cc/editor](https://create.arduino.cc/editor) |
+| 3 | Arduino Nesso N1 Documentation | [https://docs.arduino.cc/hardware/nesso-n1/](https://docs.arduino.cc/hardware/nesso-n1/) |
+| 4 | Project Hub | [https://create.arduino.cc/projecthub](https://create.arduino.cc/projecthub) |
+| 5 | Library Reference | [https://github.com/arduino-libraries/](https://github.com/arduino-libraries/) |
+| 6 | Arduino Store | [https://store.arduino.cc/](https://store.arduino.cc/) |
+
+## Document Revision History
+
+| **Date** | **Revision** | **Changes** |
+|:----------:|:------------:|---------------|
+| 14/10/2025 | 1 | First release |
\ No newline at end of file
diff --git a/content/hardware/09.kits/maker/nesso-n1/downloads/TPX00227-full-pinout.pdf b/content/hardware/09.kits/maker/nesso-n1/downloads/TPX00227-full-pinout.pdf
new file mode 100644
index 0000000000..59aed82894
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/downloads/TPX00227-full-pinout.pdf differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/essentials.md b/content/hardware/09.kits/maker/nesso-n1/essentials.md
new file mode 100644
index 0000000000..f90f481cc1
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/essentials.md
@@ -0,0 +1,23 @@
+---
+productsLibrariesMap:
+ - m5gfx
+ - nimble-arduino
+ - arduino-modulino
+ - radiolib
+ - wire
+ - arduino_bmi270_bmm150
+ - irremote
+---
+
+
+
+
+ A simple interface to control the Arduino Modulino family of products via the Qwiic connector.
+
+
+
+ The standard library for communicating with I2C devices connected via the Grove or Qwiic ports.
+
+
+
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/features.md b/content/hardware/09.kits/maker/nesso-n1/features.md
new file mode 100644
index 0000000000..517cafeb6e
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/features.md
@@ -0,0 +1,45 @@
+
+
+Powered by M5Stack, this sleek, compact device delivers power, versatility, and ease of use. Its ESP32-C6 core allows seamless, long-range connectivity for smart home devices, industrial automation tools, and wearables. Enjoy instant interaction with its touch display, programmable buttons, and built-in sensors, and expand possibilities with Grove, Qwiic, and M5StickC HAT-compatible connectors.
+
+
+
+
+
+
+Seamlessly connect your projects with multiple protocols, including Wi-Fi® 6, Bluetooth® LE 5.3, 802.15.4 (Thread/Zigbee®), and LoRa®, enabling versatile and reliable communication for any IoT application.
+
+
+
+The detachable LoRa® antenna can be securely stored within the device enclosure when not in use, maintaining a portable form factor for on-the-go projects.
+
+
+
+The onboard 1.14-inch color touchscreen provides a clear and intuitive way to display data and create user interfaces directly on your device.
+
+
+
+Easily integrate a wide range of sensors and peripherals from the Arduino Modulino family and third-party modules using the built-in Grove, Qwiic, and 8-pin HAT connectors for plug-and-play expansion.
+
+
+
+The integrated BMI270 Inertial Measurement Unit (IMU) offers precise motion and posture detection, perfect for wearables, gesture control, and orientation-aware projects.
+
+
+
+A built-in 250 mAh LiPo battery and advanced power management chip provide portability and real-time monitoring of battery status, with over-current and over-voltage protection.
+
+
+
+The Nesso N1 features a modern USB-C® connector for streamlined power delivery, battery charging, and data transfer.
+
+
+
+Transform traditional appliances into smart devices using the onboard infrared (IR) transmitter to create custom remote controls and IoT gateways.
+
+
+
+Three programmable buttons and an onboard buzzer offer flexible control and audible feedback for your applications.
+
+
+
\ No newline at end of file
diff --git a/content/hardware/09.kits/maker/nesso-n1/image.svg b/content/hardware/09.kits/maker/nesso-n1/image.svg
new file mode 100644
index 0000000000..a0c676fdbb
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/image.svg
@@ -0,0 +1,31 @@
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/interactive/TPX00227-pinout.png b/content/hardware/09.kits/maker/nesso-n1/interactive/TPX00227-pinout.png
new file mode 100644
index 0000000000..e631bd7f71
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/interactive/TPX00227-pinout.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/product.md b/content/hardware/09.kits/maker/nesso-n1/product.md
new file mode 100644
index 0000000000..d40eef6a04
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/product.md
@@ -0,0 +1,11 @@
+---
+title: Nesso N1
+url_shop: https://store.arduino.cc/products/nesso-n1
+primary_button_url: /tutorials/nesso-n1/user-manual
+primary_button_title: User Manual
+core: RISC-V
+forumCategorySlug: '/hardware/kits/nesso-n1'
+sku: [TPX00227]
+---
+
+The **Arduino Nesso N1** is a high-performance, all-in-one development board for remote monitoring and automation. Powered by an **ESP32-C6** SoC, it integrates **Wi-Fi® 6**, **Bluetooth® LE 5.3**, **Thread/Zigbee®**, and **LoRa®** communication protocols. Featuring a **1.14" color touchscreen**, built-in **IMU sensor**, **programmable buttons**, and a rechargeable **battery**, the Nesso N1 is the ultimate tool for developing sophisticated IoT solutions.
\ No newline at end of file
diff --git a/content/hardware/09.kits/maker/nesso-n1/suggestions.md b/content/hardware/09.kits/maker/nesso-n1/suggestions.md
new file mode 100644
index 0000000000..4ad7321884
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/suggestions.md
@@ -0,0 +1,18 @@
+
+
+
+ Get started with the Arduino Cloud
+
+
+
+
+
+ Built-in Examples are sketches included in the Arduino IDE and demonstrate all basic Arduino commands.
+
+
+ Discover interesting articles, principles and techniques related to the Arduino ecosystem.
+
+
+ Arduino programming language can be divided in three main parts: functions, values (variables and constants), and structure.
+
+
diff --git a/content/hardware/09.kits/maker/nesso-n1/tech-specs.md b/content/hardware/09.kits/maker/nesso-n1/tech-specs.md
new file mode 100644
index 0000000000..8c20c1eef4
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/tech-specs.md
@@ -0,0 +1,5 @@
+Here you will find the technical specifications for the Arduino Nesso N1.
+
+**Note on Connectors:** The Qwiic, and 8-pin expansion port connectors operate at **3.3 V**. Connecting modules or devices that use higher logic levels, such as 5 V, may permanently damage the board.
+
+**Note on GPIO Current:** Be mindful of the current limits for the GPIO pins. Exceeding the specifications in the ESP32-C6 datasheet may damage the pin or the board.
diff --git a/content/hardware/09.kits/maker/nesso-n1/tech-specs.yml b/content/hardware/09.kits/maker/nesso-n1/tech-specs.yml
new file mode 100644
index 0000000000..06c07a46e1
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/tech-specs.yml
@@ -0,0 +1,60 @@
+Board:
+ Name: Arduino Nesso N1
+ SKU: TPX00227
+
+Microcontroller:
+ SoC: ESP32-C6
+ Architecture: Single-core 32-bit RISC-V CPU
+ Clock Speed: up to 160 MHz
+
+Wireless Communication:
+ Wi-Fi: 2.4 GHz Wi-Fi® 6
+ Bluetooth: Bluetooth® LE 5.3
+ 802.15.4: Thread / Zigbee® (Supports Matter Thread endpoint devices)
+ LoRa®: SX1262 module (850–960 MHz)
+
+Memory:
+ Flash: 16 MB external
+ SRAM: 512 kB (Internal)
+
+Power:
+ Input Voltage: 5 V (via USB-C®)
+ Power Source: USB DC-5V input or built-in battery power
+ Battery: 250 mAh LiPo (rechargeable)
+ Power Management: AW32001 (power path management, charge control, and over-current & over-voltage protection)
+ Battery Monitoring: BQ27220 (real-time monitoring of battery capacity, voltage, and current)
+
+Interfaces:
+ USB: 1× USB-C® (Programming / Power)
+ Grove: 1× Standard Grove interface
+ Qwiic: 1× Qwiic interface standard
+ Expansion Port: 1× 8-pin (M5StickC HAT compatible)
+
+Onboard Peripherals:
+ Display: 1.14" IPS LCD touchscreen (135×240 px, 262K colors, ST7789P3 driver, FT6336U capacitive touch)
+ IMU: BMI270 (6-axis)
+ Infrared: 1× IR transmitter (IR LED, connected to GPIO9 pin)
+ Audio: 1× Buzzer (connected to GPIO11 pin)
+ User Buttons: 2× programmable (KEY1/KEY2) + 1× Power/Reset/Bootloader button
+ User LEDs: 1× Green programmable (LED_BUILTIN) + 1× Blue (status indications)
+
+Operating Temperature: 0–40 °C
+
+Antennas:
+ ESP32-C6: on-board FPC antenna (dedicated)
+ LoRa®: detachable external antenna
+
+Dimensions (Device without antenna storage):
+ Width: 24 mm
+ Length: 48 mm
+ Height: 14 mm
+
+Dimensions (Device with antenna storage):
+ Width: 24 mm
+ Length: 48 mm
+ Height: 21.1 mm
+
+Dimensions (LoRa® antenna):
+ Width: 10.8 mm
+ Length: 45.5 mm
+ Height: 4.8 mm
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/anomaly-detection.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/anomaly-detection.png
new file mode 100644
index 0000000000..f32ed8b463
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/anomaly-detection.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/anomaly-explorer.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/anomaly-explorer.png
new file mode 100644
index 0000000000..25aab650ee
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/anomaly-explorer.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/classifier.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/classifier.png
new file mode 100644
index 0000000000..e0b13b0d51
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/classifier.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/daemon-version.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/daemon-version.png
new file mode 100644
index 0000000000..8bec712940
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/daemon-version.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/dashboard.gif b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/dashboard.gif
new file mode 100644
index 0000000000..b81e05bb5f
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/dashboard.gif differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/data-collection.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/data-collection.png
new file mode 100644
index 0000000000..862d24f5bf
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/data-collection.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/data-forwarder-configuration.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/data-forwarder-configuration.png
new file mode 100644
index 0000000000..8f14f6fdde
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/data-forwarder-configuration.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/device-verification.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/device-verification.png
new file mode 100644
index 0000000000..ec1e100c9f
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/device-verification.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/download-button.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/download-button.png
new file mode 100644
index 0000000000..4ff5d7f9e6
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/download-button.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/example-sketch-output-1.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/example-sketch-output-1.png
new file mode 100644
index 0000000000..1a4cdd9c56
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/example-sketch-output-1.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/example-sketch-output-display-1.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/example-sketch-output-display-1.png
new file mode 100644
index 0000000000..a0439c3721
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/example-sketch-output-display-1.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/feature-explorer.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/feature-explorer.png
new file mode 100644
index 0000000000..d2ff7d9758
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/feature-explorer.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/hardware-setup-nesso.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/hardware-setup-nesso.png
new file mode 100644
index 0000000000..070cd4770a
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/hardware-setup-nesso.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/hero-banner.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/hero-banner.png
new file mode 100644
index 0000000000..dd0f3c72e8
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/hero-banner.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/impulse-design.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/impulse-design.png
new file mode 100644
index 0000000000..21402ea4a2
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/impulse-design.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/model-deployment.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/model-deployment.png
new file mode 100644
index 0000000000..21f537d645
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/model-deployment.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/model-validation.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/model-validation.png
new file mode 100644
index 0000000000..715ed8cb73
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/model-validation.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_anomaly_detection_cloud.zip b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_anomaly_detection_cloud.zip
new file mode 100644
index 0000000000..b8d33c5aa4
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_anomaly_detection_cloud.zip differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_anomaly_detection_nesso.zip b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_anomaly_detection_nesso.zip
new file mode 100644
index 0000000000..ee7bb06bf4
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_anomaly_detection_nesso.zip differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_vibration_collector.zip b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_vibration_collector.zip
new file mode 100644
index 0000000000..bbab3c0dcd
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/motor_vibration_collector.zip differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/new-project.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/new-project.png
new file mode 100644
index 0000000000..12115a269f
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/new-project.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/spectral-features.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/spectral-features.png
new file mode 100644
index 0000000000..342f563803
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/spectral-features.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/visual-indication-cloud.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/visual-indication-cloud.png
new file mode 100644
index 0000000000..2e7dba110e
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/visual-indication-cloud.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/visual-indication.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/visual-indication.png
new file mode 100644
index 0000000000..66ac822b21
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/assets/visual-indication.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/content.md b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/content.md
new file mode 100644
index 0000000000..918b484328
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/tutorials/anomaly-detection-application-note/content.md
@@ -0,0 +1,1888 @@
+---
+title: 'Motor Anomaly Detection with the Nesso N1'
+description: "This application note describes how to implement a motor anomaly detection system using the Nesso N1 development kit, its built-in IMU sensor, and Edge Impulse."
+difficulty: intermediate
+compatible-products: [nesso-n1]
+tags:
+ - Motor monitoring
+ - Anomaly detection
+ - Classification
+ - Application note
+ - Machine learning
+ - Edge Impulse
+ - IMU
+ - Nesso N1
+ - LoRaWAN
+ - Wi-Fi
+author: 'José Bagur'
+hardware:
+ - hardware/09.kits/maker/nesso-n1
+software:
+ - ide-v2
+ - edge-impulse
+---
+
+## Introduction
+
+Motor condition monitoring is crucial in industrial settings, where unexpected equipment failures can lead to significant downtime and high maintenance costs. This application note demonstrates how to construct a motor anomaly detection system utilizing the Nesso N1 development kit, its onboard 6-axis Inertial Measurement Unit (IMU), and Edge Impulse®.
+
+
+
+
+The developed system monitors vibration patterns in real-time to identify unusual operating conditions that may signal mechanical problems, wear, or potential failures. The system utilizes machine learning to identify vibration patterns that deviate from regular motor operation, enabling predictive maintenance. The Nesso N1's multiple connectivity options (Wi-Fi® 6, LoRa®, Thread, and Bluetooth® 5.3) enable flexible deployment in various industrial environments, ranging from local monitoring to long-range remote sensing applications.
+
+
+## Goals
+
+This application note will help you to:
+
+- Build a motor anomaly detection system that monitors vibration patterns in real-time using the Nesso N1's built-in 6-axis IMU sensor.
+- Collect and analyze vibration data from motors to create baseline patterns and detect changes.
+- Train a machine learning model using Edge Impulse to detect anomalies based on vibration data.
+- Deploy the trained model directly to the Nesso N1 development kit for real-time anomaly detection without needing cloud connectivity.
+- Set up visual and audio feedback through the kit's built-in RGB LED, touch display, and buzzer to show detected anomalies and system status.
+- Leverage the Nesso N1's multiple connectivity protocols (Wi-Fi® 6, LoRa®, Thread, Bluetooth® 5.3) to transmit alerts and data to remote monitoring systems.
+
+- Create industrial predictive maintenance solutions using cost-effective embedded intelligence in a compact, pre-assembled enclosure.
+
+## Hardware and Software Requirements
+
+### Hardware Requirements
+
+- [Arduino Nesso N1 development kit](https://store.arduino.cc/products/nesso-n1) (x1)
+- [USB-C® cable](https://store.arduino.cc/products/usb-cable2in1-type-c) (x1)
+- Motor or rotating equipment for testing (for example, a small DC motor or fan) (x1)
+- Power supply for the motor (if needed) (x1)
+- Mounting accessories or adhesive tape to secure the Nesso N1 to the motor (x1 set)
+
+### Software Requirements
+
+- [Arduino IDE 2.0+](https://www.arduino.cc/en/software) or [Arduino Web Editor](https://create.arduino.cc/editor)
+- [ESP32 Arduino Core](https://github.com/espressif/arduino-esp32) (needed for the Nesso N1 ESP32-C6 processor)
+- [Edge Impulse account](https://studio.edgeimpulse.com/) (free tier available)
+- [Edge Impulse CLI tools](https://docs.edgeimpulse.com/docs/cli-installation) for data collection
+
+***The Nesso N1 development kit features a powerful ESP32-C6 processor with a single-core 32-bit RISC-V CPU running at up to 160 MHz, 16 MB NOR Flash memory and 512 KB SRAM for machine learning tasks. The onboard 6-axis IMU (BMI270) eliminates the need for external accelerometer connections. For complete hardware specifications, see the [Nesso N1 documentation](https://docs.arduino.cc/hardware/nesso-n1/).***
+
+## Hardware Setup Overview
+
+The electrical connections for the motor anomaly detection system are simplified with the Nesso N1 development kit, as all its essential components are integrated into a single, compact device.
+
+
+
+This diagram shows the system components using the Nesso N1 development kit. **The Nesso N1 acts as an all-in-one solution**, combining the kit's microcontroller (ESP32-C6), onboard IMU (BMI270), wireless connectivity, display, and battery in a single enclosed unit. **The onboard 6-axis IMU collects vibration data** from the motor through direct physical coupling when the device is mounted on the motor housing.
+
+The Nesso N1 operates from its built-in rechargeable lithium-polymer battery or can be powered via the USB-C connector with a +5 VDC supply. The compact form factor (18 mm x 45 mm) and integrated enclosure make it ideal for direct mounting on motor equipment without the need for additional protective housing.
+
+***__Important note__: This power setup is for testing and demonstration purposes only. In real industrial environments, proper power system design should include electrical isolation, noise filtering, surge protection, and compliance with industrial safety standards for your specific application.***
+
+### Physical Mounting Considerations
+
+Proper mounting of the Nesso N1 is essential for effective vibration monitoring. The development kit must be securely attached to the motor housing or equipment using appropriate mechanical fasteners or industrial-grade adhesive. A good mechanical connection between the mounting surface and the device guaranteess accurate vibration transmission from the motor to the onboard IMU.
+
+The Nesso N1's enclosed design provides basic protection against dust and minor vibrations, making it suitable for many industrial environments. However, additional protective measures may be needed in extreme conditions.
+
+***For this application note, we will use a computer cooling fan to simulate motor operation and demonstrate the anomaly detection system. The Nesso N1 can be mounted directly on top of the fan using double-sided adhesive tape or a custom 3D-printed mounting bracket, providing a stable and consistent mounting solution for testing.***
+
+## Understanding Motor Vibration Analysis
+
+Motor vibrations contain valuable information about the mechanical condition of the equipment. Regular motor operation produces characteristic vibration patterns that stay relatively consistent during healthy operation. Abnormal conditions manifest as changes in vibration amplitude, frequency content, or timing patterns.
+
+### Common Motor Faults
+
+Common motor faults that can be detected through vibration analysis include:
+
+- **Bearing wear**: Creates higher frequency components and increased vibration levels across all axes
+- **Misalignment**: Produces specific frequency patterns related to rotational speed, typically appearing in radial directions
+- **Imbalance**: Results in increased vibration at the main rotational frequency, primarily in radial directions
+- **Looseness**: Causes widespread increases in vibration across multiple frequencies and directions
+- **Electrical issues**: May create vibrations at twice the line frequency due to magnetic field changes
+
+### The Role of the IMU in Vibration Monitoring
+
+The Nesso N1's onboard BMI270 6-axis IMU combines a 3-axis accelerometer and 3-axis gyroscope, providing complete motion sensing capabilities for vibration analysis. The accelerometer measures linear acceleration along the X, Y, and Z axes, capturing the intensity and direction of vibrations. The gyroscope complements this by detecting rotational movements, which can indicate wobbling or angular vibrations in the motor.
+
+The BMI270 offers several advantages for industrial vibration monitoring:
+
+- High sensitivity and low noise for detecting subtle vibration changes
+- Programmable measurement ranges (±2g to ±16g for accelerometer)
+- High sampling rates up to 1.6 kHz for capturing fast vibration events
+- Built-in digital filters to reduce noise and improve signal quality
+- Low power consumption, extending battery life in the Nesso N1
+
+This integrated sensor approach eliminates the need for external accelerometer wiring, ensuring consistent and reliable measurements. The digital I²C interface between the BMI270 and the ESP32-C6 microcontroller enables noise-immune data transmission, which is important to have in electrically noisy industrial environments.
+
+### Data Collection Strategy
+
+The Nesso N1 collects vibration data at regular intervals to build a complete picture of the motor's behavior. The system samples the IMU at 100 Hz, providing sufficient resolution to capture vibration patterns up to 50 Hz, as per the Nyquist theorem. This sampling rate covers most mechanical vibration frequencies found in typical motor applications.
+
+Each data collection window consists of 200 samples (2 seconds of data), providing enough information for the machine learning model to identify patterns while keeping computational requirements manageable. The Nesso N1's 512 KB SRAM provides ample buffer space for storing multiple windows of vibration data during processing.
+
+## Simple Vibration Monitor Example Sketch
+
+Now that we have covered the hardware components and vibration analysis basics, let's look at the software that enables vibration data collection. Before implementing intelligent anomaly detection, we need to collect training data representing normal motor operation for Edge Impulse, a platform that simplifies embedded AI development.
+
+Edge Impulse needs training data in a specific format to build effective anomaly detection models. Our data collection sketch formats the IMU readings so Edge Impulse can analyze normal operation patterns and create a model that identifies when new data differs from these patterns.
+
+This section breaks down the example sketch and guides you through its functionality. We will explore how the IMU is initialized, how vibration data is collected at consistent intervals, and how the results are formatted for Edge Impulse data collection and model training.
+
+The complete example sketch is shown below.
+
+```arduino
+/**
+ Motor Vibration Data Collection for Edge Impulse
+ Name: motor_vibration_collector.ino
+ Purpose: This sketch reads 6-axis IMU data from the onboard BMI270 sensor
+ of the Nesso N1 development kit. The data is formatted for Edge Impulse
+ data collection and training, with real-time display visualization.
+
+ @version 1.0 01/11/25
+ @author Arduino Product Experience Team
+*/
+
+#include
+#include
+
+// Display instance
+M5GFX display;
+
+// Sampling parameters
+const int sampleRate = 100; // 100 Hz
+const unsigned long sampleTime = 1000 / sampleRate; // 10ms between samples
+
+// Data collection variables
+unsigned long lastSample = 0;
+
+void setup() {
+ // Initialize USB serial communication at 115200 baud
+ Serial.begin(115200);
+ for (auto startNow = millis() + 2500; !Serial && millis() < startNow; delay(500));
+
+ // Initialize display
+ display.begin();
+ display.setRotation(1); // Landscape mode
+ display.setTextColor(TFT_WHITE, TFT_BLACK);
+ display.fillScreen(TFT_BLACK);
+ display.setTextSize(1.5);
+ display.setTextDatum(MC_DATUM);
+ display.drawString("- Initializing IMU...", display.width() / 2, display.height() / 2);
+
+ // Initialize IMU
+ if (!IMU.begin()) {
+ Serial.println("- Failed to initialize BMI270 IMU!");
+ display.fillScreen(TFT_BLACK);
+ display.setTextColor(TFT_RED, TFT_BLACK);
+ display.drawString("- IMU Failed!", display.width() / 2, display.height() / 2);
+ while (1);
+ }
+
+ Serial.println("- Motor Vibration Data Collector (BMI270)");
+ Serial.println("- 6-axis sensor initialized!");
+
+ // Display sensor information
+ Serial.print("- Accelerometer sample rate: ");
+ Serial.print(IMU.accelerationSampleRate());
+ Serial.println(" Hz");
+
+ // Wait for sensor stabilization
+ delay(500);
+
+ // Test initial reading
+ float testX, testY, testZ;
+ if (IMU.accelerationAvailable()) {
+ IMU.readAcceleration(testX, testY, testZ);
+
+ Serial.print("- Initial readings (g): X=");
+ Serial.print(testX, 3);
+ Serial.print(", Y=");
+ Serial.print(testY, 3);
+ Serial.print(", Z=");
+ Serial.println(testZ, 3);
+
+ Serial.println("- Sensor ready (values already in g units)");
+ }
+
+ Serial.println("- Streaming continuous data for Edge Impulse!");
+ Serial.println("- Data format: X_accel,Y_accel,Z_accel");
+
+ // Setup display for live data
+ display.fillScreen(TFT_BLACK);
+ display.setTextSize(1.5);
+ display.setTextDatum(TL_DATUM);
+ display.drawString("- Motor Vibration Data:", 5, 5);
+ display.drawString("- X:", 5, 30);
+ display.drawString("- Y:", 5, 45);
+ display.drawString("- Z:", 5, 60);
+ display.drawString("g", 100, 30);
+ display.drawString("g", 100, 45);
+ display.drawString("g", 100, 60);
+
+ delay(1000);
+}
+
+void loop() {
+ unsigned long currentTime = millis();
+
+ if (currentTime - lastSample >= sampleTime) {
+ float xAccel, yAccel, zAccel;
+ bool dataValid = false;
+
+ // Read new acceleration data from the IMU
+ if (IMU.accelerationAvailable()) {
+ IMU.readAcceleration(xAccel, yAccel, zAccel);
+ dataValid = true;
+ }
+
+ // Output CSV format for Edge Impulse
+ if (dataValid) {
+ Serial.print(xAccel, 4);
+ Serial.print(",");
+ Serial.print(yAccel, 4);
+ Serial.print(",");
+ Serial.println(zAccel, 4);
+
+ // Update display with current values
+ display.fillRect(45, 30, 50, 45, TFT_BLACK);
+ display.setTextColor(TFT_GREEN, TFT_BLACK);
+ display.setTextSize(1.5);
+ display.setCursor(40, 30);
+ display.printf("%+.3f", xAccel);
+ display.setCursor(40, 45);
+ display.printf("%+.3f", yAccel);
+ display.setCursor(40, 60);
+ display.printf("%+.3f", zAccel);
+ }
+
+ lastSample = currentTime;
+ }
+}
+```
+
+The following sections will help you understand the main components of the example sketch, which can be divided into the following areas:
+
+- Sensor selection and initialization
+- Hardware configuration and calibration
+- Data collection timing and control
+- Signal processing and conversion
+- Edge Impulse data formatting
+
+### Sensor Selection and Initialization
+
+The sketch begins by including the necessary libraries for the Nesso N1's integrated components:
+```arduino
+#include
+#include
+
+// Display instance
+M5GFX display;
+```
+
+In this code:
+
+- The `Arduino_BMI270_BMM150` library provides access to the onboard 6-axis IMU of the Nesso N1
+- The `M5GFX` library controls the 1.14" touch display
+
+### Hardware Configuration and Calibration
+
+Before we can collect vibration data, we need to configure the Nesso N1 development kit to interface with its onboard BMI270 IMU.
+
+**BMI270 Configuration**
+
+For the Nesso N1, the configuration is simplified as the BMI270 is factory-calibrated and internally connected:
+
+```arduino
+// Initialize IMU
+if (!IMU.begin()) {
+ Serial.println("- Failed to initialize BMI270 IMU!");
+ while (1);
+}
+
+Serial.println("- Motor Vibration Data Collector (BMI270)");
+Serial.println("- 6-axis sensor initialized!");
+
+// Display sensor information
+Serial.print("- Accelerometer sample rate: ");
+Serial.print(IMU.accelerationSampleRate());
+Serial.println(" Hz");
+```
+
+In this code:
+
+- The IMU is initialized with its default settings
+- No pin assignments are needed as the IMU is internally connected via I²C
+
+### Data Collection Timing and Control
+
+To guarantees accurate vibration analysis and successful machine learning training, we need consistent data collection timing. These parameters control how data is gathered:
+
+```arduino
+// Sampling parameters
+const int sampleRate = 100; // 100 Hz
+const unsigned long sampleTime = 1000 / sampleRate; // 10 ms between samples
+```
+
+In this code:
+
+- Sample rate of 100 Hz captures enough frequency response for detecting most motor faults
+- Sample time calculation determines the precise timing needed between measurements
+
+### Signal Processing and Conversion
+
+Once we have the sensor readings, the BMI270 IMU provides pre-processed digital values ready for use.
+
+**BMI270 Signal Processing**
+
+For the onboard BMI270 IMU, the data is already processed and calibrated:
+
+```arduino
+// Read new acceleration data from the IMU
+if (IMU.accelerationAvailable()) {
+ IMU.readAcceleration(xAccel, yAccel, zAccel);
+ dataValid = true;
+}
+```
+
+In this code:
+
+- `IMU.accelerationAvailable()` checks if new data is ready from the IMU
+- The acceleration values are returned directly in **g** units
+
+### Edge Impulse Data Formatting
+
+The final step formats our acceleration data so it can be used with Edge Impulse data collection tools:
+
+```arduino
+// Output CSV format for Edge Impulse
+if (dataValid) {
+ Serial.print(xAccel, 4);
+ Serial.print(",");
+ Serial.print(yAccel, 4);
+ Serial.print(",");
+ Serial.println(zAccel, 4);
+}
+```
+
+In this code:
+
+- CSV format with four decimal places gives us the precision needed for machine learning training
+- Single-line output per sample makes it easy to integrate with the Edge Impulse data forwarder
+- Comma separation follows standard CSV format that most data processing tools expect
+- The display provides real-time visual feedback of the acceleration values
+
+After uploading the example sketch to the Nesso N1 development kit, you should see the following output in the Arduino IDE's Serial Monitor:
+
+
+
+### Optional: Display Visualization
+
+The Nesso N1's built-in 1.14" touch display provides real-time visual feedback during data collection, which is particularly useful for verifying proper sensor mounting and monitoring vibration levels without needing a serial connection.
+
+**Display Setup**
+
+The display initialization configures the screen orientation and text properties:
+
+```arduino
+// Initialize display
+display.begin();
+display.setRotation(1); // Landscape mode for better data layout
+display.setTextColor(TFT_WHITE, TFT_BLACK);
+display.fillScreen(TFT_BLACK);
+display.setTextSize(1.5); // Readable size for the small screen
+```
+
+**Real-time Data Visualization**
+
+The display updates with each new sensor reading, showing the acceleration values for all three axes:
+
+```arduino
+// Update display with current values
+display.fillRect(45, 30, 50, 45, TFT_BLACK); // Clear previous values only
+display.setTextColor(TFT_GREEN, TFT_BLACK);
+display.setTextSize(1.5);
+display.setCursor(40, 30);
+display.printf("%+.3f", xAccel); // Format with sign and 3 decimals
+display.setCursor(40, 45);
+display.printf("%+.3f", yAccel);
+display.setCursor(40, 60);
+display.printf("%+.3f", zAccel);
+```
+
+In this code:
+
+- The `fillRect()` function clears only the area where values are displayed, preserving the labels
+- Green text color provides good contrast against the black background
+- The `printf()` format guarantees consistent display with sign (+/-) and three decimal places
+- Values update at 100 Hz
+
+This visual feedback helps during setup by:
+
+- Confirming the IMU is responding to vibrations
+- Verifying proper mounting (values should change when motor runs)
+- Monitoring data quality without a computer connection
+- Providing immediate indication of sensor saturation or disconnection
+
+After uploading the example sketch to the Nesso N1 development kit, you should see the following output in the Nesso N1's built-in 1.14" touch display:
+
+
+
+### Complete Example Sketch
+
+Download the complete data collection example sketch [here](assets/motor_vibration_collector.zip).
+
+[](assets/motor_vibration_collector.zip)
+
+## Connecting the Vibration Monitor to Edge Impulse
+
+As vibration-based condition monitoring becomes more important for predictive maintenance, connecting our data collection system to Edge Impulse enables the development of intelligent anomaly detection models. Edge Impulse provides a complete platform for embedded machine learning, allowing us to transform raw vibration data into useful insights about motor health.
+
+In this section, we will connect the vibration monitor to Edge Impulse platform to collect training data, develop machine learning models and deploy intelligent anomaly detection directly to the Nesso N1 development kit. This connection transforms our simple vibration monitor into an intelligent system that can detect motor anomalies without needing cloud connectivity.
+
+***If you are new to Edge Impulse, please check out [this tutorial](https://docs.edgeimpulse.com/docs/tutorials/end-to-end-tutorials/time-series/continuous-motion-recognition/) for an introduction to the platform.***
+
+### Setting up Edge Impulse Account and Project
+
+The first step involves creating an Edge Impulse account and setting up a new project for motor anomaly detection. These steps establish the foundation for machine learning model development:
+
+**(1) Create Account**: Register for a free Edge Impulse account at [studio.edgeimpulse.com](https://studio.edgeimpulse.com/)
+
+**(2) New Project**: Create a new project with the following settings:
+
+- Enter a project name (for example, "`nesso-n1-anomaly-detection`")
+- Choose project type: Personal (free tier with 60 min job limit, 4 GB data limit)
+- Choose project setting: Private (recommended for this application)
+
+
+
+**(3) Project Configuration**: Once created, the project will be ready for data collection. Sampling frequency and window settings will be configured later during impulse design.
+
+### Data Collection with Edge Impulse CLI
+
+The Edge Impulse CLI provides tools for streaming data directly from the Nesso N1 to the Edge Impulse platform. This eliminates manual file transfers and enables efficient data collection.
+
+#### Installing Edge Impulse CLI
+
+Before you can collect data from the Nesso N1, you need to install the Edge Impulse CLI tools on your computer. The installation process varies depending on your operating system.
+
+Prerequisites:
+
+- [Node.js](https://nodejs.org/en) 14 or higher
+- [Python 3](https://www.python.org/downloads/)
+
+For detailed installation instructions specific to your operating system, follow the [official Edge Impulse CLI installation guide](https://docs.edgeimpulse.com/docs/tools/edge-impulse-cli/cli-installation).
+
+Verify the installation with the following command:
+
+```bash
+edge-impulse-daemon --version
+```
+
+
+
+#### Setting up Data Forwarding
+
+Now that you have the CLI installed, you can set up data forwarding to stream vibration data directly from your Nesso N1 to Edge Impulse.
+
+Connect your Nesso N1 to your computer via USB-C cable and upload the data collection sketch. Then open a terminal and run the following command:
+
+```bash
+edge-impulse-data-forwarder
+```
+
+The tool will guide you through the setup process:
+
+1. **Login**: Enter your Edge Impulse username/email and password when prompted
+2. **Select Device**: Choose the correct serial port for your Nesso N1 development kit (for example, `COM10`)
+3. **Data Detection**: The tool will automatically detect the data frequency (100 Hz) and number of sensor axes (3)
+4. **Name Axes**: When asked "What do you want to call them?", enter: `X`,`Y`,`Z`
+5. **Device Name**: Give your device a name (for example, `nesso-n1`)
+6. **Project Connection**: If you have multiple projects, the tool will ask which Edge Impulse project you want to connect the device to. Select your motor anomaly detection project.
+
+
+
+Once configured, the forwarder will stream data from your Nesso N1 board to Edge Impulse. You can verify the device connection by checking the "Devices" tab in Edge Impulse Studio. You can then start collecting training data for your machine learning model.
+
+
+
+#### Data Collection Process
+
+With the data forwarder running, you can now collect training data for your anomaly detection model. For effective anomaly detection, you need high-quality data representing normal motor operation in different states.
+
+Start by mounting the accelerometer securely to the motor housing. You will collect two types of normal operation data:
+
+1. **Idle data collection**: With the motor turned off, **collect 2 to 5 minutes of "idle" operation** data through multiple two second windows. This captures the baseline vibration environment without motor operation. Label all data as `idle` in Edge Impulse Studio.
+
+2. **Nominal data collection**: With the motor running under normal operating conditions, **collect 2 to 5 minutes of "nominal" operation** data through multiple two second windows. Vary motor load conditions slightly to capture different normal operating scenarios. Label all data as `nominal` in Edge Impulse Studio.
+
+Edge Impulse can automatically split your collected data into **training (80%) and testing (20%) sets**. The 4 to 10 minutes total of data guarantees you have enough samples for both training the model and validating its performance on unseen data.
+
+
+
+After data collection, review the collected samples in Edge Impulse Studio for consistency. Check for proper amplitude ranges and no clipping, verify sample rate consistency and timing accuracy and remove any corrupted or unusual samples from the training set.
+
+***__Important note__: The anomaly detection model learns what "normal" looks like from both idle and nominal data. Any future vibration patterns that significantly differ from these learned patterns will be flagged as anomalies. This approach allows the system to detect unknown fault conditions without needing examples of actual motor failures.***
+
+### Training the Anomaly Detection Model
+
+Once you have collected sufficient `idle` and `nominal` operation data, the next step involves configuring and training the machine learning model for anomaly detection.
+
+#### Impulse Design Configuration
+
+Within Edge Impulse Studio, configure the impulse design with appropriate processing and learning blocks. Navigate to the "Impulse design" tab and set up the following blocks:
+
+1. **Input Block**: Configure time series data with window size of 1000 ms, window increase of 100 ms, and frequency of 100 Hz to match your data collection sampling rate.
+2. **Processing Block**: Add "Spectral Analysis" block for frequency domain feature extraction
+3. **Classification Learning Block**: Add "Classification (Keras)" to distinguish between `idle` and `nominal` operating states.
+4. **Learning Block**: Select "Anomaly Detection (K-means)" for unsupervised learning approach
+
+
+
+This dual approach provides a more robust monitoring system where the classifier identifies the current operating state (`idle` vs `nominal`) while the anomaly detector flags unusual patterns that don't fit either normal category.
+
+#### Feature Extraction Configuration
+
+The spectral analysis block extracts relevant features from the raw vibration signals. Configure the following parameters optimized for the Nesso N1's BMI270 IMU:
+
+- **Type**: None (no filter) to preserve all frequency information from the IMU
+- **Cut-off frequency**: Not applicable when filter type is None
+- **Order**: Not applicable when filter type is None
+- **FFT length**: 64 points for efficient processing on the ESP32-C6
+- **Take log of spectrum**: Disable this option for more linear response with the BMI270
+- **Overlap FFT frames**: Enable this option to increase the number of features extracted from each window
+
+
+
+***__Important note__: The BMI270 IMU in the Nesso N1 provides very clean digital data, so heavy filtering is not necessary. Using no filter with a smaller FFT length (64 points) provides better discrimination between `idle` and `nominal` states while reducing computational load on the ESP32-C6 processor.***
+
+#### Model Training Process
+
+Follow these steps to train the anomaly detection model using the collected idle and nominal operation data:
+
+**(1) Generate Features**: Before clicking "Generate features", enable "Calculate feature importance" to identify which frequency bands are most relevant for distinguishing between idle and nominal states. Then click "Generate features" to extract spectral features from all training data. Edge Impulse will process your data and create the feature vectors needed for training.
+
+**(2) Feature Explorer**: Review the feature explorer visualization to verify data quality and feature separation between your idle and nominal classes.
+
+
+
+**(3) Train Classification Model**: Navigate to the "Classifier" tab and configure the neural network with the following simplified settings optimized for the Nesso N1:
+
+- Number of training cycles: 50 (increased for better convergence)
+- Learning rate: 0.001 (slightly higher for faster training)
+- Neural network architecture: Configure dense layers with 20 neurons (first layer) and 10 neurons (second layer) to provide efficient pattern recognition without overfitting
+- Validation set size: 20%
+
+Start training and monitor the accuracy metrics.
+
+
+
+**(4) Train Anomaly Detection Model**: Navigate to the "Anomaly detection" tab and configure K-means clustering with reduced complexity:
+
+- **Cluster count**: 12 clusters (reduced from 32) for more stable anomaly scores
+- **Axes selection**: Use "Select suggested axes" to automatically choose the most relevant spectral features
+- Click "Start training" to train the anomaly detection model
+
+
+
+***__Important note__: Using 12 clusters instead of 32 produces more reasonable anomaly scores (typically in the 0 to 5 range) that are easier to threshold in your application. The BMI270's high sensitivity means fewer clusters are needed to map normal operation patterns effectively.***
+
+
+
+#### Special Considerations for the Nesso N1
+
+The Nesso N1's integrated BMI270 IMU has high sensitivity and low noise, which requires some adjustments to the typical training approach:
+
+1. **Gravity Compensation**: The BMI270 always measures 1g acceleration due to gravity. Make sure your training data includes the device in its intended mounting orientation.
+
+2. **Micro-vibration Sensitivity**: The IMU can detect very small vibrations. Collect `idle` data in a truly vibration-free environment, or the model may struggle to distinguish idle from nominal states.
+
+3. **Data Collection Duration**: Due to the sensor's stability, you may need only 5 to 10 minutes each of idle and nominal data rather than the 10 to 15 minutes suggested for analog sensors.
+
+4. **Threshold Calibration**: After deployment, expect to adjust the anomaly threshold based on your specific motor and environment. Start with a threshold of 2.0 and adjust based on false positive/negative rates.
+
+***__Important note__: If the model consistently misclassifies idle as nominal, the IMU may be detecting ambient vibrations or electrical noise. Consider adding a magnitude-based override in your Arduino code to force `idle` classification when vibration levels are below a certain threshold (typically 0.02g variation from baseline).***
+
+#### Model Validation and Testing
+
+After training completion, validate both model performances using the following methods:
+
+- **Live Classification**: Use the "Live classification" feature with data collected directly from the Nesso N1
+- **Classification Performance**: Verify >95% accuracy for `idle`/`nominal` distinction
+- **Anomaly Score Range**: Confirm anomaly scores stay below 2.0 for normal operation
+- **Edge Cases**: Test with motor at different speeds and loads
+- **Environmental Testing**: Verify performance with ambient vibrations present
+
+
+
+### Model Deployment
+
+After successful training and validation, deploy the model as an Arduino library:
+
+1. **Deployment Section**: Navigate to the "Deployment" tab in Edge Impulse Studio
+2. **Arduino Library**: Select "Arduino library" as the deployment target
+3. **Optimization Settings**: Choose `int8` quantization for memory efficiency on the ESP32-C6
+4. **EON Compiler**: Enable "Enable EON Compiler" for optimized performance
+5. **Download Library**: Download the generated Arduino library ZIP file
+6. **Library Installation**: Install in Arduino IDE using "Sketch > Include Library > Add .ZIP Library"
+
+
+
+The generated library is optimized for the Nesso N1's ESP32-C6 processor, providing efficient real-time inference with typical processing times under 20ms for both classification and anomaly detection.
+
+## Improving the Vibration Monitor with Machine Learning
+
+Now that we have trained our machine learning models, we can create a smart vibration monitor that automatically detects motor problems in real-time.
+
+The enhanced system does two things: it identifies whether the motor is running (nominal) or stopped (idle), and it alerts you when it detects unusual vibration patterns that might indicate a problem. This all happens directly on the Nesso N1 development kit without needing an internet connection.
+
+The smart monitoring system can do the following:
+
+- Tell if the motor is running (nominal) or stopped (idle)
+- Detect unusual vibrations that might indicate problems
+- Provide full-screen color-coded visual feedback for immediate status recognition
+- Work continuously without needing internet or cloud services
+
+The complete enhanced example sketch is shown below:
+
+```arduino
+/**
+ Intelligent Motor Anomaly Detection System
+ Name: motor_anomaly_detection_nesso.ino
+ Purpose: This sketch implements real-time motor anomaly detection using
+ the Nesso N1's integrated BMI270 IMU and Edge Impulse machine learning
+ model with full-screen visual feedback for predictive maintenance.
+
+ @version 5.0 01/11/25
+ @author Arduino Product Experience Team
+*/
+
+// Include the Edge Impulse library (name will match your project name)
+#include
+
+// Include libraries for Nesso's IMU and display control
+#include
+#include
+
+// Display instance for the 1.14" touch screen
+M5GFX display;
+
+// Data buffers for model inference
+static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
+static float inference_buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
+
+// Maximum accepted acceleration range (±2g)
+#define MAX_ACCEPTED_RANGE 2.0f
+
+// Detection parameters
+const float ANOMALY_THRESHOLD = 3.0f; // Threshold for anomaly detection
+const float WARNING_THRESHOLD = 1.5f; // Warning zone threshold
+const float IDLE_THRESHOLD = 0.02f; // Vibration threshold for idle detection
+
+// System status variables
+int totalInferences = 0;
+int anomalyCount = 0;
+unsigned long lastInferenceTime = 0;
+const unsigned long INFERENCE_INTERVAL = 2000; // Inference interval in milliseconds
+
+// Buffer management variables
+bool bufferFilled = false;
+int sampleCount = 0;
+
+// Current state tracking
+String currentState = "INITIALIZING";
+bool currentAnomaly = false;
+
+// Function declarations
+float ei_get_sign(float number);
+int raw_feature_get_data(size_t offset, size_t length, float *out_ptr);
+void runInference();
+void updateFullScreenDisplay(String state, bool anomaly);
+float calculateVibrationLevel();
+void processResults(ei_impulse_result_t result, float vibration);
+
+/**
+ Initializes the IMU, display, and machine learning system.
+ Configures the Nesso N1 for optimal performance with the
+ Edge Impulse model and prepares for real-time anomaly detection.
+*/
+void setup() {
+ // Initialize serial communication at 115200 baud
+ Serial.begin(115200);
+ while (!Serial && millis() < 3000);
+
+ Serial.println("- Nesso N1 Motor Anomaly Monitor");
+
+ // Initialize the 1.14" touch display
+ display.begin();
+ display.setRotation(1); // Set to landscape orientation
+ display.fillScreen(TFT_BLACK);
+ display.setTextSize(2);
+ display.setTextColor(TFT_WHITE, TFT_BLACK);
+ display.setTextDatum(MC_DATUM);
+ display.drawString("INITIALIZING...", display.width() / 2, display.height() / 2);
+
+ // Initialize BMI270 IMU sensor
+ if (!IMU.begin()) {
+ Serial.println("- ERROR: Failed to initialize IMU!");
+ display.fillScreen(TFT_RED);
+ display.setTextColor(TFT_WHITE, TFT_RED);
+ display.drawString("IMU FAILED!", display.width() / 2, display.height() / 2);
+ while (1); // Halt execution on IMU failure
+ }
+
+ Serial.println("- BMI270 IMU initialized!");
+ Serial.print("- Sample rate: ");
+ Serial.print(IMU.accelerationSampleRate());
+ Serial.println(" Hz");
+
+ // Verify Edge Impulse model configuration
+ if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != 3) {
+ Serial.println("ERROR: EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME should be 3");
+ while (1); // Halt execution on configuration error
+ }
+
+ Serial.println("\n- Edge Impulse Model loaded!");
+ Serial.print("- Project: ");
+ Serial.println(EI_CLASSIFIER_PROJECT_NAME);
+
+ Serial.println("\n- Filling buffer...");
+
+ // Display starting message while buffer fills
+ display.fillScreen(TFT_DARKGREY);
+ display.setTextColor(TFT_WHITE, TFT_DARKGREY);
+ display.drawString("STARTING...", display.width() / 2, display.height() / 2);
+
+ delay(1000);
+}
+
+/**
+ Main loop that continuously collects vibration data and performs
+ real-time classification and anomaly detection using the embedded
+ machine learning models.
+*/
+void loop() {
+ // Calculate the next sampling tick for precise timing
+ uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);
+
+ // Shift the buffer by 3 samples to create a rolling window
+ numpy::roll(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, -3);
+
+ // Wait for new acceleration data from the IMU
+ float x, y, z;
+ while (!IMU.accelerationAvailable()) {
+ delayMicroseconds(10);
+ }
+
+ // Read acceleration values (already in g units)
+ IMU.readAcceleration(x, y, z);
+
+ // Store new data at the end of the buffer
+ buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] = x;
+ buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] = y;
+ buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] = z;
+
+ // Clip acceleration values to the maximum accepted range
+ for (int i = 0; i < 3; i++) {
+ float* val = &buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3 + i];
+ if (fabs(*val) > MAX_ACCEPTED_RANGE) {
+ *val = ei_get_sign(*val) * MAX_ACCEPTED_RANGE;
+ }
+ }
+
+ // Track buffer filling progress during initialization
+ if (!bufferFilled) {
+ sampleCount++;
+ if (sampleCount >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE / 3) {
+ bufferFilled = true;
+ Serial.println("- Buffer filled, starting monitoring...\n");
+ }
+ }
+
+ // Maintain precise sampling rate
+ uint64_t time_to_wait = next_tick - micros();
+ if (time_to_wait > 0 && time_to_wait < 1000000) {
+ delayMicroseconds(time_to_wait);
+ }
+
+ // Execute inference at the specified interval
+ if (bufferFilled && (millis() - lastInferenceTime >= INFERENCE_INTERVAL)) {
+ lastInferenceTime = millis();
+ runInference();
+ }
+}
+
+/**
+ Executes the Edge Impulse inference on collected vibration data.
+ Processes the data through both classification and anomaly detection
+ models to determine motor state and detect unusual patterns.
+*/
+void runInference() {
+ // Copy the current buffer for inference processing
+ memcpy(inference_buffer, buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * sizeof(float));
+
+ // Calculate vibration level for additional state verification
+ float vibration = calculateVibrationLevel();
+
+ // Create signal structure for Edge Impulse
+ signal_t signal;
+ signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
+ signal.get_data = &raw_feature_get_data;
+
+ // Run the Edge Impulse classifier
+ ei_impulse_result_t result = { 0 };
+ EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
+
+ if (res != EI_IMPULSE_OK) {
+ Serial.printf("- ERROR: Failed to run classifier (%d)!\n", res);
+ return;
+ }
+
+ // Override classification if vibration indicates clear idle state
+ if (vibration < IDLE_THRESHOLD) {
+ for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
+ if (strcmp(ei_classifier_inferencing_categories[ix], "idle") == 0) {
+ result.classification[ix].value = 0.99f;
+ } else {
+ result.classification[ix].value = 0.01f;
+ }
+ }
+ }
+
+ // Process and display the inference results
+ processResults(result, vibration);
+}
+
+/**
+ Processes inference results and updates the full-screen display.
+ Analyzes classification confidence and anomaly scores to determine
+ the current motor state and trigger appropriate visual feedback.
+*/
+void processResults(ei_impulse_result_t result, float vibration) {
+ totalInferences++;
+
+ // Find the classification with highest confidence
+ String bestLabel = "unknown";
+ float bestValue = 0;
+
+ Serial.printf("- Inference #%d\n", totalInferences);
+
+ for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
+ if (result.classification[ix].value > bestValue) {
+ bestValue = result.classification[ix].value;
+ bestLabel = String(ei_classifier_inferencing_categories[ix]);
+ }
+ }
+
+ Serial.printf("- State: %s (%.0f%% confidence)\n", bestLabel.c_str(), bestValue * 100);
+ Serial.printf("- Vibration: %.4f g\n", vibration);
+
+ // Evaluate anomaly detection results
+ bool isAnomaly = false;
+
+#if EI_CLASSIFIER_HAS_ANOMALY
+ float anomalyScore = result.anomaly;
+ Serial.printf("- Anomaly score: %.3f", anomalyScore);
+
+ if (anomalyScore < WARNING_THRESHOLD) {
+ Serial.println(" [NORMAL]");
+ } else if (anomalyScore < ANOMALY_THRESHOLD) {
+ Serial.println(" [WARNING]");
+ } else {
+ Serial.println(" [ANOMALY!]");
+ isAnomaly = true;
+ anomalyCount++;
+ }
+#endif
+
+ // Update display only when state or anomaly status changes
+ if (bestLabel != currentState || isAnomaly != currentAnomaly) {
+ currentState = bestLabel;
+ currentAnomaly = isAnomaly;
+ updateFullScreenDisplay(currentState, currentAnomaly);
+ }
+
+ Serial.printf("- Timing: DSP %d ms, Classification %d ms\n\n",
+ result.timing.dsp, result.timing.classification);
+}
+
+/**
+ Updates the full-screen display with color-coded motor status.
+ Provides immediate visual feedback using background colors:
+ Blue for idle, Green for nominal operation, Red for anomalies.
+*/
+void updateFullScreenDisplay(String state, bool anomaly) {
+ uint16_t bgColor;
+ uint16_t textColor;
+ String displayText;
+
+ if (anomaly) {
+ // Anomaly detected - Display red background with white text
+ bgColor = TFT_RED;
+ textColor = TFT_WHITE;
+ displayText = "ANOMALY";
+ Serial.println(">>> Display: RED - ANOMALY");
+ } else if (state == "idle") {
+ // Motor idle - Display blue background with white text
+ bgColor = TFT_BLUE;
+ textColor = TFT_WHITE;
+ displayText = "IDLE";
+ Serial.println(">>> Display: BLUE - IDLE");
+ } else if (state == "nominal") {
+ // Normal operation - Display green background with black text
+ bgColor = TFT_GREEN;
+ textColor = TFT_BLACK;
+ displayText = "NOMINAL";
+ Serial.println(">>> Display: GREEN - NOMINAL");
+ } else {
+ // Unknown state - Display grey background with white text
+ bgColor = TFT_DARKGREY;
+ textColor = TFT_WHITE;
+ displayText = "UNKNOWN";
+ Serial.println(">>> Display: GREY - UNKNOWN");
+ }
+
+ // Fill entire screen with the status color
+ display.fillScreen(bgColor);
+
+ // Configure text properties for centered display
+ display.setTextColor(textColor, bgColor);
+ display.setTextSize(3);
+ display.setTextDatum(MC_DATUM);
+
+ // Draw the status text in the center of the screen
+ display.drawString(displayText, display.width() / 2, display.height() / 2);
+}
+
+/**
+ Calculates the vibration level from collected acceleration data.
+ Removes gravity component and computes the average magnitude
+ of vibration across multiple samples.
+*/
+float calculateVibrationLevel() {
+ float sum = 0;
+ int samples = min(30, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE / 3);
+
+ // Calculate vibration magnitude for each sample
+ for (int i = 0; i < samples; i++) {
+ float x = buffer[i * 3];
+ float y = buffer[i * 3 + 1];
+ float z = buffer[i * 3 + 2] - 1.0f; // Remove gravity component
+ sum += sqrt(x*x + y*y + z*z);
+ }
+
+ return sum / samples;
+}
+
+/**
+ Returns the sign of a number.
+ Used for clipping acceleration values to the maximum range.
+*/
+float ei_get_sign(float number) {
+ return (number >= 0.0) ? 1.0 : -1.0;
+}
+
+/**
+ Callback function for Edge Impulse library to access feature data.
+ Provides the machine learning model with vibration data in the
+ required format for inference processing.
+*/
+int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
+ memcpy(out_ptr, inference_buffer + offset, length * sizeof(float));
+ return 0;
+}
+```
+
+The following sections will help you understand the main components of the enhanced example sketch, which can be divided into the following areas:
+
+- Edge Impulse library integration
+- Real-time data collection using the integrated IMU
+- Machine learning inference execution
+- Visual feedback system with full-screen color coding
+
+### Edge Impulse Library Integration and IMU Setup
+
+The enhanced sketch starts by including the Edge Impulse library and configuring the integrated BMI270 IMU sensor.
+
+```arduino
+// Include the Edge Impulse library (name will match your project name)
+#include
+
+// Include libraries for IMU and display control
+#include
+#include
+
+// Detection parameters
+const float ANOMALY_THRESHOLD = 3.0f; // Adjusted for K-means clustering
+const float IDLE_THRESHOLD = 0.02f; // Vibration threshold for idle detection
+
+// Data buffers for the models
+static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
+static float inference_buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
+```
+
+The library contains both the classification model (to identify if the motor is idle or running) and the anomaly detection model (to spot unusual vibrations). The integrated BMI270 IMU provides calibrated digital acceleration data directly in g units, eliminating the need for analog-to-digital conversion or manual calibration.
+
+### Machine Learning Inference Execution
+
+The system analyzes the collected vibration data using both machine learning models to determine motor state and detect anomalies.
+
+```arduino
+/**
+ Executes the Edge Impulse inference on collected vibration data.
+ Processes the data through both classification and anomaly detection
+ models to determine motor state and detect unusual patterns.
+*/
+void runInference() {
+ // Copy the current buffer for inference processing
+ memcpy(inference_buffer, buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * sizeof(float));
+
+ // Calculate vibration level for additional state verification
+ float vibration = calculateVibrationLevel();
+
+ // Create signal structure for Edge Impulse
+ signal_t signal;
+ signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
+ signal.get_data = &raw_feature_get_data;
+
+ // Run the Edge Impulse classifier
+ ei_impulse_result_t result = { 0 };
+ EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
+
+ if (res != EI_IMPULSE_OK) {
+ Serial.printf("- ERROR: Failed to run classifier (%d)!\n", res);
+ return;
+ }
+
+ // Override classification if vibration indicates clear idle state
+ if (vibration < IDLE_THRESHOLD) {
+ for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
+ if (strcmp(ei_classifier_inferencing_categories[ix], "idle") == 0) {
+ result.classification[ix].value = 0.99f;
+ } else {
+ result.classification[ix].value = 0.01f;
+ }
+ }
+ }
+
+ // Process and display the inference results
+ processResults(result, vibration);
+}
+```
+
+This function performs the complete inference pipeline. It first copies the rolling buffer data, calculates the current vibration level, and then runs the Edge Impulse classifier. If the vibration level is very low (below 0.02g), it overrides the classification to force an "idle" state, which helps compensate for the high sensitivity of the BMI270 IMU.
+
+### Processing Results and Anomaly Detection
+
+After inference, the system processes the results to determine the motor state and check for anomalies:
+
+```arduino
+/**
+ Processes inference results and updates the full-screen display.
+ Analyzes classification confidence and anomaly scores to determine
+ the current motor state and trigger appropriate visual feedback.
+*/
+void processResults(ei_impulse_result_t result, float vibration) {
+ totalInferences++;
+
+ // Find the classification with highest confidence
+ String bestLabel = "unknown";
+ float bestValue = 0;
+
+ for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
+ if (result.classification[ix].value > bestValue) {
+ bestValue = result.classification[ix].value;
+ bestLabel = String(ei_classifier_inferencing_categories[ix]);
+ }
+ }
+
+ // Evaluate anomaly detection results
+ bool isAnomaly = false;
+
+#if EI_CLASSIFIER_HAS_ANOMALY
+ float anomalyScore = result.anomaly;
+
+ if (anomalyScore > ANOMALY_THRESHOLD) {
+ isAnomaly = true;
+ anomalyCount++;
+ }
+#endif
+
+ // Update display only when state changes
+ if (bestLabel != currentState || isAnomaly != currentAnomaly) {
+ currentState = bestLabel;
+ currentAnomaly = isAnomaly;
+ updateFullScreenDisplay(currentState, currentAnomaly);
+ }
+}
+```
+
+This function analyzes the inference results to find the most likely motor state (idle or nominal) and checks if the anomaly score exceeds the threshold. It only updates the display when the state actually changes, avoiding unnecessary screen refreshes.
+
+### Visual Feedback System
+
+The Nesso N1's display provides immediate visual feedback using full-screen color coding:
+
+```arduino
+/**
+ Updates the full-screen display with color-coded motor status.
+ Provides immediate visual feedback using background colors:
+ Blue for idle, Green for nominal operation, Red for anomalies.
+*/
+void updateFullScreenDisplay(String state, bool anomaly) {
+ uint16_t bgColor;
+ uint16_t textColor;
+ String displayText;
+
+ if (anomaly) {
+ bgColor = TFT_RED;
+ textColor = TFT_WHITE;
+ displayText = "ANOMALY";
+ } else if (state == "idle") {
+ bgColor = TFT_BLUE;
+ textColor = TFT_WHITE;
+ displayText = "IDLE";
+ } else if (state == "nominal") {
+ bgColor = TFT_GREEN;
+ textColor = TFT_BLACK;
+ displayText = "NOMINAL";
+ }
+
+ display.fillScreen(bgColor);
+ display.setTextColor(textColor, bgColor);
+ display.setTextSize(3);
+ display.setTextDatum(MC_DATUM);
+ display.drawString(displayText, display.width() / 2, display.height() / 2);
+}
+```
+
+This function creates a clear, unmistakable visual indication of the motor status that can be seen from across a room. After uploading the enhanced sketch to the Nesso N1 development kit, the display will show real-time motor status with color-coded feedback:
+
+- **Blue screen with "IDLE"**: Motor is stopped
+- **Green screen with "NOMINAL"**: Motor is running normally
+- **Red screen with "ANOMALY"**: Unusual vibration pattern detected
+
+
+
+The IDE's Serial Monitor also provides detailed information including classification confidence, anomaly scores, and timing metrics for debugging and performance monitoring.
+
+### Complete Enhanced Example Sketch
+
+The complete intelligent motor anomaly detection sketch can be downloaded [here](assets/motor_anomaly_detection_nesso.zip).
+
+[](assets/motor_anomaly_detection_nesso.zip)
+
+### System Integration Considerations
+
+When deploying the intelligent anomaly detection system in industrial environments, consider the following factors based on your sensor choice:
+
+- **Environmental Protection**: Protect the Nano R4 board and accelerometer from dust, moisture and temperature extremes using appropriate enclosures rated for the operating environment.
+- **Mounting Stability**: Make sure secure mechanical mounting of both the accelerometer sensor and the Nano R4 enclosure to prevent sensor movement that could affect measurement accuracy.
+- **Power Management**: Implement appropriate power supply filtering and protection circuits, especially in electrically noisy industrial environments with motor drives and switching equipment.
+- **Calibration Procedures**: Establish baseline measurements for each motor installation to account for mounting variations and motor-specific characteristics that may affect anomaly thresholds.
+- **Maintenance Integration**: Plan integration with existing maintenance management systems through data logging interfaces or communication protocols for complete predictive maintenance programs.
+
+## Arduino IoT Cloud Integration
+
+The motor anomaly detection system can be extended with remote monitoring capabilities through [Arduino Cloud](https://cloud.arduino.cc/), enabling real-time status visualization from anywhere with internet connectivity. This integration maintains all local functionality while adding cloud-based dashboard indicators for remote monitoring.
+
+***__Important Note__: The Arduino Cloud integration requires the `ArduinoIoTCloud` library and the ESP32 boards core. Install the ESP32 boards core through the Arduino IDE Boards Manager by searching for and installing "esp32" by Espressif Systems. For the `ArduinoIoTCloud` library, use the IDE's Library Manager to search and install `ArduinoIoTCloud` by Arduino, accepting all dependencies when prompted.***
+
+### Cloud Architecture Overview
+
+The cloud integration implements a three-state monitoring system using `boolean` variables that mirror the local display states. Each state (`idle`, `nominal`, and `anomaly`) is represented by an exclusive boolean indicator on the Arduino Cloud dashboard, guaranteeing clear and immediate visual feedback for remote operators.
+
+The system maintains bidirectional synchronization between the Nesso N1 development kit and the Arduino Cloud platform, updating dashboard widgets in real-time as motor conditions change. This architecture complement remote monitoring capabilities rather than replace local visualization, providing redundancy and flexibility in deployment scenarios.
+
+### Setting Up Arduino Cloud Components
+
+**A. Create Device**
+
+Begin by establishing the device identity in the Arduino Cloud platform:
+
+1. Navigate to the [Arduino Cloud "**Devices**" page](https://app.arduino.cc/devices)
+2. Click the **+ CREATE** button in the top right corner
+3. Select "**Any device**" from the Setup Device dialog
+4. Click **CONTINUE** to generate device credentials
+5. Adjust the device name if desired (for example, "Nesso-Motor-Monitor")
+6. Save the generated Device ID and Secret Key securely
+7. Confirm credential storage and click "**CONTINUE**"
+
+**B. Create Thing**
+
+Configure the Thing to represent your motor monitoring system:
+
+1. Open the [Arduino Cloud "**Things**" page](https://app.arduino.cc/things)
+2. Click "**+ THING**" to create a new Thing
+3. Rename the Thing to "Motor_Anomaly_Monitor" using the dropdown menu
+4. Add three Cloud Variables with the specifications shown below
+5. Associate the Thing with your previously created Device using the "**Select Device**" button
+
+**Cloud variables to add:**
+
+| **Variable Name** | **Type** | **Permission** | **Update Policy** |
+|:-----------------:|:--------:|:--------------:|:-----------------:|
+| `idle` | Boolean | Read Only | On Change |
+| `nominal` | Boolean | Read Only | On Change |
+| `anomaly` | Boolean | Read Only | On Change |
+
+**C. Create Dashboard**
+
+Design the visual interface for remote monitoring:
+
+1. Access the [Arduino Cloud Dashboards page](https://app.arduino.cc/dashboards)
+2. Click "**+ DASHBOARD**" to create a new dashboard
+3. Rename the dashboard to "Motor Status Monitor"
+4. Enter Edit mode and click "**ADD**" to add widgets
+5. Select the "**THINGS**" tab and choose your Motor_Anomaly_Monitor Thing
+6. Configure three STATUS widgets (idle in blue, nominal inn green, and anomaly in red)
+7. Arrange widgets horizontally for optimal visibility
+8. Click DONE to save the dashboard configuration
+
+### Complete Cloud-Enabled Sketch
+
+The complete enhanced example sketch with Arduino Cloud integration is shown below:
+
+```arduino
+/**
+ Intelligent Motor Anomaly Detection System - Arduino Cloud Edition
+ Name: motor_anomaly_detection_cloud.ino
+ Purpose: This sketch implements real-time motor anomaly detection using
+ the Nesso N1's integrated BMI270 IMU and Edge Impulse machine learning
+ model with Arduino IoT Cloud integration for remote monitoring through
+ three boolean state indicators.
+
+ @version 6.0 01/11/25
+ @author Arduino Product Experience Team
+*/
+
+// Include Arduino Cloud configuration and connection handler
+#include "thingProperties.h"
+
+// Include the Edge Impulse library (name will match your project name)
+#include
+
+// Include libraries for Nesso's IMU and display control
+#include
+#include
+
+// Display instance for the 1.14" touch screen
+M5GFX display;
+
+// Data buffers for model inference
+static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };
+static float inference_buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
+
+// Maximum accepted acceleration range (±2g)
+#define MAX_ACCEPTED_RANGE 2.0f
+
+// Detection parameters
+const float ANOMALY_THRESHOLD = 3.0f; // Threshold for anomaly detection
+const float WARNING_THRESHOLD = 1.5f; // Warning zone threshold
+const float IDLE_THRESHOLD = 0.02f; // Vibration threshold for idle detection
+
+// System status variables
+int totalInferences = 0;
+int anomalyCount = 0;
+unsigned long lastInferenceTime = 0;
+const unsigned long INFERENCE_INTERVAL = 2000; // Inference interval in milliseconds
+
+// Buffer management variables
+bool bufferFilled = false;
+int sampleCount = 0;
+
+// Current state tracking
+String currentState = "INITIALIZING";
+bool currentAnomaly = false;
+
+// Cloud connection status
+bool cloudConnected = false;
+
+// Function declarations
+float ei_get_sign(float number);
+int raw_feature_get_data(size_t offset, size_t length, float *out_ptr);
+void runInference();
+void updateFullScreenDisplay(String state, bool anomaly);
+float calculateVibrationLevel();
+void processResults(ei_impulse_result_t result, float vibration);
+void updateCloudStates(String state, bool isAnomaly);
+void onCloudConnect();
+void onCloudDisconnect();
+
+/**
+ Initializes the IMU, display, machine learning system, and Arduino Cloud.
+ Configures the Nesso N1 for optimal performance with the Edge Impulse model
+ and establishes connection to Arduino IoT Cloud for remote monitoring.
+*/
+void setup() {
+ // Initialize serial communication at 115200 baud
+ Serial.begin(115200);
+ // Don't wait too long for Serial in case running standalone
+ unsigned long serialStart = millis();
+ while (!Serial && millis() - serialStart < 3000);
+
+ Serial.println("- Nesso N1 Motor Anomaly Monitor with Cloud");
+ Serial.println("- Version 6.0 - Arduino IoT Cloud Integration");
+
+ // Initialize the 1.14" touch display
+ display.begin();
+ display.setRotation(1); // Set to landscape orientation
+ display.fillScreen(TFT_BLACK);
+ display.setTextSize(2);
+ display.setTextColor(TFT_WHITE, TFT_BLACK);
+ display.setTextDatum(MC_DATUM);
+ display.drawString("CLOUD CONNECT", display.width() / 2, display.height() / 2);
+
+ // Initialize Arduino Cloud properties defined in thingProperties.h
+ initProperties();
+
+ // Connect to Arduino IoT Cloud with preferred connection method
+ ArduinoCloud.begin(ArduinoIoTPreferredConnection);
+ ArduinoCloud.addCallback(ArduinoIoTCloudEvent::CONNECT, onCloudConnect);
+ ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, onCloudDisconnect);
+
+ // Set debug message level for cloud connection troubleshooting
+ setDebugMessageLevel(2);
+ ArduinoCloud.printDebugInfo();
+
+ Serial.println("- Connecting to Arduino IoT Cloud...");
+
+ // Attempt cloud connection with 30 second timeout
+ unsigned long cloudStart = millis();
+ while (!ArduinoCloud.connected() && millis() - cloudStart < 30000) {
+ ArduinoCloud.update();
+ delay(100);
+ }
+
+ if (ArduinoCloud.connected()) {
+ Serial.println("- Connected to Arduino IoT Cloud!");
+ cloudConnected = true;
+ } else {
+ Serial.println("- Cloud connection timeout - continuing offline");
+ cloudConnected = false;
+ }
+
+ // Initialize all cloud state variables to false
+ idle = false;
+ nominal = false;
+ anomaly = false;
+
+ // Update display for IMU initialization phase
+ display.fillScreen(TFT_BLACK);
+ display.drawString("INITIALIZING...", display.width() / 2, display.height() / 2);
+
+ // Initialize BMI270 IMU sensor
+ if (!IMU.begin()) {
+ Serial.println("- ERROR: Failed to initialize IMU!");
+ display.fillScreen(TFT_RED);
+ display.setTextColor(TFT_WHITE, TFT_RED);
+ display.drawString("IMU FAILED!", display.width() / 2, display.height() / 2);
+ while (1) {
+ ArduinoCloud.update(); // Keep cloud connection alive during error
+ delay(100);
+ }
+ }
+
+ Serial.println("- BMI270 IMU initialized!");
+ Serial.print("- Sample rate: ");
+ Serial.print(IMU.accelerationSampleRate());
+ Serial.println(" Hz");
+
+ // Verify Edge Impulse model configuration
+ if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != 3) {
+ Serial.println("ERROR: EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME should be 3");
+ while (1) {
+ ArduinoCloud.update();
+ delay(100);
+ }
+ }
+
+ Serial.println("\n- Edge Impulse Model loaded!");
+ Serial.print("- Project: ");
+ Serial.println(EI_CLASSIFIER_PROJECT_NAME);
+
+ Serial.println("\n- Filling buffer...");
+
+ // Display starting message while buffer fills
+ display.fillScreen(TFT_DARKGREY);
+ display.setTextColor(TFT_WHITE, TFT_DARKGREY);
+ display.drawString("STARTING...", display.width() / 2, display.height() / 2);
+
+ delay(1000);
+}
+
+/**
+ Main loop that continuously collects vibration data, performs real-time
+ classification and anomaly detection, and updates both local display
+ and Arduino Cloud dashboard indicators.
+*/
+void loop() {
+ // Update Arduino Cloud connection and synchronize variables
+ ArduinoCloud.update();
+
+ // Calculate the next sampling tick for precise timing
+ uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);
+
+ // Shift the buffer by 3 samples to create a rolling window
+ numpy::roll(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, -3);
+
+ // Wait for new acceleration data from the IMU
+ float x, y, z;
+ while (!IMU.accelerationAvailable()) {
+ delayMicroseconds(10);
+ }
+
+ // Read acceleration values (already in g units)
+ IMU.readAcceleration(x, y, z);
+
+ // Store new data at the end of the buffer
+ buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3] = x;
+ buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 2] = y;
+ buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 1] = z;
+
+ // Clip acceleration values to the maximum accepted range
+ for (int i = 0; i < 3; i++) {
+ float* val = &buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE - 3 + i];
+ if (fabs(*val) > MAX_ACCEPTED_RANGE) {
+ *val = ei_get_sign(*val) * MAX_ACCEPTED_RANGE;
+ }
+ }
+
+ // Track buffer filling progress during initialization
+ if (!bufferFilled) {
+ sampleCount++;
+ if (sampleCount >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE / 3) {
+ bufferFilled = true;
+ Serial.println("- Buffer filled, starting monitoring...\n");
+ }
+ }
+
+ // Maintain precise sampling rate
+ uint64_t time_to_wait = next_tick - micros();
+ if (time_to_wait > 0 && time_to_wait < 1000000) {
+ delayMicroseconds(time_to_wait);
+ }
+
+ // Execute inference at the specified interval
+ if (bufferFilled && (millis() - lastInferenceTime >= INFERENCE_INTERVAL)) {
+ lastInferenceTime = millis();
+ runInference();
+ }
+}
+
+/**
+ Executes the Edge Impulse inference on collected vibration data.
+ Processes the data through both classification and anomaly detection
+ models to determine motor state and detect unusual patterns.
+*/
+void runInference() {
+ // Copy the current buffer for inference processing
+ memcpy(inference_buffer, buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * sizeof(float));
+
+ // Calculate vibration level for additional state verification
+ float vibration = calculateVibrationLevel();
+
+ // Create signal structure for Edge Impulse
+ signal_t signal;
+ signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
+ signal.get_data = &raw_feature_get_data;
+
+ // Run the Edge Impulse classifier
+ ei_impulse_result_t result = { 0 };
+ EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
+
+ if (res != EI_IMPULSE_OK) {
+ Serial.printf("- ERROR: Failed to run classifier (%d)!\n", res);
+ return;
+ }
+
+ // Override classification if vibration indicates clear idle state
+ if (vibration < IDLE_THRESHOLD) {
+ for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
+ if (strcmp(ei_classifier_inferencing_categories[ix], "idle") == 0) {
+ result.classification[ix].value = 0.99f;
+ } else {
+ result.classification[ix].value = 0.01f;
+ }
+ }
+ }
+
+ // Process and display the inference results
+ processResults(result, vibration);
+}
+
+/**
+ Processes inference results and updates both the full-screen display
+ and Arduino Cloud dashboard. Analyzes classification confidence and
+ anomaly scores to determine the current motor state and trigger
+ appropriate visual feedback locally and remotely.
+*/
+void processResults(ei_impulse_result_t result, float vibration) {
+ totalInferences++;
+
+ // Find the classification with highest confidence
+ String bestLabel = "unknown";
+ float bestValue = 0;
+
+ Serial.printf("- Inference #%d", totalInferences);
+ if (cloudConnected) {
+ Serial.println(" [Cloud: Connected]");
+ } else {
+ Serial.println(" [Cloud: Offline]");
+ }
+
+ for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
+ if (result.classification[ix].value > bestValue) {
+ bestValue = result.classification[ix].value;
+ bestLabel = String(ei_classifier_inferencing_categories[ix]);
+ }
+ }
+
+ Serial.printf("- State: %s (%.0f%% confidence)\n", bestLabel.c_str(), bestValue * 100);
+ Serial.printf("- Vibration: %.4f g\n", vibration);
+
+ // Evaluate anomaly detection results
+ bool isAnomaly = false;
+
+#if EI_CLASSIFIER_HAS_ANOMALY
+ float anomalyScore = result.anomaly;
+ Serial.printf("- Anomaly score: %.3f", anomalyScore);
+
+ if (anomalyScore < WARNING_THRESHOLD) {
+ Serial.println(" [NORMAL]");
+ } else if (anomalyScore < ANOMALY_THRESHOLD) {
+ Serial.println(" [WARNING]");
+ } else {
+ Serial.println(" [ANOMALY!]");
+ isAnomaly = true;
+ anomalyCount++;
+ }
+#endif
+
+ // Update display and cloud only when state or anomaly status changes
+ if (bestLabel != currentState || isAnomaly != currentAnomaly) {
+ currentState = bestLabel;
+ currentAnomaly = isAnomaly;
+ updateFullScreenDisplay(currentState, currentAnomaly);
+ updateCloudStates(currentState, currentAnomaly);
+ }
+
+ Serial.printf("- Timing: DSP %d ms, Classification %d ms\n\n",
+ result.timing.dsp, result.timing.classification);
+}
+
+/**
+ Updates Arduino Cloud dashboard variables based on motor state.
+ Sets one of three boolean indicators (idle, nominal, anomaly) to true
+ while ensuring the others are false, providing exclusive state indication
+ for remote monitoring through the IoT Cloud dashboard.
+*/
+void updateCloudStates(String state, bool isAnomaly) {
+ // Reset all state indicators to false
+ idle = false;
+ nominal = false;
+ anomaly = false;
+
+ // Set the appropriate state indicator based on current condition
+ if (isAnomaly) {
+ anomaly = true;
+ Serial.println(">>> Cloud Update: ANOMALY = true");
+ } else if (state == "idle") {
+ idle = true;
+ Serial.println(">>> Cloud Update: IDLE = true");
+ } else if (state == "nominal") {
+ nominal = true;
+ Serial.println(">>> Cloud Update: NOMINAL = true");
+ }
+
+ // Force immediate cloud variable synchronization
+ ArduinoCloud.update();
+}
+
+/**
+ Updates the full-screen display with color-coded motor status.
+ Provides immediate visual feedback using background colors:
+ Blue for idle, Green for nominal operation, Red for anomalies.
+ Also displays cloud connection status in the corner.
+*/
+void updateFullScreenDisplay(String state, bool isAnomaly) {
+ uint16_t bgColor;
+ uint16_t textColor;
+ String displayText;
+
+ if (isAnomaly) {
+ // Anomaly detected - Display red background with white text
+ bgColor = TFT_RED;
+ textColor = TFT_WHITE;
+ displayText = "ANOMALY";
+ Serial.println(">>> Display: RED - ANOMALY");
+ } else if (state == "idle") {
+ // Motor idle - Display blue background with white text
+ bgColor = TFT_BLUE;
+ textColor = TFT_WHITE;
+ displayText = "IDLE";
+ Serial.println(">>> Display: BLUE - IDLE");
+ } else if (state == "nominal") {
+ // Normal operation - Display green background with black text
+ bgColor = TFT_GREEN;
+ textColor = TFT_BLACK;
+ displayText = "NOMINAL";
+ Serial.println(">>> Display: GREEN - NOMINAL");
+ } else {
+ // Unknown state - Display grey background with white text
+ bgColor = TFT_DARKGREY;
+ textColor = TFT_WHITE;
+ displayText = "UNKNOWN";
+ Serial.println(">>> Display: GREY - UNKNOWN");
+ }
+
+ // Fill entire screen with the status color
+ display.fillScreen(bgColor);
+
+ // Configure text properties for centered display
+ display.setTextColor(textColor, bgColor);
+ display.setTextSize(3);
+ display.setTextDatum(MC_DATUM);
+
+ // Draw the status text in the center of the screen
+ display.drawString(displayText, display.width() / 2, display.height() / 2);
+
+ // Add cloud connection status indicator in top-left corner
+ display.setTextSize(1);
+ display.setTextDatum(TL_DATUM);
+ if (cloudConnected) {
+ display.drawString("CLOUD: ON", 5, 5);
+ } else {
+ display.drawString("CLOUD: OFF", 5, 5);
+ }
+}
+
+/**
+ Calculates the vibration level from collected acceleration data.
+ Removes gravity component and computes the average magnitude
+ of vibration across multiple samples for accurate state detection.
+*/
+float calculateVibrationLevel() {
+ float sum = 0;
+ int samples = min(30, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE / 3);
+
+ // Calculate vibration magnitude for each sample
+ for (int i = 0; i < samples; i++) {
+ float x = buffer[i * 3];
+ float y = buffer[i * 3 + 1];
+ float z = buffer[i * 3 + 2] - 1.0f; // Remove gravity component
+ sum += sqrt(x*x + y*y + z*z);
+ }
+
+ return sum / samples;
+}
+
+/**
+ Callback function triggered when Arduino Cloud connection is established.
+ Updates the cloud connection status and synchronizes the current motor
+ state with the cloud dashboard for immediate remote visibility.
+*/
+void onCloudConnect() {
+ cloudConnected = true;
+ Serial.println(">>> Arduino IoT Cloud CONNECTED");
+
+ // Synchronize current state with cloud dashboard on connection
+ updateCloudStates(currentState, currentAnomaly);
+}
+
+/**
+ Callback function triggered when Arduino Cloud connection is lost.
+ Updates the connection status to allow the system to continue
+ operating in offline mode while attempting reconnection.
+*/
+void onCloudDisconnect() {
+ cloudConnected = false;
+ Serial.println(">>> Arduino IoT Cloud DISCONNECTED");
+}
+
+/**
+ Returns the sign of a number.
+ Used for clipping acceleration values to the maximum range.
+*/
+float ei_get_sign(float number) {
+ return (number >= 0.0) ? 1.0 : -1.0;
+}
+
+/**
+ Callback function for Edge Impulse library to access feature data.
+ Provides the machine learning model with vibration data in the
+ required format for inference processing.
+*/
+int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
+ memcpy(out_ptr, inference_buffer + offset, length * sizeof(float));
+ return 0;
+}
+```
+
+The cloud-enabled sketch extends the original motor anomaly detection code with Arduino Cloud integration. The implementation requires two primary files: the main sketch and two supporting configuration files.
+
+### Supporting Configuration Files
+
+#### Thing Properties Configuration
+
+Create a `thingProperties.h` file in the Arduino IDE in a new tab (Ctrl + Shift + N) to define cloud variables and connection parameters:
+
+```arduino
+/**
+ Arduino IoT Cloud Thing Properties Configuration
+ Defines cloud variables and connection settings for remote monitoring
+*/
+
+#include
+#include "arduino_secrets.h"
+
+// Cloud dashboard state indicators
+bool idle; // Motor in idle state
+bool nominal; // Normal operation
+bool anomaly; // Anomaly detected
+
+void initProperties() {
+ // Register state variables
+ ArduinoCloud.addProperty(idle, READ, ON_CHANGE, NULL);
+ ArduinoCloud.addProperty(nominal, READ, ON_CHANGE, NULL);
+ ArduinoCloud.addProperty(anomaly, READ, ON_CHANGE, NULL);
+
+ ArduinoCloud.setBoardId(SECRET_DEVICE_ID);
+ ArduinoCloud.setSecretDeviceKey(SECRET_DEVICE_KEY);
+}
+
+// Network connection handler
+WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
+```
+
+#### Arduino Secrets Configuration
+
+Create an `arduino_secrets.h` file in the Arduino IDE in a new tab (Ctrl + Shift + N) to store sensitive credentials (created and stored before):
+
+```arduino
+// Credentials for your Wi-Fi access point.
+#define SECRET_WIFI_SSID "your-wifi-network-name"
+#define SECRET_WIFI_PASS "your-wifi-password"
+
+// Device ID is not actually secret, but is defined alongside the secret key for convenience.
+#define SECRET_DEVICE_ID "your-device-secret-id"
+#define SECRET_DEVICE_KEY "your-device-secret-key"
+```
+
+### Cloud Integration Implementation
+
+The cloud-enabled sketch version maintains all original functionality while adding remote monitoring capabilities. Key modifications include the following:
+
+#### Initialization Enhancements
+
+The setup function now initializes cloud connectivity before starting motor monitoring:
+
+```arduino
+void setup() {
+ // Initialize display with cloud connection status
+ display.drawString("CLOUD CONNECT", display.width() / 2, display.height() / 2);
+
+ // Initialize Arduino Cloud
+ initProperties();
+ ArduinoCloud.begin(ArduinoIoTPreferredConnection);
+ ArduinoCloud.addCallback(ArduinoIoTCloudEvent::CONNECT, onCloudConnect);
+ ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, onCloudDisconnect);
+
+ // Attempt connection with timeout
+ unsigned long cloudStart = millis();
+ while (!ArduinoCloud.connected() && millis() - cloudStart < 30000) {
+ ArduinoCloud.update();
+ delay(100);
+ }
+
+ // Continue with IMU and model initialization...
+}
+```
+
+#### State Synchronization
+
+The system updates cloud variables whenever the motor state changes:
+
+```arduino
+void updateCloudStates(String state, bool isAnomaly) {
+ // Reset all indicators
+ idle = false;
+ nominal = false;
+ anomaly = false;
+
+ // Set appropriate state
+ if (isAnomaly) {
+ anomaly = true;
+ } else if (state == "idle") {
+ idle = true;
+ } else if (state == "nominal") {
+ nominal = true;
+ }
+
+ // Force cloud synchronization
+ ArduinoCloud.update();
+}
+```
+
+#### Connection Management
+
+Callback functions handle cloud connection events:
+
+```arduino
+void onCloudConnect() {
+ cloudConnected = true;
+ Serial.println(">>> Arduino IoT Cloud CONNECTED");
+ updateCloudStates(currentState, currentAnomaly);
+}
+
+void onCloudDisconnect() {
+ cloudConnected = false;
+ Serial.println(">>> Arduino IoT Cloud DISCONNECTED");
+}
+```
+
+#### Monitoring and Operation
+
+Once deployed, the system provides dual monitoring capabilities:
+
+**Local Display**:
+
+The Nesso N1's display continues to show real-time status with color-coded backgrounds:
+- **Blue**: Motor idle (no vibration detected)
+- **Green**: Nominal operation (normal vibration patterns)
+- **Red**: Anomaly detected (abnormal vibration patterns)
+
+Also, a small indicator in the corner of the Nesso N1's display shows cloud connection status ("CLOUD: ON" or "CLOUD: OFF").
+
+
+
+**Remote Dashboard**:
+
+The Arduino Cloud dashboard displays three STATUS widgets that mirror the local display state. Only one STATUS wiget is active at any time, providing clear status indication for remote monitoring. The system maintains full offline functionality, automatically reconnecting to the cloud when network connectivity is restored.
+
+
+
+This cloud integration transforms the motor anomaly detection system into an EdgeAIoT solution, enabling predictive maintenance teams to monitor multiple motors remotely while maintaining the reliability and responsiveness of local edge computing.
+
+### Complete Enhanced Example Sketch
+
+The complete intelligent motor anomaly detection sketch with Arduino Cloud integration can be downloaded [here](assets/motor_anomaly_detection_cloud.zip).
+
+[](assets/motor_anomaly_detection_cloud.zip)
+
+## Conclusions
+
+This application note demonstrates how to implement motor anomaly detection using the Nesso N1 development kit, combining Edge Impulse machine learning with Arduino Cloud for industrial predictive maintenance applications.
+
+The solution uses the Nesso N1's ESP32-S3 dual-core processor to perform real-time anomaly detection directly on-device with inference times under 20 milliseconds, while Arduino Cloud integration enables remote monitoring without compromising edge processing performance.
+The unsupervised K-means clustering approach requires only normal operation data for training, making it practical for industrial deployment where fault data may be scarce. This methodology effectively detects previously unseen fault conditions that deviate from established normal patterns.
+
+The dual-mode architecture, featuring edge processing with cloud connectivity, provides system resilience through continued operation during network interruptions, while also offering remote monitoring capabilities when connected. Visual feedback through both local display and cloud dashboard widgets delivers intuitive status indication for operators and remote maintenance teams.s
+
+
+## Next Steps
+
+Building upon this foundation, several enhancements can further improve the motor anomaly detection system:
+
+- **Multi-Sensor Fusion**: Integrate additional sensors such as temperature, current or acoustic sensors to provide a more complete view of motor health and improve detection accuracy. The onboard IMU's built-in gyroscope can provide additional motion analysis capabilities.
+- **Wireless Communication**: Add wireless connectivity using the onboard LoRa module to enable remote monitoring and integration with existing plant systems.
+- **Advanced Analysis**: Implement data logging for trend analysis, industrial protocol integration for SCADA systems or multi-class fault classification to distinguish between different types of motor problems.
+
+The foundation provided in this application note enables rapid development of custom motor monitoring solutions tailored to specific industrial requirements, with the flexibility to choose the sensor option that best fits your application needs.
\ No newline at end of file
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/antenna-mounted.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/antenna-mounted.png
new file mode 100644
index 0000000000..a086921df4
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/antenna-mounted.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/antenna-storage-removable.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/antenna-storage-removable.png
new file mode 100644
index 0000000000..ab8fe6db1b
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/antenna-storage-removable.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/bmi_accel.gif b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/bmi_accel.gif
new file mode 100644
index 0000000000..203c259812
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/bmi_accel.gif differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/bmi_gyro.gif b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/bmi_gyro.gif
new file mode 100644
index 0000000000..2e5803dde7
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/bmi_gyro.gif differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/board-manager.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/board-manager.png
new file mode 100644
index 0000000000..7b206d2647
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/board-manager.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/built-in-led.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/built-in-led.png
new file mode 100644
index 0000000000..27923062c9
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/built-in-led.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-1.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-1.png
new file mode 100644
index 0000000000..a96c5d7d2c
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-1.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-2.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-2.png
new file mode 100644
index 0000000000..7b8bf3484b
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-2.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-3.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-3.png
new file mode 100644
index 0000000000..89d5db3ebd
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/display-example-3.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/expansion-port.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/expansion-port.png
new file mode 100644
index 0000000000..3bd0e2775f
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/expansion-port.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/grove-connector.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/grove-connector.png
new file mode 100644
index 0000000000..1ecc9768ca
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/grove-connector.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/hero-banner.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/hero-banner.png
new file mode 100644
index 0000000000..b8d86041ec
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/hero-banner.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/lora-antenna.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/lora-antenna.png
new file mode 100644
index 0000000000..a5376bcc3e
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/lora-antenna.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/modulino.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/modulino.png
new file mode 100644
index 0000000000..f916c80d89
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/modulino.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/power-button.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/power-button.png
new file mode 100644
index 0000000000..fcf8922c0a
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/power-button.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/programmable-buttons.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/programmable-buttons.png
new file mode 100644
index 0000000000..e38a71702c
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/programmable-buttons.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/qwiic-connector.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/qwiic-connector.png
new file mode 100644
index 0000000000..5a5caabd87
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/qwiic-connector.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/simple-pinout.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/simple-pinout.png
new file mode 100644
index 0000000000..e631bd7f71
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/simple-pinout.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/unboxing.png b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/unboxing.png
new file mode 100644
index 0000000000..3dfcc627e1
Binary files /dev/null and b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/assets/unboxing.png differ
diff --git a/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/content.md b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/content.md
new file mode 100644
index 0000000000..942a894cad
--- /dev/null
+++ b/content/hardware/09.kits/maker/nesso-n1/tutorials/user-manual/content.md
@@ -0,0 +1,1422 @@
+---
+title: 'Nesso N1 User Manual'
+difficulty: beginner
+compatible-products: [nesso-n1]
+description: 'Learn how to set up and use the Arduino Nesso N1, a ready to use IoT development board.'
+tags:
+ - User Manual
+ - Cheat sheet
+ - ESP32-C6
+ - Bluetooth®
+ - Wi-Fi® 6
+ - LoRa®
+ - Thread
+ - Zigbee®
+ - Matter
+author: 'Ernesto Voltaggio'
+hardware:
+ - hardware/09.kits/maker/nesso-n1
+software:
+ - ide-v1
+ - ide-v2
+ - iot-cloud
+ - web-editor
+---
+
+The **Arduino® Nesso N1** is an all-in-one enclosed development board. Based on the ESP32-C6 System on Chip (SoC), it integrates a suite of communication protocols, including 2.4 GHz Wi-Fi® 6, Bluetooth® 5.3 LE, 802.15.4 (Thread/Zigbee®), and long-range LoRa®. It also includes a 1.14" color touchscreen, buttons, and a built-in LiPo battery for immediate user interaction in portable applications.
+
+This document serves as a comprehensive user manual for the Nesso N1, providing technical specifications, set up guides, and detailed explanations of its features to help you bring your projects to life.
+
+
+
+## Hardware and Software Requirements
+
+### Hardware Requirements
+
+- [Nesso N1](https://store.arduino.cc/products/nesso-n1) (x1)
+- [USB-C® cable](https://store.arduino.cc/products/usb-cable2in1-type-c) (x1)
+
+### Software Requirements
+
+- [Arduino IDE](https://www.arduino.cc/en/software) or [Arduino Cloud Editor](https://app.arduino.cc/sketches)
+- [ESP32 Boards core by Espressif](https://github.com/espressif/arduino-esp32)
+
+## Product Overview
+
+The Nesso N1 packs a rich set of features into a compact and portable form factor. It includes an integrated color touchscreen, multiple sensors, programmable buttons, and extensive expansion options, all powered by a rechargeable LiPo battery with power management.
+
+### Product Architecture
+
+- **ESP32-C6 SoC**: A powerful single-core RISC-V microcontroller with integrated Wi-Fi® 6, Bluetooth® 5.3 LE, and an 802.15.4 radio supporting Thread and Zigbee® for low-power mesh networking.
+- **SX1262 LoRa® Module**: A long-range, low-power LoRa® transceiver for communication in remote or challenging environments.
+- **1.14" Color Touchscreen**: An intuitive IPS display for user interaction and data visualization.
+- **BMI270 IMU**: A 6-axis Inertial Measurement Unit for precise motion and orientation sensing.
+- **Rechargeable Battery**: A built-in 250 mAh LiPo battery with a sophisticated power management system for portable applications.
+- **Expansion Connectors**: Standard Grove and Qwiic interfaces, plus an 8-pin port compatible with the M5StickC HAT series for easy hardware expansion.
+- **Onboard Peripherals**: Includes an infrared (IR) transmitter, a buzzer for audio feedback, a built-in LED, and two programmable user buttons.
+
+### Pinout
+
+
+
+The full pinout is available and downloadable as a PDF from the link below:
+
+- [Nesso N1 pinout](../../downloads/TPX00227-full-pinout.pdf)
+
+### Datasheet
+
+The full datasheet is available as a downloadable PDF from the link below:
+
+- [Nesso N1 datasheet](/resources/datasheets/TPX00227-datasheet.pdf)
+
+
+## Installation
+
+The Nesso N1 can be programmed using the Arduino IDE or the Arduino Cloud Editor. To get started, you will need to install the appropriate board package.
+
+### Arduino IDE
+
+To use the board in the Arduino IDE, you need to install the latest version of the **esp32 by Espressif Systems** package from the boards manager.
+
+1. Open the Arduino IDE.
+2. Navigate to **Boards Manager** (**Tools > Board > Boards Manager...**).
+3. Search for **"esp32"** and find the package by **Espressif Systems**.
+4. Click the **Install** button.
+5. Once installed, select **Arduino Nesso N1** from the **Tools > Board > esp32** menu.
+
+
+
+### Arduino Cloud Editor
+
+The Arduino Cloud Editor is an online IDE that supports the Nesso N1 without requiring manual installation of the board package.
+
+Read more in the [Getting Started with the Cloud Editor](https://docs.arduino.cc/arduino-cloud/guides/editor/) guide.
+
+## First Use
+
+### Unboxing the Product
+
+When opening the Nesso N1 box, you will find the device and a hexagon key. The device comes pre-assembled in a sleek enclosure.
+
+
+
+The detachable LoRa® antenna is conveniently stored in a compartment on the back of the device. You can slide it out to connect it to the MMCX connector for long-range communication.
+
+
+
+For projects where a slimmer profile is desired, the included hexagon key can be used to remove the antenna storage compartment, making the device thinner.
+
+
+
+***The Nesso N1 does not include a USB-C® cable, which is required to connect the board to your computer. A compatible cable is [available separately here](https://store.arduino.cc/products/usb-cable2in1-type-c).***
+
+## Power Supply
+
+The Nesso N1 can be powered in three ways:
+
+- **USB-C® Connector**: Provide a regulated 5 V DC supply through the USB-C® port. This method also charges the internal battery.
+- **Built-in Battery**: The onboard 250 mAh LiPo battery allows the device to operate untethered, making it ideal for portable and remote monitoring applications.
+- **VIN Pin**: You can use the `VIN` pin on the 8-pin expansion header to power the board from an external 5 V DC source.
+
+***WARNING: Handle the internal LiPo battery with care. Do not puncture, short-circuit, or expose it to high temperatures.***
+
+## Battery Management
+
+The board incorporates a power management system featuring the **AW32001** power path management chip and the **BQ27220** battery monitoring chip. This system provides:
+
+- **Automatic Charging**: The battery charges automatically when a 5 V source is connected via USB-C®.
+- **Real-Time Monitoring**: You can programmatically access battery voltage, current, and capacity to monitor the power status of your application.
+- **Over-Current & Over-Voltage Protection**: Ensures safe and stable operation during charging and discharging cycles.
+
+## Microcontroller (ESP32-C6)
+
+At the core of the Nesso N1 is the **ESP32-C6**, a highly integrated SoC from Espressif.
+
+### Key Features
+
+- **CPU**: Single-core 32-bit RISC-V, up to 160 MHz.
+- **Memory (on-chip)**: 512 kB SRAM.
+- **Memory (external)**: 16 MB Flash.
+
+The ESP32-C6 features a comprehensive set of connectivity options:
+
+- 2.4 GHz Wi-Fi® 6 (802.11ax).
+- Bluetooth® 5.3 Low Energy.
+- 802.15.4 radio for Thread and Zigbee® protocols.
+- Support for the Matter protocol.
+
+***WARNING: All GPIO pins are 3.3 V logic only and are not 5 V tolerant.***
+
+## Pins
+
+The Nesso N1 exposes a variety of pins for interacting with internal and external hardware. Some pins are connected directly to the ESP32-C6, while others are managed by two PI4IOE5V6408 I/O expanders to provide additional functionality.
+
+### Direct ESP32-C6 Pins
+
+These pins are directly controlled by the main microcontroller.
+
+| Pin Name | GPIO | Function |
+| :----------- | :--- | :----------------------------------------- |
+| `SDA` | 10 | I2C Data |
+| `SCL` | 8 | I2C Clock |
+| `MOSI` | 21 | SPI Master Out Slave In |
+| `MISO` | 22 | SPI Master In Slave Out |
+| `SCK` | 20 | SPI Serial Clock |
+| `IR_TX_PIN` | 9 | Infrared Transmitter Output |
+| `BEEP_PIN` | 11 | Buzzer Output |
+| `GROVE_IO_0` | 5 | Grove Connector I/O |
+| `GROVE_IO_1` | 4 | Grove Connector I/O |
+| `LORA_IRQ` | 15 | LoRa® Module Interrupt Request |
+| `LORA_CS` | 23 | LoRa® Module Chip Select (SPI) |
+| `LORA_BUSY` | 19 | LoRa® Module Busy Indicator |
+| `SYS_IRQ` | 3 | System Interrupt (from IMU & I/O expander) |
+| `LCD_CS` | 17 | LCD Chip Select (SPI) |
+| `LCD_RS` | 16 | LCD Register Select |
+| `D1` | 7 | 8-pin Header Digital I/O |
+| `D2` | 2 | 8-pin Header Digital I/O |
+| `D3` | 6 | 8-pin Header Digital I/O |
+
+### I/O Expander Pins
+
+The Nesso N1 uses two PI4IOE5V6408 I/O expanders (addresses `0x43` and `0x44`) to manage additional pins over the I2C bus. These pins are accessed in code using special `ExpanderPin` objects, which are pre-defined as part of the Nesso N1 board package. You do not need to include any extra libraries to use them.
+
+| Pin Object | Expander Port | Function |
+| :-------------------- | :------------ | :------------------------------- |
+| `KEY1` | E0.P0 | Programmable Button 1 |
+| `KEY2` | E0.P1 | Programmable Button 2 |
+| `LORA_LNA_ENABLE` | E0.P5 | LoRa® Low-Noise Amplifier Enable |
+| `LORA_ANTENNA_SWITCH` | E0.P6 | LoRa® RF Antenna Switch Control |
+| `LORA_ENABLE` | E0.P7 | LoRa® Module Reset/Enable |
+| `POWEROFF` | E1.P0 | System Power Off Control |
+| `LCD_RESET` | E1.P1 | LCD Reset |
+| `GROVE_POWER_EN` | E1.P2 | Grove Connector Power Enable |
+| `VIN_DETECT` | E1.P5 | External Power (VIN) Detection |
+| `LCD_BACKLIGHT` | E1.P6 | LCD Backlight Control |
+| `LED_BUILTIN` | E1.P7 | Onboard Status LED (Green) |
+
+
+The configuration of a digital pin is done in the `setup()` function with the `pinMode()` function:
+
+```arduino
+// Pin configured as an input
+pinMode(D1, INPUT);
+
+// Pin configured as an output
+pinMode(D1, OUTPUT);
+
+// Pin configured as an input with internal pull-up resistor enabled
+pinMode(D1, INPUT_PULLUP);
+```
+
+The state of a digital pin configured as an input can be read using `digitalRead()`:
+
+```arduino
+// Read pin state and store it in a variable
+int buttonState = digitalRead(KEY1);
+```
+
+The state of a digital pin configured as an output can be changed using `digitalWrite()`:
+
+```arduino
+// Set pin HIGH
+digitalWrite(D1, HIGH);
+
+// Set pin LOW
+digitalWrite(D1, LOW);
+```
+
+### PWM Pins
+
+The Nesso N1 has three PWM (Pulse Width Modulation) capable pins, accessible via the **8-pin expansion header**:
+
+| Pin Name | GPIO | Function |
+| :------- | :--- | :---------------- |
+| `D1` | 7 | Digital I/O / PWM |
+| `D2` | 2 | Digital I/O / PWM |
+| `D3` | 6 | Digital I/O / PWM |
+
+This functionality can be used with the built-in `analogWrite()` function. By default, the resolution is 8-bit (value 0-255), but it can be configured up to 16-bit using `analogWriteResolution()`.
+
+```arduino
+// Set PWM resolution to 10-bit (0-1023)
+analogWriteResolution(10);
+
+// Set pin D1 to a 50% duty cycle
+analogWrite(D1, 512);
+```
+
+### Analog Pins (ADC)
+
+The Nesso N1 provides access to two analog input pins through its onboard **Grove connector**. These pins, `GROVE_IO_0` (GPIO5) and `GROVE_IO_1` (GPIO4), are connected to the ESP32-C6's 12-bit Analog-to-Digital Converter (ADC).
+
+***Please note that these analog inputs are not available on the standard pin headers and must be accessed using a Grove-compatible cable.***
+
+The `analogRead()` function will return a value between 0 and 4095, corresponding to an input voltage range of 0 V to 3.3 V.
+
+```arduino
+// Read the analog value from the Grove connector pin
+int sensorValue = analogRead(GROVE_IO_0);
+```
+
+## Communication
+
+The Nesso N1 supports several wired communication protocols for interfacing with sensors, displays, and other devices.
+
+### I2C
+
+The Nesso N1 supports I2C communication, which allows data transmission between the board and other I2C-compatible devices. The pins used for the I2C communication protocol are the following:
+
+| Microcontroller Pin | Arduino Pin Mapping |
+| :------------------ | :------------------ |
+| GPIO8 | `SCL` |
+| GPIO10 | `SDA` |
+
+To use I2C communication, include the `Wire` library at the top of your sketch. The `Wire` library provides functions for I2C communication:
+
+```cpp
+#include
+```
+
+In the `setup()` function, initialize the I2C library. On the Nesso N1, all I2C communication, including the Qwiic connector, is handled by the primary `Wire` object.
+
+```cpp
+// Initialize the primary I2C bus
+Wire.begin();
+```
+
+To scan for connected I2C devices and verify their addresses, you can use the following example sketch. This is a useful utility to ensure your hardware is connected and recognized correctly.
+
+```cpp
+#include
+
+void setup() {
+ // Initialize the I2C bus
+ Wire.begin();
+
+ // Initialize Serial for printing the results
+ Serial.begin(115200);
+ while (!Serial); // Wait for Serial to be ready
+
+ Serial.println("\nI2C Scanner");
+ Serial.println("Scanning for I2C devices...");
+}
+
+void loop() {
+ byte error, address;
+ int nDevices;
+
+ nDevices = 0;
+ for (address = 1; address < 127; address++) {
+ // The i2c_scanner uses the return value of
+ // the Write.endTransmisstion to see if
+ // a device did acknowledge to the address.
+ Wire.beginTransmission(address);
+ error = Wire.endTransmission();
+
+ if (error == 0) {
+ Serial.print("I2C device found at address 0x");
+ if (address < 16) {
+ Serial.print("0");
+ }
+ Serial.println(address, HEX);
+ nDevices++;
+ } else if (error == 4) {
+ Serial.print("Unknown error at address 0x");
+ if (address < 16) {
+ Serial.print("0");
+ }
+ Serial.println(address, HEX);
+ }
+ }
+ if (nDevices == 0) {
+ Serial.println("No I2C devices found\n");
+ } else {
+ Serial.println("Scan complete.\n");
+ }
+
+ delay(5000); // Wait 5 seconds before scanning again
+}
+```
+
+
+### SPI
+
+The board features one Serial Peripheral Interface (SPI) bus, which is used internally to communicate with the LoRa® module and the color display.
+
+- **MOSI**: GPIO21
+- **MISO**: GPIO22
+- **SCK**: GPIO20
+
+While these pins are primarily used by onboard components, they can be shared with external SPI devices if you use a separate, available digital pin as a Chip Select (CS).
+
+### UART
+
+The Nesso N1 has two hardware UART (Serial) ports.
+
+- **`Serial`**: This object corresponds to the primary UART, which is connected to the USB-C® port. It is used for programming the board and for communication with the Arduino IDE's Serial Monitor. It is not connected to any external pins.
+
+- **`Serial1`**: This is a secondary hardware UART that can be mapped to any available GPIO pins. This allows you to establish serial communication with external devices like GPS modules or other microcontrollers using pins on the **8-pin expansion header** or the **Grove connector**.
+
+To use `Serial1`, you must specify the RX and TX pins in the `Serial1.begin()` function. The following example shows how to set up a UART on pins `D1` (TX) and `D2` (RX).
+
+```arduino
+// D1 (GPIO7) will be TX1
+// D2 (GPIO2) will be RX1
+
+void setup() {
+ // Initialize USB Serial for debugging
+ Serial.begin(115200);
+
+ // Initialize Serial1 on D1 and D2
+ // Format: Serial1.begin(baudrate, config, rxPin, txPin);
+ Serial1.begin(9600, SERIAL_8N1, D2, D1);
+
+ Serial.println("UART communication example started.");
+ Serial.println("Anything you type here will be sent from D1.");
+}
+
+void loop() {
+ // If data is available from USB Serial, send it to Serial1 (D1)
+ if (Serial.available()) {
+ char c = Serial.read();
+ Serial1.print(c);
+ }
+
+ // If data is available from Serial1 (D2), send it to USB Serial
+ if (Serial1.available()) {
+ char c = Serial1.read();
+ Serial.print(c);
+ }
+}
+```
+
+
+## Battery
+
+
+To interact with the battery system from your sketch, the Nesso N1 board package provides a built-in `NessoBattery` object named `battery`. It is available for use in your sketch without needing to include a specific library.
+
+
+### Enable Charging
+
+***WARNING: By default, the battery charging circuit is disabled. You must explicitly call `battery.enableCharge()` in your `setup()` function for the battery to charge when the device is powered via USB-C® or VIN.***
+
+```arduino
+// The NessoBattery object is available by default
+NessoBattery battery;
+
+void setup() {
+ // Enable the charging circuit
+ battery.enableCharge();
+}
+```
+
+### Get Battery Voltage
+
+Returns the current, instantaneous battery voltage in Volts. This is a direct electrical measurement.
+
+```arduino
+float voltage = battery.getVoltage();
+Serial.print("Voltage: ");
+Serial.print(voltage);
+Serial.println(" V");
+```
+
+### Get Charge Level
+
+Returns the battery's estimated state of charge as a percentage (0-100%). This value is calculated by the BQ27220 fuel gauge IC.
+
+```arduino
+uint16_t chargeLevel = battery.getChargeLevel();
+Serial.print("Charge Level: ");
+Serial.print(chargeLevel);
+Serial.println(" %");
+```
+
+### Understanding Voltage vs. Charge Level
+
+It is important to understand the difference between the two battery reading functions:
+
+- **`getVoltage()`** provides a direct, real-time measurement of the battery's voltage. This value can fluctuate depending on whether the battery is charging or under load (e.g., when Wi-Fi® or the display is active). It's a good raw indicator of the battery's state but not a precise measure of remaining capacity.
+
+- **`getChargeLevel()`** provides a much more accurate *estimate* of the remaining capacity. The BQ27220 fuel gauge uses a sophisticated algorithm that tracks the flow of energy into and out of the battery over time (a technique known as Coulomb counting).
+
+***For the fuel gauge to become reliable, it needs a few full charge and discharge cycles. During the first few uses, you may observe the charge level staying low for a while before ramping up to a more accurate value. This is normal behavior as the IC calibrates itself.***
+
+### Checking for External Power
+
+You can determine if the device is running on external power by reading the `VIN_DETECT` expander pin. This is useful for adjusting your application's behavior, such as entering a low-power mode when on battery.
+
+```arduino
+void setup() {
+ pinMode(VIN_DETECT, INPUT);
+}
+
+void loop() {
+ if (digitalRead(VIN_DETECT) == HIGH) {
+ Serial.println("Running on external power.");
+ } else {
+ Serial.println("Running on battery power.");
+ }
+ delay(5000);
+}
+```
+
+## Buttons and LED
+
+The Nesso N1 features several physical controls for user interaction.
+
+### Power Button
+
+The Nesso N1 has a multi-function button for power control:
+
+- **Click (from off state)**: Power on.
+- **Click (from on state)**: Reset the device.
+- **Double-click (from on state)**: Power off.
+- **Press and hold (from on state)**: Enter Download/Bootloader mode.
+
+
+
+
+Additionally, the `POWEROFF` expander pin allows you to shut down the device programmatically.
+
+
+### User Buttons
+
+The board has two physical buttons, **KEY1** and **KEY2**, that are connected to the I/O expander. These can be read using `digitalRead()`.
+
+
+
+```arduino
+void setup() {
+ Serial.begin(115200);
+ pinMode(KEY1, INPUT_PULLUP);
+ pinMode(KEY2, INPUT_PULLUP);
+}
+
+void loop() {
+ if (digitalRead(KEY1) == LOW) {
+ Serial.println("Button 1 pressed!");
+ delay(200); // Simple debounce
+ }
+ if (digitalRead(KEY2) == LOW) {
+ Serial.println("Button 2 pressed!");
+ delay(200); // Simple debounce
+ }
+}
+```
+
+### Built-in Programmable LED
+
+The board has an onboard green LED that can be controlled using the `LED_BUILTIN` object. It is visible on the side of the board through the power button gaps.
+
+
+
+```arduino
+void setup() {
+ // Configure the built-in LED as an output
+ pinMode(LED_BUILTIN, OUTPUT);
+}
+
+void loop() {
+ // Blink the LED
+ digitalWrite(LED_BUILTIN, LOW); // Turn LED ON
+ delay(500);
+ digitalWrite(LED_BUILTIN, HIGH); // Turn LED OFF
+ delay(500);
+}
+```
+
+***Please note that `LED_BUILTIN` uses inverted logic. Writing `LOW` to the pin turns the LED on, while writing `HIGH` turns it off.***
+
+
+## Display & Touchscreen
+
+The Nesso N1 features a 1.14-inch IPS color touchscreen with a resolution of 135 x 240 pixels, providing a vibrant and intuitive interface for your projects.
+
+- **Display Controller**: ST7789, controlled via SPI.
+- **Touch Controller**: FT6336U, controlled via I2C.
+
+The display can be programmed using the [**M5GFX**](https://github.com/m5stack/M5GFX) library, which is a powerful graphics library that simplifies drawing text, shapes, and images. You can install it from the Arduino IDE Library Manager by searching for "M5GFX".
+
+### Basic Text Display
+
+The following example initializes the display and prints a simple text string.
+
+
+
+```arduino
+#include
+
+M5GFX display; // Create a display instance
+
+void setup() {
+ display.begin();
+ display.setRotation(1); // Set to landscape mode
+
+ // Set text properties
+ display.setTextDatum(MC_DATUM); // Middle-Center datum for text alignment
+ display.setTextColor(TFT_WHITE, TFT_BLACK); // White text, black background
+ display.setTextSize(2);
+
+ // Clear the screen and draw the string
+ display.fillScreen(TFT_BLACK);
+ display.drawString("Hello, Nesso N1!", display.width() / 2, display.height() / 2);
+}
+
+void loop() {
+ // Nothing to do in the loop
+}
+```
+
+### Drawing Shapes and Colors
+
+The M5GFX library includes functions for drawing basic geometric shapes. You can use predefined color constants (e.g., `TFT_RED`, `TFT_GREEN`, `TFT_BLUE`) or specify 16-bit RGB565 color values.
+
+
+
+```arduino
+#include
+
+M5GFX display;
+
+void setup() {
+ display.begin();
+ display.setRotation(1);
+ display.fillScreen(TFT_BLACK);
+
+ // Draw a red rectangle outline
+ display.drawRect(10, 10, 100, 50, TFT_RED);
+
+ // Draw a filled green circle
+ display.fillCircle(180, 60, 30, TFT_GREEN);
+
+ // Draw a blue diagonal line
+ display.drawLine(0, 0, display.width(), display.height(), TFT_BLUE);
+}
+
+void loop() {
+}
+```
+
+### Handling Touch Input
+
+This example demonstrates how to read touch coordinates. It displays an initial message in the center of the screen. When you touch the screen, a "cursor" (a small circle) will appear at the point of contact, and the X/Y coordinates will be displayed in a fixed position at the center of the screen, updating in real-time as you move your finger.
+
+
+
+```arduino
+#include
+
+M5GFX display;
+
+void setup() {
+ display.begin();
+ display.setRotation(1); // Set to landscape mode
+ display.fillScreen(TFT_BLACK);
+
+ // Set text properties that will be used for all text in this sketch
+ display.setTextDatum(MC_DATUM); // Middle-Center datum for text alignment
+ display.setTextColor(TFT_WHITE);
+ display.setTextSize(2);
+
+ // Display the initial message centered on the screen
+ display.drawString("Touch the screen", display.width() / 2, display.height() / 2);
+}
+
+void loop() {
+ // Create a structure to hold touch data
+ lgfx::touch_point_t tp;
+
+ // Check if the screen is being touched
+ if (display.getTouch(&tp)) {
+ // Clear the screen to update both the circle and the text
+ display.fillScreen(TFT_BLACK);
+
+ // Draw a white circle at the current touch coordinates
+ display.fillCircle(tp.x, tp.y, 5, TFT_WHITE);
+
+ // Create a string with the updated coordinates
+ String coords = "X:" + String(tp.x) + " Y:" + String(tp.y);
+
+ // Draw the coordinates string at the FIXED center of the screen
+ display.drawString(coords, display.width() / 2, display.height() / 2);
+ }
+
+ delay(20); // Small delay for responsiveness
+}
+```
+
+
+#### Finding More Examples
+
+The M5GFX library is incredibly versatile and supports advanced features like displaying images (JPG/PNG), using custom fonts, and creating complex animations with sprites. The best way to learn these techniques is by exploring the official examples provided with the library.
+
+You can find a comprehensive collection of examples covering all major features in the [**M5GFX GitHub repository**](https://github.com/m5stack/M5GFX/tree/master/examples/Basic). These examples can be opened directly in the Arduino IDE after you have installed the library.
+
+
+## Connectivity
+
+The Nesso N1 is a versatile IoT device, equipped with a comprehensive suite of wireless protocols to suit a wide range of applications, from local device communication to long-range data transmission.
+
+### Wi-Fi®
+
+The ESP32-C6 features **Wi-Fi® 6 (802.11ax)**, offering higher efficiency, lower latency, and improved performance in dense wireless environments compared to older standards. This makes it ideal for applications requiring a reliable and fast connection to a local network or the internet.
+
+#### Wi-Fi® Connection Example
+
+This example demonstrates the most basic Wi-Fi® functionality: connecting to a network. It initializes the Wi-Fi® module, attempts to connect to a specified network, and prints the assigned IP address to the Serial Monitor once connected.
+
+```arduino
+#include
+
+// Replace with your network credentials
+const char* ssid = "YOUR_SSID";
+const char* password = "YOUR_PASSWORD";
+
+void setup() {
+ Serial.begin(115200);
+ delay(1000); // Give serial a moment to initialize
+
+ Serial.println("Connecting to Wi-Fi...");
+
+ // Start Wi-Fi connection
+ WiFi.begin(ssid, password);
+
+ // Wait until the connection is established
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(500);
+ Serial.print(".");
+ }
+
+ Serial.println("\nConnected!");
+ Serial.print("IP address: ");
+ Serial.println(WiFi.localIP());
+}
+
+void loop() {
+ // Nothing to do in the loop for this basic example
+ delay(1000);
+}
+```
+
+### Bluetooth® Low Energy
+
+The Nesso N1 supports **Bluetooth® 5.3 Low Energy (LE)**, enabling efficient, short-range communication with smartphones, sensors, and other BLE-enabled devices.
+
+***WARNING: The ESP32 board package includes its own library for Bluetooth® that conflicts with the standard `ArduinoBLE` library. If you have the `ArduinoBLE` library installed in your IDE, you may encounter compilation errors. To resolve this, you must uninstall the `ArduinoBLE` library from the Library Manager before compiling sketches for the Nesso N1.***
+
+#### Simple BLE Server Example
+
+This basic example turns your Nesso N1 into a simple Bluetooth® peripheral. It creates a BLE server that advertises a specific name ("Nesso N1 BLE Server"). You can use a free BLE scanner app on your phone to verify that your Nesso N1 appears in the list of nearby devices.
+
+```arduino
+#include
+#include
+#include
+
+// See https://www.uuidgenerator.net/ to create your own unique UUIDs
+#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
+
+void setup() {
+ Serial.begin(115200);
+ Serial.println("Starting BLE Server...");
+
+ // 1. Initialize the BLE device and set its name
+ BLEDevice::init("Nesso N1 BLE Server");
+
+ // 2. Create the BLE Server
+ BLEServer *pServer = BLEDevice::createServer();
+
+ // 3. Create a BLE Service using the UUID
+ BLEService *pService = pServer->createService(SERVICE_UUID);
+
+ // 4. Start the service. A service must be started before it can be advertised.
+ pService->start();
+
+ // 5. Get the advertising object and add the service UUID to the advertisement
+ BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
+ pAdvertising->addServiceUUID(SERVICE_UUID);
+
+ // 6. Start advertising
+ BLEDevice::startAdvertising();
+
+ Serial.println("Device is now advertising. Check for 'Nesso N1 BLE Server' on your phone.");
+}
+
+void loop() {
+ // The main work is done in the setup; the loop can be empty for this example.
+ delay(2000);
+}
+```
+
+### Thread
+
+**Thread** is a low-power, secure, and self-healing mesh networking protocol based on IPv6. Two Nesso N1 boards can form a minimal Thread network on their own, without needing an external border router. One device will automatically become the "Router" for the network, and the other will join as a "Child".
+
+This test is performed by interacting directly with the OpenThread Command Line Interface (CLI) via the Serial Monitor.
+
+#### Thread CLI Sketch (Upload to Both Boards)
+
+This sketch simply starts the OpenThread stack and opens a console on the Serial Monitor, giving you direct access to the CLI. Upload this exact same sketch to **both** of your Nesso N1 boards.
+
+```arduino
+#include "OThreadCLI.h"
+void setup() {
+ Serial.begin(115200);
+ // Initialize the OpenThread stack but do not autostart the network interface.
+ // This gives us manual control via the CLI.
+ OThreadCLI.begin(false);
+ Serial.println("OpenThread CLI started. Type 'help' for a list of commands.");
+ // Start the console to pass Serial input directly to the CLI
+ OThreadCLI.startConsole(Serial);
+}
+void loop() {
+ // The console handles all the work. The loop can be empty.
+}
+```
+
+#### How to Test Manually via CLI
+
+You will need two separate Serial Monitor windows, one for each Nesso N1.
+
+1. **Prepare:** Upload the sketch above to both boards. Connect both boards to your computer and open a Serial Monitor for each one.
+
+2. **Form a Network (Board 1):** In the Serial Monitor for your first board, create a new Thread network.
+
+ ```
+ dataset init new
+ ```
+
+ The board should respond with `Done`. Then, commit the new network settings:
+
+ ```
+ dataset commit active
+ ```
+
+ It will respond with `Done`.
+
+3. **Get the Network Key (Board 1):** Get the key for the network you just created.
+
+ ```
+ networkkey
+ ```
+
+ It will print a 32-character hexadecimal string. **Copy this key.**
+
+4. **Start the Network (Board 1):** Enable the radio and start the Thread protocol.
+
+ ```
+ ifconfig up
+ thread start
+ ```
+
+ After a few seconds, this board will become the network leader. You can verify this by typing `state`, which should return `leader`.
+
+5. **Join the Network (Board 2):** In the Serial Monitor for your second board, use the key you copied from Board 1.
+
+ ```
+ dataset networkkey
+ ```
+
+ Replace `` with the key. It should respond with `Done`. Then, commit the settings:
+
+ ```
+ dataset commit active
+ ```
+
+6. **Start the Network (Board 2):** Enable the radio and start the Thread protocol.
+
+ ```
+ ifconfig up
+ thread start
+ ```
+
+ After a few seconds, this board will join the network. You can verify this by typing `state`, which should return `child`.
+
+7. **Set up the Server (Board 1):** In the Serial Monitor for your first board, set up a UDP listener on port `1234`.
+
+ ```
+ udp open
+ udp bind :: 1234
+ ```
+
+ Both commands should respond with `Done`. This board is now listening for messages.
+
+8. **Send a Message (Board 2):** In the Serial Monitor for your second board, you must also open a UDP socket before you can send.
+
+ ```
+ udp open
+ ```
+
+ Once it responds with `Done`, send a UDP message to all devices on the Thread network.
+
+ ```
+ udp send ff03::1 1234 Hello!
+ ```
+
+ `ff03::1` is a multicast address that means "all Thread devices here.".
+
+9. **Verify Communication:**
+
+ The Serial Monitor for **Board 2** (the client) should respond with `Done`.
+
+ The Serial Monitor for **Board 1** (the server) should print a message showing it received the packet, for example: `8 bytes from fdde:ad00:beef:0:35e3:3c2f:273f:9442 Hello!`.
+
+You have now successfully sent and received a message over a peer-to-peer Thread network.
+
+### Zigbee®
+
+The Nesso N1's 802.15.4 radio allows it to act as a **Zigbee® End Device**, enabling it to join existing Zigbee® mesh networks. This is ideal for creating low-power devices like sensors or light controllers that integrate with popular smart home hubs.
+
+To compile this example, you must configure the following settings in the Arduino IDE:
+- Navigate to **Tools > Zigbee Mode** and select **End device**.
+- Navigate to **Tools > Partition Scheme** and select **Zigbee SPIFF 4MB**.
+
+#### Zigbee® Light Bulb Example
+
+This example configures the Nesso N1 to act as a simple Zigbee® On/Off light bulb. It cannot be tested with a second Nesso N1 running the same code. Instead, it is designed to be added to an existing Zigbee® network controlled by a central hub.
+
+```arduino
+#ifndef ZIGBEE_MODE_ED
+#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
+#endif
+
+#include "Zigbee.h"
+
+// Define the Zigbee endpoint for the light
+#define ZIGBEE_LIGHT_ENDPOINT 10
+
+// Create a ZigbeeLight object
+ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT);
+
+// Callback function to control the LED
+void setLED(bool value) {
+ // The built-in LED is active-low, so we invert the logic
+ digitalWrite(LED_BUILTIN, !value);
+}
+
+void setup() {
+ Serial.begin(115200);
+
+ // Initialize the built-in LED
+ pinMode(LED_BUILTIN, OUTPUT);
+ digitalWrite(LED_BUILTIN, HIGH); // Start with LED OFF
+
+ // Set a manufacturer and model name for the Zigbee device
+ zbLight.setManufacturerAndModel("Arduino", "Nesso-Light");
+
+ // Set the callback function that gets called when a command is received
+ zbLight.onLightChange(setLED);
+
+ // Add the light endpoint to the Zigbee core
+ Zigbee.addEndpoint(&zbLight);
+
+ // Start the Zigbee stack
+ if (!Zigbee.begin()) {
+ Serial.println("Zigbee failed to start! Rebooting...");
+ ESP.restart();
+ }
+
+ Serial.println("Zigbee started. Waiting to connect to a network...");
+}
+
+void loop() {
+ // The Zigbee stack runs in the background.
+ // The main loop can be used for other tasks or left empty.
+ delay(1000);
+}
+```
+
+#### How to Test
+
+1. Upload the sketch to your Nesso N1.
+2. You will need a **Zigbee® Hub/Coordinator**. Many popular smart home devices have this functionality built-in, such as the Amazon Echo (4th Gen, Plus, Studio, Show 10), Philips Hue Bridge, or Samsung SmartThings Hub.
+3. Open the companion app for your hub (e.g., Amazon Alexa app, Philips Hue app).
+4. Put your hub into pairing or "discover devices" mode.
+5. The hub should discover a new light bulb named "Arduino Nesso-Light".
+6. Once paired, you can add the device to a room and control the Nesso N1's built-in LED by toggling the light on and off in the app.
+
+### Matter
+
+**Matter** is a smart home connectivity standard that aims to unify the ecosystem, allowing devices from different brands to work together seamlessly. The Nesso N1 supports Matter communication over both **Wi-Fi®** and **Thread**.
+
+The choice of transport is determined by **compile-time definitions** you add at the top of your sketch.
+
+#### Matter On/Off Light Example
+
+This example turns your Nesso N1 into a simple On/Off light bulb. The same code works for both Matter over Wi-Fi® and Matter over Thread. After commissioning, you can control the Nesso N1's built-in LED from your smart home app.
+
+```arduino
+#include
+// Include WiFi.h only if you plan to use Matter over Wi-Fi
+#include
+
+// --- Transport Layer Configuration ---
+// To use Matter over Thread, include the three defines below.
+// To use Matter over Wi-Fi, comment out or remove these three defines.
+#define CONFIG_ENABLE_CHIPOBLE 1 // Enables BLE for commissioning
+#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 // Enables the Thread stack
+#define CHIP_DEVICE_CONFIG_ENABLE_WIFI 0 // CRITICAL: Disables the Wi-Fi stack
+// -------------------------------------
+
+// --- For Matter over Wi-Fi only ---
+const char* ssid = "YOUR_SSID";
+const char* password = "YOUR_PASSWORD";
+// ------------------------------------
+
+// Create an On/Off Light Endpoint
+MatterOnOffLight OnOffLight;
+
+// This callback function is executed when a Matter controller sends a command
+bool setLightOnOff(bool state) {
+ Serial.printf("Received Matter command: Light %s\r\n", state ? "ON" : "OFF");
+
+ // Control the built-in LED (inverted logic: LOW is ON)
+ digitalWrite(LED_BUILTIN, state ? LOW : HIGH);
+
+ return true; // Return true to confirm the command was successful
+}
+
+void setup() {
+ pinMode(LED_BUILTIN, OUTPUT);
+ digitalWrite(LED_BUILTIN, HIGH); // Start with the LED off
+ Serial.begin(115200);
+ delay(1000);
+
+ // --- For Matter over Wi-Fi only ---
+ if (!CHIP_DEVICE_CONFIG_ENABLE_THREAD) {
+ Serial.printf("Connecting to %s ", ssid);
+ WiFi.begin(ssid, password);
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(500);
+ Serial.print(".");
+ }
+ Serial.println(" Connected");
+ }
+ // ------------------------------------
+
+ // Initialize the OnOffLight endpoint with an initial state of OFF
+ OnOffLight.begin(false);
+ // Attach the callback function to handle state changes
+ OnOffLight.onChange(setLightOnOff);
+
+ // Start the Matter service.
+ Matter.begin();
+
+ // If the device was already commissioned, sync its LED state on boot
+ if (Matter.isDeviceCommissioned()) {
+ Serial.println("Matter Node is already commissioned. Ready for use.");
+ setLightOnOff(OnOffLight.getOnOff());
+ }
+}
+
+void loop() {
+ // This block periodically prints the pairing information until the device is commissioned
+ if (!Matter.isDeviceCommissioned()) {
+ static unsigned long lastPrintTime = 0;
+ if (millis() - lastPrintTime > 5000) {
+ Serial.println("\n----------------------------------------------------");
+ Serial.println("Matter Node not commissioned. Waiting for pairing...");
+ Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
+ Serial.println("----------------------------------------------------");
+ lastPrintTime = millis();
+ }
+ }
+
+ // A small delay is needed to allow background tasks to run
+ delay(100);
+}
+```
+
+#### How to Configure and Test Your Matter Device
+
+The same sketch can be used for both Matter over Wi-Fi® and Matter over Thread. The behavior is controlled by **compile-time flags** at the top of the code.
+
+**1. To Run as Matter over Wi-Fi®:**
+* **Action:** In the sketch, **comment out or delete** the three `#define` flags related to Thread. Fill in your Wi-Fi® credentials in the `ssid` and `password` variables.
+* **Requirements:** Your Nesso N1 and Matter Controller (e.g., smartphone) must be on the same Wi-Fi® network.
+
+**2. To Run as Matter over Thread:**
+* **Action:** In the sketch, ensure the three `#define` flags for Thread are **active and not commented out**.
+* **Requirements:** You must have a **Thread Border Router** (e.g., a compatible Google Nest Hub or Apple HomePod) active on your network.
+
+**3. Commissioning the Device:**
+After uploading the correctly configured sketch:
+1. Open the Serial Monitor. A manual pairing code will be printed every few seconds.
+2. Open your Matter Controller app (e.g., Google Home, Apple Home) and choose to add a new device.
+3. When prompted, enter the manual pairing code from the Serial Monitor to complete the setup.
+
+**4. Control the Device:** Once commissioned, a new light bulb device will appear in your app or be controllable via the command line tool. You can now toggle it on and off to control the Nesso N1's built-in LED.
+
+### LoRa®
+
+The onboard **SX1262** module provides long-range, low-power communication capabilities, operating in the 850–960 MHz frequency range. It comes with a detachable external antenna that connects via an MMCX connector.
+
+
+
+***WARNING: To avoid damage to your board, always use the LoRa® module with the antenna attached.***
+
+The LoRa® module is controlled via SPI and several dedicated pins on both the ESP32-C6 and the I/O expander.
+
+| Pin Name | GPIO | Expander Port | Function |
+| :-------------------- | :--- | :------------ | :------------------------------- |
+| `MOSI` | 21 | | SPI Master Out Slave In |
+| `MISO` | 22 | | SPI Master In Slave Out |
+| `SCK` | 20 | | SPI Serial Clock |
+| `LORA_IRQ` | 15 | | LoRa® Module Interrupt Request |
+| `LORA_CS` | 23 | | LoRa® Module Chip Select (SPI) |
+| `LORA_BUSY` | 19 | | LoRa® Module Busy Indicator |
+| `LORA_LNA_ENABLE` | | E0.P5 | LoRa® Low-Noise Amplifier Enable |
+| `LORA_ANTENNA_SWITCH` | | E0.P6 | LoRa® RF Antenna Switch Control |
+| `LORA_ENABLE` | | E0.P7 | LoRa® Module Reset/Enable |
+
+#### LoRa® Peer-to-Peer (P2P) Examples
+
+The following examples demonstrate basic LoRa® peer-to-peer (P2P) communication using the [RadioLib](https://github.com/jgromes/RadioLib) library. This is the foundational step for testing your hardware and building more complex network applications.
+
+**LoRa® Transmitter Example**
+
+This example configures the Nesso N1 to send a "Hello World!" packet every five seconds.
+
+***WARNING: You must configure the LoRa® frequency (`LORA_FREQUENCY`) variable to match your geographical region. to a value that is legal for your geographical region. Transmitting on an unauthorized frequency can result in fines. Common frequencies are 915.0 MHz for North America/Australia, 868.0 MHz for Europe, and 433.0 MHz for Asia.***
+
+```arduino
+#include
+
+// LoRa® frequency regions
+// Europe: 868.0
+// North America: 915.0
+// Australia: 915.0
+// Asia: 433.0
+
+const float LORA_FREQUENCY = ; // Set the LoRa® frequency based on your region
+
+// Initialize the radio module, passing RADIOLIB_NC for the reset pin.
+// The reset will be handled manually.
+SX1262 radio = new Module(LORA_CS, LORA_IRQ, RADIOLIB_NC, LORA_BUSY);
+
+// Counter for transmitted packets
+int packetCounter = 0;
+
+void setup() {
+ Serial.begin(115200);
+
+ // Manually reset the LoRa module using the expander pin for reliability.
+ pinMode(LORA_ENABLE, OUTPUT);
+ digitalWrite(LORA_ENABLE, LOW);
+ delay(10);
+ digitalWrite(LORA_ENABLE, HIGH);
+ delay(10);
+
+ // Initialize the LoRa® module
+ Serial.print(F("[SX1262] Initializing... "));
+ int state = radio.begin(LORA_FREQUENCY);
+ if (state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true);
+ }
+ Serial.println(F("success!"));
+}
+
+void loop() {
+ Serial.print(F("[SX1262] Transmitting packet... "));
+
+ // Create a packet with a counter
+ String packet = "Hello from Nesso N1! #" + String(packetCounter++);
+ int state = radio.transmit(packet);
+
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ delay(5000); // Wait 5 seconds between transmissions
+}
+```
+
+**LoRa® Receiver Example**
+
+This example configures a second Nesso N1 to listen for LoRa® packets and print them to the Serial Monitor. It uses a simple polling method where the main loop waits until a packet is received.
+
+```arduino
+#include
+
+// LoRa® frequency regions
+// Europe: 868.0
+// North America: 915.0
+// Australia: 915.0
+// Asia: 433.0
+
+const float LORA_FREQUENCY = ; // Set the LoRa® frequency based on your region
+
+// Initialize the radio module, passing RADIOLIB_NC for the reset pin.
+SX1262 radio = new Module(LORA_CS, LORA_IRQ, RADIOLIB_NC, LORA_BUSY);
+
+void setup() {
+ Serial.begin(115200);
+
+ // Manually reset the LoRa module.
+ pinMode(LORA_ENABLE, OUTPUT);
+ digitalWrite(LORA_ENABLE, LOW);
+ delay(10);
+ digitalWrite(LORA_ENABLE, HIGH);
+ delay(10);
+
+ // Initialize the LoRa® module.
+ Serial.print(F("[SX1262] Initializing... "));
+ int state = radio.begin(LORA_FREQUENCY);
+ if (state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true);
+ }
+
+ // Start listening for LoRa packets.
+ Serial.print(F("[SX1262] Starting to listen... "));
+ state = radio.startReceive();
+ if (state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true);
+ }
+ Serial.println(F("success!"));
+}
+
+void loop() {
+ // Create a string to store the received message.
+ String str;
+
+ // Try to receive a packet.
+ int state = radio.receive(str);
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // Packet was received successfully.
+ Serial.print(F("\n[SX1262] Received packet: "));
+ Serial.println(str);
+
+ // Print packet statistics.
+ Serial.print(F("[SX1262] RSSI: "));
+ Serial.print(radio.getRSSI());
+ Serial.print(F(" dBm, SNR: "));
+ Serial.print(radio.getSNR());
+ Serial.println(F(" dB"));
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
+ Serial.println(F("[SX1262] CRC error!"));
+ } else if (state != RADIOLIB_ERR_RX_TIMEOUT) {
+ // Some other error occurred. Timeout is expected and ignored.
+ Serial.print(F("[SX1262] Failed, code "));
+ Serial.println(state);
+ }
+}
+```
+
+***Please note: because the `LORA_ENABLE` pin is on an I/O expander, it cannot be passed directly to the RadioLib library constructor. The library must be initialized with the reset pin set to `RADIOLIB_NC` and it is best practice to perform a manual reset in setup.***
+
+#### Configuring for Public LoRa® Networks
+
+The onboard SX1262 module can be configured to communicate on public LoRa® networks such as [**The Things Network (TTN)**](https://www.thethingsnetwork.org/) or [**Helium**](https://helium.com/). These networks operate on specific frequencies and use defined radio parameters based on regional plans (e.g., `EU868`, `US915`, `AU915`). To ensure your device can be heard by gateways in your area, you must first configure your LoRa® radio to match your region's frequency.
+
+## Onboard Sensors & Peripherals
+
+### 6-Axis IMU
+
+The **BMI270** is a high-performance 6-axis Inertial Measurement Unit (IMU) that combines a 3-axis accelerometer and a 3-axis gyroscope. It connects to the ESP32-C6 via the I2C bus (`SCL` on GPIO8, `SDA` on GPIO10) and provides an interrupt signal on `SYS_IRQ` (GPIO3). It is ideal for motion tracking, gesture recognition, and orientation sensing.
+
+Here is a minimal example using the [Arduino_BMI270_BMM150](https://github.com/arduino-libraries/arduino_bmi270_bmm150) library:
+
+```arduino
+#include
+
+void setup() {
+ Serial.begin(115200);
+ while (!Serial); // Wait for serial port to connect
+
+ Serial.println("Initializing IMU...");
+ if (!IMU.begin()) {
+ Serial.println("Failed to initialize IMU!");
+ while (1);
+ }
+
+ Serial.print("Accel Rate: ");
+ Serial.print(IMU.accelerationSampleRate());
+ Serial.println(" Hz");
+
+ Serial.print("Gyro Rate: ");
+ Serial.print(IMU.gyroscopeSampleRate());
+ Serial.println(" Hz");
+
+ Serial.println("X\tY\tZ\t\t| X\tY\tZ");
+ Serial.println("Accel (g)\t\t| Gyro (°/s)");
+}
+
+void loop() {
+ float ax, ay, az;
+ float gx, gy, gz;
+
+ if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
+ IMU.readAcceleration(ax, ay, az);
+ IMU.readGyroscope(gx, gy, gz);
+
+ Serial.print("aX:");
+ Serial.print(ax, 2);
+ Serial.print(" aY:");
+ Serial.print(ay, 2);
+ Serial.print(" aZ:");
+ Serial.print(az, 2);
+ Serial.print("\t gX:");
+ Serial.print(gx, 2);
+ Serial.print(" gY:");
+ Serial.print(gy, 2);
+ Serial.print(" gZ:");
+ Serial.println(gz, 2);
+ }
+
+ delay(100);
+}
+```
+
+#### Visualizing the Output
+
+After uploading the sketch, open the **Serial Plotter** (**Tools > Serial Plotter**) in the Arduino IDE. As you move the Nesso N1, you will see the sensor data graphed in real-time.
+
+By using the checkboxes in the Serial Plotter window, you can isolate different data streams. The animation below shows the accelerometer data (`aX`, `aY`, `aZ`) as the device is tilted.
+
+
+
+Similarly, you can deselect the accelerometer variables and view only the gyroscope data (`gX`, `gY`, `gZ`) to visualize the rate of rotation, as shown here.
+
+
+
+
+### Buzzer
+
+A passive buzzer connected to `BEEP_PIN` (GPIO11) provides audible feedback. You can generate simple tones using the standard `tone()` function.
+
+```arduino
+void setup() {
+ // No setup needed for tone()
+}
+
+void loop() {
+ // Play a 1 kHz tone for 500 ms
+ tone(BEEP_PIN, 1000, 500);
+ delay(2000);
+}
+```
+
+### Infrared (IR) Transmitter
+
+An onboard IR LED connected to `IR_TX_PIN` (GPIO9) allows the Nesso N1 to function as a remote control for various electronic devices.
+
+Here is an example using the [IRremote](https://github.com/Arduino-IRremote/Arduino-IRremote) library to send a NEC command:
+
+```arduino
+#include
+
+void setup() {
+ Serial.begin(115200);
+ IrSender.begin(IR_TX_PIN);
+}
+
+void loop() {
+ Serial.println("Sending IR signal...");
+ // Send a NEC command: Address 0x01, Command 0x04
+ IrSender.sendNEC(0x01, 0x04, 1);
+ delay(2000);
+}
+```
+
+***Please note: There is a known hardware timer conflict between the `tone()` function and the IRremote library. To use both features in the same sketch, you must fully reset the pin and re-initialize the IR sender before each transmission. First, set the pin mode to INPUT to release it from the timer, then call `IrSender.begin()` to reconfigure it for IR.***
+
+## Expansion Ports
+
+### Voltage Compatibility Considerations
+
+Before connecting any external components to your Nesso N1, it is important to understand its voltage characteristics to prevent damage to your sensors and modules:
+
+**The Nesso N1 operates at 3.3 VDC**, which means:
+
+- All digital I/O pins use 3.3 VDC logic levels (HIGH = 3.3 VDC, LOW = 0 VDC).
+- Analog inputs can safely accept 0 to 3.3 VDC.
+- Communication pins (I2C, SPI, UART) operate at 3.3 VDC logic levels.
+
+**For 5 VDC components**, you must add **external level shifters** for digital communication pins.
+
+Always check your component's datasheet for voltage specifications before connecting. When in doubt, use a multimeter to verify voltage levels or add protective level shifting.
+
+### Qwiic Connector
+
+The Nesso N1 features an onboard Qwiic connector that provides a simple, tool-free solution for connecting I2C devices. The Qwiic ecosystem, developed by SparkFun, has become an industry standard for rapid prototyping, allowing you to connect sensors, displays, and other peripherals without soldering or complex wiring.
+
+
+
+The Qwiic system’s key advantages include:
+
+- **Plug-and-play connectivity**: No breadboards, jumper wires, or soldering required.
+- **Polarized connectors**: Prevents accidental reverse connections.
+- **Daisy-chain capability**: Connect multiple devices in series.
+- **Standard pinout**: Compatible across all Qwiic ecosystem devices.
+
+***The Qwiic connector on the Nesso N1 is connected to the primary I2C bus, which uses the standard `Wire` object. The connector provides a 3.3 V supply, making it ideal for modern sensors.***
+
+The Qwiic connector allows you to interface with our Modulino family for developing soldering-free projects.
+
+
+
+You can check our [Modulino family](https://store.arduino.cc/collections/modulino) where you will find a variety of **sensors** and **actuators** to expand your projects.
+
+
+### Grove Connector
+
+The Nesso N1 also includes one standard **Grove** connector. It provides a 5 V interface with two digital I/O pins (`GROVE_IO_0` on GPIO5, `GROVE_IO_1` on GPIO4), making it compatible with the extensive ecosystem of [Grove modules](https://search.arduino.cc/search?q=grove%20module&tab=store), including those from [M5Stack](https://shop.m5stack.com/pages/search-results-page?q=grove&page=1&rb_tags=ACTUATORS%7CSENSOR) and [Arduino Sensor Kit](https://store.arduino.cc/products/sensor-kit-base).
+
+
+
+### 8-Pin Expansion Port
+
+An 8-pin female header provides access to additional I/O and power pins. It is designed to be fully compatible with the **M5StickC HAT** series of expansion boards, allowing you to easily add functionality with modules for everything from sensors to communication. You can explore the range of compatible HATs on the [M5Stack store](https://shop.m5stack.com/collections/for-stick).
+
+
+
+
+| # | Pin Name | GPIO | Function |
+| :--- | :------------ | :--- | :---------------------------- |
+| 1 | `GND` | - | Ground |
+| 2 | `+5V OUT` | - | 5 V Output |
+| 3 | `D1` | 7 | Digital PWM I/O |
+| 4 | `D3` | 6 | Digital PWM I/O |
+| 5 | `D2` | 2 | Digital PWM I/O |
+| 6 | `BATTERY OUT` | - | Direct Battery Voltage Output |
+| 7 | `+3V3 OUT` | - | 3.3 V Output |
+| 8 | `+5V IN` | - | 5 V Input (VIN) |
+
+***The `BATTERY OUT` pin provides the direct, unregulated voltage from the LiPo battery. Be cautious when using this pin, as the voltage will vary depending on the charge level.***
+
+## Support
+
+If you encounter any issues or have questions while working with the Arduino Nesso N1, we provide various support resources to help you find answers and solutions.
+
+### Help Center
+
+Explore our [Help Center](https://support.arduino.cc/hc/en-us), which offers a comprehensive collection of articles and guides for the Nesso N1. The Arduino Help Center is designed to provide in-depth technical assistance and help you make the most of your device.
+
+- [Nesso N1 Help Center page](https://support.arduino.cc/hc/en-us/sections/)
+
+### Forum
+
+Join our community forum to connect with other Nesso N1 users, share your experiences, and ask questions. The forum is an excellent place to learn from others, discuss issues, and discover new ideas and projects related to the Nesso N1.
+
+- [Nesso N1 category in the Arduino Forum](https://forum.arduino.cc/c/official-hardware/kits/nesso-n1/225)
+
+### Contact Us
+
+Please get in touch with our support team if you need personalized assistance or have questions not covered by the help and support resources described before. We are happy to help you with any issues or inquiries about the Nesso N1.
+
+- [Contact us page](https://www.arduino.cc/en/contact-us/)
+
+
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/certifications/Arduino_K000007_R4-DoC_CE.pdf b/content/hardware/09.kits/maker/starter-kit-r4/certifications/Arduino_K000007_R4-DoC_CE.pdf
new file mode 100644
index 0000000000..bd3a3293e3
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/certifications/Arduino_K000007_R4-DoC_CE.pdf differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/certifications/Arduino_K000007_R4-DoC_UKCA.pdf b/content/hardware/09.kits/maker/starter-kit-r4/certifications/Arduino_K000007_R4-DoC_UKCA.pdf
new file mode 100644
index 0000000000..1112259916
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/certifications/Arduino_K000007_R4-DoC_UKCA.pdf differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/compatibility.yml b/content/hardware/09.kits/maker/starter-kit-r4/compatibility.yml
new file mode 100644
index 0000000000..94dcf76b65
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/compatibility.yml
@@ -0,0 +1,21 @@
+software:
+ - arduino-ide
+ - arduino-cli
+ - cloud-editor
+hardware:
+ boards:
+ - uno-r4-wifi
+ shields:
+ - 4-relays-shield
+ - motor-shield-rev3
+ - ethernet-shield-rev2
+ - 9-axis-motion-shield
+ carriers: ~
+ accessories:
+ - modulino-buttons
+ - modulino-buzzer
+ - modulino-distance
+ - modulino-knob
+ - modulino-movement
+ - modulino-pixels
+ - modulino-thermo
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/featured.png b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/featured.png
new file mode 100644
index 0000000000..5a1aeb1690
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/featured.png differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/kit-components.png b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/kit-components.png
new file mode 100644
index 0000000000..d386d42ebe
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/kit-components.png differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/kit-project.png b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/kit-project.png
new file mode 100644
index 0000000000..ed3a95ede5
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/kit-project.png differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/mechanicalDrawing_R4WiFi.png b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/mechanicalDrawing_R4WiFi.png
new file mode 100644
index 0000000000..74cd81eb37
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/mechanicalDrawing_R4WiFi.png differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/uno-r4-wifi.png b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/uno-r4-wifi.png
new file mode 100644
index 0000000000..11bc0ee99e
Binary files /dev/null and b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/assets/uno-r4-wifi.png differ
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/datasheet/datasheet.md b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/datasheet.md
new file mode 100644
index 0000000000..4836083550
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/datasheet/datasheet.md
@@ -0,0 +1,522 @@
+---
+identifier: K000007_R4
+title: Arduino® Starter Kit R4
+type: maker
+---
+
+
+
+# Description
+
+
The Arduino® Starter Kit R4 is a hands-on learning platform built around the Arduino® UNO R4 WiFi. Featuring an Arm® Cortex®-M4 microcontroller, integrated Wi-Fi® and Bluetooth® via ESP32-S3, and a 12x8 red LED matrix, this kit provides makers, students, and educators with a reliable foundation to learn, prototype, and build interactive electronics projects. With included sensors, motors, and actuators, the Starter Kit R4 bridges theoretical learning and practical experimentation through engaging, hands-on activities that teach fundamental programming and electronics concepts.
+
+The Starter Kit R4 offers a wide variety of practical applications, from classroom-friendly tutorials to interactive prototypes. Below are a few examples of what learners and developers can build with the kit:
+
+
+
+
Interactive Interfaces: Create game controllers and HID devices that can interact with computers, exploring the bridge between physical and digital controls.
+
Educational Tools: Teach students the fundamentals of electronics, embedded coding, and control logic using interactive guided experiments and hands-on projects.
+
LED Matrix Animations: Use the onboard 12x8 red LED matrix to create visual displays, heartbeat monitors, status indicators, or animations for feedback and communication.
+
Temperature Sensing: Build temperature-based monitoring systems using included thermistors to create chill-o-meters and responsive feedback devices.
+
Robotics & Motion: Drive DC or servo motors to explore basic robotics and automated movement control applications like motorized pinwheels.
+
Sound & Music Projects: Create musical instruments, synthesizers, and sound-responsive devices using piezo speakers, capacitive touch, and light sensors.
+
Sensor-Based Feedback Systems: Develop touch-sensitive lamps, knock detectors, and mood indicators that respond to physical interactions and environmental changes.
+The Arduino Starter Kit R4 includes a printed book with 14 projects. Each project helps you learn how to use different components and write code with the Arduino UNO R4 WiFi. The projects start simple and become more advanced as you go.
+
+
+| **No.** | **Project Title** | **What You Learn** |
+| ------: | ---------------------- | ------------------------------------------------ |
+| 00 | Get Started | How to set up the software and board |
+| 01 | Get to Know Your Tools | How to use a breadboard, resistors, and switches |
+| 02 | Spaceship Interface | How to control LEDs with buttons |
+| 03 | Chill-o-Meter | How to read temperature using a sensor |
+| 04 | Color Mixing Lamp | How to use light sensors and fade LEDs |
+| 05 | Mood Cue | How to give feedback using lights and sensors |
+| 06 | Light Theremin | How to use light to make sound |
+| 07 | Keyboard Instrument | How to play tones with a piezo speaker |
+| 08 | Digital Hourglass | How to build a timer using LEDs |
+| 09 | Motorized Pinwheel | How to control a motor |
+| 10 | Crystal Ball | How to make random responses |
+| 11 | Knock Lock | How to detect knocks with a piezo sensor |
+| 12 | Touchy-feely Lamp | How to control light with a touch sensor |
+| 13 | Hacking Buttons | How to reuse parts to make new controls |
+
+
+The book explains each step clearly and includes drawings and sample code. You can also visit the official project page at:
+arduino.cc/starterkit for updates and more projects.
+
+Suggested additional materials are listed in the details of each project, such as basic crafting materials: paper, tape, markers, scissors and more. These are not included in the kit.
+
+### Starter Kit R4 Online Projects
+
+
+The Starter Kit R4 includes a set of online projects. These projects build on the skills developed in the first 14 lessons, introducing topics such as computer interaction via USB (Human Interface Device - HID), capacitive touch, and enhanced use of the LED matrix. The first online module, "Welcome Online", provides an introduction to the Arduino Cloud platform and how to use it with your kit.
+
+
+
+The projects listed below represent the content available at the time of the kit's launch. Additional online projects will continue to be added over time to expand the learning experience and showcase new projects.
+
+
+| **No.** | **Project Title** | **What You Learn** |
+|--------:|-------------------------------------------|------------------------------------------------------------------------------------------|
+| 00-1 | Welcome Online | Learn how to use the online Arduino Cloud platform. |
+| 00-2 | Build a Project with Arduino AI Assistant | Learn how to build a project with the help of the Arduino AI assistant speaker. |
+| 14 | HIDden Powers | Build a game controller that can interact with your computer, using HID and pushbuttons. |
+| 15 | Heartbeat Monitor | Use the Love Button to pulse a heartbeat on the LED Matrix. |
+| 16 | Funky Synth | Build a funky synth using capacitive touch and a piezo speaker. |
+
+
+You can follow the link below to access the official online course platform [11], where you will find the online projects with step-by-step instructions:
+courses.arduino.cc/starterkitr4.
+To access the course, users need an Arduino account.
+
+
+
+
+## Features
+
+### Kit Contents
+
+
+The Starter Kit R4 includes the UNO R4 WiFi board and a wide selection of electronic components to build, test and explore interactive projects. All components are curated for step-by-step guided experimentation.
+
+
+- **K000007_R4**: This is the SKU that represents the Starter Kit R4.
+- **K000007_R4-6P**: This SKU represents the Starter Kit R4 Classroom pack, which contains Starter Kit R4 (x 6)
+
+#### Main Board
+
+- Arduino UNO R4 WiFi (SKU: ABX00087) (x1)
+
+#### Learning Materials
+
+- Project book - 150 pages (x1)
+
+#### Cables & Power
+
+- USB-C® cable (x1)
+- 9V battery snap connector (x1)
+
+#### Prototyping Tools
+
+- Breadboard (x1)
+- Easy-to-assemble base (x1)
+- Solid core jumper wires (x70)
+- Stranded jumper wires (x2)
+- Male pin strip - 40x1 (x1)
+
+#### Input & Output Components
+
+- Pushbuttons (x6)
+- LCD display - 16x2 characters (x1)
+- Piezo capsule (x1)
+
+#### LEDs
+
+- Bright white LED (x1)
+- RGB LED (x1)
+- Red LEDs (x8)
+- Green LEDs (x8)
+- Yellow LEDs (x8)
+- Blue LEDs (x3)
+
+#### Sensors
+
+- Phototransistors (x4)
+- Temperature sensor (x1)
+- Tilt sensor (x1)
+
+#### Actuators
+
+- Small DC motor 6/9 V (x1)
+- Small servo motor (x1)
+
+#### Semiconductor Components
+
+- H-bridge motor driver (x1)
+- Optocoupler (x2)
+- MOSFET transistor (x1)
+- Diodes (x3)
+
+#### Passive Components
+
+- Potentiometers (x3)
+- Capacitors - 100 µF (x3)
+- Resistors - 220 Ω (x11)
+- Resistors - 560 Ω (x3)
+- Resistors - 1 kΩ (x3)
+- Resistors - 4.7 kΩ (x3)
+- Resistors - 10 kΩ (x11)
+- Resistors - 1 MΩ (x7)
+- Resistors - 10 MΩ (x3)
+
+#### Accessories
+
+- Transparent color gels - red, green, blue (x3)
+
+
+
+
+
+#### Arduino UNO R4 WiFi (SKU: ABX00087)
+
+
+The UNO R4 WiFi is a modern 32-bit development board that combines the performance of the Renesas RA4M1 microcontroller with the wireless connectivity of the ESP32-S3-MINI-1 module. While preserving the classic UNO form factor and 5 V logic compatibility, it introduces new features including a built-in 12x8 LED matrix, CAN bus and QWIIC I2C connector. These additions make it suitable for both traditional prototyping and interactive electronics projects.
+
+
+
+
+| **Feature** | **Specification** |
+|---------------------------------------|------------------------------------------|
+| Main MCU | Renesas RA4M1 (R7FA4M1AB3CFM#AA0) |
+| Core | Arm® Cortex®-M4, 48 MHz with FPU |
+| Memory | 256 kB Flash, 32 kB SRAM, 8 kB EEPROM |
+| Wireless MCU | ESP32-S3-MINI-1-N8 |
+| Wireless Connectivity | Wi-Fi® 4 (802.11 b/g/n), Bluetooth® 5 LE |
+| Operating Voltage | 5 V (RA4M1), 3.3 V (ESP32-S3) |
+| USB Connector | USB-C |
+| Power Input | VIN: 6-24 V / USB: 5 V |
+| Digital I/O Pins | 14 |
+| Analog Input Pins | 6 |
+| PWM (Pulse Width Modulation) Outputs | 6 |
+| DAC (Digital-to-Analog Converter) | 1 × 12-bit (A0 pin) |
+| LED Matrix | 12x8 red matrix, programmable |
+| Communication Interfaces | UART (1), I2C (2), SPI (1), CAN (1) |
+| Special Interfaces | QWIIC connector (3.3 V I2C), ESP header |
+| Additional Features | RTC, OPAMP, DMA controller, CTSU |
+| Dimensions | 68.58 mm × 53.34 mm |
+
+
+By default, programming the RA4M1 microcontroller is handled through the ESP32-S3, which works as a USB bridge. This configuration allows uploading via USB-C without requiring additional setup.
+
+
+
+The board features a USB-C port for both powering and programming. It also supports serial communication and works as the main development interface.
+
+
+
+
Warning: Do not exceed 5 V on the USB-C port to avoid hardware damage.
+
+
+
+The RA4M1 microcontroller provides a 12-bit DAC connected to the A0 pin. It can generate analog output signals such as variable voltage levels or waveforms for audio and signal testing applications.
+
+
+
+The onboard QWIIC connector (SM04B-SRSS-TB) allows plug-and-play I2C communication with 3.3 V QWIIC-compatible modules. It is connected to a secondary I2C bus powered by the onboard 3.3 V regulator.
+
+
+
+The main I2C bus is also accessible on A4 (SDA) and A5 (SCL) pins. Avoid using A4/A5 as analog inputs while I2C communication is active.
+
+
+
+
+## Ratings
+
+### Recommended Operating Conditions
+
+The recommended electrical and thermal operating ranges for the Arduino UNO R4 WiFi board are as follows:
+
+| **Symbol** | **Description** | **Minimum** | **Typical** | **Maximum** | **Unit** |
+|-----------------|--------------------------------------|-------------|-------------|-------------|----------|
+| VIN | Input voltage from VIN pad / DC Jack | 6 | 7.0 | 24 | V |
+| VUSB | Input voltage from USB connector | 4.8 | 5.0 | 5.5 | V |
+| TOP | Operating Temperature | -40 | 25 | 85 | °C |
+
+
+
Note: Operating conditions reflect general limits for the main board and consider reasonable usage of connected peripherals. Component-specific ratings may vary.
+
+
+
+The UNO R4 WiFi supports power inputs via USB-C or the VIN pin (DC barrel jack). A buck converter (ISL854102FRZ) regulates VIN input (6-24 V) down to 5 V. USB input is internally dropped to ~4.7 V due to a Schottky diode.
+
+
+A 3.3 V linear regulator (SGM2205-3.3XKC3G/TR) supplies the ESP32-S3 and other 3.3 V peripherals.
+
+### Pin Voltage and Current
+
+- **Logic Levels**: RA4M1 operates at 5 V / ESP32-S3 at 3.3 V
+- **Current per GPIO**: Up to 8 mA
+- **Important**: Do not apply 5 V signals to ESP32-S3 pins
+
+Always use external power supplies for high-current loads like servos or DC motors.
+
+
+The Starter Kit R4 supports multiple powering options via the Arduino UNO R4 WiFi board. When connecting additional peripherals, ensure they are within the supported voltage and current limits.
+
+-
VIN / Barrel Jack: Accepts 6-24 VDC input, regulated to 5 V using the onboard buck converter (ISL854102FRZ). Recommended for projects requiring higher or isolated input voltage sources.
+
+
+
Note: A 9 V battery snap connector is included in the kit for use with a 9 V battery as a power source if desired. The 9 V battery is not included and must be purchased separately.
+
+
+-
USB-C Connector: Provides 5 V directly from the USB host. Actual voltage seen by the board is slightly reduced due to a Schottky diode (~4.7 V). Suitable for desktop or classroom use.
+-
5 V Pin: Provides regulated 5 V output when the board is powered via USB or VIN. Use with caution and avoid connecting high-current loads (e.g., motors) directly to this pin.
+
+
+
Warning: Exceeding the voltage or current ratings of the board or connected components may result in damage or unsafe operation. Always check the specifications of peripherals before connecting them.
+
+
+
+## Device Operation
+
+### Getting Started - IDE
+
+
+If you want to program your Arduino Starter Kit R4 offline, install the Arduino Desktop IDE [2]. To connect the Arduino UNO R4 WiFi to your computer, you will need a USB-C cable.
+
+
+### Getting Started - Arduino Cloud Editor
+
+
+All components of the Arduino Starter Kit R4 work seamlessly on the Arduino Cloud Editor [3] by installing a simple plugin. The Arduino Cloud Editor is hosted online, ensuring it is always up-to-date with the latest features and support for all boards and devices. Follow the Getting Started guide [6] to start coding in the browser and upload your sketches onto the Arduino UNO R4 WiFi.
+
+
+### Getting Started - Arduino Cloud
+
+
+The Arduino Starter Kit R4 is fully compatible with the Arduino Cloud, allowing you to explore online development tools and AI-assisted project building using the UNO R4 WiFi board. The kit includes guided tutorials for getting started with the Arduino Cloud platform and leveraging the Arduino AI Assistant for project development. To learn how to integrate your projects with the Cloud, refer to the official documentation [6].
+
+
+### Sample Sketches
+
+
+Sample sketches for the Starter Kit R4 can be found either in the "Examples" menu in the Arduino IDE or the LED Matrix tutorial section of Arduino documentation [7]. These examples include basic and advanced applications showcasing motion and environmental monitoring capabilities.
+
+
+### Online Resources
+
+
+Now that you have gone through the basics of what you can do with the Starter Kit R4, you can explore the endless possibilities it provides by checking exciting projects on Arduino Project Hub [5], the Arduino Library Reference [9], and the online Starter Kit R4 product page [10].
+
+The Arduino Starter Kit R4 is composed of multiple individual components, with the UNO R4 WiFi being the main board, it complies with specific regulations and certifications. For detailed product compliance information, please refer to the corresponding datasheets of each component included in the kit:
+
+The UNO R4 WiFi of the Arduino Starter Kit R4 is subject to individual FCC regulations. Please refer to the FCC documentation linked in each Arduino component's datasheet for specific compliance details:
+
+Any Changes or modifications not expressly approved by the party responsible for compliance could void the user’s authority to operate the equipment.
+
+
+This device complies with part 15 of the FCC Rules. Operation is subject to the following two conditions:
+
+(1) This device may not cause harmful interference
+
+(2) this device must accept any interference received, including interference that may cause undesired operation.
+
+**FCC RF Radiation Exposure Statement:**
+
+1. This Transmitter must not be co-located or operating in conjunction with any other antenna or transmitter.
+
+2. This equipment complies with RF radiation exposure limits set forth for an uncontrolled environment.
+
+3. This equipment should be installed and operated with a minimum distance of 20 cm between the radiator & your body.
+
+
+Note: This equipment has been tested and found to comply with the limits for a Class B digital
+device, pursuant to part 15 of the FCC Rules. These limits are designed to provide
+reasonable protection against harmful interference in a residential installation. This equipment
+generates, uses and can radiate radio frequency energy and, if not installed and used in
+accordance with the instructions, may cause harmful interference to radio communications.
+However, there is no guarantee that interference will not occur in a particular installation. If
+this equipment does cause harmful interference to radio or television reception, which can be
+determined by turning the equipment off and on, the user is encouraged to try to correct the
+interference by one or more of the following measures:
+
+- Reorient or relocate the receiving antenna.
+- Increase the separation between the equipment and receiver.
+- Connect the equipment into an outlet on a circuit different from that to which the
+receiver is connected.
+- Consult the dealer or an experienced radio/TV technician for help.
+
+
+English:
+User manuals for licence-exempt radio apparatus shall contain the following or equivalent notice in a conspicuous location in the user manual or alternatively on the device or both. This device complies with Industry Canada licence-exempt RSS standard(s). Operation is subject to the following two conditions:
+
+
+(1) this device may not cause interference
+
+(2) this device must accept any interference, including interference that may cause undesired operation of the device.
+
+
+French:
+Le présent appareil est conforme aux CNR d’Industrie Canada applicables aux appareils radio exempts de licence. L’exploitation est autorisée aux deux conditions suivantes :
+
+
+(1) l’ appareil nedoit pas produire de brouillage
+
+(2) l’utilisateur de l’appareil doit accepter tout brouillage radioélectrique subi, même si le brouillage est susceptible d’en compromettre le fonctionnement.
+
+**IC SAR Warning:**
+
+English
+This equipment should be installed and operated with a minimum distance of 20 cm between the radiator and your body.
+
+French:
+Lors de l’ installation et de l’ exploitation de ce dispositif, la distance entre le radiateur et le corps est d ’au moins 20 cm.
+
+## Declaration of Conformity CE DoC (EU)
+
+
+We declare under our sole responsibility that the products above are in conformity with the essential requirements of the following EU Directives and therefore qualify for free movement within markets comprising the European Union (EU) and European Economic Area (EEA).
+
+
+## Declaration of Conformity to EU RoHS & REACH 211 01/19/2021
+
+
+Arduino boards are in compliance with RoHS 2 Directive 2011/65/EU of the European Parliament and RoHS 3 Directive 2015/863/EU of the Council of 4 June 2015 on the restriction of the use of certain hazardous substances in electrical and electronic equipment.
+
+Arduino Boards are fully compliant with the related requirements of European Union Regulation (EC) 1907 /2006 concerning the Registration, Evaluation, Authorization and Restriction of Chemicals (REACH). We declare none of the SVHCs (https://echa.europa.eu/web/guest/candidate-list-table), the Candidate List of Substances of Very High Concern for authorization currently released by ECHA, is present in all products (and also package) in quantities totaling in a concentration equal or above 0.1%. To the best of our knowledge, we also declare that our products do not contain any of the substances listed on the "Authorization List" (Annex XIV of the REACH regulations) and Substances of Very High Concern (SVHC) in any significant amounts as specified by the Annex XVII of Candidate list published by ECHA (European Chemical Agency) 1907 /2006/EC.
+
+
+## Conflict Minerals Declaration
+
+
+As a global supplier of electronic and electrical components, Arduino is aware of our obligations with regards to laws and regulations regarding Conflict Minerals, specifically the Dodd-Frank Wall Street Reform and Consumer Protection Act, Section 1502. Arduino does not directly source or process conflict minerals such as Tin, Tantalum, Tungsten, or Gold. Conflict minerals are contained in our products in the form of solder, or as a component in metal alloys. As part of our reasonable due diligence Arduino has contacted component suppliers within our supply chain to verify their continued compliance with the regulations. Based on the information received thus far we declare that our products contain Conflict Minerals sourced from conflict-free areas.
+
+
+
+
+## Company Information
+
+| **Company name** | Arduino S.r.l. |
+|------------------|----------------------------------------------|
+| **Address** | Via Andrea Appiani, 25 – 20900 Monza (Italy) |
+
+## Reference Documentation
+
+| **No.** | **Reference** | **Link** |
+|--------:|------------------------------|--------------------------------------------------------------------|
+| 1 | UNO R4 WiFi Documentation | https://docs.arduino.cc/hardware/uno-r4-wifi/ |
+| 2 | Arduino IDE | https://www.arduino.cc/en/software |
+| 3 | Arduino Cloud Editor | https://create.arduino.cc/editor |
+| 4 | Language Reference | https://www.arduino.cc/reference/en/ |
+| 5 | Project Hub | https://create.arduino.cc/projecthub |
+| 6 | Cloud Getting Started Guide | https://docs.arduino.cc/cloud/web-editor/tutorials/getting-started |
+| 7 | LED Matrix Examples | https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix |
+| 8 | Wi-Fi Examples | https://docs.arduino.cc/tutorials/uno-r4-wifi/wifi-examples |
+| 9 | Library Reference | https://github.com/arduino-libraries/ |
+| 10 | Online Store | https://store.arduino.cc/products/starter-kit-r4 |
+| 11 | Online Starter Kit R4 Course | https://courses.arduino.cc/starterkitr4 |
+
+## Document Revision History
+
+| **Date** | **Revision** | **Changes** |
+|------------|--------------|--------------------|
+| 18/11/2025 | 1 | First release |
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/essentials.md b/content/hardware/09.kits/maker/starter-kit-r4/essentials.md
new file mode 100644
index 0000000000..4b9da8d4fc
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/essentials.md
@@ -0,0 +1,6 @@
+---
+productsLibrariesMap:
+ - Servo
+ - LiquidCrystal
+ - Arduino_CapacitiveTouch
+---
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/features.md b/content/hardware/09.kits/maker/starter-kit-r4/features.md
new file mode 100644
index 0000000000..6ae0e1760e
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/features.md
@@ -0,0 +1,59 @@
+
+
+The Arduino Starter Kit R4 includes everything you need to dive into the world of electronics and IoT. Based on the powerful UNO R4 WiFi, this kit guides you through 14 hands-on projects with a printed book and offers even more online.
+
+
+
+
+
+
+
+The kit is built around the powerful Arduino UNO R4 WiFi, featuring a 32-bit microcontroller, Wi-Fi®, Bluetooth®, and a 12x8 LED matrix for dynamic projects.
+
+
+
+
+
+
+
+
+
+Includes a wide selection of sensors, actuators, and electronic components to build 14 guided projects and countless others.
+
+
+
+
+
+Comes with a detailed, full-color project book that guides you from basic electronics to more complex concepts, making learning hands-on and fun.
+
+
+
+
+
+All book content and online projects are available in English, Spanish, Italian, German, and French, accessible and easy to learn for makers worldwide.
+
+
+
+
+
+Access additional projects online and learn how to connect your creations to the Arduino Cloud, bringing your ideas to the digital world.
+
+
+
+
+
+Built into the Arduino online editor, the AI assistant helps beginners overcome coding challenges with smart suggestions, answers, and inspiration.
+
+
+
+
+
+Use the exam voucher included in the box to take one attempt at the official Arduino Certification exam online, and validate your new skills with an internationally recognized certificate.
+
+
+
+
+
+
+
+
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/image.svg b/content/hardware/09.kits/maker/starter-kit-r4/image.svg
new file mode 100644
index 0000000000..8c86b21ea8
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/image.svg
@@ -0,0 +1,2241 @@
+
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/product.md b/content/hardware/09.kits/maker/starter-kit-r4/product.md
new file mode 100644
index 0000000000..2ccf4a50e3
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/product.md
@@ -0,0 +1,10 @@
+---
+title: Starter Kit R4
+url_shop: https://store.arduino.cc/products/starter-kit-r4
+primary_button_url: https://courses.arduino.cc/starter-kit-r4/
+primary_button_title: Go To Course
+sku: [K000007_R4, K000007_R4-6P]
+productCode: '228'
+---
+
+The Arduino® Starter Kit R4 is your hands-on introduction to the world of electronics and programming. This all-in-one kit includes everything you need to get started: a powerful [Arduino UNO R4 WiFi](../../hardware/uno-r4-wifi/), a wide selection of electronic components, and a detailed project book. Follow 13+ easy projects to learn the fundamentals, from making LEDs blink to controlling motors and reading sensors. Once you master the basics, online content will guide you in using the board's advanced features: Wi-Fi®, Bluetooth®, and the 12x8 LED matrix, to build Internet of Things projects.
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/tech-specs.md b/content/hardware/09.kits/maker/starter-kit-r4/tech-specs.md
new file mode 100644
index 0000000000..1b7b493ef2
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/tech-specs.md
@@ -0,0 +1 @@
+Here you will find the technical specifications for the Arduino® Starter Kit R4.
\ No newline at end of file
diff --git a/content/hardware/09.kits/maker/starter-kit-r4/tech-specs.yml b/content/hardware/09.kits/maker/starter-kit-r4/tech-specs.yml
new file mode 100644
index 0000000000..192dfe3691
--- /dev/null
+++ b/content/hardware/09.kits/maker/starter-kit-r4/tech-specs.yml
@@ -0,0 +1,40 @@
+Kit:
+ Name: Arduino® Starter Kit R4
+ SKU: K000007_R4
+Components:
+ Arduino UNO R4 WiFi (ABX00087): 1x
+ USB-C® cable: 1x
+ 9V battery snap connector: 1x
+ Breadboard: 1x
+ Easy-to-assemble base: 1x
+ Solid core jumper wires: 70x
+ Stranded jumper wires: 2x
+ Male pin strip (40x1): 1x
+ Pushbuttons: 6x
+ LCD display (16x2 characters): 1x
+ Piezo capsule: 1x
+ Bright white LED: 1x
+ RGB LED: 1x
+ Red LEDs: 8x
+ Green LEDs: 8x
+ Yellow LEDs: 8x
+ Blue LEDs: 3x
+ Phototransistors: 4x
+ Temperature sensor: 1x
+ Tilt sensor: 1x
+ Small DC motor (6/9 V): 1x
+ Small servo motor: 1x
+ H-bridge motor driver: 1x
+ Optocouplers: 2x
+ MOSFET transistor: 1x
+ Diodes: 3x
+ Potentiometers (10k ohm): 3x
+ Capacitors (100 µF): 3x
+ Resistors (220 Ω): 11x
+ Resistors (560 Ω): 3x
+ Resistors (1 kΩ): 3x
+ Resistors (4.7 kΩ): 3x
+ Resistors (10 kΩ): 11x
+ Resistors (1 MΩ): 7x
+ Resistors (10 MΩ): 3x
+ Transparent color gels (red, green, blue): 3x
\ No newline at end of file
diff --git a/content/software/app-lab/tutorials/03.cli/apps-lab-cli.md b/content/software/app-lab/tutorials/03.cli/apps-lab-cli.md
index 8ce9ded84c..0ca8340782 100644
--- a/content/software/app-lab/tutorials/03.cli/apps-lab-cli.md
+++ b/content/software/app-lab/tutorials/03.cli/apps-lab-cli.md
@@ -15,51 +15,15 @@ The following hardware is required:
- [Arduino UNO Q](https://store.arduino.cc/products/uno-q)
- [USB-C® type cable](https://store.arduino.cc/products/usb-cable2in1-type-c)
-You will also need to have the following software installed:
+To access the board via `adb` (over USB), you will also need to have the following software installed:
- [Android Debug Bridge](https://developer.android.com/tools/releases/platform-tools)
-## Installing ADB (Host Computer)
-
-***Note: if you are using the board as a Single Board Computer (SBC Mode (Preview) without a host computer), you do not need to install ADB. You can run `arduino-app-cli` directly from the terminal.***
-
-The ADB command line tool is supported on MacOS, Windows & Linux. For more specific instructions for your OS, see the sections below.
-
-***You can find more information and download the latest version for the tool for all operating systems directly from the [Android SDK Platform Tools](https://developer.android.com/tools/releases/platform-tools#downloads) page.***
-
-### MacOS
-
-To install the ADB tools on **MacOS**, we can use `homebrew`. Open the terminal and run the following command:
-
-```sh
-brew install android-platform-tools
-```
-
-To verify the tool is installed, run `adb version`.
-
-### Windows
-
-To install the ADB tools on **Windows**, we can use `winget`, supported on Windows 11 and on some earlier Windows 10 versions.
-
-Open a terminal and run the following:
-
-```sh
-winget install Google.PlatformTools
-```
-
-To verify the tool is installed, run `adb version`.
-
-### Linux
-
-To install ADB tools on a **Debian/Ubuntu Linux distribution**, open a terminal and run the following command:
-
-```sh
-sudo apt-get install android-sdk-platform-tools
-```
-
-To verify the tool is installed, run `adb version`.
+You can also access the board via SSH, which is typically installed on your system by default.
## Connect via ADB
+***To learn more about setting up `adb`, check out the [Connect to UNO Q via ADB](/tutorials/uno-q/adb/) tutorial. This guide will walk you through the installation steps.***
+
1. Connect the UNO Q board to your computer via USB-C.
2. Run `adb devices` in the terminal. This should list the connected devices.
@@ -67,16 +31,18 @@ To verify the tool is installed, run `adb version`.
>Note that it may take up to a minute for the device to appear after connecting it.
-3. Run `adb shell`. If you have not set up your board prior to this via the Arduino App Lab, you may be required to provide a password, which is `arduino`.
+3. Run `adb shell`.
4. You should now be inside your board's terminal.

5. You are now able to run commands via the terminal on your board! To exit from the terminal, simply type `exit`.
+>Note: If you have not set up your board prior to this via the Arduino App Lab, the first time you run a command that requires authentication (such as `sudo`), you will be prompted to create a new password.
+
## Connect via SSH
-***Note: to use SSH, the [first setup]() needs to be completed. This is done by connecting your board via USB, open the Arduino App Lab, and select the USB option. Here you will need to give your board a name, a new password as well as providing Wi-Fi® credentials. SSH will be automatically configured during this setup.***
+***Note: to use SSH, the [first setup](/software/app-lab/tutorials/getting-started#install--set-up-arduino-app-lab) needs to be completed. This is done by connecting your board via USB, open the Arduino App Lab, and select the USB option. Here you will need to give your board a name, a new password as well as providing Wi-Fi® credentials. SSH will be automatically configured during this setup.***
1. Open a terminal on your machine.
2. Run `ssh arduino@.local`
@@ -183,15 +149,6 @@ This will list all available Apps (including examples), and their status:

-## Set Board Name
-
-To set a board name using the `arduino-app-cli`, we can use the `set-name` command.
-
-```sh
-arduino-app-cli board set-name "my-board"
-```
-
-This will change the name of the board, which will take effect after resetting the board.
## System Configuration and Updates
@@ -204,6 +161,13 @@ arduino-app-cli system update
```
This will prompt you to install any available updates.
+To set the board name, use:
+
+```sh
+arduino-app-cli system set-name "my-board"
+```
+This will change the name of the board, which will take effect after resetting the board.
+
To enable or disable the network mode, use:
```sh
diff --git a/package-lock.json b/package-lock.json
index 8283bed12f..8967cc2a20 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
- "@arduino/docs-arduino-cc": "^2.1.5",
+ "@arduino/docs-arduino-cc": "^2.1.7",
"gatsby": "^5.11.0",
"gatsby-background-image": "^1.6.0",
"gatsby-image": "^3.11.0",
@@ -309,9 +309,9 @@
}
},
"node_modules/@arduino/docs-arduino-cc": {
- "version": "2.1.5",
- "resolved": "https://npm.pkg.github.com/download/@arduino/docs-arduino-cc/2.1.5/978d46ad46deff546f34ced958f00318e27ab7df",
- "integrity": "sha512-T//UGZWImL6R8J5HBwEOBx9JzUxjIYASPphASTIQVZmb/KvS732IeSqk9dHC5SuVom7x9nrPLEbw7glYjtAYAA==",
+ "version": "2.1.7",
+ "resolved": "https://npm.pkg.github.com/download/@arduino/docs-arduino-cc/2.1.7/98b9e5b71a6376dd72bc18870490ee68ae4fb95c",
+ "integrity": "sha512-UmTbbN+WCNjzXdRGDwGp3Nj7kFkVeeMeKx791PvaJlK7fNOY4epsAMt1q36bMlGiNrC+XBGiFF/VQG/B9XigCg==",
"dependencies": {
"@algolia/autocomplete-core": "^1.10.0",
"@algolia/autocomplete-plugin-recent-searches": "^1.17.0",
diff --git a/package.json b/package.json
index 1f04b68a17..ed97deb764 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
},
"homepage": "https://github.com/arduino/docs-content#readme",
"dependencies": {
- "@arduino/docs-arduino-cc": "^2.1.5",
+ "@arduino/docs-arduino-cc": "^2.1.7",
"gatsby": "^5.11.0",
"gatsby-background-image": "^1.6.0",
"gatsby-image": "^3.11.0",