Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ESP32-C6 ZigbeeDimmableLight + Sensor Touch #11467

Closed Answered by MikaFromTheRoof
JimDarmody asked this question in Q&A
Discussion options

Hello,

I try to configure my esp32-c6 to control a LED light in PWM with Zigbee and a touch sensor, but I have a problem with the Zigbee feedback.

No issue to control the light in Zigbee but when I touch the sensor manually to enable/disable the light, nothing is sent in Zigbee, the light status is not updated (I'm on zigbee2mqtt).

I'm not sure how to get the touch sensor to change the Zigbee status of the light.

Thanks for your help

(my code if you need)

#include "Zigbee.h"
/* Pin configuration */
#define PIN_PWM 14
#define PIN_TOUCH 20
#define PIN_RESET BOOT_PIN
/* PWM configuration */
#define PWM_FREQ 2000
#define PWM_RESOLUTION 8
#define PWM_CHANNEL 0
/* Zigbee configuration */
#define ZIGBEE_ENDPOINT 10
#define MANUFACTURER "Espressif"
#define MODEL "ZBLightTouch"
/* Button configuration */
#define RESET_DELAY 3000 // Factory reset delay (3 seconds)
#define TOUCH_DEBOUNCE 200 // Touch sensor debounce time (ms)
/* Zigbee light instance */
ZigbeeDimmableLight zbDimmableLight(ZIGBEE_ENDPOINT);
// LED functions
void setLight(bool state, uint8_t level) {
 uint8_t duty = state ? level : 0;
 ledcWriteChannel(PWM_CHANNEL, duty);
 Serial.printf("setLight -> State: %s | Brightness: %u\n", state ? "ON" : "OFF", duty);
}
// Create a task on identify call to handle the identify function
void identify(uint16_t time) {
 static bool blink = false;
 log_d("Identify called for %d seconds", time);
 
 if (time == 0) {
 zbDimmableLight.restoreLight();
 return;
 }
 for (int i = 0; i < time * 2; ++i) {
 ledcWriteChannel(PWM_CHANNEL, blink ? 254 : 0);
 blink = !blink;
 delay(500);
 }
 zbDimmableLight.restoreLight();
}
void setup() {
 // Initialize serial communication
 Serial.begin(115200);
 Serial.println("\nStarting Zigbee light...");
 // Configure pins
 pinMode(PIN_TOUCH, INPUT);
 pinMode(PIN_RESET, INPUT_PULLUP);
 // Configure PWM
 if (!ledcAttachChannel(PIN_PWM, PWM_FREQ, PWM_RESOLUTION, PWM_CHANNEL)) {
 Serial.println("Error: PWM configuration failed");
 while (true);
 }
 ledcWriteChannel(PWM_CHANNEL, 0); // Off at startup
 // Configure Zigbee
 zbDimmableLight.onLightChange(setLight);
 zbDimmableLight.onIdentify(identify);
 zbDimmableLight.setManufacturerAndModel(MANUFACTURER, MODEL);
 zbDimmableLight.setPowerSource(ZB_POWER_SOURCE_MAINS);
 Zigbee.addEndpoint(&zbDimmableLight);
 // Start Zigbee network
 if (!Zigbee.begin()) {
 Serial.println("Error: Zigbee startup failed. Restarting...");
 delay(1000);
 ESP.restart();
 }
 // Wait for Zigbee network connection
 Serial.print("Connecting to Zigbee network");
 while (!Zigbee.connected()) {
 Serial.print(".");
 delay(100);
 }
 Serial.println("\nZigbee connected!");
}
void loop() {
 static bool lastTouchState = false;
 // Handle touch sensor
 bool touchState = digitalRead(PIN_TOUCH);
 if (touchState && !lastTouchState) {
 bool currentState = zbDimmableLight.getLightState();
 zbDimmableLight.setLight(!currentState, zbDimmableLight.getLightLevel());
 Serial.printf("Touch toggle -> %s\n", !currentState ? "ON" : "OFF");
 delay(TOUCH_DEBOUNCE);
 }
 lastTouchState = touchState;
 // Handle factory reset
 if (digitalRead(PIN_RESET) == LOW) {
 delay(100);
 int start = millis();
 while (digitalRead(PIN_RESET) == LOW) {
 delay(50);
 if ((millis() - start) > RESET_DELAY) {
 Serial.println("Zigbee factory reset...");
 delay(1000);
 Zigbee.factoryReset();
 }
 }
 }
 delay(50);
}
You must be logged in to vote

Yes, @P-R-O-C-H-Y is right. I had exactly the same problem.

I asked for help in the Zigbee2MQTT Discord, but only got quite diffuse answers. They said, that it might be possible to get the light state to report automatically by using external converters. I also got the answer, that there would be no default reporting in place for the light state, when it doesn't get reported to Z2M automatically. I don't know if this is really the case when using the Espressif Arduino Core library, but since it works with ZHA without any further configuration I believe the light endpoint should already have some default reporting configuration. Maybe @P-R-O-C-H-Y can elaborate more on this point.

If you w...

Replies: 2 comments 1 reply

Comment options

Hi @JimDarmody, this code will work for ZHA. I think z2m does not poll the light attributes automatically. You need to set it up manually.
Maybe @MikaFromTheRoof can help here as he have experience with Z2M.

You must be logged in to vote
0 replies
Comment options

Yes, @P-R-O-C-H-Y is right. I had exactly the same problem.

I asked for help in the Zigbee2MQTT Discord, but only got quite diffuse answers. They said, that it might be possible to get the light state to report automatically by using external converters. I also got the answer, that there would be no default reporting in place for the light state, when it doesn't get reported to Z2M automatically. I don't know if this is really the case when using the Espressif Arduino Core library, but since it works with ZHA without any further configuration I believe the light endpoint should already have some default reporting configuration. Maybe @P-R-O-C-H-Y can elaborate more on this point.

If you want to ask for help in the Z2M Discord yourself, this is the invitation link to the Discord: https://discord.gg/uZgC4vtv
I would love to hear about your findings!

Nonetheless as @P-R-O-C-H-Y already said, there is a way to add the reporting manually in Z2M:

  • choose the device
  • go to tab "Reporting"
  • add a reporting entry by editing the last line
  • Select endpoint: Select your light endpoint
  • Select cluster: Select the OnOff cluster
  • For attribute select OnOff again
  • Min rep interval: 0 (will always report instantly, when state has changed)
  • Max rep interval: 3600 (not important in that case, you can leave it as is)
  • Min rep change: 1
  • Click "Apply"
  • Repeat the same for the light level cluster
  • For Cluster select "LevelCtl" and for Attribute select "currentLevel"
  • Min rep, Max rep, Min rep change the same as above

If you have any further questions dont hesitate to ask.

You can also join the Arduino Core for Espressif Discord, if you want: https://discord.gg/X4smTNPE

You must be logged in to vote
1 reply
Comment options

One additional note: it might happen that the light state on the exposes tab does not refresh immediately even if the state change is correctly reported to Z2M. You might have to hit the refresh button in your browser or switch to another tab and back to see the change. Light level always refreshes correctly though. But don't worry. The state changes get handed over to Home Assistant even if it's not displayed directly in the Z2M frontend.

Answer selected by P-R-O-C-H-Y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /