Skip to content

Commit 7fcd6bd

Browse files
authored
Initial Commit
This is the ESP32 Arduino Matter Enhanced Color Light example code structured to be built using Arduino as IDF Component. The application will use Thread network instead of WiFi using the ESP32-C6.
1 parent cbd49cf commit 7fcd6bd

File tree

8 files changed

+3968
-0
lines changed

8 files changed

+3968
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# The following lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.5)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
7+
#target_compile_options(espressif__esp_matter PUBLIC
8+
# -DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=<lib/address_resolve/AddressResolve_DefaultImpl.h>
9+
# -DCHIP_HAVE_CONFIG_H)
10+
#list(APPEND compile_definitions "CHIP_HAVE_CONFIG_H=1")
11+
#list(APPEND compile_definitions "CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=<lib/address_resolve/AddressResolve_DefaultImpl.h>")
12+
13+
project(Matter_C6_Thread_Light)
14+
15+
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++2a;-Os;-DCHIP_HAVE_CONFIG_H" APPEND)
16+
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
17+
# For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various
18+
# flags that depend on -Wformat
19+
idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Arduino ESP-Matter over Thread example using ESP32-C6
2+
This is an Arduino as IDF Project to build an ESP-Matter over Thread RGB Light using ESP32-C6 and ESP-Matter Arduino API \
3+
The example requires IDF 5.5.0 and ESP32 Arduino Core 3.0.0
4+
5+
# Instructions:
6+
7+
1- Install IDF 5.5.0 into your computer. It can be done following the guide in
8+
https://docs.espressif.com/projects/esp-idf/en/stable/esp32c6/get-started/index.html
9+
10+
For Windows: https://docs.espressif.com/projects/esp-idf/en/stable/esp32c6/get-started/index.html \
11+
For Linux or MacOS: https://docs.espressif.com/projects/esp-idf/en/stable/esp32c6/get-started/linux-macos-setup.html
12+
13+
2- Test IDF with `idf.py --version` to check if it is installed and configured correctly.
14+
<img width="539" height="215" alt="image" src="https://github.com/user-attachments/assets/ed95e767-9451-4e03-ab85-f83e08a2f936" />
15+
16+
3- Clone the repository with the Arduino as IDF Component project.
17+
`git clone https://github.com/SuGlider/Arduino_ESP-Matter-over-Thread_ESP32-C6`
18+
19+
4- Open an IDF terminal and execute `idf.py set-target esp32c6`
20+
21+
5- Execute `idf.py -p <your COM or /dev/tty port connected to the ESP32-C6> flash monitor`
22+
23+
6- It will build, upload and show the UART0 output in the screen.
24+
25+
7- Try to add the Matter RGB light to your Matter environment.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
idf_component_register(
2+
SRCS "MatterEnhancedColorLight.cpp"
3+
INCLUDE_DIRS ""
4+
)
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Matter Manager
16+
#include <Matter.h>
17+
#if !CONFIG_ENABLE_CHIPOBLE
18+
// if the device can be commissioned using BLE, WiFi is not used - save flash space
19+
#include <WiFi.h>
20+
#endif
21+
#include <Preferences.h>
22+
23+
// List of Matter Endpoints for this Node
24+
// Color Light Endpoint
25+
MatterEnhancedColorLight EnhancedColorLight;
26+
27+
// CONFIG_ENABLE_CHIPOBLE is enabled when BLE is used to commission the Matter Network
28+
#if !CONFIG_ENABLE_CHIPOBLE
29+
// WiFi is manually set and started
30+
const char *ssid = "your-ssid"; // Change this to your WiFi SSID
31+
const char *password = "your-password"; // Change this to your WiFi password
32+
#endif
33+
34+
// It will use HSV color to control all Matter Attribute Changes
35+
HsvColor_t currentHSVColor = {0, 0, 0};
36+
37+
// it will keep last OnOff & HSV Color state stored, using Preferences
38+
Preferences matterPref;
39+
const char *onOffPrefKey = "OnOff";
40+
const char *hsvColorPrefKey = "HSV";
41+
42+
// set your board RGB LED pin here
43+
#ifdef RGB_BUILTIN
44+
const uint8_t ledPin = RGB_BUILTIN;
45+
#else
46+
const uint8_t ledPin = 2; // Set your pin here if your board has not defined LED_BUILTIN
47+
#warning "Do not forget to set the RGB LED pin"
48+
#endif
49+
50+
// set your board USER BUTTON pin here
51+
const uint8_t buttonPin = BOOT_PIN; // Set your pin here. Using BOOT Button.
52+
53+
// Button control
54+
uint32_t button_time_stamp = 0; // debouncing control
55+
bool button_state = false; // false = released | true = pressed
56+
const uint32_t debouceTime = 250; // button debouncing time (ms)
57+
const uint32_t decommissioningTimeout = 5000; // keep the button pressed for 5s, or longer, to decommission
58+
59+
// Set the RGB LED Light based on the current state of the Enhanced Color Light
60+
bool setLightState(bool state, espHsvColor_t colorHSV, uint8_t brighteness, uint16_t temperature_Mireds) {
61+
62+
if (state) {
63+
#ifdef RGB_BUILTIN
64+
// currentHSVColor keeps final color result
65+
espRgbColor_t rgbColor = espHsvColorToRgbColor(currentHSVColor);
66+
// set the RGB LED
67+
rgbLedWrite(ledPin, rgbColor.r, rgbColor.g, rgbColor.b);
68+
#else
69+
// No Color RGB LED, just use the HSV value (brightness) to control the LED
70+
analogWrite(ledPin, colorHSV.v);
71+
#endif
72+
} else {
73+
#ifndef RGB_BUILTIN
74+
// after analogWrite(), it is necessary to set the GPIO to digital mode first
75+
pinMode(ledPin, OUTPUT);
76+
#endif
77+
digitalWrite(ledPin, LOW);
78+
}
79+
// store last HSV Color and OnOff state for when the Light is restarted / power goes off
80+
matterPref.putBool(onOffPrefKey, state);
81+
matterPref.putUInt(hsvColorPrefKey, currentHSVColor.h << 16 | currentHSVColor.s << 8 | currentHSVColor.v);
82+
// This callback must return the success state to Matter core
83+
return true;
84+
}
85+
86+
void setup() {
87+
// Initialize the USER BUTTON (Boot button) GPIO that will act as a toggle switch
88+
pinMode(buttonPin, INPUT_PULLUP);
89+
// Initialize the LED (light) GPIO and Matter End Point
90+
pinMode(ledPin, OUTPUT);
91+
92+
Serial.begin(115200);
93+
94+
// CONFIG_ENABLE_CHIPOBLE is enabled when BLE is used to commission the Matter Network
95+
#if !CONFIG_ENABLE_CHIPOBLE
96+
// We start by connecting to a WiFi network
97+
Serial.print("Connecting to ");
98+
Serial.println(ssid);
99+
// Manually connect to WiFi
100+
WiFi.begin(ssid, password);
101+
// Wait for connection
102+
while (WiFi.status() != WL_CONNECTED) {
103+
delay(500);
104+
Serial.print(".");
105+
}
106+
Serial.println("\r\nWiFi connected");
107+
Serial.println("IP address: ");
108+
Serial.println(WiFi.localIP());
109+
delay(500);
110+
#endif
111+
112+
// Initialize Matter EndPoint
113+
matterPref.begin("MatterPrefs", false);
114+
// default OnOff state is ON if not stored before
115+
bool lastOnOffState = matterPref.getBool(onOffPrefKey, true);
116+
// default HSV color is (21, 216, 25) - Warm White Color at 10% intensity
117+
uint32_t prefHsvColor = matterPref.getUInt(hsvColorPrefKey, 21 << 16 | 216 << 8 | 25);
118+
currentHSVColor = {uint8_t(prefHsvColor >> 16), uint8_t(prefHsvColor >> 8), uint8_t(prefHsvColor)};
119+
EnhancedColorLight.begin(lastOnOffState, currentHSVColor);
120+
// set the callback function to handle the Light state change
121+
EnhancedColorLight.onChange(setLightState);
122+
123+
// lambda functions are used to set the attribute change callbacks
124+
EnhancedColorLight.onChangeOnOff([](bool state) {
125+
Serial.printf("Light OnOff changed to %s\r\n", state ? "ON" : "OFF");
126+
return true;
127+
});
128+
EnhancedColorLight.onChangeColorTemperature([](uint16_t colorTemperature) {
129+
Serial.printf("Light Color Temperature changed to %d\r\n", colorTemperature);
130+
// get correspondent Hue and Saturation of the color temperature
131+
HsvColor_t hsvTemperature = espRgbColorToHsvColor(espCTToRgbColor(colorTemperature));
132+
// keep previous the brightness and just change the Hue and Saturation
133+
currentHSVColor.h = hsvTemperature.h;
134+
currentHSVColor.s = hsvTemperature.s;
135+
return true;
136+
});
137+
EnhancedColorLight.onChangeBrightness([](uint8_t brightness) {
138+
Serial.printf("Light brightness changed to %d\r\n", brightness);
139+
// change current brightness (HSV value)
140+
currentHSVColor.v = brightness;
141+
return true;
142+
});
143+
EnhancedColorLight.onChangeColorHSV([](HsvColor_t hsvColor) {
144+
Serial.printf("Light HSV Color changed to (%d,%d,%d)\r\n", hsvColor.h, hsvColor.s, hsvColor.v);
145+
// keep the current brightness and just change Hue and Saturation
146+
currentHSVColor.h = hsvColor.h;
147+
currentHSVColor.s = hsvColor.s;
148+
return true;
149+
});
150+
151+
// Matter beginning - Last step, after all EndPoints are initialized
152+
Matter.begin();
153+
// This may be a restart of a already commissioned Matter accessory
154+
if (Matter.isDeviceCommissioned()) {
155+
Serial.println("Matter Node is commissioned and connected to the network. Ready for use.");
156+
Serial.printf(
157+
"Initial state: %s | RGB Color: (%d,%d,%d) \r\n", EnhancedColorLight ? "ON" : "OFF", EnhancedColorLight.getColorRGB().r,
158+
EnhancedColorLight.getColorRGB().g, EnhancedColorLight.getColorRGB().b
159+
);
160+
// configure the Light based on initial on-off state and its color
161+
EnhancedColorLight.updateAccessory();
162+
}
163+
}
164+
165+
void loop() {
166+
// Check Matter Light Commissioning state, which may change during execution of loop()
167+
if (!Matter.isDeviceCommissioned()) {
168+
Serial.println("");
169+
Serial.println("Matter Node is not commissioned yet.");
170+
Serial.println("Initiate the device discovery in your Matter environment.");
171+
Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
172+
Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
173+
Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
174+
// waits for Matter Light Commissioning.
175+
uint32_t timeCount = 0;
176+
while (!Matter.isDeviceCommissioned()) {
177+
delay(100);
178+
if ((timeCount++ % 50) == 0) { // 50*100ms = 5 sec
179+
Serial.println("Matter Node not commissioned yet. Waiting for commissioning.");
180+
}
181+
}
182+
Serial.printf(
183+
"Initial state: %s | RGB Color: (%d,%d,%d) \r\n", EnhancedColorLight ? "ON" : "OFF", EnhancedColorLight.getColorRGB().r,
184+
EnhancedColorLight.getColorRGB().g, EnhancedColorLight.getColorRGB().b
185+
);
186+
// configure the Light based on initial on-off state and its color
187+
EnhancedColorLight.updateAccessory();
188+
Serial.println("Matter Node is commissioned and connected to the network. Ready for use.");
189+
}
190+
191+
// A button is also used to control the light
192+
// Check if the button has been pressed
193+
if (digitalRead(buttonPin) == LOW && !button_state) {
194+
// deals with button debouncing
195+
button_time_stamp = millis(); // record the time while the button is pressed.
196+
button_state = true; // pressed.
197+
}
198+
199+
// Onboard User Button is used as a Light toggle switch or to decommission it
200+
uint32_t time_diff = millis() - button_time_stamp;
201+
if (button_state && time_diff > debouceTime && digitalRead(buttonPin) == HIGH) {
202+
button_state = false; // released
203+
// Toggle button is released - toggle the light
204+
Serial.println("User button released. Toggling Light!");
205+
EnhancedColorLight.toggle(); // Matter Controller also can see the change
206+
}
207+
208+
// Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node
209+
if (button_state && time_diff > decommissioningTimeout) {
210+
Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again.");
211+
EnhancedColorLight = false; // turn the light off
212+
Matter.decommission();
213+
button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so
214+
}
215+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
dependencies:
2+
espressif/esp_matter:
3+
version: "^1.4.0"
4+
require: public
5+
espressif/arduino-esp32:
6+
version: "3.3.0"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Name, Type, SubType, Offset, Size, Flags
2+
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
3+
esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted
4+
nvs, data, nvs, 0x10000, 0xC000,
5+
nvs_keys, data, nvs_keys,, 0x1000, encrypted
6+
otadata, data, ota, , 0x2000
7+
phy_init, data, phy, , 0x1000,
8+
ota_0, app, ota_0, 0x20000, 0x1E0000,
9+
ota_1, app, ota_1, 0x200000, 0x1E0000,
10+
fctry, data, nvs, 0x3E0000, 0x6000

0 commit comments

Comments
 (0)