Matter
About
The Matter library provides support for creating Matter-compatible devices including:
Support for Wi-Fi, Thread, and Ethernet connectivity
Matter commissioning via QR code or manual pairing code
Multiple endpoint types for various device categories
Semantic tags (Descriptor cluster TagList) via
MatterEndPoint::setTagList()to disambiguate sibling endpointsEvent monitoring and callback support
Integration with Home Assistant, Apple Home, Amazon Alexa, and Google Home
Smart home ecosystem compatibility
The Matter library is built on top of ESP Matter SDK and provides a high-level Arduino-style interface for creating Matter devices.
Building and Flashing Matter Examples
Before uploading any Matter example sketch, it is necessary to configure the Arduino IDE with the following settings:
Partition Scheme: Select “Huge APP (3 MB No OTA / 1 MB SPIFFS)” from Tools > Partition Scheme menu.
Erase Flash: Enable “Erase All Flash Before Sketch Upload” option from Tools menu.
These settings are required for the following reasons:
Partition Scheme: Matter firmware requires a large application partition (3 MB) to accommodate the Matter stack and application code.
Erase Flash: Erasing flash is necessary to remove any leftover Wi-Fi or Matter configuration from the NVS (Non-Volatile Storage) partition. Without erasing, previous network credentials, Matter fabric information, or device commissioning data may interfere with the new firmware, causing commissioning failures or connectivity issues.
On a ESP32 SoC that has PSRAM and PSRAM is enabled and initialized (SPIRAM heap present), the Matter data model (endpoints, clusters, attributes) is placed in PSRAM. ESP.getFreeHeap() can stay flat while ESP.getFreePsram() drops as endpoints are created; that is expected. CHIP, AES DMA bounce buffers, and NimBLE still use internal malloc / DMA. Without a SPIRAM heap the data model stays in internal RAM.
Matter Protocol Overview
Matter (formerly Project CHIP - Connected Home over IP) is an open-source connectivity standard for smart home devices. It enables seamless communication between devices from different manufacturers, allowing them to work together within a single ecosystem.
Key Features:
Multi-Protocol Support: Works over Wi-Fi, Thread, and Ethernet
Interoperability: Devices from different manufacturers work together
Security: Built-in security features including encryption and authentication
Local Control: Devices can communicate locally without requiring cloud connectivity
Simple Setup: Easy commissioning via QR code or pairing code
Matter Network Topology
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Matter hub │◄─────►│ Wi-Fi Router │◄─────►│ ESP Thread │
│ │ │ │ │ Border Router │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Matter Device │ │
│ │ (via Wi-Fi) │ │
│ └─────────────────┘ │
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Matter Device │ │ Matter Device │
│ (via Wi-Fi) │ │ (via Thread) │
└─────────────────┘ └─────────────────┘
Network Interfaces:
Wi-Fi: High-bandwidth connection for devices that require constant power
Thread: Low-power mesh networking for battery-operated devices
Ethernet: Wired connection for stationary devices
Matter Library Structure
The library is split into these components:
Matter: The main class that manages the Matter network and device commissioningMatterEndPoint: The base class for all Matter endpoints, which provides common functionality for all endpoint typesSpecific endpoint classes: The classes for all Matter endpoints, which provides the specific functionality for each endpoint typeSketch helpers (
MatterHelpers.h,MatterButton.h, included byMatter.h): Commissioning wait, fabric-loss reboot, and board-button events. Not members ofMatter
Matter
The Matter class is the main entry point for all Matter operations. It serves as the central manager that handles:
Device Commissioning: Managing the commissioning process via QR code or manual pairing code
Network Connectivity: Checking and managing Wi-Fi and Thread connections
Event Handling: Monitoring Matter events and device state changes
Device Management: Decommissioning and factory reset functionality
The Matter class is implemented as a singleton, meaning there’s only one instance available globally. You access it directly as Matter without creating an instance.
The Matter class provides the following key methods:
begin(): Initializes the Matter stack. On Wi-Fi station builds, starts the Wi-Fi driver first with reduced RX/TX buffers (4 static RX, 8 dynamic RX, 8 dynamic TX, AMPDU RX BA window 6) so CHIP inherits those counts, unless Thread or Ethernet was selected. Skipped if the sketch already calledmatterConnectWiFi()/WiFi.begin()/WiFi.mode().isDeviceCommissioned(): Checks if the device is commissioned (a fabric exists)isWiFiConnected(): Checks Wi-Fi connection statusisThreadConnected(): Checks Thread connection statusisDeviceConnected(): Checks overall device connectivity (Wi-Fi, Thread, or Ethernet IPv6)isEthernetEnabled():CONFIG_ETH_ENABLED— ETH library builds; not “cable present”isNetworkSupported(net): Same compile-time check as the matchingis*Enabled().MATTER_NETWORK_NONEis falseselectNetwork(): Records intent before any accessorybegin(). Does not start Wi-Fi, Thread, or Ethernet, and does not apply a Thread dataset. One-argument form: Ethernet disables CHIPoBLE; Wi-Fi and Thread leave it on.selectNetwork(net, true)turns CHIPoBLE off;falsedoes not turn it back on.NONEclears intent and does not change BLEgetSelectedNetwork(): Last successfulselectNetwork(), orNONEgetActiveNetwork(): First netif with IPv6 (prefers the selection). NotisWiFiConnected()/isThreadConnected()getNetworkEndPointId(): Expected Network Commissioning endpoint on the root (0 Wi-Fi, 0 Thread when Thread is on the root,0xFFFFif none). ESP32-C6 is Wi-Fi or Thread, not both. Valid before the endpoint is createdwaitForNetwork(): Blocks until that IPv6 is present.MATTER_NETWORK_NONEwaits for any interface. Does not start hardware.timeoutMs0 is a single checkisOnline(): Checks if a controller has an active CASE session with this node. Stays true until CHIP idle-evicts that session, not until the user closes a controller app.isWiFiStationEnabled(): Checks if Wi-Fi Station mode is supported and enabledisWiFiAccessPointEnabled(): Checks if Wi-Fi AP mode is supported and enabledisThreadEnabled():CONFIG_ENABLE_MATTER_OVER_THREAD(ESP32-C6 / ESP32-H2; ESP32-C5 when Tools → Matter Network → Thread). Not “OpenThread is compiled in”isBLECommissioningEnabled(): Checks if BLE commissioning is compiled in and still enabled (seesetBLECommissioningEnabled())setBLECommissioningEnabled(): Enables or disables CHIPoBLE. Call beforeMatter.begin(). Commissioning sketches useselectNetwork(net, true)instead of this setter.falseis only when you keep the default network and just want BLE off (connect Wi-Fi or Ethernet first). This call only stores the flag; BLE RAM is released afterMatter.begin(), not at the settersetBLEMemoryReleaseEnabled(): After CHIPoBLE commissioning, release BLE RAM (defaulttrue). Call beforeMatter.begin(). Only takes effect whenCONFIG_ENABLE_CHIPOBLEis set and CHIPoBLE commissioning is enabled. No effect when CHIPoBLE is compiled out. Arduino-as-IDF-component builds that keep BLE must also setCONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=nisBLEMemoryReleaseEnabled():truewhen CHIPoBLE is on and BLE RAM will be released after commissioningdecommission(): Factory resets the devicegetManualPairingCode(): Gets the manual pairing code for commissioning (generated afterbegin(); empty and a warning beforebegin())getOnboardingQRCodeUrl(): Gets the QR code URL for commissioning (generated afterbegin(); empty and a warning beforebegin())onEvent(): Sets a callback for Matter events. TheChipDeviceEventpointer is only valid during the callback; do not store itonBLEMemoryReleased(): Called when CHIPoBLE BLE RAM has been returned to the heap (same moment asMATTER_BLE_DEINITIALIZED). Register beforeMatter.begin(). Runs on the CHIP task: do not block; allocate large buffers fromloop(). May never run if CHIPoBLE is off orsetBLEMemoryReleaseEnabled(false)
Commissioning wait, fabric-loss reboot, and the board button are sketch helpers (MatterHelpers.h), not Matter methods. #include <Matter.h> pulls them in. See Sketch helpers.
Warning
A Matter sketch owns the CHIPoBLE host (NimBLE when that stack is selected). Do not use the Arduino BLE library (BLE.h / BLEDevice) in the same sketch. After Matter starts CHIPoBLE — or after it disables CHIPoBLE and releases BLE RAM, or after CHIPoBLE commissioning with setBLEMemoryReleaseEnabled(true) (the default) — BLEDevice::init() will fail or crash. setBLECommissioningEnabled(false) does not free the radio for Arduino BLE.
CHIPoBLE and NimBLE
Matter BLE commissioning is CHIPoBLE. The Arduino Matter APIs follow CONFIG_ENABLE_CHIPOBLE at build time, not a hardcoded SoC list.
CHIPoBLE (
CONFIG_ENABLE_CHIPOBLE): CHIP compiles the BLE commissioning layer andBLEMgr(). ArduinoisBLECommissioningEnabled()can be true only in this build.NimBLE (
CONFIG_BT_NIMBLE_ENABLED): ESP-Matter selects the NimBLEBLEManagerImpl(host + controller). This is the stack used for CHIPoBLE RAM reclaim afterBLEMgr().Shutdown().Bluetooth (
CONFIG_BT_ENABLED): If Bluetooth is off in sdkconfig, CHIP disables CHIPoBLE. The Arduino setters remain in the API and returnfalse/ no-op as documented.
Arduino IDE (precompiled Matter libraries) follow the sdkconfig of each Matter static library. Columns below are those Kconfig flags, not silicon capability.
SoC |
Default network |
Matter-over-Thread |
Ethernet |
CHIPoBLE (NimBLE) |
Notes |
|---|---|---|---|---|---|
ESP32 |
Wi-Fi |
No |
Yes |
No (Bluedroid) |
EMAC or SPI PHY |
ESP32-S2 |
Wi-Fi |
No |
SPI PHY |
No (no Bluetooth) |
On-network Wi-Fi |
ESP32-S3 |
Wi-Fi |
No |
SPI PHY |
Yes |
|
ESP32-C3 |
Wi-Fi |
No |
SPI PHY |
Yes |
|
ESP32-C5 |
Wi-Fi (menu default) |
Yes (Matter Network / Thread) |
SPI PHY |
Yes |
Two Matter .a |
ESP32-C6 |
Wi-Fi until |
Yes (one NC on endpoint 0) |
SPI PHY |
Yes |
|
ESP32-H2 |
Thread |
Yes |
SPI PHY |
Yes |
No Wi-Fi |
CONFIG_ENABLE_CHIPOBLE is off on original ESP32 and ESP32-S2. Those targets must not use CHIPoBLE sketches; setBLECommissioningEnabled(true) fails. Use MatterOnNetworkWiFi (or Ethernet). Example sketches that #if !CONFIG_ENABLE_CHIPOBLE call matterConnectWiFi() match this. Ethernet commissioning is always on-network: Matter.selectNetwork(MATTER_NETWORK_ETHERNET) turns CHIPoBLE off. Wi-Fi and Thread leave CHIPoBLE on when it is compiled in; Matter.selectNetwork(net, true) turns it off.
Ethernet is available on every Arduino Matter SoC when you attach a PHY. SPI modules (W5500, DM9051, KSZ8851SNL) work on all of them — tested with original ESP32 + W5500. Internal RMII EMAC is original ESP32 only. There is no Ethernet Network Commissioning cluster; the sketch must ETH.begin(), enableIPv6(), and Matter.waitForNetwork() before Matter.begin(). See MatterOnNetworkEthernet.
Arduino as an ESP-IDF component: You choose the stacks in sdkconfig. Original ESP32 can run CHIPoBLE if you set CONFIG_BT_ENABLED=y, CONFIG_BT_NIMBLE_ENABLED=y, and CONFIG_ENABLE_CHIPOBLE=y. The same sketch then uses BLE commissioning (no hardcoded Wi-Fi) because it keys off CONFIG_ENABLE_CHIPOBLE. To keep NimBLE after commissioning, also set CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n and call Matter.setBLEMemoryReleaseEnabled(false) before Matter.begin().
Waiting for BLE RAM
BLEMgr().Shutdown() is asynchronous. Heap at Matter.begin() or at MATTER_COMMISSIONING_COMPLETE is not the post-reclaim size. Shutdown() only deinitializes the CHIPoBLE host; it does not return the RAM. CHIP reclaims it in BLEManagerImpl::ClaimBLEMemory(), which it compiles in only when CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING is set — off in the precompiled Arduino libraries — and which has no release branch for every SoC even then. The Arduino Matter library therefore performs the reclaim itself: it waits for the NimBLE host task to exit, releases the BLE regions to the heap, then posts kBLEDeinitialized. Both onBLEMemoryReleased() and MATTER_BLE_DEINITIALIZED fire from that event, exactly once, whichever path did the work.
Reclaim is not instant. Releasing the BLE regions while the NimBLE host task still runs would corrupt the heap, so the library polls for that task to exit every 2 seconds for up to 30 seconds. If the host never exits it logs an error and the callback does not run.
To return BLE RAM before setup() (so accessory begin() already sees it), provide a strong C bleInUse() that returns false. A C++ bool bleInUse() is mangled and does not override the HAL. That path is on-network only: still call selectNetwork(net, true) and connect Wi-Fi or Ethernet first. See MatterEarlyBLERelease (mode 1). On CHIPoBLE prebuilds the Matter .a may still start NimBLE in Matter.begin(); onBLEMemoryReleased() then means teardown after begin().
Register Matter.onBLEMemoryReleased() before Matter.begin(). Use it to set a flag; allocate a large buffer from loop():
volatile bool bleRamFree = false;
void setup() {
Matter.onBLEMemoryReleased([]() { bleRamFree = true; });
Light.begin();
Matter.begin();
}
void loop() {
static uint8_t *buf = nullptr;
if (bleRamFree && buf == nullptr) {
bleRamFree = false;
buf = (uint8_t *)malloc(16 * 1024);
}
}
The callback may never run (no CHIPoBLE, setBLEMemoryReleaseEnabled(false), or a reclaim that timed out). Do not wait forever. onEvent() still delivers MATTER_BLE_DEINITIALIZED if you need other Matter events in the same sketch. See MatterCHIPoBLERelease.
Device identity
Call these setters before Matter.begin(). After begin() they log a warning and have no effect. String setters copy into internal storage; the argument does not need to remain valid. setDeviceName() writes Basic Information NodeLabel. Do not change Vendor ID / Product ID from a sketch unless the DAC matches. SoftwareVersion is compile-time CHIP configuration.
Matter.setVendorName("Espressif"); // max 32
Matter.setProductName("KitchenLight"); // max 32
Matter.setDeviceName("KitchenHub"); // NodeLabel, max 32
Matter.setSerialNumber("KH-000123"); // max 32
Matter.setHardwareVersion(7);
Matter.setHardwareVersionString("RevA"); // max 64
Matter.setSetupDiscriminator(0xF01); // 0–0xFFF; Arduino test default 0xF00
Matter.setSetupPasscode(20202024); // valid PIN; test default 20202021
// Prefer selectNetwork(MATTER_NETWORK_WIFI or MATTER_NETWORK_THREAD, true) to pick a transport and turn CHIPoBLE off.
// setBLECommissioningEnabled(false) only if you keep the default network and just want BLE off.
Matter.setBLECommissioningEnabled(false);
// Matter.setBLEMemoryReleaseEnabled(false); // only if CHIPoBLE is left on: keep NimBLE after commission
Light.begin();
Matter.begin();
On a single-endpoint node, controllers often use DeviceName as the accessory title. On a composed node it is the parent/node name; child lights are not renamed. Use MatterEndPoint::setTagList() for switch-style Descriptor tags, not as a light title.
getManualPairingCode() and getOnboardingQRCodeUrl() are generated from the live discriminator and PIN after Matter.begin(). Before begin() they log a warning and return an empty string. The Arduino test defaults are PIN 20202021, discriminator 0xF00, manual code 34970112332. The 11-digit short manual code uses only the top 4 bits of the discriminator, so 0xF00 and 0xF01 collide if the PIN is unchanged. Changing the PIN requires a matching SPAKE2+ verifier; the library regenerates it. Test while uncommissioned and erase flash after changing codes. Production belongs in factory NVS with a unique PIN per unit.
Identity and commissioning APIs (all setters must run before Matter.begin()):
setVendorName()setProductName()setDeviceName()setSerialNumber()setHardwareVersion()setHardwareVersionString()setSetupDiscriminator()setSetupPasscode()setBLECommissioningEnabled()setBLEMemoryReleaseEnabled()selectNetwork()
Matter.waitForNetwork() is a runtime method, not a setter. It does not start hardware. Ethernet sketches typically call it after ETH.begin() / enableIPv6() and before Matter.begin(). timeoutMs 0 is a single check; MATTER_NETWORK_NONE waits for any interface.
Runtime status
API |
Meaning |
|---|---|
|
A Matter fabric exists |
|
Wi-Fi, Thread, or Ethernet IPv6 is up |
|
A controller has an active CASE session (until idle-evicted) |
|
Wi-Fi station associated |
|
Thread attached |
|
Block until the selected netif has IPv6 |
|
Expected Network Commissioning endpoint, or |
|
CHIPoBLE is compiled in and still enabled |
|
CHIPoBLE is on and BLE RAM will be released after commission |
|
Matching |
|
Last |
|
Interface that currently has a usable IPv6 address |
Do not gate physical outputs (LEDs) on isOnline(). Restore last local state after commissioned. Use isOnline() for hub-discovery logs. A CASE session can remain active after the user leaves the app, until the hub or CHIP tears it down. See the Matter Status example. Official examples use the sketch helpers from Matter.h (see Sketch helpers): matterWaitUntilReady() in setup() and matterRestartIfNoFabric() in loop().
Wi-Fi and Thread each have two commissioning paths. Do not mix them: CHIPoBLE plus a sketch SSID/dataset fights the hub; CHIPoBLE off plus no credentials is a dead end. Ethernet is on-network only (no commissioning cluster).
Example |
Transport |
CHIPoBLE |
Credentials in the sketch |
When to use |
|---|---|---|---|---|
|
Wi-Fi |
On |
No. Hub sends SSID/password |
Factory-fresh Wi-Fi node |
|
Wi-Fi |
Off |
Yes. |
Already on Wi-Fi, or no BLE |
|
Thread |
On |
No. Hub sends the dataset |
Factory-fresh Thread node (ESP32-C5 / ESP32-C6 / ESP32-H2) |
|
Thread |
Off |
Yes. Network key after |
Already on the mesh |
|
Ethernet |
Off |
EMAC or SPI |
Wired only |
|
Default |
On, then reclaimed |
No |
BLE reclaim demo (Wi-Fi; Thread on ESP32-C5 / ESP32-C6 / ESP32-H2) |
|
Dual |
Dual |
Mode 1 SSID; mode 0 hub |
Heap demo; see the example README |
MatterEarlyBLERelease mode 1 is on-network Wi-Fi (CHIPoBLE off at boot). Mode 0 is CHIPoBLE then reclaim. [heap] prints internal RAM and PSRAM.
MatterOnOffLight is the generic accessory demo (CHIPoBLE when compiled in, otherwise sketch Wi-Fi). Use the table when you care about the commissioning path.
Network selection
Call Matter.selectNetwork() before any accessory begin(). With no call the selection is MATTER_NETWORK_NONE and existing sketches are unchanged.
Network |
Supported when |
CHIPoBLE default |
Endpoint |
|---|---|---|---|
Wi-Fi |
|
Enabled |
0 (primary) |
Thread |
|
Enabled |
0 on the root after Thread is selected |
Ethernet |
|
Disabled |
None ( |
The library does not call
ETH.begin(). PHY macros are sketch-local. Internal EMAC (original ESP32, variant definesETH_PHY_MDC/ETH_PHY_MDIO):ETH.begin(). SPI PHY (default W5500):SPI.begin()thenETH.begin(..., SPI). ThenenableIPv6()andMatter.waitForNetwork()beforeMatter.begin().Do not start Arduino
ESPmDNS. CHIP owns the responder.MDNS.begin()overwrites the hostname;MDNS.end()destroys CHIP’s services.selectNetwork(network, disableBLECommissioning)overrides the CHIPoBLE default.trueturns CHIPoBLE off; do not also callsetBLECommissioningEnabled(). A selected-but-down interface plus no BLE leaves no commissioning path.Ethernet and Thread skip CHIP’s
InitWiFiStack()via a linker--wrap.After
Matter.begin(),OThread.begin()attaches to CHIP’s stack (isAttachedToExternalStack()).OThread.end()must not tear that stack down.ESP32-C6: one Network Commissioning cluster on endpoint 0.
Matter.selectNetwork(MATTER_NETWORK_THREAD)replaces root Wi-Fi with Thread. Do not usecreateSecondaryNetworkInterface()(deprecated; it does not create a second NC endpoint).ESP32-C5:
isThreadEnabled()is true when Tools → Matter Network → Thread (ARDUINO_MATTER_NETWORK_THREAD+libespressif__esp_matter.thread.a). Default Wi-Fi menu keeps Matter-over-Wi-Fi.
See MatterOnNetworkEthernet, MatterCHIPoBLEWiFi / MatterOnNetworkWiFi, and MatterCHIPoBLEThread / MatterOnNetworkThread.
Sketch helpers
These are not members of Matter. #include <Matter.h> pulls in MatterHelpers.h (and MatterButton.h). They print to Serial and may reboot. Do not wait for commissioning in loop().
matterConnectWiFi(ssid, password): Present only whenCONFIG_ENABLE_CHIPOBLEis off.MatterHelpers.cppincludesWiFi.hin that build so regular sketches just call the helper. Enables station IPv6 beforeWiFi.begin()(Arduino does not do that by default). CHIPoBLE / Thread builds do not includeWiFi.h(noWiFiClasscost). On-network sketches that start STA with CHIPoBLE compiled in includeWiFi.hand callWiFi.begin()themselves. Not present on ESP32-H2.matterWaitUntilReady(): Call fromsetup()afterMatter.begin(). Prints pairing codes if there is no fabric; one-line status every 10 s and once more when CASE is up. Waits up to 5 minutes (default) for CASE.timeoutMs0 waits forever (unlikeMatter.waitForNetwork(0), which is a single check). Reboots if still uncommissioned. If commissioned but CASE never arrives, continues.matterRestartIfNoFabric(): Call fromloop(). Reboots if the hub removed the fabric.Matter.decommission()already factory-resets.
MatterButton is a board-button class, not a Generic Switch cluster. An esp_timer samples the pin; loop() only drains poll(). Do not call Matter APIs from the timer callback.
Events:
PRESS,CLICK,DOUBLE_CLICK,LONG_HOLDDefaults: 50 ms debounce, 5 s long-hold, double-click off (click on release), 20 ms sample, active-low
INPUT_PULLUP(BOOT)
#include <Matter.h>
const uint8_t buttonPin = BOOT_PIN;
MatterButton button;
void setup() {
button.begin(buttonPin);
// ... endpoint begin() ...
Matter.begin();
matterWaitUntilReady();
}
void loop() {
matterRestartIfNoFabric();
matterButtonEvent_t ev;
while ((ev = button.poll()) != MATTER_BUTTON_NONE) {
if (ev == MATTER_BUTTON_CLICK) {
// toggle accessory
} else if (ev == MATTER_BUTTON_LONG_HOLD) {
Matter.decommission();
}
}
}
MatterEndPoint
The MatterEndPoint class is the base class for all Matter endpoints. It provides common functionality for all endpoint types.
Endpoint Management: Each endpoint has a unique endpoint ID for identification
Attribute Access: Methods to get and set attribute values from Matter clusters
Identify Cluster: Support for device identification (visual feedback)
Attribute Change Callbacks: Base framework for handling attribute changes from Matter controllers
Specific endpoint classes
The library provides specialized endpoint classes for different device types. Each endpoint type includes specific clusters and functionality relevant to that device category.
Lighting Endpoints:
MatterOnOffLight: Simple on/off light controlMatterDimmableLight: Light with brightness controlMatterColorTemperatureLight: Light with brightness and color temperature (no RGB wheel)MatterColorLight: RGB color light (HSV/XY, no color temperature slider in Matter APPs)MatterEnhancedColorLight: Extended color light with RGB, brightness, and color temperature
Sensor Endpoints:
MatterTemperatureSensor: Temperature sensor (read-only)MatterHumiditySensor: Humidity sensor (read-only)MatterPressureSensor: Pressure sensor (read-only)MatterContactSensor: Contact sensor (open/closed state)MatterWaterLeakDetector: Water leak detector (detected/not detected state)MatterWaterFreezeDetector: Water freeze detector (detected/not detected state)MatterRainSensor: Rain sensor (detected/not detected state)MatterOccupancySensor: Occupancy sensor (occupied/unoccupied state)MatterLightSensor: Light sensor (read-only)
Control Endpoints:
MatterTemperatureControlledCabinet: Temperature controlled cabinet (setpoint control with min/max limits)MatterFan: Fan with speed and mode controlMatterThermostat: Thermostat with temperature control and setpointsMatterOnOffPlugin: On/off plugin unit (power outlet/relay)MatterDimmablePlugin: Dimmable plugin unit (power outlet/relay with brightness control)MatterGenericSwitch: Generic switch endpoint (smart button with optional long-press and multi-press)MatterWindowCovering: Window covering with lift and tilt control (blinds, shades)
- MatterColorLight
- MatterColorTemperatureLight
- MatterContactSensor
- MatterDimmableLight
- MatterDimmablePlugin
- MatterEnhancedColorLight
- MatterFan
- MatterGenericSwitch
- MatterHumiditySensor
- MatterLightSensor
- MatterOccupancySensor
- MatterOnOffLight
- MatterOnOffPlugin
- MatterPressureSensor
- MatterRainSensor
- MatterTemperatureControlledCabinet
- MatterTemperatureSensor
- MatterThermostat
- MatterWaterFreezeDetector
- MatterWaterLeakDetector
- MatterWindowCovering
Matter Examples
The Matter library includes a comprehensive set of examples demonstrating various device types and use cases. All examples are available in the ESP Arduino GitHub repository.
Getting Started:
Matter Minimum - The smallest code required to create a Matter-compatible device. Ideal starting point for understanding Matter basics. View Matter Minimum code on GitHub
Matter Status - Demonstrates how to check enabled Matter features and connectivity status, including
isDeviceCommissioned(),isDeviceConnected(), andisOnline(). Implements a basic on/off light and periodically reports capability and connection status. View Matter Status code on GitHubMatter Device Identity - Sets VendorName, ProductName, DeviceName (NodeLabel), SerialNumber, hardware version, and custom commissioning codes on
Matterbeforebegin(). View Matter Device Identity code on GitHubMatter Events - Shows how to monitor and handle Matter events. Provides a comprehensive view of all Matter events during device operation. View Matter Events code on GitHub
Commissioning:
Matter CHIPoBLE Wi-Fi - CHIPoBLE on, no SSID in the sketch. The hub sends Wi-Fi credentials. View Matter CHIPoBLE Wi-Fi code on GitHub
Matter On-Network Wi-Fi - CHIPoBLE off,
Matter.selectNetwork(MATTER_NETWORK_WIFI, true)thenWiFi.begin(WIFI_SSID, WIFI_PASSWORD). View Matter On-Network Wi-Fi code on GitHubMatter CHIPoBLE Thread - CHIPoBLE on, no dataset. The hub sends the Thread dataset (ESP32-C5 / ESP32-C6 / ESP32-H2). View Matter CHIPoBLE Thread code on GitHub
Matter On-Network Thread - CHIPoBLE off, sketch network key after
Matter.begin(). View Matter On-Network Thread code on GitHubMatter On-Network Ethernet - CHIPoBLE off, EMAC or SPI
ETH.begin()and IPv6 beforeMatter.begin(). View Matter On-Network Ethernet code on GitHubMatter CHIPoBLE Release - CHIPoBLE commissioning, then BLE RAM reclaim. Uses
onBLEMemoryReleased()and allocates a demo buffer fromloop(). View Matter CHIPoBLE Release code on GitHubMatter Commission Test - Tests Matter commissioning functionality with automatic decommissioning after a 30-second delay for continuous testing cycles. View Matter Commission Test code on GitHub
Lighting Examples:
Matter On/Off Light - Creates a Matter-compatible on/off light device with commissioning, device control via smart home ecosystems, and manual control using a physical button with state persistence. View Matter On/Off Light code on GitHub
Matter Dimmable Light - Creates a Matter-compatible dimmable light device with brightness control. View Matter Dimmable Light code on GitHub
Matter Color Temperature Light - Creates a Matter-compatible color temperature light device with adjustable color temperature control. View Matter Color Temperature Light code on GitHub
Matter Color Light - Creates a Matter-compatible RGB color light (HSV/XY, no color temperature). View Matter Color Light code on GitHub
Matter Enhanced Color Light - Creates a Matter-compatible extended color light with RGB, brightness, and color temperature. View Matter Enhanced Color Light code on GitHub
Matter Composed Lights - Creates a Matter node with multiple light endpoints (On/Off Light, Dimmable Light, and Color Light) in a single node. View Matter Composed Lights code on GitHub
Matter On Identify - Identify cluster on an on/off light:
onIdentify(bool)plusgetIdentifyRequest()so IdentifyTime and TriggerEffect Blink / Breathe / Okay / ChannelChange can look different. View Matter On Identify code on GitHub
Sensor Examples:
Matter Temperature Sensor - Creates a Matter-compatible temperature sensor device with sensor data reporting to smart home ecosystems. View Matter Temperature Sensor code on GitHub
Matter Humidity Sensor - Creates a Matter-compatible humidity sensor device with sensor data reporting. View Matter Humidity Sensor code on GitHub
Matter Pressure Sensor - Creates a Matter-compatible pressure sensor device with automatic simulation of pressure readings. View Matter Pressure Sensor code on GitHub
Matter Contact Sensor - Creates a Matter-compatible contact sensor device (open/closed state). View Matter Contact Sensor code on GitHub
Matter Occupancy Sensor - Creates a Matter-compatible occupancy sensor device with automatic simulation of occupancy state changes. View Matter Occupancy Sensor code on GitHub
Matter Occupancy Sensor with HoldTime - Creates a Matter-compatible occupancy sensor device with HoldTime functionality, automatic simulation of occupancy state changes, HoldTime configuration with persistence across reboots, and HoldTime change callback for real-time updates from Matter controllers. View Matter Occupancy Sensor with HoldTime code on GitHub
Matter Water Leak Detector - Creates a Matter-compatible water leak detector device with automatic simulation of water leak detection state changes. View Matter Water Leak Detector code on GitHub
Matter Water Freeze Detector - Creates a Matter-compatible water freeze detector device with automatic simulation of water freeze detection state changes. View Matter Water Freeze Detector code on GitHub
Matter Rain Sensor - Creates a Matter-compatible rain sensor device with automatic simulation of rain detection state changes. View Matter Rain Sensor code on GitHub
Matter Light Sensor - Creates a Matter-compatible light (illuminance) sensor device with automatic simulation of illuminance readings. View Matter Light Sensor code on GitHub
Control Examples:
Matter Fan - Creates a Matter-compatible fan device with speed and mode control. View Matter Fan code on GitHub
Matter Thermostat - Creates a Matter-compatible thermostat device with temperature setpoint management and simulated heating/cooling systems with automatic temperature regulation. View Matter Thermostat code on GitHub
Matter Temperature Controlled Cabinet - Creates a Matter-compatible temperature controlled cabinet device with precise temperature setpoint control with min/max limits (temperature_number mode). View Matter Temperature Controlled Cabinet code on GitHub
Matter Temperature Controlled Cabinet Levels - Creates a Matter-compatible temperature controlled cabinet device using predefined temperature levels (temperature_level mode) with hub-visible names (Off / Low / Medium / High / Max). View Matter Temperature Controlled Cabinet Levels code on GitHub
Matter On/Off Plugin - Creates a Matter-compatible on/off plugin unit (power relay) device with state persistence for power control applications. View Matter On/Off Plugin code on GitHub
Matter Dimmable Plugin - Creates a Matter-compatible dimmable plugin unit (power outlet with level control) device with state persistence for dimmable power control applications. View Matter Dimmable Plugin code on GitHub
Matter Smart Button - One Generic Switch. Short click only (
InitialPress+ShortRelease). View Matter Smart Button code on GitHubMatter Enhanced Smart Button - One BOOT button with Switch
FEATURE_ALL: single click, double click, triple click, and long press. Serial prints the gesture name plus the Matter events. View Matter Enhanced Smart Button code on GitHubMatter Smart Buttons TagList - Three short-click Generic Switches (On, Off, Scene) told apart with Descriptor
TagList. No long-press or multi-press. View Matter Smart Buttons TagList code on GitHubMatter Window Covering - Creates a Matter-compatible window covering device with lift and tilt control (blinds, shades) with manual control using a physical button. View Matter Window Covering code on GitHub
Matter Simple Blinds - A minimal example that only controls lift percentage using a single onGoToLiftPercentage() callback. View Matter Simple Blinds code on GitHub
Advanced Examples:
Matter Lambda Single Callback Many Endpoints - Demonstrates how to create multiple Matter endpoints in a single node using a shared lambda function callback with capture for efficient callback handling. View Matter Lambda Single Callback Many Endpoints code on GitHub
Matter Early BLE Release - One On/Off Light.
MATTER_EARLY_BLE_RELEASE1 (default):bleInUse()==falsethen on-network Wi-Fi. 0: CHIPoBLE. Serial reports Tools PSRAM and[heap]internal / PSRAM. View Matter Early BLE Release code on GitHub
Common Problems and Issues
Troubleshooting
Common Issues
- Device won’t commission
Ensure the Matter hub is in pairing mode
Check that Wi-Fi or Thread connectivity is properly configured
Verify the QR code or pairing code is correct
For builds without CHIPoBLE (
CONFIG_ENABLE_CHIPOBLE=n: Arduino IDE on original ESP32 or ESP32-S2, or Bluetooth off), set Wi-Fi credentials in the sketch. Original ESP32 can use CHIPoBLE when built as an IDF component with NimBLE andCONFIG_ENABLE_CHIPOBLE.
- Commissioning fails
Try factory resetting the device by calling
Matter.decommission()Erase flash memory:
Arduino IDE Menu->Tools->Erase All Flash Before Sketch Upload: "Enabled"Or use esptool:
esptool.py --port <PORT> erase_flash
- Wi-Fi connection issues
Verify Wi-Fi credentials (SSID and password) are correct
Check that the device is within range of the Wi-Fi router
Ensure the Wi-Fi network is 2.4 GHz (Matter requires 2.4 GHz Wi-Fi)
- Thread connection issues
Verify Thread border router is properly configured
Check that Thread network credentials are correct
Ensure device supports Thread (ESP32-H2, ESP32-C6, or ESP32-C5 with Tools → Matter Network → Thread)
- Device not responding
Check Serial Monitor for error messages (115200 baud)
Verify endpoint initialization with
begin()methodEnsure
Matter.begin()is called after all endpoints are initializedFor Boolean State sensors (contact, leak, freeze, rain), call the setter after
Matter.begin().begin()does not take an initial state.
- Callbacks not firing
Verify callback functions are registered before
Matter.begin()Check that callback functions are properly defined
Ensure endpoint is properly initialized with
begin()
Factory Reset
If you have problems with commissioning or device connectivity, you can try to factory reset the device. This will erase all the Matter network settings and act as a brand new device.
Matter.decommission();
This will reset the device and it will need to be commissioned again.
Event Monitoring
For debugging and monitoring Matter events, you can set up an event callback:
Matter.onEvent([](matterEvent_t event, const chip::DeviceLayer::ChipDeviceEvent *eventData) {
Serial.printf("Matter Event: 0x%04X\r\n", event);
// Handle specific events
switch(event) {
case MATTER_COMMISSIONING_COMPLETE:
Serial.println("Device commissioned!");
break;
case MATTER_WIFI_CONNECTIVITY_CHANGE:
Serial.println("Wi-Fi connectivity changed");
break;
// ... handle other events
}
});
This allows you to monitor commissioning progress, connectivity changes, and other Matter events in real-time.
To run code only after BLE RAM is back on the heap, use Matter.onBLEMemoryReleased() (see Waiting for BLE RAM above). MATTER_BLE_DEINITIALIZED is the matching onEvent() type.