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
+ /* *
16
+ * @brief This example demonstrates Zigbee Window Covering.
17
+ *
18
+ * The example demonstrates how to use Zigbee library to create a end device window covering device.
19
+ * The window covering is a Zigbee end device, which is moving the blinds (lift+tilt) and reporting
20
+ * its current position to the Zigbee network.
21
+ *
22
+ * Use setCoveingType() to set the type of covering (blind, shade, etc.).
23
+ *
24
+ * The example also demonstrates how to use the button to manually control the lift position.
25
+ *
26
+ * Proper Zigbee mode must be selected in Tools->Zigbee mode
27
+ * and also the correct partition scheme must be selected in Tools->Partition Scheme.
28
+ *
29
+ * Please check the README.md for instructions and more detailed description.
30
+ *
31
+ * Created by hennikul and Jan Procházka (https://github.com/P-R-O-C-H-Y/)
32
+ */
33
+
34
+ #ifndef ZIGBEE_MODE_ED
35
+ #error "Zigbee end device mode is not selected in Tools->Zigbee mode"
36
+ #endif
37
+
38
+ #include " ZigbeeCore.h"
39
+ #include " ep/ZigbeeWindowCovering.h"
40
+
41
+
42
+ #define ZIGBEE_COVERING_ENDPOINT 10
43
+ #define BUTTON_PIN 9 // ESP32-C6/H2 Boot button
44
+
45
+ #define MAX_LIFT 200 // centimeters from open position (0-900)
46
+ #define MIN_LIFT 0
47
+
48
+ #define MAX_TILT 40 // centimeters from open position (0-900)
49
+ #define MIN_TILT 0
50
+
51
+ uint16_t currentLift = MAX_LIFT;
52
+ uint8_t currentLiftPercentage = 100 ;
53
+
54
+ uint16_t currentTilt = MAX_TILT;
55
+ uint8_t currentTiltPercentage = 100 ;
56
+
57
+ ZigbeeWindowCovering zbCovering = ZigbeeWindowCovering(ZIGBEE_COVERING_ENDPOINT);
58
+
59
+ void setup () {
60
+ Serial.begin (115200 );
61
+
62
+ // Init button for factory reset
63
+ pinMode (BUTTON_PIN, INPUT_PULLUP);
64
+
65
+ // Optional: set Zigbee device name and model
66
+ zbCovering.setManufacturerAndModel (" Espressif" , " WindowBlinds" );
67
+
68
+ // Set proper covering type, it defines which attributes are available
69
+ zbCovering.setCoveringType (BLIND_LIFT_AND_TILT);
70
+
71
+ // Set configuration: operational, online, not commands_reversed, lift / tilt closed_loop, lift / tilt encoder_controlled
72
+ zbCovering.setConfigStatus (true , true , false , true , true , true , true );
73
+
74
+ // Set mode: not motor_reversed, calibration_mode, not maintenance_mode, not leds_on
75
+ zbCovering.setMode (false , true , false , false );
76
+
77
+ // Set limits of motion
78
+ zbCovering.setLimits (MIN_LIFT, MAX_LIFT, MIN_TILT, MAX_TILT);
79
+
80
+ // Set callback function for open, close, filt and tilt change, stop
81
+ zbCovering.onOpen (fullOpen);
82
+ zbCovering.onClose (fullClose);
83
+ zbCovering.onGoToLiftPercentage (goToLiftPercentage);
84
+ zbCovering.onGoToTiltPercentage (goToTiltPercentage);
85
+ zbCovering.onStop (stopMotor);
86
+
87
+ // Add endpoint to Zigbee Core
88
+ Serial.println (" Adding ZigbeeWindowCovering endpoint to Zigbee Core" );
89
+ Zigbee.addEndpoint (&zbCovering);
90
+
91
+ // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE
92
+ Serial.println (" Calling Zigbee.begin()" );
93
+ if (!Zigbee.begin ()) {
94
+ Serial.println (" Zigbee failed to start!" );
95
+ Serial.println (" Rebooting..." );
96
+ ESP.restart ();
97
+ }
98
+ Serial.println (" Connecting to network" );
99
+ while (!Zigbee.connected ()) {
100
+ Serial.print (" ." );
101
+ delay (100 );
102
+ }
103
+ Serial.println ();
104
+
105
+ // Set initial position
106
+ zbCovering.setLiftPercentage (currentLiftPercentage);
107
+ zbCovering.setTiltPercentage (currentTiltPercentage);
108
+ }
109
+
110
+ void loop () {
111
+ // Checking button for factory reset
112
+ if (digitalRead (BUTTON_PIN) == LOW) { // Push button pressed
113
+ // Key debounce handling
114
+ delay (100 );
115
+ int startTime = millis ();
116
+ while (digitalRead (BUTTON_PIN) == LOW) {
117
+ delay (50 );
118
+ if ((millis () - startTime) > 3000 ) {
119
+ // If key pressed for more than 3secs, factory reset Zigbee and reboot
120
+ Serial.printf (" Resetting Zigbee to factory settings, reboot.\n " );
121
+ Zigbee.factoryReset ();
122
+ delay (30000 );
123
+ }
124
+ }
125
+ // Manual lift controll simulation by pressing button
126
+ manualControl ();
127
+ }
128
+ delay (500 );
129
+ }
130
+
131
+ void fullOpen (){
132
+ /* This is where you would trigger your motor to go to full open state, currentLift should
133
+ be updated until full open has been reached in order to provide feedback to controller of actual position
134
+ The stop can be always called, so the movement can be stopped at any time */
135
+
136
+ // Our cover updates instantly!
137
+ currentLift = MAX_LIFT;
138
+ currentLiftPercentage = 100 ;
139
+ Serial.println (" Opening cover" );
140
+ // Update the current position
141
+ zbCovering.setLiftPercentage (currentLiftPercentage);
142
+ }
143
+
144
+ void fullClose (){
145
+ /* This is where you would trigger your motor to go to full close state, currentLift should
146
+ be updated until full close has been reached in order to provide feedback to controller of actual position
147
+ The stop can be always called, so the movement can be stopped at any time */
148
+
149
+ // Our cover updates instantly!
150
+ currentLift = MIN_LIFT;
151
+ currentLiftPercentage = 0 ;
152
+ Serial.println (" Closing cover" );
153
+ // Update the current position
154
+ zbCovering.setLiftPercentage (currentLiftPercentage);
155
+ }
156
+
157
+ void goToLiftPercentage (uint8_t liftPercentage) {
158
+ /* This is where you would trigger your motor to go towards liftPercentage, currentLift should
159
+ be updated until liftPercentage has been reached in order to provide feedback to controller */
160
+
161
+ // Our simulated cover updates instantly!
162
+ currentLift = (liftPercentage * MAX_LIFT) / 100 ;
163
+ currentLiftPercentage = liftPercentage;
164
+ Serial.printf (" New requsted lift from Zigbee: %d (%d)\n " , currentLift, liftPercentage);
165
+
166
+ // Update the current position
167
+ zbCovering.setLiftPercentage (currentLiftPercentage); // or setLiftPosition()
168
+ }
169
+
170
+ void goToTiltPercentage (uint8_t tiltPercentage) {
171
+ /* This is where you would trigger your motor to go towards tiltPercentage, currentTilt should
172
+ be updated until tiltPercentage has been reached in order to provide feedback to controller */
173
+
174
+ // Our simulated cover updates instantly!
175
+ currentTilt = (tiltPercentage * MAX_TILT) / 100 ;
176
+ currentTiltPercentage = tiltPercentage;
177
+ Serial.printf (" New requsted tilt from Zigbee: %d (%d)\n " , currentTilt, tiltPercentage);
178
+
179
+ // Update the current position
180
+ zbCovering.setTiltPercentage (currentTiltPercentage); // or setTiltPosition()
181
+ }
182
+
183
+
184
+ void stopMotor () {
185
+ // Motor can be stopped while moving cover toward current target, when stopped the actual position should be updated
186
+ Serial.println (" Stopping motor" );
187
+ // Update the current position of both lift and tilt
188
+ zbCovering.setLiftPercentage (currentLiftPercentage);
189
+ zbCovering.setTiltPercentage (currentTiltPercentage);
190
+ }
191
+
192
+ void manualControl () {
193
+ // Simulate lift percentage move by increasing it by 20% each time
194
+ currentLiftPercentage += 20 ;
195
+ if (currentLiftPercentage > 100 ) {
196
+ currentLiftPercentage = 0 ;
197
+ }
198
+ zbCovering.setLiftPercentage (currentLiftPercentage);
199
+ // Also setLiftPosition() can be used to set the exact position instead of percentage
200
+ }
0 commit comments