Skip to content

Matter Over Thread on ESP 32 C6 #11820

@SuGlider

Description

@SuGlider

Discussed in #11777

Originally posted by adm1nsys August 29, 2025
Hello to everyone! Is it possible to run Matter Over Thread no WiFi in Arduno IDE?
I made code which enable BLE first setup and then it's Matter Over WiFi. It's like mix mode. Can I make Matter Over Thread?

#define CONFIG_ENABLE_CHIPOBLE 1 
#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1
#define CHIP_DEVICE_CONFIG_ENABLE_WIFI 0 

#include <Matter.h>
#include <Preferences.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/ConnectivityManager.h>
using namespace chip::DeviceLayer;
#include "esp_mac.h"

// Matter endpoint: On/Off Light
MatterOnOffLight OnOffLight;
Preferences matterPref;

#ifndef LED_BUILTIN
#  define LED_BUILTIN 2
#endif
const uint8_t ledPin    = LED_BUILTIN;
const uint8_t buttonPin = BOOT_PIN;   // BOOT 

const char *nsName = "MatterPrefs";
const char *onOffKey = "OnOff";

uint32_t btn_ts = 0;
bool btn_down = false;
const uint32_t debounceMs = 250;
const uint32_t decommissionHoldMs = 5000;

bool setLightOnOff(bool state) {
  digitalWrite(ledPin, state ? HIGH : LOW);
  matterPref.putBool(onOffKey, state);
  return true;
}

void printMacs() {
  uint8_t mac[6];
  esp_read_mac(mac, ESP_MAC_WIFI_STA);
  Serial.printf("WiFi STA MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
                mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
  esp_read_mac(mac, ESP_MAC_WIFI_SOFTAP);
  Serial.printf("WiFi AP  MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
                mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled);
  ConnectivityMgr().ClearWiFiStationProvision();
  printMacs();
  matterPref.begin(nsName, false);
  bool last = matterPref.getBool(onOffKey, true);
  OnOffLight.begin(last);
  OnOffLight.onChange(setLightOnOff);

  Matter.begin();

  if (!Matter.isDeviceCommissioned()) {
    Serial.println("\n=== Matter over Thread (BLE commissioning) ===");
    Serial.printf("Manual pairing code: %s\n", Matter.getManualPairingCode().c_str());
    Serial.printf("QR code URL:        %s\n", Matter.getOnboardingQRCodeUrl().c_str());
  } else {
    Serial.printf("Resumed. Initial state: %s\n", OnOffLight.getOnOff() ? "ON" : "OFF");
    OnOffLight.updateAccessory();
  }
}

void loop() {
  static uint32_t lastNote = 0;
  if (!Matter.isDeviceCommissioned() && millis() - lastNote > 5000) {
    Serial.println("Waiting for commissioning…");
    lastNote = millis();
  }

  if (digitalRead(buttonPin) == LOW && !btn_down) {
    btn_down = true;
    btn_ts = millis();
  }
  uint32_t dt = millis() - btn_ts;
  if (btn_down && dt > debounceMs && digitalRead(buttonPin) == HIGH) {
    btn_down = false;
    OnOffLight.toggle();
  }
  if (btn_down && dt > decommissionHoldMs) {
    Serial.println("Decommissioning…");
    OnOffLight.setOnOff(false);
    Matter.decommission();
    btn_ts = millis();
  }
}

ESP32-C6: OpenThread init fails in Arduino Core 3.3.0 (IDF 5.5) due to missing eventfd/select in core build

Repro (ESP32-C6, Arduino Core 3.3.0 / IDF 5.5):

  • Boards Manager: Zigbee Mode = Off

  • build_opt.h:

    -DCHIP_DEVICE_CONFIG_ENABLE_WIFI=0
    -DCHIP_DEVICE_CONFIG_SOC_WIFI_SUPPORTED=0
    -DCHIP_DEVICE_CONFIG_ENABLE_THREAD=1
    -DCONFIG_ENABLE_CHIPOBLE=1
    -DINET_CONFIG_ENABLE_IPV4=0
    -DINET_CONFIG_ENABLE_IPV6=1
    
  • Core compile flags (.../esp32c6/flags/defines) include:

    -DOPENTHREAD_FTD=1
    -DOPENTHREAD_CONFIG_FILE="openthread-core-esp32x-ftd-config.h"
    

    but do not include:

    -DCONFIG_VFS_SUPPORT_SELECT=1
    -DCONFIG_ESP_EVENTFD=1
    

Runtime:

E (xxxx) OPENTHREAD: esp_openthread_task_queue_init(...): Failed to create OpenThread task queue event fd
E (xxxx) OPENTHREAD: esp_openthread_platform_init(...): esp_openthread_task_queue_init failed
assert failed: modem_clock_device_disable modem_clock.c:236 (refs >= 0)

Hypothesis / root cause:
OpenThread port on ESP requires eventfd + select() (i.e., esp_vfs_eventfd_register()) before OT init. The current Arduino core for ESP32-C6 appears to be built without CONFIG_VFS_SUPPORT_SELECT and CONFIG_ESP_EVENTFD, so OT init fails and the cleanup path trips the modem clock refcount assert.

Request:
Please provide a C6/H2 core build with the following Kconfig options enabled (preview/nightly is fine). I can test binaries immediately.

# 802.15.4 + OpenThread
CONFIG_IEEE802154_ENABLED=y
CONFIG_OPENTHREAD_ENABLED=y
CONFIG_OPENTHREAD_RADIO_NATIVE=y
CONFIG_OPENTHREAD_FTD=y          # (or MTD if preferred)

# VFS / eventfd (fixes the crash)
CONFIG_VFS_SUPPORT_SELECT=y
CONFIG_ESP_EVENTFD=y

# Network for Matter over Thread
CONFIG_LWIP_IPV6=y
CONFIG_LWIP_IPV4=n

# Matter / CHIP
CONFIG_ENABLE_MATTER_OVER_THREAD=y
CONFIG_ENABLE_CHIPOBLE=y

# Disable radio competitors in this build
CONFIG_ZB_ENABLED=n
CONFIG_WIFI_ENABLED=n

Notes:

  • The presence of -DOPENTHREAD_FTD=1 in flags/defines shows OT libs are linked, but without eventfd/select the platform init cannot create the task queue FD.
  • Target: ESP32-C6 (Thread via native 802.15.4), BLE on, Wi-Fi off, IPv6-only.
  • Happy to validate a preview Boards Manager package or drop-in esp32-arduino-libs archive.

Metadata

Metadata

Assignees

Labels

Area: MatterIssues and Feature Request about Matter ProtocolType: Feature requestFeature request for Arduino ESP32

Projects

Status

Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions