Skip to content

Esp32 with W5500 lost matter Connection after poweroff #11621

@giulioto

Description

@giulioto

Board

esp32-wroom32ue

Device Description

devkitc

Hardware Configuration

spi
cs 15
irq 4
rst 5
sck 14
miso 12
mosi 13

Version

latest stable Release (if not listed below)

IDE Name

Arduino

Operating System

Windows, Linux

Flash frequency

80 MHz

PSRAM enabled

no

Upload speed

921600

Description

Hi,
i'm using W5500 with esp32 (arduino ethernet library) and matter library on my iot device.
The commissioning with Home Assistant is ok, i can manage my device normally.
Also after poweroff-poweron for a few seconds the device is available on Home Assistant.
But if i poweroff the device for over 2 minutes and Home Assistant detect the device as unavailable, after poweron the device don't reconnect to Home Assistant. I must decommission and recommission the device if i want to see it on Home Assistant.
From Home Assistant, the device responds to ping even if it is not visible via matter.
If i use wifi instead W5500 ethernet shield, the device reconnect normally and the problem does not occur.
Does anyone know of any bugs on the w5500 and Matter?
Thanks

Sketch

#include <ETH.h>
#include <SPI.h>
// Matter Manager
#include <Matter.h>
#include <Preferences.h>

// Set this to 1 to enable dual Ethernet support
#define USE_TWO_ETH_PORTS 0

#ifndef ETH_PHY_CS
  #define ETH_PHY_TYPE ETH_PHY_W5500
  #define ETH_PHY_ADDR 1
  #define ETH_PHY_CS   15
  #define ETH_PHY_IRQ  4
  #define ETH_PHY_RST  5
#endif

// SPI pins
#define ETH_SPI_SCK  14
#define ETH_SPI_MISO 12
#define ETH_SPI_MOSI 13

#if USE_TWO_ETH_PORTS
  // Second port on shared SPI bus
  #ifndef ETH1_PHY_CS
  #define ETH1_PHY_TYPE ETH_PHY_W5500
  #define ETH1_PHY_ADDR 1
  #define ETH1_PHY_CS   32
  #define ETH1_PHY_IRQ  33
  #define ETH1_PHY_RST  18
  #endif
  ETHClass ETH1(1);
#endif

static bool eth_connected = false;

void onEvent(arduino_event_id_t event, arduino_event_info_t info) {
  switch (event) {
    case ARDUINO_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-eth0");
      break;
    case ARDUINO_EVENT_ETH_CONNECTED: Serial.println("ETH Connected - wait for IP..."); break;
    case ARDUINO_EVENT_ETH_GOT_IP:    Serial.printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif)); Serial.println(ETH);
#if USE_TWO_ETH_PORTS
      Serial.println(ETH1);
#endif
      eth_connected = true;
      break;
    case ARDUINO_EVENT_ETH_LOST_IP:
      Serial.println("ETH Lost IP");
      eth_connected = false;
      break;
    case ARDUINO_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case ARDUINO_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default: break;
  }
}

// List of Matter Endpoints for this Node
// On/Off Light Endpoint
MatterOnOffLight OnOffLight;

// it will keep last OnOff state stored, using Preferences
Preferences matterPref;
const char *onOffPrefKey = "OnOff";

// set your board LED pin here
#ifdef LED_BUILTIN
const uint8_t ledPin = LED_BUILTIN;
#else
const uint8_t ledPin = 17;  // Set your pin here if your board has not defined LED_BUILTIN
#warning "Do not forget to set the LED pin"
#endif

// set your board USER BUTTON pin here
const uint8_t buttonPin = 25;  // Set your pin here. Using BOOT Button.

// Button control
uint32_t button_time_stamp = 0;                // debouncing control
bool button_state = false;                     // false = released | true = pressed
const uint32_t debouceTime = 250;              // button debouncing time (ms)
const uint32_t decommissioningTimeout = 5000;  // keep the button pressed for 5s, or longer, to decommission

// Matter Protocol Endpoint Callback
bool setLightOnOff(bool state) {
  Serial.printf("User Callback :: New Light State = %s\r\n", state ? "ON" : "OFF");
  if (state) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
  // store last OnOff state for when the Light is restarted / power goes off
  matterPref.putBool(onOffPrefKey, state);
  // This callback must return the success state to Matter core
  return true;
}

void setup() {
  // Initialize the USER BUTTON (Boot button) GPIO that will act as a toggle switch
  pinMode(buttonPin, INPUT_PULLUP);
  // Initialize the LED (light) GPIO and Matter End Point
  pinMode(ledPin, OUTPUT);

  Serial.begin(115200);

  Network.onEvent(onEvent);

// *************************
  ETH.enableIPv6(true);
// ***********************

  SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);

  // ********** ENABLE IPV6 TO RECONNECT COMMISSIONED DEVICE AFTER REBOOT *************
  ETH.enableIPv6(true);
  // **********************************************************************************

  ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, SPI);
