Description
Board
seeed xiao esp32-c6
Device Description
The development board is used without any other attachments. Only a powering / data USB-C cable.
See https://wiki.seeedstudio.com/xiao_esp32c6_getting_started/# for more details.
Hardware Configuration
nothing else attached
Version
latest master (checkout manually)
IDE Name
Arduino IDE 2
Operating System
Ubuntu 2024.04
Flash frequency
80Mhz
PSRAM enabled
no
Upload speed
921600
Description
Short: The esp32-c6 doesn't remember the zigbee bounds from the last reset.
Problem description:
I run the example Zigbee_on_off_switch, but removed the waiting period in the setup().
When I run the script for the first time and bind a new device, I can toggle the status of the device. Tested successfully with the light example on a second xiao esp32-c6 and an actuall ikea tradfri plug.
Now I reset / power cycle the switch.
The former established connections are forgotten: If I just press the button again, no devices are bound. I don't want to pair the plug or light again after a power reset of the switch.
Expected behavior:
When I reset the controller, I expect, that the controller remembers the bound devices from last time. A press on the button of the switch shall remember the bound devices from the last power cycle.
Sketch
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @brief This example demonstrates simple Zigbee light switch.
*
* The example demonstrates how to use Zigbee library to control a light bulb.
* The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator (Switch).
* Button switch and Zigbee runs in separate tasks.
*
* Proper Zigbee mode must be selected in Tools->Zigbee mode
* and also the correct partition scheme must be selected in Tools->Partition Scheme.
*
* Please check the README.md for instructions and more detailed description.
*
* Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/)
*/
#ifndef ZIGBEE_MODE_ZCZR
#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode"
#endif
#include "ZigbeeCore.h"
#include "ep/ZigbeeSwitch.h"
#define SWITCH_ENDPOINT_NUMBER 5
/* Switch configuration */
#define GPIO_INPUT_IO_TOGGLE_SWITCH 9
#define PAIR_SIZE(TYPE_STR_PAIR) (sizeof(TYPE_STR_PAIR) / sizeof(TYPE_STR_PAIR[0]))
typedef enum {
SWITCH_ON_CONTROL,
SWITCH_OFF_CONTROL,
SWITCH_ONOFF_TOGGLE_CONTROL,
SWITCH_LEVEL_UP_CONTROL,
SWITCH_LEVEL_DOWN_CONTROL,
SWITCH_LEVEL_CYCLE_CONTROL,
SWITCH_COLOR_CONTROL,
} SwitchFunction;
typedef struct {
uint8_t pin;
SwitchFunction func;
} SwitchData;
typedef enum {
SWITCH_IDLE,
SWITCH_PRESS_ARMED,
SWITCH_PRESS_DETECTED,
SWITCH_PRESSED,
SWITCH_RELEASE_DETECTED,
} SwitchState;
static SwitchData buttonFunctionPair[] = {{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}};
ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER);
/********************* Zigbee functions **************************/
static void onZbButton(SwitchData *button_func_pair) {
if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) {
// Send toggle command to the light
zbSwitch.lightToggle();
}
}
/********************* GPIO functions **************************/
static QueueHandle_t gpio_evt_queue = NULL;
static void IRAM_ATTR onGpioInterrupt(void *arg) {
xQueueSendFromISR(gpio_evt_queue, (SwitchData *)arg, NULL);
}
static void enableGpioInterrupt(bool enabled) {
for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); ++i) {
if (enabled) {
enableInterrupt((buttonFunctionPair[i]).pin);
} else {
disableInterrupt((buttonFunctionPair[i]).pin);
}
}
}
/********************* Arduino functions **************************/
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
//Optional: set Zigbee device name and model
zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch");
//Optional to allow multiple light to bind to the switch
zbSwitch.allowMultipleBinding(true);
//Add endpoint to Zigbee Core
log_d("Adding ZigbeeSwitch endpoint to Zigbee Core");
Zigbee.addEndpoint(&zbSwitch);
//Open network for 180 seconds after boot
Zigbee.setRebootOpenNetwork(180);
// Init button switch
for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); i++) {
pinMode(buttonFunctionPair[i].pin, INPUT_PULLUP);
/* create a queue to handle gpio event from isr */
gpio_evt_queue = xQueueCreate(10, sizeof(SwitchData));
if (gpio_evt_queue == 0) {
log_e("Queue was not created and must not be used");
while (1);
}
attachInterruptArg(buttonFunctionPair[i].pin, onGpioInterrupt, (void *)(buttonFunctionPair + i), FALLING);
}
// When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode
log_d("Calling Zigbee.begin()");
Zigbee.begin(ZIGBEE_COORDINATOR);
Serial.println("Waiting for Light to bound to the switch");
//Wait for switch to bound to a light:
/*while (!zbSwitch.isBound()) {
Serial.printf(".");
delay(500);
}*/
// Optional: read manufacturer and model name from the bound light
std::list<zb_device_params_t *> boundLights = zbSwitch.getBoundDevices();
//List all bound lights
for (const auto &device : boundLights) {
Serial.printf("Device on endpoint %d, short address: 0x%x\n", device->endpoint, device->short_addr);
Serial.printf(
"IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", device->ieee_addr[0], device->ieee_addr[1], device->ieee_addr[2], device->ieee_addr[3],
device->ieee_addr[4], device->ieee_addr[5], device->ieee_addr[6], device->ieee_addr[7]
);
Serial.printf("Light manufacturer: %s", zbSwitch.readManufacturer(device->endpoint, device->short_addr));
Serial.printf("Light model: %s", zbSwitch.readModel(device->endpoint, device->short_addr));
}
Serial.println();
}
void loop() {
// Handle button switch in loop()
uint8_t pin = 0;
SwitchData buttonSwitch;
static SwitchState buttonState = SWITCH_IDLE;
bool eventFlag = false;
/* check if there is any queue received, if yes read out the buttonSwitch */
if (xQueueReceive(gpio_evt_queue, &buttonSwitch, portMAX_DELAY)) {
pin = buttonSwitch.pin;
enableGpioInterrupt(false);
eventFlag = true;
}
while (eventFlag) {
bool value = digitalRead(pin);
switch (buttonState) {
case SWITCH_IDLE: buttonState = (value == LOW) ? SWITCH_PRESS_DETECTED : SWITCH_IDLE; break;
case SWITCH_PRESS_DETECTED: buttonState = (value == LOW) ? SWITCH_PRESS_DETECTED : SWITCH_RELEASE_DETECTED; break;
case SWITCH_RELEASE_DETECTED:
buttonState = SWITCH_IDLE;
/* callback to button_handler */
(*onZbButton)(&buttonSwitch);
break;
default: break;
}
if (buttonState == SWITCH_IDLE) {
enableGpioInterrupt(true);
eventFlag = false;
break;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
// print the bound lights every 10 seconds
static uint32_t lastPrint = 0;
if (millis() - lastPrint > 10000) {
lastPrint = millis();
zbSwitch.printBoundDevices();
}
}
Debug Message
For the initial pairing:
========== Before Setup Start ===========
Chip Info:
------------------------------------------
Model : ESP32-C6
Package : 1
Revision : 0.01
Cores : 1
CPU Frequency : 160 MHz
XTAL Frequency : 40 MHz
Features Bitfield : 0x00000052
Embedded Flash : No
Embedded PSRAM : No
2.4GHz WiFi : Yes
Classic BT : No
BT Low Energy : Yes
IEEE 802.15.4 : Yes
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
Total Size : 451212 B ( 440.6 KB)
Free Bytes : 422568 B ( 412.7 KB)
Allocated Bytes : 21564 B ( 21.1 KB)
Minimum Free Bytes: 417680 B ( 407.9 KB)
Largest Free Block: 401396 B ( 392.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
Chip Size : 4194304 B (4 MB)
Block Size : 65536 B ( 64.0 KB)
Sector Size : 4096 B ( 4.0 KB)
Page Size : 256 B ( 0.2 KB)
Bus Speed : 40 MHz
Bus Mode : QIO
------------------------------------------
Partitions Info:
------------------------------------------
nvs : addr: 0x00009000, size: 20.0 KB, type: DATA, subtype: NVS
otadata : addr: 0x0000E000, size: 8.0 KB, type: DATA, subtype: OTA
app0 : addr: 0x00010000, size: 1280.0 KB, type: APP, subtype: OTA_0
app1 : addr: 0x00150000, size: 1280.0 KB, type: APP, subtype: OTA_1
spiffs : addr: 0x00290000, size: 1388.0 KB, type: DATA, subtype: SPIFFS
zb_storage : addr: 0x003EB000, size: 16.0 KB, type: DATA, subtype: FAT
zb_fct : addr: 0x003EF000, size: 4.0 KB, type: DATA, subtype: FAT
coredump : addr: 0x003F0000, size: 64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
Compile Date/Time : Nov 24 2024 17:41:30
Compile Host OS : linux
ESP-IDF Version : v5.1.4-972-g632e0c2a9f-dirty
Arduino Version : 3.0.7
------------------------------------------
Board Info:
------------------------------------------
Arduino Board : XIAO_ESP32C6
Arduino Variant : XIAO_ESP32C6
Arduino FQBN : esp32:esp32:XIAO_ESP32C6:UploadSpeed=921600,CDCOnBoot=cdc,CPUFreq=160,FlashFreq=80,FlashMode=qio,FlashSize=4M,PartitionScheme=zigbee,DebugLevel=verbose,EraseFlash=all,JTAGAdapter=default,ZigbeeMode=zczr
============ Before Setup End ============
[ 995][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 12 already has type USB_DM (38) with bus 0x4080f17c
[ 996][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 13 already has type USB_DP (39) with bus 0x4080f17c
[ 996][D][Zigbee_On_Off_Switch.ino:110] setup(): Adding ZigbeeSwitch endpoint to Zigbee Core
[ 997][D][ZigbeeCore.cpp:63] addEndpoint(): Endpoint: 5, Device ID: 0x0000
[ 997][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x4200379e
[ 998][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 9 successfully set to type GPIO (1) with bus 0xa
[ 998][D][Zigbee_On_Off_Switch.ino:129] setup(): Calling Zigbee.begin()
[ 999][D][ZigbeeCore.cpp:94] zigbeeInit(): Initialize Zigbee stack
[ 1047][D][ZigbeeCore.cpp:101] zigbeeInit(): Register all Zigbee EPs in list
[ 1048][I][ZigbeeCore.cpp:109] zigbeeInit(): List of registered Zigbee EPs:
[ 1048][I][ZigbeeCore.cpp:111] zigbeeInit(): Device type: General On/Off switch, Endpoint: 5, Device ID: 0x0000
Waiting for Light to bound to the switch
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
Total Size : 451212 B ( 440.6 KB)
Free Bytes : 392860 B ( 383.7 KB)
Allocated Bytes : 50592 B ( 49.4 KB)
Minimum Free Bytes: 392860 B ( 383.7 KB)
Largest Free Block: 368628 B ( 360.0 KB)
--------[ 1053][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
[ 1054][I][ZigbeeCore.cpp:179] esp_zb_app_signal_handler(): Zigbee stack initialized
[ 1058][I][ZigbeeCore.cpp:282] esp_zb_app_signal_handler(): Network(0x5dac) closed, devices joining not allowed.
[ 1060][I][ZigbeeCore.cpp:185] esp_zb_app_signal_handler(): Device started up in non factory-reset mode
[ 1060][I][ZigbeeCore.cpp:198] esp_zb_app_signal_handler(): Device rebooted
[ 1060][I][ZigbeeCore.cpp:201] esp_zb_app_signal_handler(): Opening network for joining for 180 seconds
----------------------------------
GPIO Info:
------------------------------------------
GPIO : BUS_TYPE[bus/unit][chan]
--------------------------------------
3 : GPIO
9 : GPIO
12 : USB_DM
13 : USB_DP
14 : GPIO
16 : UART_TX[0]
17 : UART_RX[0]
============ After Setup End =============
[ 1527][I][ZigbeeCore.cpp:280] esp_zb_app_signal_handler(): Network(0x5dac) is open for 180 seconds
[ 29266][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: NWK Device Associated (0x12), status: ESP_OK
[ 29268][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: ZDO Device Update (0x30), status: ESP_OK
[ 32617][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: NWK Device Associated (0x12), status: ESP_OK
[ 32619][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: ZDO Device Update (0x30), status: ESP_OK
[ 32651][I][ZigbeeCore.cpp:251] esp_zb_app_signal_handler(): New device commissioned or rejoined (short: 0x4fd2)
[ 32652][V][ZigbeeCore.cpp:255] esp_zb_app_signal_handler(): Device capabilities: 0x8e
[ 32711][D][ZigbeeSwitch.cpp:31] findCb(): Found light endpoint
[ 32712][I][ZigbeeSwitch.cpp:44] findCb(): Try to bind On/Off
[ 32715][I][ZigbeeSwitch.cpp:19] bindCb(): Bound successfully!
[ 32715][I][ZigbeeSwitch.cpp:22] bindCb(): The light originating from address(0x4fd2) on endpoint(1)
[ 35974][I][ZigbeeSwitch.cpp:73] lightToggle(): Sending 'light toggle' command
[ 35975][I][ZigbeeEP.cpp:124] printBoundDevices(): Bound devices:
[ 35977][I][ZigbeeEP.cpp:127] printBoundDevices(): Device on endpoint 1, short address: 0x4fd2
[ 35978][I][ZigbeeEP.cpp:128] printBoundDevices(): IEEE Address: D0:28:DC:FE:FF:27:71:84
[ 36035][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x4fd2), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 0x0
[ 36234][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: ZDO Device Authorized (0x2f), status: ESP_OK
[ 37210][I][ZigbeeSwitch.cpp:73] lightToggle(): Sending 'light toggle' command
[ 37276][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x4fd2), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 0x0
[ 39705][I][ZigbeeCore.cpp:280] esp_zb_app_signal_handler(): Network(0x5dac) is open for 180 seconds
--> After a reset:
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
Model : ESP32-C6
Package : 1
Revision : 0.01
Cores : 1
CPU Frequency : 160 MHz
XTAL Frequency : 40 MHz
Features Bitfield : 0x00000052
Embedded Flash : No
Embedded PSRAM : No
2.4GHz WiFi : Yes
Classic BT : No
BT Low Energy : Yes
IEEE 802.15.4 : Yes
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
Total Size : 451212 B ( 440.6 KB)
Free Bytes : 422424 B ( 412.5 KB)
Allocated Bytes : 21692 B ( 21.2 KB)
Minimum Free Bytes: 417592 B ( 407.8 KB)
Largest Free Block: 401396 B ( 392.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
Chip Size : 4194304 B (4 MB)
Block Size : 65536 B ( 64.0 KB)
Sector Size : 4096 B ( 4.0 KB)
Page Size : 256 B ( 0.2 KB)
Bus Speed : 40 MHz
Bus Mode : QIO
------------------------------------------
Partitions Info:
------------------------------------------
nvs : addr: 0x00009000, size: 20.0 KB, type: DATA, subtype: NVS
otadata : addr: 0x0000E000, size: 8.0 KB, type: DATA, subtype: OTA
app0 : addr: 0x00010000, size: 1280.0 KB, type: APP, subtype: OTA_0
app1 : addr: 0x00150000, size: 1280.0 KB, type: APP, subtype: OTA_1
spiffs : addr: 0x00290000, size: 1388.0 KB, type: DATA, subtype: SPIFFS
zb_storage : addr: 0x003EB000, size: 16.0 KB, type: DATA, subtype: FAT
zb_fct : addr: 0x003EF000, size: 4.0 KB, type: DATA, subtype: FAT
coredump : addr: 0x003F0000, size: 64.0 KB, type: DATA, subtype: COREDUMP
-----------------------------------------
Software Info:
------------------------------------------
Compile Date/Time : Nov 24 2024 17:41:30
Compile Host OS : linux
ESP-IDF Version : v5.1.4-972-g632e0c2a9f-dirty
Arduino Version : 3.0.7
------------------------------------------
Board Info:
------------------------------------------
Arduino Board : XIAO_ESP32C6
Arduino Variant : XIAO_ESP32C6
Arduino FQBN : esp32:esp32:XIAO_ESP32C6:UploadSpeed=921600,CDCOnBoot=cdc,CPUFreq=160,FlashFreq=80,FlashMode=qio,FlashSize=4M,PartitionScheme=zigbee,DebugLevel=verbose,EraseFlash=all,JTAGAdapter=default,ZigbeeMode=zczr
============ Before Setup End ============
[ 991][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 12 already has type USB_DM (38) with bus 0x4080f17c
[ 992][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 13 already has type USB_DP (39) with bus 0x4080f17c
[ 992][D][Zigbee_On_Off_Switch.ino:110] setup(): Adding ZigbeeSwitch endpoint to Zigbee Core
[ 993][D][ZigbeeCore.cpp:63] addEndpoint(): Endpoint: 5, Device ID: 0x0000
[ 993][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x4200379e
[ 994][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 9 successfully set to type GPIO (1) with bus 0xa
[ 994][D][Zigbee_On_Off_Switch.ino:129] setup(): Calling Zigbee.begin()
[ 994][D][ZigbeeCore.cpp:94] zigbeeInit(): Initialize Zigbee stack
[ 1035][D][ZigbeeCore.cpp:101] zigbeeInit(): Register all Zigbee EPs in list
[ 1036][I][ZigbeeCore.cpp:109] zigbeeInit(): List of registered Zigbee EPs:
[ 1036][I][ZigbeeCore.cpp:111] zigbeeInit(): Device type: General On/Off switch, Endpoint: 5, Device ID: 0x0000
Waiting for Light to bound to the switch
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
Total Size : 451212 B ( 440.6 KB)
Free Bytes : 392848 B ( 383.6 KB)
Allocated Bytes : 50604 B ( 49.4 KB)
Minimum Free Bytes: 392848 B ( 383.6 KB)
Largest Free Block: 376820 B ([ 1044][V][ZigbeeCore.cpp:287] esp_zb_app_signal_handler(): ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
[ 1044][I][ZigbeeCore.cpp:179] esp_zb_app_signal_handler(): Zigbee stack initialized
[ 1049][I][ZigbeeCore.cpp:282] esp_zb_app_signal_handler(): Network(0x5dac) closed, devices joining not allowed.
[ 1051][I][ZigbeeCore.cpp:185] esp_zb_app_signal_handler(): Device started up in non factory-reset mode
[ 1051][I][ZigbeeCore.cpp:198] esp_zb_app_signal_handler(): Device rebooted
[ 1051][I][ZigbeeCore.cpp:201] esp_zb_app_signal_handler(): Opening network for joining for 180 seconds
368.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
GPIO : BUS_TYPE[bus/unit][chan]
--------------------------------------
3 : GPIO
9 : GPIO
12 : USB_DM
13 : USB_DP
14 : GPIO
16 : UART_TX[0]
17 : UART_RX[0]
============ After Setup End =============
[ 1150][I][ZigbeeCore.cpp:280] esp_zb_app_signal_handler(): Network(0x5dac) is open for 180 seconds[ 46677][E][ZigbeeSwitch.cpp:76] lightToggle(): Light not bound
[ 46678][I][ZigbeeEP.cpp:124] printBoundDevices(): Bound devices:
[ 47926][E][ZigbeeSwitch.cpp:76] lightToggle(): Light not bound
[ 49143][E][ZigbeeSwitch.cpp:76] lightToggle(): Light not bound
Other Steps to Reproduce
I first mentioned this problem here: #10135 (comment)
With the espressif SDK this problem seems already to be solved, regarding:
espressif/esp-idf#11904
Therefore, I also tried the example from the esp zigbee sdk which is NOT showing the problem.
If necessary, you can see my fork here, which is working on a xiao esp32-c6, because I needed to enable the internal antenna.
I think, the problem is that the arduino implementation is using the variable _is_bound and the list of bound devices which are not initialized based on remebered connections.
-> How to "save" the list of bound_devices or releoad them after a power cycle?
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.