Nano Matter User Manual
Learn about the hardware and software features of the Arduino® Nano Matter.
Overview
This user manual will guide you through a practical journey covering the most interesting features of the Arduino Nano Matter. With this user manual, you will learn how to set up, configure and use this Arduino board.
Hardware and Software Requirements
Hardware Requirements
- Nano Matter (x1)
- USB-C® cable (x1)
Software Requirements
Board Core and Libraries
The Silicon Labs core contains the libraries and examples you need to work with the board's components, such as its Matter, Bluetooth® Low Energy, and I/Os. To install the Nano Matter core, navigate to File > Preferences and in the Additional boards manager URLs, add the following:
https://siliconlabs.github.io/arduino/package_arduinosilabs_index.json
Now navigate to Tools > Board > Boards Manager or click the Boards Manager icon in the left tab of the IDE. In the Boards Manager tab, search for
Nano Matter
and install the latest Silicon Labs
core version.Product Overview
The Nano Matter merges the well-known Arduino way of making complex technology more accessible with the powerful MGM240S from Silicon Labs, to bring Matter closer to the maker world, in one of the smallest form factors in the market.
It enables 802.15.4 (Thread®) and Bluetooth® Low Energy connectivity, to interact with Matter-compatible devices with a user-friendly software layer ready for quick prototyping.
Board Architecture Overview
The Nano Matter features a compact and efficient architecture powered by the MGM240S (32-bit Arm® Cortex®-M33) from Silicon Labs, a high-performance wireless module optimized for the needs of battery and line-powered IoT devices for 2.4 GHz mesh networks.
Here is an overview of the board's main components, as shown in the image above:
- Microcontroller: at the heart of the Nano Matter is the MGM240S, a high-performance wireless module from Silicon Labs. The MGM240S is built around a 32-bit Arm® Cortex®-M33 processor running at 78 MHz.
- Wireless connectivity: the Nano Matter microcontroller also features multi-protocol connectivity to enable Matter IoT protocol and Bluetooth® Low Energy. This allows the Nano Matter to be integrated with smart home systems and communicate wirelessly with other devices.
Pinout
The full pinout is available and downloadable as PDF from the link below:
Datasheet
The complete datasheet is available and downloadable as PDF from the link below:
Schematics
The complete schematics are available and downloadable as PDF from the link below:
STEP Files
The complete STEP files are available and downloadable from the link below:
Form Factor
The Nano Matter board features castellated pins, which are ideal for integrating the board into final solutions.
You can easily solder the Nano Matter in your custom PCB, since the board does not present any bottom-mounted components.
First Use
Powering the Board
The Nano Matter can be powered by:
- A USB-C® cable (not included).
- An external 5 V power supply connected to
pin (please, refer to the board pinout section of the user manual).IN5V
For low-power consumption applications, the following hacks are recommended:
- Cut the power status LED jumper off to save energy.
- Power the board with an external 3.3 V power supply connected to 3.3V pin. This will not power the USB bridge IC, so more energy will be saved.
To power the board through the VIN pin you need to close the jumper pads with solder. The maximum voltage supported is +5 VDC.
Install Board Core and Libraries
The Silicon Labs core contains the libraries and examples you need to work with the board's components, such as its Matter, Bluetooth® Low Energy, and I/Os. To install the Nano Matter core, navigate to File > Preferences and in the Additional boards manager URLs, add the following:
https://siliconlabs.github.io/arduino/package_arduinosilabs_index.json
Now navigate to Tools > Board > Boards Manager or click the Boards Manager icon in the left tab of the IDE. In the Boards Manager tab, search for
Nano Matter
and install the latest Silicon Labs
core version.Hello World Example
Let's program the Nano Matter with the classic
hello world
example typical of the Arduino ecosystem: the Blink
sketch. We will use this example to verify that the board is correctly connected to the Arduino IDE and that the Silicon Labs core and the board itself are working as expected. Copy and paste the code below into a new sketch in the Arduino IDE.
1// the setup function runs once when you press reset or power the board2void setup() {3 // initialize digital pin LED_BUILTIN as an output.4 pinMode(LED_BUILTIN, OUTPUT);5}6
7// the loop function runs over and over again forever8void loop() {9 digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)10 delay(1000); // wait for a second11 digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW12 delay(1000); // wait for a second13}
In the Nano Matter, the
LED_BUILTIN
macro represents the red LED of the built-in RGB LED of the board. Please refer to the image below.To upload the code to the Nano Matter, click the Verify button to compile the sketch and check for errors; then click the Upload button to program the board with the sketch.
You should now see the red LED of the built-in RGB LED turning on for one second, then off for one second, repeatedly.
If everything works as expected, you are ready to continue searching and experimenting with this mighty board.
Matter
Developing Matter-compatible IoT solutions has never been easier with the Arduino ecosystem.
The Nano Matter can communicate with Matter hubs through a Thread® network, so the hubs used must be Thread® border routers.
The Silicon Labs core in the Arduino IDE comes with several Matter examples ready to be tested with the Nano Matter and works as a starting point for almost any IoT device we can imagine building.
The matter_lightbulb example is the only officially Matter-certified profile for the Nano Matter Community Preview. Consequently, while running any of the other available profile examples, it is expected to get an Uncertified device message in the different Matter-compatible apps. This does not prevent the user from prototyping a solution with different configurations.
First, to start creating Matter-enabled solutions, we need to select the Matter protocol in Tools > Protocol stack > Matter:
In the example below, we are going to use the Nano Matter as a RGB Lightbulb. For this, navigate to File > Examples > Matter and open the built-in sketch called nano_matter_lightbulb_color.
1#include <Matter.h>2#include <MatterLightbulb.h>3
4#define LED_R LED_BUILTIN5#define LED_G LED_BUILTIN_16#define LED_B LED_BUILTIN_27
8MatterColorLightbulb matter_color_bulb;9
10void update_led_color();11void led_off();12void handle_button_press();13volatile bool button_pressed = false;14
15void setup()16{17 Serial.begin(115200);18 Matter.begin();19 matter_color_bulb.begin();20 matter_color_bulb.boost_saturation(51); // Boost saturation by 20 percent21
22 // Set up the onboard button23 pinMode(BTN_BUILTIN, INPUT_PULLUP);24 attachInterrupt(BTN_BUILTIN, &handle_button_press, FALLING);25
26 // Turn the LED off27 led_off();28
29 Serial.println("Arduino Nano Matter - color lightbulb");30
31 if (!Matter.isDeviceCommissioned()) {32 Serial.println("Matter device is not commissioned");33 Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");34 Serial.printf("Manual pairing code: %s\n", Matter.getManualPairingCode().c_str());35 Serial.printf("QR code URL: %s\n", Matter.getOnboardingQRCodeUrl().c_str());36 }37 while (!Matter.isDeviceCommissioned()) {38 delay(200);39 }40
41 Serial.println("Waiting for Thread network...");42 while (!Matter.isDeviceThreadConnected()) {43 delay(200);44 }45 Serial.println("Connected to Thread network");46
47 Serial.println("Waiting for Matter device discovery...");48 while (!matter_color_bulb.is_online()) {49 delay(200);50 }51 Serial.println("Matter device is now online");52}53
54void loop()55{56 // If the physical button state changes - update the lightbulb's on/off state57 if (button_pressed) {58 button_pressed = false;59 // Toggle the on/off state of the lightbulb60 matter_color_bulb.toggle();61 }62
63 // Get the current on/off state of the lightbulb64 static bool matter_lightbulb_last_state = false;65 bool matter_lightbulb_current_state = matter_color_bulb.get_onoff();66
67 // If the current state is ON and the previous was OFF - turn on the LED68 if (matter_lightbulb_current_state && !matter_lightbulb_last_state) {69 matter_lightbulb_last_state = matter_lightbulb_current_state;70 Serial.println("Bulb ON");71 // Set the LEDs to the last received state72 update_led_color();73 }74
75 // If the current state is OFF and the previous was ON - turn off the LED76 if (!matter_lightbulb_current_state && matter_lightbulb_last_state) {77 matter_lightbulb_last_state = matter_lightbulb_current_state;78 Serial.println("Bulb OFF");79 led_off();80 }81
82 static uint8_t hue_prev = 0;83 static uint8_t saturation_prev = 0;84 static uint8_t brightness_prev = 0;85 uint8_t hue_curr = matter_color_bulb.get_hue();86 uint8_t saturation_curr = matter_color_bulb.get_saturation_percent();87 uint8_t brightness_curr = matter_color_bulb.get_brightness_percent();88
89 // If either the hue, saturation or the brightness changes - update the LED to reflect the latest change90 if (hue_prev != hue_curr || saturation_prev != saturation_curr || brightness_prev != brightness_curr) {91 update_led_color();92 hue_prev = hue_curr;93 saturation_prev = saturation_curr;94 brightness_prev = brightness_curr;95 }96}97
98// Updates the color of the RGB LED to match the Matter lightbulb's color99void update_led_color()100{101 if (!matter_color_bulb.get_onoff()) {102 return;103 }104 uint8_t r, g, b;105 matter_color_bulb.get_rgb(&r, &g, &b);106 // If our built-in LED is active LOW, we need to invert the brightness values107 if (LED_BUILTIN_ACTIVE == LOW) {108 analogWrite(LED_R, 255 - r);109 analogWrite(LED_G, 255 - g);110 analogWrite(LED_B, 255 - b);111 } else {112 analogWrite(LED_R, r);113 analogWrite(LED_G, g);114 analogWrite(LED_B, b);115 }116 Serial.printf("Setting bulb color to > r: %u g: %u b: %u\n", r, g, b);117}118
119// Turns the RGB LED off120void led_off()121{122 // If our built-in LED is active LOW, we need to invert the brightness values123 if (LED_BUILTIN_ACTIVE == LOW) {124 analogWrite(LED_R, 255);125 analogWrite(LED_G, 255);126 analogWrite(LED_B, 255);127 } else {128 analogWrite(LED_R, 0);129 analogWrite(LED_G, 0);130 analogWrite(LED_B, 0);131 }132}133
134void handle_button_press()135{136 static uint32_t btn_last_press = 0;137 if (millis() < btn_last_press + 200) {138 return;139 }140 btn_last_press = millis();141 button_pressed = true;142}
Here is the example sketch main functions explanation:
In the
function, Matter is initialized withsetup()
alongside the initial configurations of the board to handle the different inputs and outputs.Matter.begin()
The device commissioning is verified with
to show the user the network pairing credentials if needed, and the connection is confirmed with theMatter.isDeviceCommissioned()
function.Matter.isDeviceThreadConnected()
With the
function, we confirm that the device is online and reachable by the coordinator app.matter_color_bulb.is_online()
In the
function, the RGB LED is controlled on and off withloop()
, the current state is retrieved withmatter_color_bulb.set_onoff(state)
and the button state is read to control the LED manually.matter_color_bulb.get_onoff()
In the
function, the color defined in the app is retrieved using the functionupdate_led_color()
that stores the requested color code in RGB format variables.matter_color_bulb.get_rgb(&r, &g, &b)
To upload the code to the Nano Matter, click the Verify button to compile the sketch and check for errors; then click the Upload button to program the board with the sketch.
After the code is uploaded, open the Arduino IDE Serial Monitor and reset the board by clicking on the reset button. To commission a Matter device to the network you will need the credentials shown in the terminal.
You will find a Manual pairing code and a QR code URL as follows:
Open the QR code URL on your browser to generate the QR code.
With Google Home™
To create your first IoT device with the Nano Matter and the Google Home ecosystem, you first need to have a Matter-compatible hub. The Google Home products that can work as a Matter hub through Thread® are listed below:
- Nest Hub (2nd Gen)
- Nest Hub Max
- Nest Wifi Pro (Wi-Fi 6E)
- Nest Wifi
Other Google devices are compatible with Matter but not Thread®.
To commission your device, open the Google Home app, navigate to devices, click on add device and select the matter-enabled device option:
Then, wait for the device to be commissioned and added to the Google Home app:
Finally, you will be able to control the Nano Matter built-in RGB LED as a native smart device. You can turn it on and off and control its color and brightness.
You are also able to control your device using voice commands with your personal assistant.
If you want to commission your Nano Matter solution with another service, follow the steps in the decommissioning section.
With Amazon Alexa
The Amazon Alexa products that can work as a Matter hub through Thread® are listed below:
- Echo (4th Gen)
- Echo Show 10 (3rd Gen)
- Echo Show 8 (3rd Gen)
- Echo Hub
- Echo Studio (2nd Gen)
- Echo Plus (2nd Gen)
- eero Pro 6 and 6E
- eero 6 and 6+
- eero PoE 6 and gateway
- eero Pro
- eero Beacon
- eero Max 7
Other Amazon devices are compatible with Matter but not Thread®.
To commission your device, open the Amazon Alexa app, click on the upper right + symbol, select device and select the Matter logo option:
Read the QR code generated by the Nano Matter sketch, select the Thread® network available and then wait for the device to be commissioned and added to the Alexa app:
Finally, you will be able to control the Nano Matter built-in RGB LED as a native smart device. You can turn it on and off and control its color and brightness.
You are also able to control your device using voice commands with your personal assistant.
If you want to commission your Nano Matter solution with another service, follow the steps in the decommissioning section.
With Apple Home
The Apple Home products that can work as a Matter hub through Thread® are listed below:
- Apple TV 4K (3rd generation) Wi-Fi + Ethernet
- Apple TV 4K (2nd generation)
- HomePod (2nd generation)
- HomePod mini
To commission your device, open the Apple Home app, click on the upper right + symbol, select Add Accessory and scan the QR code generated by the Nano Matter in the Serial Monitor:
If this is your first Matter device, you may be asked to define the Matter hub to be used. Select its house location and give it a name:
Then, follow the steps for adding and naming the Matter Light bulb:
Finally, you will be able to control the Nano Matter built-in RGB LED as a native smart device. You can turn it on and off and control its color and brightness.
You are also able to control your device using voice commands with your personal assistant.
If you want to commission your Nano Matter solution with another service, follow the steps in the decommissioning section.
With Home Assistant
To use Matter with Home Assistant, you will need one of the Google Home or Apple Home devices that can work as a Thread® Border Router, as listed in the previous sections.
To set up Home Assistant so that it can manage Matter devices, we need first to install the Matter Server add-on. For this, navigate to Settings > Add-Ons > Add-On Store and search for Matter server:
When the Matter server is correctly installed, navigate to Settings > Devices & Services > Add Integration and search for Matter:
A prompt will show up asking for a connection method; if you are working with custom containers running the Matter server, uncheck the box.
In our case, we leave it checked as the Matter server is running in Home Assistant.
You will receive a Success message if everything is okay. With the Home Assistant integration ready, we can start with the Nano Matter commissioning.
To commission your device, open the Home Assistant app on your smartphone, go to Settings > Devices & Services, in the lower tabs bar, go to Devices and tap on Add Device. Tap on Add Matter device and scan the QR code generated by the Nano Matter in the Serial Monitor:
Then, wait for the device to be commissioned and added to the Home Assistant app:
Finally, you will be able to control the Nano Matter built-in RGB LED as a native smart device. You can turn it on and off and control its color and brightness.
You can use the Home Assistant web view or mobile app to control your device.
If you want to commission your Nano Matter solution with another service, follow the steps in the decommissioning section.
We tested the Matter integration with the Home Assistant OS and hosting Home Assistant in Docker containers.
Home Assistant Tips
- Make sure you are using a 64-bit Home Assistant version (OS or Docker containerized version).
- Use the Thread® add-on to verify your available Thread® networks.
- You can just have a Matter device commissioned to one platform at a time.
Be aware that the Matter integration for Home Assistant is still in BETA, it can receive major updates and its functionality may vary between different vendors.
Device Decommissioning
If you have a Matter device configured and working with a specific platform, for example with the Google Home ecosystem, and you want to integrate it with Alexa or Apple Home instead, you need to decommission it first from the previous service.
In simple terms, decommissioning refers to unpairing your device from a current service to be able to pair it with a new one.
You can integrate this method in your solutions to leverage the Nano Matter built-in button to handle decommissioning:
1#include <Matter.h>2
3void setup() {4 // put your setup code here, to run once:5 Serial.begin(115200);6
7 Matter.begin();8 pinMode(BTN_BUILTIN, INPUT_PULLUP);9 pinMode(LEDR, OUTPUT);10 digitalWrite(LEDR, HIGH);11}12
13void loop() {14 // put your main code here, to run repeatedly:15 decommission_handler();16}17
18
19void decommission_handler() {20 if (digitalRead(BTN_BUILTIN) == LOW) { //Push button pressed21 // measures time pressed22 int startTime = millis();23 while (digitalRead(BTN_BUILTIN) == LOW) {24
25 int elapsedTime = (millis() - startTime) / 1000.0;26
27 if (elapsedTime > 10) {28 Serial.printf("Decommissioning!\n");29 for (int i = 0; i < 10; i++) {30 digitalWrite(LEDR, !(digitalRead(LEDR)));31 delay(100);32 };33
34 if (!Matter.isDeviceCommissioned()) {35 Serial.println("Decommission done!");36 digitalWrite(LEDR, LOW);37 } else {38 Serial.println("Matter device is commissioned-> Starting Decommission process");39 nvm3_eraseAll(nvm3_defaultHandle); // Decomission command40 digitalWrite(LED_BUILTIN, LOW);41 Serial.println("Decommission done!");42 }43 break;44 }45 }46 }47}
The sketch above allows you to decommission your board manually after pressing the Nano Matter user button for 10 seconds. You can monitor the status in the Arduino IDE Serial Monitor.
Arduino Cloud
The Nano Matter has no built-in Wi-Fi® but can be seamlessly integrated with the Arduino Cloud using its API and Matter.
We are going to use the Home Assistant Matter integration to create automations and scripts that help us forward the Nano Matter data to the Arduino Cloud.
In case it is the first time you are using the Arduino Cloud:
- To use the Arduino Cloud, you need an account. If you do not have an account, create one for free here.
- See the Arduino Cloud plans and choose one that features API support.
As a practical example, we are going to use the Nano Matter CPU temperature sensor and send the data to Arduino Cloud for monitoring. We will leverage the variety of widgets to create a professional and nice-looking user interface.
Nano Matter Programming
The application sketch below is based on the
matter_temp_sensor
example that can be also found in File > Examples > Matter. This variation includes the decommission feature to show it implemented in a real application.1#include <Matter.h>2#include <MatterTemperature.h>3
4MatterTemperature matter_temp_sensor;5
6void setup()7{8 Serial.begin(115200);9 Matter.begin();10
11 pinMode(BTN_BUILTIN, INPUT_PULLUP);12 pinMode(LEDR, OUTPUT);13 digitalWrite(LEDR, HIGH);14
15 matter_temp_sensor.begin();16
17 Serial.println("Matter temperature sensor");18
19 if (!Matter.isDeviceCommissioned()) {20 Serial.println("Matter device is not commissioned");21 Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");22 Serial.printf("Manual pairing code: %s\n", Matter.getManualPairingCode().c_str());23 Serial.printf("QR code URL: %s\n", Matter.getOnboardingQRCodeUrl().c_str());24 }25 while (!Matter.isDeviceCommissioned()) {26 delay(200);27 decommission_handler(); // if the user button is pressed for 10 seconds28 }29
30 Serial.println("Waiting for Thread network...");31 while (!Matter.isDeviceThreadConnected()) {32 delay(200);33 decommission_handler();34 }35 Serial.println("Connected to Thread network");36
37 Serial.println("Waiting for Matter device discovery...");38 while (!matter_temp_sensor.is_online()) {39 delay(200);40 decommission_handler();41 }42 Serial.println("Matter device is now online");43}44
45void loop()46{47 decommission_handler(); // if the user button is pressed for 10 seconds48
49 float current_cpu_temp = getCPUTemp();50 matter_temp_sensor.set_measured_value_celsius(current_cpu_temp);51 Serial.printf("Current CPU temperature: %.02f C\n", current_cpu_temp);52 delay(2000);53}54
55void decommission_handler() {56 if (digitalRead(BTN_BUILTIN) == LOW) { //Push button pressed57 // measures time pressed58 int startTime = millis();59 while (digitalRead(BTN_BUILTIN) == LOW) {60 //delay(50);61
62 int elapsedTime = (millis() - startTime) / 1000.0;63
64 if (elapsedTime > 10) {65 Serial.printf("Decommissioning!\n");66 for (int i = 0; i < 10; i++) {67 digitalWrite(LEDR, !(digitalRead(LEDR)));68 delay(100);69 };70
71 if (!Matter.isDeviceCommissioned()) {72 Serial.println("Decommission done!");73 digitalWrite(LEDR, LOW);74 } else {75 Serial.println("Matter device is commissioned-> Starting Decommission process");76 nvm3_eraseAll(nvm3_defaultHandle); // Decomission command77 digitalWrite(LED_BUILTIN, LOW);78 Serial.println("Decommission done!");79 }80 break;81 }82 }83 }84}
The main code functions are explained below:
- The temperature sensor object is created with the
statement. To initiate it, in theMatterTemperature matter_temp_sensor;
function, we usedsetup()
matter_temp_sensor.begin();
- The
lets us unpair the device from a previous platform.decommission_handler()
- The microcontroller's internal temperature is measured with the function
.getCPUTemp();
- The temperature value is advertised using the
function.matter_temp_sensor.set_measured_value_celsius(current_cpu_temp);
After uploading the code to the Nano Matter, verify it is decommissioned from any other service previously used. For this, open the Serial Monitor and reset the board by clicking on the reset button.
If it is not decommissioned you will see temperature readings printed in the Serial Monitor. To decommission it, follow these steps:
Press the user button for 10 seconds until the board's built-in LED starts blinking in red. You will also see a message confirming the process in the Serial Monitor.
Finally, reset the board by clicking on the reset button and you should see the Matter commissioning credentials in the Serial Monitor.
Device Commissioning
Now it is time to commission the Nano Matter with Home Assistant, for this, follow the steps explained in this section.
Once you have everything set up and running you will be able to monitor the Nano Matter temperature in Home Assistant:
Be aware that the Matter integration for Home Assistant is still in BETA, it can receive major updates and its functionality may vary between different vendors.
Arduino Cloud Set-Up
Let's walk through a step-by-step demonstration of how to set up the Arduino Cloud.
Log in to your Arduino Cloud account; you should see the following:
Navigate to Things in the left bar menu and click on + Thing to add a Thing:
Give your Thing a name and click on ADD to add the temperature variable:
Define the variable with the following settings:
- Name: temperature
- Type: Floating Point Number
- Permission: Read & Write
- Update Policy: On change
Click on the created variable and copy its ID, we will need it later.
Navigate to your Thing metadata and copy the Thing ID, we will need it later.
In the left bar menu, navigate to Space Settings and copy the Space ID, we will need it later.
If you can't see the Space Settings section is because you are using an Arduino Cloud free plan, check the plans with the API feature enabled.
At this point you should have three IDs related to your project:
- Variable ID
- Thing ID
- Space ID
To properly authenticate the requests we are going to use to upload the data to the Arduino Cloud we need to create API Keys.
For this, navigate to API Keys in the upper left corner drop-down menu and click on Create API Key:
You should get a Client ID and a Client Secret. Save these credentials in a safe place, you will not be able to see them again.
Home Assistant Set-Up
Now, let's configure Home Assistant to set the forwarding method to Arduino Cloud.
First, we are going to save and define our project IDs, credentials and Keys in a safe place inside the Home Assistant directory called secrets.yaml. Use the File Editor Add-on to easily edit this file, and format the data as follows:
1arduino_organization: <Space ID>2
3token_get_payload: '{"grant_type":"client_credentials","client_id":"<your client ID>","client_secret":"<your client secret>","audience":"https://api2.arduino.cc/iot"}'4
5arduino_temp_url: https://api2.arduino.cc/iot/v2/things/<your Thing ID>/properties/<temperature variable ID>/publish
This will let us use this data without exposing it later.
Now, let's define the services that will help us do the HTTP requests to Arduino Cloud sending the temperature value to it. Using the File Editor navigate to the configuration.yaml file and add the following blocks:
1rest:2 - resource: "https://api2.arduino.cc/iot/v1/clients/token"3 scan_interval: 240 #4 min4 timeout: 605 method: "POST"6 headers:7 content_type: 'application/json,application/x-www-form-urlencoded'8 payload: !secret token_get_payload9 sensor: 10 - name: "API_Token_Bearer"11 value_template: "OK"12 json_attributes_path: '$..'13 json_attributes:14 - 'access_token'
The RESTful integration lets us periodically gather from our Arduino Cloud account a token that is mandatory to authenticate our requests. This token expires every 5 minutes, this is why we generate it every 4 minutes. The token is stored in a sensor attribute called API_Token_Bearer.
1rest_command: 2 send_temperature:3 method: PUT4 headers:5 Authorization: "Bearer {{ state_attr('sensor.api_token_bearer', 'access_token') }}"6 accept: "application/vnd.arduino.property+json,application/vnd.goa.error+json"7 content_type: 'application/json,application/x-www-form-urlencoded'8 X-Organization: !secret arduino_organization9 url: !secret arduino_temp_url10 payload: "{\"value\":{{states('sensor.matter_device_temperature')}}}"
The RESTful command integration lets us define the HTTP request structure to be able to send the Nano Matter temperature sensor data to the Arduino Cloud. We can call this service from an automation.
As you may noticed, the sensitive data we stored in the "secrets.yaml" file is being called here with the !secret prefix.
To learn more about the Arduino Cloud API, follow this guide.
For the changes to take effect, navigate to Developers Tools and click on Check Configuration, if there are no errors, click on Restart and restart Home Assistant.
Finally, let's set up the automation that will call the send_temperature service every time the temperature sensor values change.
For this, navigate to Settings > Automations & scenes and click on Create Automation.
In the upper right corner, click on the "three dots" menu and select Edit in YAML, replace the text there with the following:
1alias: Nano Matter Temperature2description: ""3trigger:4 - platform: state5 entity_id:6 - sensor.matter_device_temperature7condition: []8action:9 - service: rest_command.send_temperature10 data: {}11mode: single
This automation will be triggered if the Nano Matter sensor temperature value changes and will act by calling the rest_command.send_temperature service.
If you used different names for the services or devices, make sure to update them in the YAML code above.
Final Results
With this done, Home Assistant should be forwarding the Nano Matter sensor data to Arduino Cloud where you can monitor it with different widgets and charts as follows:
Bluetooth® Low Energy
To enable Bluetooth® Low Energy communication on the Nano Matter, you must enable the "BLE" protocol stack in the Arduino IDE board configurations.
In the upper menu, navigate to Tools > Protocol stack and select BLE.
For this Bluetooth® Low Energy application example, we are going to control the Nano Matter built-in LED and read the onboard button status. The example sketch to be used can be found in File > Examples > Silicon Labs > ble_blinky:
1/*2 BLE blinky example3*/4
5bool btn_notification_enabled = false;6bool btn_state_changed = false;7uint8_t btn_state = LOW;8static void btn_state_change_callback();9static void send_button_state_notification();10static void set_led_on(bool state);11
12void setup()13{14 pinMode(LED_BUILTIN, OUTPUT);15 digitalWrite(LED_BUILTIN, LED_BUILTIN_INACTIVE);16 set_led_on(false);17 Serial.begin(115200);18 Serial.println("Silicon Labs BLE blinky example");19
20 // If the board has a built-in button configure it for usage21 #ifdef BTN_BUILTIN22 pinMode(BTN_BUILTIN, INPUT_PULLUP);23 attachInterrupt(BTN_BUILTIN, btn_state_change_callback, CHANGE);24 #else // BTN_BUILTIN25 // Avoid warning for unused function on boards without a button26 (void)btn_state_change_callback;27 #endif // BTN_BUILTIN28}29
30void loop()31{32 if (btn_state_changed) {33 btn_state_changed = false;34 send_button_state_notification();35 }36}37
38static void ble_initialize_gatt_db();39static void ble_start_advertising();40
41static const uint8_t advertised_name[] = "Blinky Example";42static uint16_t gattdb_session_id;43static uint16_t generic_access_service_handle;44static uint16_t name_characteristic_handle;45static uint16_t blinky_service_handle;46static uint16_t led_control_characteristic_handle;47static uint16_t btn_report_characteristic_handle;48
49/**************************************************************************//**50 * Bluetooth stack event handler51 * Called when an event happens on BLE the stack52 *53 * @param[in] evt Event coming from the Bluetooth stack54 *****************************************************************************/55void sl_bt_on_event(sl_bt_msg_t *evt)56{57 switch (SL_BT_MSG_ID(evt->header)) {58 // -------------------------------59 // This event indicates the device has started and the radio is ready.60 // Do not call any stack command before receiving this boot event!61 case sl_bt_evt_system_boot_id:62 {63 Serial.println("BLE stack booted");64
65 // Initialize the application specific GATT table66 ble_initialize_gatt_db();67
68 // Start advertising69 ble_start_advertising();70 Serial.println("BLE advertisement started");71 }72 break;73
74 // -------------------------------75 // This event indicates that a new connection was opened76 case sl_bt_evt_connection_opened_id:77 Serial.println("BLE connection opened");78 break;79
80 // -------------------------------81 // This event indicates that a connection was closed82 case sl_bt_evt_connection_closed_id:83 Serial.println("BLE connection closed");84 // Restart the advertisement85 ble_start_advertising();86 Serial.println("BLE advertisement restarted");87 break;88
89 // -------------------------------90 // This event indicates that the value of an attribute in the local GATT91 // database was changed by a remote GATT client92 case sl_bt_evt_gatt_server_attribute_value_id:93 // Check if the changed characteristic is the LED control94 if (led_control_characteristic_handle == evt->data.evt_gatt_server_attribute_value.attribute) {95 Serial.println("LED control characteristic data received");96 // Check the length of the received data97 if (evt->data.evt_gatt_server_attribute_value.value.len == 0) {98 break;99 }100 // Get the received byte101 uint8_t received_data = evt->data.evt_gatt_server_attribute_value.value.data[0];102 // Turn the LED on/off according to the received data103 if (received_data == 0x00) {104 set_led_on(false);105 Serial.println("LED off");106 } else if (received_data == 0x01) {107 set_led_on(true);108 Serial.println("LED on");109 }110 }111 break;112
113 // -------------------------------114 // This event is received when a GATT characteristic status changes115 case sl_bt_evt_gatt_server_characteristic_status_id:116 // If the 'Button report' characteristic has been changed117 if (evt->data.evt_gatt_server_characteristic_status.characteristic == btn_report_characteristic_handle) {118 // The client just enabled the notification - send notification of the current button state119 if (evt->data.evt_gatt_server_characteristic_status.client_config_flags & sl_bt_gatt_notification) {120 Serial.println("Button state change notification enabled");121 btn_notification_enabled = true;122 btn_state_change_callback();123 } else {124 Serial.println("Button state change notification disabled");125 btn_notification_enabled = false;126 }127 }128 break;129
130 // -------------------------------131 // Default event handler132 default:133 break;134 }135}136
137/**************************************************************************//**138 * Called on button state change - stores the current button state and139 * sets a flag that a button state change occurred.140 * If the board doesn't have a button the function does nothing.141 *****************************************************************************/142static void btn_state_change_callback()143{144 // If the board has a built-in button145 #ifdef BTN_BUILTIN146 // The real button state is inverted - most boards have an active low button configuration147 btn_state = !digitalRead(BTN_BUILTIN);148 btn_state_changed = true;149 #endif // BTN_BUILTIN150}151
152/**************************************************************************//**153 * Sends a BLE notification the the client if notifications are enabled and154 * the board has a built-in button.155 *****************************************************************************/156static void send_button_state_notification()157{158 if (!btn_notification_enabled) {159 return;160 }161 sl_status_t sc = sl_bt_gatt_server_notify_all(btn_report_characteristic_handle,162 sizeof(btn_state),163 &btn_state);164 if (sc == SL_STATUS_OK) {165 Serial.print("Notification sent, button state: ");166 Serial.println(btn_state);167 }168}169
170/**************************************************************************//**171 * Sets the built-in LED to the desired state accounting for the inverted LED172 * logic on select boards.173 *****************************************************************************/174static void set_led_on(bool state)175{176 if (state) {177 digitalWrite(LED_BUILTIN, LED_BUILTIN_ACTIVE);178 } else {179 digitalWrite(LED_BUILTIN, LED_BUILTIN_INACTIVE);180 }181}182
183/**************************************************************************//**184 * Starts BLE advertisement185 * Initializes advertising if it's called for the first time186 *****************************************************************************/187static void ble_start_advertising()188{189 static uint8_t advertising_set_handle = 0xff;190 static bool init = true;191 sl_status_t sc;192
193 if (init) {194 // Create an advertising set195 sc = sl_bt_advertiser_create_set(&advertising_set_handle);196 app_assert_status(sc);197
198 // Set advertising interval to 100ms199 sc = sl_bt_advertiser_set_timing(200 advertising_set_handle,201 160, // minimum advertisement interval (milliseconds * 1.6)202 160, // maximum advertisement interval (milliseconds * 1.6)203 0, // advertisement duration204 0); // maximum number of advertisement events205 app_assert_status(sc);206
207 init = false;208 }209
210 // Generate data for advertising211 sc = sl_bt_legacy_advertiser_generate_data(advertising_set_handle, sl_bt_advertiser_general_discoverable);212 app_assert_status(sc);213
214 // Start advertising and enable connections215 sc = sl_bt_legacy_advertiser_start(advertising_set_handle, sl_bt_advertiser_connectable_scannable);216 app_assert_status(sc);217}218
219/**************************************************************************//**220 * Initializes the GATT database221 * Creates a new GATT session and adds certain services and characteristics222 *****************************************************************************/223static void ble_initialize_gatt_db()224{225 sl_status_t sc;226 // Create a new GATT database227 sc = sl_bt_gattdb_new_session(&gattdb_session_id);228 app_assert_status(sc);229
230 // Add the Generic Access service to the GATT DB231 const uint8_t generic_access_service_uuid[] = { 0x00, 0x18 };232 sc = sl_bt_gattdb_add_service(gattdb_session_id,233 sl_bt_gattdb_primary_service,234 SL_BT_GATTDB_ADVERTISED_SERVICE,235 sizeof(generic_access_service_uuid),236 generic_access_service_uuid,237 &generic_access_service_handle);238 app_assert_status(sc);239
240 // Add the Device Name characteristic to the Generic Access service241 // The value of the Device Name characteristic will be advertised242 const sl_bt_uuid_16_t device_name_characteristic_uuid = { .data = { 0x00, 0x2A } };243 sc = sl_bt_gattdb_add_uuid16_characteristic(gattdb_session_id,244 generic_access_service_handle,245 SL_BT_GATTDB_CHARACTERISTIC_READ,246 0x00,247 0x00,248 device_name_characteristic_uuid,249 sl_bt_gattdb_fixed_length_value,250 sizeof(advertised_name) - 1,251 sizeof(advertised_name) - 1,252 advertised_name,253 &name_characteristic_handle);254 app_assert_status(sc);255
256 // Start the Generic Access service257 sc = sl_bt_gattdb_start_service(gattdb_session_id, generic_access_service_handle);258 app_assert_status(sc);259
260 // Add the Blinky service to the GATT DB261 // UUID: de8a5aac-a99b-c315-0c80-60d4cbb51224262 const uuid_128 blinky_service_uuid = {263 .data = { 0x24, 0x12, 0xb5, 0xcb, 0xd4, 0x60, 0x80, 0x0c, 0x15, 0xc3, 0x9b, 0xa9, 0xac, 0x5a, 0x8a, 0xde }264 };265 sc = sl_bt_gattdb_add_service(gattdb_session_id,266 sl_bt_gattdb_primary_service,267 SL_BT_GATTDB_ADVERTISED_SERVICE,268 sizeof(blinky_service_uuid),269 blinky_service_uuid.data,270 &blinky_service_handle);271 app_assert_status(sc);272
273 // Add the 'LED Control' characteristic to the Blinky service274 // UUID: 5b026510-4088-c297-46d8-be6c736a087a275 const uuid_128 led_control_characteristic_uuid = {276 .data = { 0x7a, 0x08, 0x6a, 0x73, 0x6c, 0xbe, 0xd8, 0x46, 0x97, 0xc2, 0x88, 0x40, 0x10, 0x65, 0x02, 0x5b }277 };278 uint8_t led_char_init_value = 0;279 sc = sl_bt_gattdb_add_uuid128_characteristic(gattdb_session_id,280 blinky_service_handle,281 SL_BT_GATTDB_CHARACTERISTIC_READ | SL_BT_GATTDB_CHARACTERISTIC_WRITE,282 0x00,283 0x00,284 led_control_characteristic_uuid,285 sl_bt_gattdb_fixed_length_value,286 1, // max length287 sizeof(led_char_init_value), // initial value length288 &led_char_init_value, // initial value289 &led_control_characteristic_handle);290
291 // Add the 'Button report' characteristic to the Blinky service292 // UUID: 61a885a4-41c3-60d0-9a53-6d652a70d29c293 const uuid_128 btn_report_characteristic_uuid = {294 .data = { 0x9c, 0xd2, 0x70, 0x2a, 0x65, 0x6d, 0x53, 0x9a, 0xd0, 0x60, 0xc3, 0x41, 0xa4, 0x85, 0xa8, 0x61 }295 };296 uint8_t btn_char_init_value = 0;297 sc = sl_bt_gattdb_add_uuid128_characteristic(gattdb_session_id,298 blinky_service_handle,299 SL_BT_GATTDB_CHARACTERISTIC_READ | SL_BT_GATTDB_CHARACTERISTIC_NOTIFY,300 0x00,301 0x00,302 btn_report_characteristic_uuid,303 sl_bt_gattdb_fixed_length_value,304 1, // max length305 sizeof(btn_char_init_value), // initial value length306 &btn_char_init_value, // initial value307 &btn_report_characteristic_handle);308
309 // Start the Blinky service310 sc = sl_bt_gattdb_start_service(gattdb_session_id, blinky_service_handle);311 app_assert_status(sc);312
313 // Commit the GATT DB changes314 sc = sl_bt_gattdb_commit(gattdb_session_id);315 app_assert_status(sc);316}
Here are the main functions explanations of the example sketch:
The
sl_bt_on_event(sl_bt_msg_t *evt)
function is the main one of the sketch and it is responsible for:- Initiating the Bluetooth® Low Energy radio, and start advertising the defined services alongside its characteristics.
- Handling the opening and closing of connections.
- Handling incoming and outgoing Bluetooth® Low Energy messages.
The
ble_initialize_gatt_db()
function is responsible for:- Adding the Generic Access service with the
UUID.1800
- Adding the Blinky service with the
UUID.de8a5aac-a99b-c315-0c80-60d4cbb51224
- Creating the device name characteristic so we can find the device as "Blinky Example" with the
UUID.2A00
- Adding the LED Control characteristic to the Blinky service with the
UUID.5b026510-4088-c297-46d8-be6c736a087a
- Adding the Button report characteristic to the Blinky service with the
UUID.61a885a4-41c3-60d0-9a53-6d652a70d29c
Note that if you want to implement a different or custom Bluetooth® Low Energy service or characteristic, the UUID arrays have to start with the least significant bit (LSB) from left to right.
After uploading the sketch to the Nano Matter, it is time to communicate with it through Bluetooth® Low Energy. For this, Silicon Labs has developed a mobile app that you can download from here:
Open the EFR Connect BLE Mobile APP on your smartphone, in the lower menu, navigate to Demo and select Blinky:
You can also manage the LED control and button status manually from the Scan tab in the lower menu.
Onboard User Interface
User Button
The Nano Matter includes an onboard push button that can be used as an input by the user. The button is connected to the GPIO
PA0
and can be read using the BTN_BUILTIN
macro.The button pulls the input to the ground when pressed, so is important to define the pull-up resistor to avoid undesired behavior by leaving the input floating.
Here you can find a complete example code to blink the built-in RGB LED of the Nano Matter:
1volatile bool button_pressed = false;2
3void handle_button_press();4
5void setup() {6 Serial.begin(115200);7
8 pinMode(BTN_BUILTIN, INPUT_PULLUP);9 attachInterrupt(BTN_BUILTIN, &handle_button_press, FALLING);10}11
12void loop() {13 // If the physical button state changes - update the state14 if (button_pressed) {15 button_pressed = false;16 Serial.println("Button Pressed!");17 }18}19
20void handle_button_press()21{22 static uint32_t btn_last_press = 0;23 if (millis() < btn_last_press + 200) {24 return;25 }26 btn_last_press = millis();27 button_pressed = true;28}
After pressing the push button, you will see a "Button Pressed!" message in the Serial Monitor.
RGB LED
The Nano Matter features a built-in RGB LED that can be a visual feedback indicator for the user. The LED is connected through the board GPIO's; therefore, usual digital pins built-in functions can be used to operate the LED colors.
LED Color Segment | Arduino Name | Microcontroller Pin |
---|---|---|
Red | LEDR or LED_BUILTIN | PC01 |
Green | LEDG or LED_BUILTIN_1 | PC02 |
Blue | LEDB or LED_BUILTIN_2 | PC03 |
The RGB LED colors are activated with zeros, this means that you need to set to LOW the color segment you want to turn on.
Here you can find a complete example code to blink the built-in RGB LED of the Nano Matter:
1void setup() {2 // initialize LED digital pins as outputs.3 pinMode(LEDR, OUTPUT);4 pinMode(LEDG, OUTPUT);5 pinMode(LEDB, OUTPUT);6}7
8// the loop function runs over and over again forever9void loop() {10 digitalWrite(LEDR, LOW); // turn the LED on (LOW is the voltage level)11 digitalWrite(LEDG, HIGH); // turn the LED off (HIGH is the voltage level)12 digitalWrite(LEDB, HIGH); // turn the LED off (HIGH is the voltage level)13 delay(1000); // wait for a second14 digitalWrite(LEDR, HIGH); // turn the LED off by making the voltage HIGH15 digitalWrite(LEDG, LOW); // turn the LED on by making the voltage LOW16 digitalWrite(LEDB, HIGH); // turn the LED off by making the voltage HIGH17 delay(1000); // wait for a second18 digitalWrite(LEDR, HIGH); // turn the LED off by making the voltage HIGH19 digitalWrite(LEDG, HIGH); // turn the LED off by making the voltage HIGH20 digitalWrite(LEDB, LOW); // turn the LED on by making the voltage LOW21 delay(1000); 22}
Pins
Digital Pins
The Nano Matter has 22 digital pins, mapped as follows:
Microcontroller Pin | Arduino Pin Mapping | Pin Functionality |
---|---|---|
PB00 | A0 / DAC0 | GPIO / ADC / DAC |
PB02 | A1 / DAC2 | GPIO / ADC / DAC |
PB05 | A2 | GPIO / ADC |
PC00 | A3 | GPIO / ADC |
PA06 | A4 / SDA | I2C / GPIO / ADC |
PA07 | A5 / SCL | I2C / GPIO / ADC |
PB01 | A6 / DAC1 | GPIO / ADC / DAC |
PB03 | A7 / DAC3 | GPIO / ADC / DAC |
PB04 | D13 / SCK | SPI / GPIO / ADC |
PA08 | D12 / MISO | SPI / GPIO / ADC |
PA09 | D11 / MOSI | SPI / GPIO / ADC |
PD05 | D10 / SS | SPI / GPIO |
PD04 | D9 | GPIO |
PD03 | D8 | GPIO / ADC |
PD02 | D7 | GPIO / ADC |
PC09 | D6 | GPIO / ADC |
PC08 | D5 / SCL1 | I2C / GPIO / ADC |
PC07 | D4 / SDA1 | I2C / GPIO / ADC |
PC06 | D3 / SS1 | GPIO / SPI / ADC |
PA03 | D2 / SCK1 | SPI / GPIO |
PA05 | D1 / PIN_SERIAL_RX1 / MISO1 | UART / SPI / GPIO / ADC |
PA04 | D0 / PIN_SERIAL_TX1 / MOSI1 | UART / SPI / GPIO / ADC |
The digital pins of the Nano Matter can be used as inputs or outputs through the built-in functions of the Arduino programming language.
The configuration of a digital pin is done in the
setup()
function with the built-in function pinMode()
as shown below:1// Pin configured as an input2pinMode(pin, INPUT); 3
4// Pin configured as an output5pinMode(pin, OUTPUT); 6
7// Pin configured as an input, internal pull-up resistor enabled8pinMode(pin, INPUT_PULLUP);
The state of a digital pin, configured as an input, can be read using the built-in function
digitalRead()
as shown below:1// Read pin state, store value in a state variable2state = digitalRead(pin);
The state of a digital pin, configured as an output, can be changed using the built-in function
digitalWrite()
as shown below:1// Set pin on2digitalWrite(pin, HIGH); 3
4// Set pin off5digitalWrite(pin, LOW);
The example code shown below uses digital pin
D5
to control an LED and reads the state of a button connected to digital pin D4
:1// Define button and LED pin2int buttonPin = D4;3int ledPin = D5;4
5// Variable to store the button state6int buttonState = 0;7
8void setup() {9 // Configure button and LED pins10 pinMode(buttonPin, INPUT_PULLUP);11 pinMode(ledPin, OUTPUT);12
13 // Initialize Serial communication14 Serial.begin(115200);15}16
17void loop() {18 // Read the state of the button19 buttonState = digitalRead(buttonPin);20
21 // If the button is pressed, turn on the LED and print its state to the Serial Monitor22 if (buttonState == LOW) {23 digitalWrite(ledPin, HIGH);24 Serial.println("- Button is pressed. LED is on.");25 } else {26 // If the button is not pressed, turn off the LED and print to the Serial Monitor27 digitalWrite(ledPin, LOW);28 Serial.println("- Button is not pressed. LED is off.");29 }30
31 // Wait for 1000 milliseconds32 delay(1000);33}
PWM Pins
All the digital and analog pins of the Nano Matter can be used as PWM (Pulse Width Modulation) pins.
You can only use 5 PWM outputs simultaneously.
This functionality can be used with the built-in function
analogWrite()
as shown below:1analogWrite(pin, value);
By default, the output resolution is 8 bits, so the output value should be between 0 and 255. To set a greater resolution, do it using the built-in function
analogWriteResolution
as shown below:1analogWriteResolution(bits);
Using this function has some limitations, for example, the PWM signal frequency is fixed at 1 kHz, and this could not be ideal for every application.
Here is an example of how to create a 1 kHz variable duty-cycle PWM signal:
1const int analogInPin = A0; // Analog input pin that the potentiometer is attached to2const int pwmOutPin = D13; // PWM output pin3
4int sensorValue = 0; // value read from the pot5int outputValue = 0; // value output to the PWM (analog out)6
7void setup() {8 // initialize serial communications at 9600 bps:9 Serial.begin(115200);10 analogWriteResolution(12);11}12
13void loop() {14 // read the analog in value:15 sensorValue = analogRead(analogInPin);16 // map it to the range of the analog out:17 outputValue = sensorValue;18 // change the analog out value:19 analogWrite(pwmOutPin, outputValue);20
21 // print the results to the Serial Monitor:22 Serial.print("sensor = ");23 Serial.print(sensorValue);24 Serial.print("\t output = ");25 Serial.println(outputValue);26
27 // wait 2 milliseconds before the next loop for the analog-to-digital28 // converter to settle after the last reading:29 delay(2);30}
If you need to work with a higher frequency PWM signal, you can do it with the following PWM class-specific function:
1PWM.frequency_mode(output_pin, frequency);
Here is an example of how to create a 10 kHz fixed duty-cycle PWM signal:
1const int analogOutPin = D13; // PWM output pin to use2
3void setup() {4 analogWriteResolution(12); 5}6
7void loop() {8 PWM.frequency_mode(analogOutPin, 10000);9}
Analog Input Pins (ADC)
The Nano Matter has 20 analog input pins, mapped as follows:
Microcontroller Pin | Arduino Pin Mapping | Pin Functionality |
---|---|---|
PB00 | A0 / DAC0 | GPIO / ADC / DAC |
PB02 | A1 / DAC2 | GPIO / ADC / DAC |
PB05 | A2 | GPIO / ADC |
PC00 | A3 | GPIO / ADC |
PA06 | A4 / SDA | I2C / GPIO / ADC |
PA07 | A5 / SCL | I2C / GPIO / ADC |
PB01 | A6 / DAC1 | GPIO / ADC / DAC |
PB03 | A7 / DAC3 | GPIO / ADC / DAC |
PB04 | D13 / SCK | SPI / GPIO / ADC |
PA08 | D12 / MISO | SPI / GPIO / ADC |
PA09 | D11 / MOSI | SPI / GPIO / ADC |
PD03 | D8 | GPIO / ADC |
PD02 | D7 | GPIO / ADC |
PC09 | D6 | GPIO / ADC |
PC08 | D5 / SCL1 | I2C / GPIO / ADC |
PC07 | D4 / SDA1 | I2C / GPIO / ADC |
PC06 | D3 / SS1 | GPIO / SPI / ADC |
PA03 | D2 / SCK1 | SPI / GPIO |
PA05 | D1 / PIN_SERIAL_RX1 / MISO1 | UART / SPI / GPIO / ADC |
PA04 | D0 / PIN_SERIAL_TX1 / MOSI1 | UART / SPI / GPIO / ADC |
Digital I/O's can also be used as analog inputs except for
and D9
.D10
Analog input pins can be used through the built-in functions of the Arduino programming language.
Nano Matter ADC resolution is fixed to 12 bits and cannot be changed by the user.
The Nano Matter ADC reference voltage is 3.3 V by default, it can be configured using the function
analogReference()
with the following arguments:Argument | Description |
---|---|
AR_INTERNAL1V2 | Internal 1.2V reference |
AR_EXTERNAL_1V25 | External 1.25V reference |
AR_VDD | VDD (unbuffered to ground) |
AR_08VDD | 0.8 * VDD (buffered to ground) |
AR_MAX | Maximum value |
To set a different analog reference from the default one, see the following example:
1analogReference(AR_INTERNAL1V2);
The example code shown below reads the analog input value from a potentiometer connected to
A0
and displays it on the IDE Serial Monitor. To understand how to properly connect a potentiometer to the Nano Matter, take the following image as a reference:1int sensorPin = A0; // select the input pin for the potentiometer2
3int sensorValue = 0; // variable to store the value coming from the sensor4
5void setup() {6 Serial.begin(115200); 7}8
9void loop() {10 // read the value from the sensor:11 sensorValue = analogRead(sensorPin);12
13 Serial.println(sensorValue);14 delay(100);15}
Analog Output Pins (DAC)
The Nano Matter has two DACs with two channels each, mapped as follows:
Microcontroller Pin | Arduino Name | Board Pin Output | Peripheral |
---|---|---|---|
PB00 | DAC0 | A0 | DAC0_CH0 |
PB01 | DAC1 | A6 | DAC0_CH1 |
PB02 | DAC2 | A1 | DAC1_CH0 |
PB03 | DAC3 | A7 | DAC1_CH1 |
The digital-to-analog converters of the Nano Matter can be used as outputs through the built-in functions of the Arduino programming language.
The DAC output resolution can be configured from 8 to 12 bits using the
analogWriteResolution()
function as follows:1analogWriteResolution(12); // enter the desired resolution in bits (8,10,12)
The DAC voltage reference can be configured using the
analogReferenceDAC()
function. The available setups are listed below:Argument | Description |
---|---|
DAC_VREF_1V25 | Internal 1.25V reference |
DAC_VREF_2V5 | Internal 2.5V reference |
DAC_VREF_AVDD | Analog VDD |
DAC_VREF_EXTERNAL_PIN | External AREF pin |
1analogReferenceDAC(DAC_VREF_2V5); // enter the desired reference as argument
To output an analog voltage value through a DAC pin, use the
analogWrite()
function with the DAC channel as an argument. See the example below:1analogWrite(DAC0, value); // the value should be in the range of the DAC resolution (e.g. 0-4095 with a 12 bits resolution)
If a normal GPIO is passed to the analogWrite() function, the output will be a PWM signal.
The following sketch will create a sine wave signal in the
A0
Nano Matter pin:1float sample_rate = 9600.0, freq = 60.0; //samples/second, AC waveform freq.2int npts = sample_rate / freq;3
4void setup()5{6 Serial.begin(115200);7 // Set the DAC resolution to 12 bits8 analogWriteResolution(12);9 // Select the 1.25V reference voltage (feel free to change it)10 analogReferenceDAC(DAC_VREF_1V25);11}12
13void loop()14{15
16 for (int i = 0; i < npts; i++) {17 int x = 2000 + 1000.0 * sin(2 * PI * (freq / sample_rate) * i);18 analogWrite(DAC0, x);19 delayMicroseconds(1.0E6 / sample_rate); //adjust constant to get correct rate20 }21}
The DAC output should look like the image below:
The following sketch will create a sawtooth wave signal in the
A0
Nano Matter pin:1void setup()2{3 Serial.begin(115200);4 // Set the DAC resolution to 8 bits5 analogWriteResolution(8);6 // Select the 2.5V reference voltage (feel free to change it)7 analogReferenceDAC(DAC_VREF_2V5);8}9
10void loop()11{12 static int value = 0;13 analogWrite(DAC0, value);14 Serial.println(value);15
16 value++;17 if (value == 255) {18 value = 0;19 }20}
The DAC output should look like the image below:
Communication
This section of the user manual covers the different communication protocols that are supported by the Nano Matter, including the Serial Peripheral Interface (SPI), Inter-Integrated Circuit (I2C) and Universal Asynchronous Receiver-Transmitter (UART). The Nano Matter features dedicated pins for each communication protocol, simplifying the connection and communication with different components, peripherals, and sensors.
SPI
The Nano Matter supports SPI communication, which enables data transmission between the board and other SPI-compatible devices. It counts with two SPI interfaces and the pins used in the Nano Matter for the SPI communication protocol are the following:
Microcontroller Pin | Arduino Pin Mapping |
---|---|
PD05 | SS or D10 |
PA09 | MOSI or D11 |
PA08 | MISO or D12 |
PB04 | SCK or D13 |
PA04 | MOSI1 or D0 |
PA05 | MISO1 or D1 |
PA03 | SCK1 or D2 |
PC06 | SS1 or D3 |
Please, refer to the board pinout section of the user manual to localize them on the board.
You can not use SPI1 and UART interfaces at the same time because they share pins.
Include the
SPI
library at the top of your sketch to use the SPI communication protocol. The SPI library provides functions for SPI communication:1#include <SPI.h>
In the
setup()
function, initialize the SPI peripheral, define and configure the chip select (SS
) pin:Use SPI.begin() for SPI0 and SPI1.begin() for SPI1.
1void setup() {2 // Set the chip select pin as output3 pinMode(SS, OUTPUT); 4
5 // Pull the CS pin HIGH to unselect the device6 digitalWrite(SS, HIGH); 7 8 // Initialize the SPI communication9 SPI.begin();10}
To transmit data to an SPI-compatible device, you can use the following commands:
1// Replace with the target device's address2byte address = 0x35; 3
4// Replace with the value to send5byte value = 0xFA; 6
7// Pull the CS pin LOW to select the device8digitalWrite(SS, LOW); 9
10// Send the address11SPI.transfer(address); 12
13// Send the value14SPI.transfer(value); 15
16// Pull the CS pin HIGH to unselect the device17digitalWrite(SS, HIGH);
The example code above should output this:
I2C
The Nano Matter supports I2C communication, which enables data transmission between the board and other I2C-compatible devices. The Nano Matter features two I2C interfaces and the pins used in the Nano Matter for the I2C communication protocol are the following:
Microcontroller Pin | Arduino Pin Mapping |
---|---|
PA06 | SDA or A4 |
PA07 | SCL or A5 |
PC07 | SDA1 or D4 |
PC08 | SCL1 or D5 |
Please, refer to the board pinout section of the user manual to localize them on the board.
To use I2C communication, include the
Wire
library at the top of your sketch. The Wire
library provides functions for I2C communication:1#include <Wire.h>
In the
setup()
function, initialize the I2C library:Use Wire.begin() for I2C0 and Wire1.begin() for I2C1.
1// Initialize the I2C communication2Wire.begin();
To transmit data to an I2C-compatible device, you can use the following commands:
1// Replace with the target device's I2C address2byte deviceAddress = 0x35; 3
4// Replace with the appropriate instruction byte5byte instruction = 0x00; 6
7// Replace with the value to send8byte value = 0xFA; 9
10// Begin transmission to the target device11Wire.beginTransmission(deviceAddress); 12
13// Send the instruction byte14Wire.write(instruction); 15
16// Send the value17Wire.write(value); 18
19// End transmission20Wire.endTransmission();
The output data should look like the image below, where we can see the device address data frame:
To read data from an I2C-compatible device, you can use the
requestFrom()
function to request data from the device and the read()
function to read the received bytes:1// The target device's I2C address2byte deviceAddress = 0x1; 3
4// The number of bytes to read5int numBytes = 2; 6
7// Request data from the target device8Wire.requestFrom(deviceAddress, numBytes);9
10// Read while there is data available11while (Wire.available()) {12 byte data = Wire.read(); 13}
UART
The Nano Matter features two UARTs. The pins used in the Nano Matter for the UART communication protocol are the following:
Microcontroller Pin | Arduino Pin Mapping |
---|---|
PA05 | PIN_SERIAL_RX1 or D1 |
PA04 | PIN_SERIAL_TX1 or D0 |
PC05 | PIN_SERIAL_RX (internal) |
PC04 | PIN_SERIAL_TX (internal) |
Please, refer to the board pinout section of the user manual to localize them on the board.
You can not use UART and SPI1 interfaces at the same time because they share pins.
Use Serial.begin() for UART0 (internal) and Serial1.begin() for UART1 (exposed).
To begin with UART communication, you will need to configure it first. In the
setup()
function, set the baud rate (bits per second) for UART communication:1// Start UART communication at 115200 baud2Serial1.begin(115200);
To read incoming data, you can use a
while()
loop to continuously check for available data and read individual characters. The code shown below stores the incoming characters in a String variable and processes the data when a line-ending character is received:1// Variable for storing incoming data2String incoming = ""; 3
4void loop() {5 // Check for available data and read individual characters6 while (Serial1.available()) {7 // Allow data buffering and read a single character8 delay(2); 9 char c = Serial1.read();10 11 // Check if the character is a newline (line-ending)12 if (c == '\n') {13 // Process the received data14 processData(incoming);15
16 // Clear the incoming data string for the next message17 incoming = ""; 18 } else {19 // Add the character to the incoming data string20 incoming += c; 21 }22 }23}
To transmit data to another device via UART, you can use the
write()
function:1// Transmit the string "Hello world!2Serial1.write("Hello world!");
You can also use the
print
and println()
to send a string without a newline character or followed by a newline character:1// Transmit the string "Hello world!" 2Serial1.print("Hello world!");3
4// Transmit the string "Hello world!" followed by a newline character5Serial1.println("Hello world!");
Support
If you encounter any issues or have questions while working with the Nano Matter, we provide various support resources to help you find answers and solutions.
Help Center
Explore our Help Center, which offers a comprehensive collection of articles and guides for the Nano Matter. The Arduino Help Center is designed to provide in-depth technical assistance and help you make the most of your device.
Forum
Join our community forum to connect with other Nano Matter 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 Nano Matter.
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're happy to help you with any issues or inquiries about the Nano Matter.
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.