#if USE_TWO_ETH_PORTS
  ETH1.begin(ETH1_PHY_TYPE, ETH1_PHY_ADDR, ETH1_PHY_CS, ETH1_PHY_IRQ, ETH1_PHY_RST, SPI);
#endif

while( !eth_connected ) {
  Serial.println(" === WAIT UNTIL ETHERNET IS CONNECTED ===");
  delay(1000);
}
  delay(2000);
  Serial.println( "local IPv6:" );
  Serial.println( ETH.linkLocalIPv6() );
  Serial.println( "MAC address:" );
  Serial.println( ETH.macAddress() );

  // Initialize Matter EndPoint
  matterPref.begin("MatterPrefs", false);
  bool lastOnOffState = matterPref.getBool(onOffPrefKey, true);
  OnOffLight.begin(lastOnOffState);
  OnOffLight.onChange(setLightOnOff);

  // Matter beginning - Last step, after all EndPoints are initialized
  Matter.begin();

  // This may be a restart of a already commissioned Matter accessory
  if (Matter.isDeviceCommissioned()) {
    Serial.println("Matter Node is commissioned and connected to network. Ready for use.");
    Serial.printf("Initial state: %s\r\n", OnOffLight.getOnOff() ? "ON" : "OFF");
    OnOffLight.updateAccessory();  // configure the Light based on initial state
  }

}

void loop() {

if( eth_connected ) {
    // Check Matter Light Commissioning state, which may change during execution of loop()
    if (!Matter.isDeviceCommissioned()) {
      Serial.println("");
      Serial.println("Matter Node is not commissioned yet.");
      Serial.println("Initiate the device discovery in your Matter environment.");
      Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
      Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
      Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
      // waits for Matter Light Commissioning.
      uint32_t timeCount = 0;
      while (!Matter.isDeviceCommissioned()) {
        delay(100);
        if ((timeCount++ % 50) == 0) {  // 50*100ms = 5 sec
          Serial.println("Matter Node not commissioned yet. Waiting for commissioning.");
        }
      }
      Serial.printf("Initial state: %s\r\n", OnOffLight.getOnOff() ? "ON" : "OFF");
      OnOffLight.updateAccessory();  // configure the Light based on initial state
      Serial.println("Matter Node is commissioned and connected to network. Ready for use.");
    }
}
  // A button is also used to control the light
  // Check if the button has been pressed
  if (digitalRead(buttonPin) == LOW && !button_state) {
    // deals with button debouncing
    button_time_stamp = millis();  // record the time while the button is pressed.
    button_state = true;           // pressed.
  }

  // Onboard User Button is used as a Light toggle switch or to decommission it
  uint32_t time_diff = millis() - button_time_stamp;
  if (button_state && time_diff > debouceTime && digitalRead(buttonPin) == HIGH) {
    button_state = false;  // released
    // Toggle button is released - toggle the light
    Serial.println("User button released. Toggling Light!");
    OnOffLight.toggle();  // Matter Controller also can see the change
  }

  // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node
  if (button_state && time_diff > decommissioningTimeout) {
    Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again.");
    OnOffLight.setOnOff(false);  // turn the light off
    Matter.decommission();
    button_time_stamp = millis();  // avoid running decommissining again, reboot takes a second or so
  }

}

Debug Message

=== WAIT UNTIL ETHERNET IS CONNECTED ===
ETH Connected - wait for IP...
 === WAIT UNTIL ETHERNET IS CONNECTED ===
 === WAIT UNTIL ETHERNET IS CONNECTED ===
 === WAIT UNTIL ETHERNET IS CONNECTED ===
 === WAIT UNTIL ETHERNET IS CONNECTED ===
 === WAIT UNTIL ETHERNET IS CONNECTED ===
ETH Got IP: 'eth0'
*eth0: <UP,100M,FULL_DUPLEX,AUTO,ADDR:0x1> (DHCPC,GARP,IP_MOD)
      ether 16:2B:2F:DB:CF:14
      inet 192.168.1.73 netmask 255.255.255.0 broadcast 192.168.1.255
      gateway 192.168.1.254 dns 192.168.1.254
      inet6 fe80::142b:2fff:fedb:cf14%en1 type LINK_LOCAL
      inet6 2001:b07:2ee:8baf:142b:2fff:fedb:cf14 type GLOBAL

local IPv6:
fe80::142b:2fff:fedb:cf14
MAC address:
16:2B:2F:DB:CF:14
[ 10111][I][MatterOnOffLight.cpp:81] begin(): On-Off Light created with endpoint_id 1
Matter Node is commissioned and connected to network. Ready for use.
Initial state: OFF
User Callback :: New Light State = OFF

Other Steps to Reproduce

Even if the device seems to be commissioned, it is not available on Home Assistant and does not respond.
If i use WiFi instead of W5500 ethernet shield, everything works fine

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions