Now I have written a code with Arduino that is supposed to transmit a binary input via Zigbee.
I can integrate the device in Zigbee2Mqtt, but it does not update the status. However, if I add another endpoint, e.g., a light, the binary input updates without any problems.
If I want to set the power source to battery on the binary input, for example, or set the endpoint number to something other than 1, the code crashes reproducibly and the ESP constantly restarts.
Are there any restrictions?
Here is my Code:
Code: Select all
#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif
#include "Zigbee.h"
#include "driver/rtc_io.h"
/* Zigbee binary sensor device configuration */
#define BINARY_DEVICE_ENDPOINT_NUMBER 1
#define LED_PIN LED_BUILTIN
#define ZIGBEE_LIGHT_ENDPOINT 10
#define GET_PIN_BITMASK(GPIO) (1ULL << GPIO)
uint8_t button = BOOT_PIN;
uint8_t sensor_pin = 11;
ZigbeeBinary zbBinaryInput = ZigbeeBinary(BINARY_DEVICE_ENDPOINT_NUMBER);
ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT);
bool lastState = true;
bool sleep_disabled = false;
void sensorSwitch(bool state) {
if (sleep_disabled && lastState == state) {
return;
}
Serial.println("Input changed to: " + String(state));
zbBinaryInput.setBinaryInput(state);
zbBinaryInput.reportBinaryInput();
lastState = state;
}
void setLED(bool value) {
digitalWrite(LED_PIN, value);
}
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
default: Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
}
void setup() {
Serial.begin(115200);
Serial.println("Starting...");
print_wakeup_reason();
// Init button, pin, led
pinMode(button, INPUT_PULLUP);
pinMode(sensor_pin, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
zbLight.onLightChange(setLED);
// Optional: set Zigbee device name and model
zbBinaryInput.setManufacturerAndModel("Espressif", "My ZigbeeBinarySensor");
zbLight.setManufacturerAndModel("Espressif", "My ZigbeeBinarySensor");
// Set up binary input
zbBinaryInput.addBinaryInput();
zbBinaryInput.setBinaryInputDescription("state");
//zbBinaryInput.setPowerSource(ZB_POWER_SOURCE_BATTERY);
// Add endpoints to Zigbee Core
Zigbee.addEndpoint(&zbBinaryInput);
Zigbee.addEndpoint(&zbLight);
Serial.println("Starting Zigbee...");
// When all EPs are registered, start Zigbee in End Device mode
if (!Zigbee.begin()) {
Serial.println("Zigbee failed to start!");
Serial.println("Rebooting...");
ESP.restart();
} else {
Serial.println("Zigbee started successfully!");
}
Serial.println("Connecting to network");
while (!Zigbee.connected()) {
Serial.print(".");
delay(100);
}
Serial.println("Connected");
}
void loop() {
if (digitalRead(sensor_pin) == LOW) {
sensorSwitch(true);
esp_sleep_enable_ext1_wakeup_io(GET_PIN_BITMASK(sensor_pin), ESP_EXT1_WAKEUP_ANY_HIGH);
esp_sleep_enable_ext1_wakeup_io(GET_PIN_BITMASK(button), ESP_EXT1_WAKEUP_ANY_LOW);
}
else
{
sensorSwitch(false);
esp_sleep_enable_ext1_wakeup_io(GET_PIN_BITMASK(sensor_pin)|GET_PIN_BITMASK(button), ESP_EXT1_WAKEUP_ANY_LOW);
}
// Checking button for factory reset and reporting
if (digitalRead(button) == LOW) { // Push button pressed
// if button is pressed, disable sleep, blink 2 times
sleep_disabled = true;
digitalWrite(LED_PIN, HIGH);
delay(50);
digitalWrite(LED_PIN, LOW);
delay(50);
digitalWrite(LED_PIN, HIGH);
delay(50);
digitalWrite(LED_PIN, LOW);
// Key debounce handling
delay(100);
int startTime = millis();
while (digitalRead(button) == LOW) {
delay(50);
if ((millis() - startTime) > 5000) {
// If key pressed for more than 5secs, factory reset Zigbee and reboot
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
delay(1000);
Zigbee.factoryReset();
}
}
}
delay(100);
if (!sleep_disabled) {
Serial.println("Deep sleep start");
Serial.flush();
esp_deep_sleep_start();
}
}