Configure the Arduino Nano Matter as Matter Sleepy End Device (SED)?

Hi everyone,

I’m working with the Arduino Nano Matter board and the Arduino Matter SDK. By default, the examples and setup configure the device as a Matter bridge (in Home Assistant), but I need to set it up as a Sleepy End Device (SED). This device will be in deep sleep frequently so I don’t want my Matter/Thread mesh to assume that this device can route traffic.

I’ve been searching through the documentation but haven’t found clear instructions on how to modify the configuration from bridge to SED. Has anyone successfully configured their Nano Matter to operate as a Matter Sleepy End Device using the Arduino Matter SDK?

Specifically, I’m looking for:

  • Steps to modify the device configuration from bridge to SED
  • Sample code or examples would be greatly appreciated

Thank you in advance for any help or guidance!

Best regards,
Francois

1 Like

arduino/libraries/ArduinoLowPower/examples at c51e6c01f2e90f46d08e6d530a015531050cc42c · SiliconLabs/arduino

This might help, I was able to add in deep sleep mode / sleep mode in my projects. Not sure if there is examples so far to convert the device from bridge to SED. I know that Eve does that to their device but this device is not connected over matter.
Personally, I think that matter over thread requires your device to be part of the network and route the traffic.

Thank you! I'll give your examples a try.

Did you get this to work? I’m looking at the same requirement. I’m building a temp/humidity sensor and I’d really like it to sleep for 5 seconds, then wake up to send the readings, and then go back to sleep.

Not yet. I don't anticipate having the time for at least two to three weeks. Please let me know if you find a solution. Good luck!

Yes. I got it to work. I have a nano matter on battery running for the last 2 weeks , it is connected to a temperature sensor and I am tracking the battery usage. Deep sleep works well with thread.

Amazing! Do you mind sharing your sketch?

I'd be interested to see the sketch too. Deepsleep runs the code from the start everytime so I'm interested if you coded to account for that. As you don't need the loop section.

From what I understand from that git repo. There is 128 bytes of memory that is saved to run a nano matter board on deep sleep. Everything else is turned off.

Yes , deep sleep basically turns off the board from all it's peripherals but once it is set into the matter fabric it doesn't have to be recommissioned to the system. Since it needs to run the sensor data capture every time it wakes up there shouldn't be any use for the loop if that's what you meant.

Thanks. Yes that's what I wondered.

/*
Created by Rohit Avadhani
Deep sleep mode with memory wakeup
use the button to wakeup the board when needed. 

Havent tried to decommision the board yet on a deep sleep mode ( works well in normal mode and sleep modes)
but included the function in the code. 

refer to arduino documentation for decommissioning nano matter

using flow module from matter to record battery level , its lame but i am working on it
*/
#include <Matter.h>
#include <MatterTemperature.h>
#include <MatterFlow.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "ArduinoLowPower.h"

#define ONE_WIRE_BUS 4 // Temperature sensor
#define hall_effect_sensor_pin A4 // flow rate
#define battery_level_pin A6 // Battery level
#define WAKE_UP_PIN BTN_BUILTIN  // Used for both decommission and wake-up

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

MatterTemperature matter_temp_sensor1;
MatterFlow matter_flow_sensor;
MatterFlow battery_level_sensor;

void setup() {
  Serial.begin(115200);
  pinMode(WAKE_UP_PIN, INPUT_PULLUP);
  pinMode(LEDR, OUTPUT);
  digitalWrite(LEDR, HIGH);


  LowPower.attachInterruptWakeup(WAKE_UP_PIN, nullptr, FALLING); 

  if (LowPower.wokeUpFromDeepSleep()) {
    Serial.println("Woke up from deep sleep");
  } else {
    Serial.println("Cold boot: resetting sleep memory");
    LowPower.deepSleepMemoryWrite(0, 0);
  }

  Matter.begin();
  battery_level_sensor.begin();
  matter_temp_sensor1.begin();
  matter_flow_sensor.begin();

  Serial.println("Matter temperature + flow sensor");

  if (!Matter.isDeviceCommissioned()) {
    Serial.println("Matter device is not commissioned");
    Serial.printf("Manual pairing code: %s\n", Matter.getManualPairingCode().c_str());
    Serial.printf("QR code URL: %s\n", Matter.getOnboardingQRCodeUrl().c_str());
  }
 

  while (!Matter.isDeviceCommissioned()) {
    delay(200);
    decommission_handler();
  }

  Serial.println("Waiting for Thread network...");
  while (!Matter.isDeviceThreadConnected()) {
    delay(200);
    decommission_handler();
  }

  Serial.println("Connected to Thread network");
  Serial.println("Waiting for Matter device discovery...");
  while (!matter_temp_sensor1.is_online() || !matter_flow_sensor.is_online()) {
    delay(200);
    decommission_handler();
  }

  Serial.println("Matter device is now online");
  sensors.begin();
}

void loop() {
  decommission_handler();

  float temp1 = readSimulatedTempC1();
  double current_flow = readSimulatedFlowCChr();
  double battery_level = readBatteryLevel();

  battery_level_sensor.set_measured_value_raw(battery_level);
  matter_temp_sensor1.set_measured_value_celsius(temp1);
  matter_flow_sensor.set_measured_value_cubic_meters_per_hour(current_flow);

  uint32_t cycles = LowPower.deepSleepMemoryRead(0);
  Serial.printf("Sleep cycles: %lu\n", cycles);
  LowPower.deepSleepMemoryWrite(0, ++cycles);

  Serial.println("Entering deep sleep for 60s...");
  LowPower.deepSleep(60000);
}

float readSimulatedTempC1() {
  sensors.requestTemperatures();
  float tempC = sensors.getTempCByIndex(0);
  Serial.printf("Temp: %.2f°C\n", tempC);
  return tempC;
}

double readSimulatedFlowCChr() {
  return analogRead(hall_effect_sensor_pin);
}

double readBatteryLevel() {
  return analogRead(battery_level_pin);
}

void decommission_handler() {
  if (digitalRead(WAKE_UP_PIN) == LOW) {
    int startTime = millis();
    while (digitalRead(WAKE_UP_PIN) == LOW) {
      int elapsedTime = (millis() - startTime) / 1000;
      if (elapsedTime > 10) {
        Serial.println("Decommissioning!");
        for (int i = 0; i < 10; i++) {
          digitalWrite(LEDR, !digitalRead(LEDR));
          delay(100);
        }

        if (!Matter.isDeviceCommissioned()) {
          Serial.println("Decommission done!");
        } else {
          Serial.println("Matter device is commissioned -> Starting Decommission");
          nvm3_eraseAll(nvm3_defaultHandle);
          Serial.println("Decommission done!");
        }

        digitalWrite(LEDR, LOW);
        break;
      }
    }
  }
}

I used deep sleep here in a loop. Nothing special

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.