📜 ⬆️ ⬇️

Z-Wave LED controller with encoder. Z-Uno + MOSFET + Encoder



In the room where the child plays, I installed an additional light in the form of LED tape. Initially, I planned that I would control the brightness of the tape, it is convenient to adjust the night light. I already had a Z-Wave 220V dimmer, so it was cheaper to buy a dimmable 12V transformer for 1000r than a special RGBW controller from Fibaro for 5500r.

This solution works, but there are downsides:


After a year of use, I decided to make my Z-Wave LED controller, but with an encoder and in the case of a dimmer, for installation in a power socket.

The circuit diagram of the device is elementary, the encoder is directly connected to the Z-Uno with 3 pins: pin A, pin B and a button. Mosfet connects to PWM pinu.



Materials and prices:
NoMaterialA photoPrice
oneZ-Wave Z-Uno board3500 r
2MOSFET IRLR872927 r
3Encoder EC1150 r

The Z-Wave Z-Uno board is programmed in the Arduino environment, the sketch for processing signals from the encoder and controlling mosfets takes only 143 lines of code with comments. The sketch works as follows:

Every 128 microsec, by interruption from the timer, we check which way the wheel is turned; we protect ourselves from bounce by a 4-fold state check. In the loop, we check the button press, with each press we turn off the tape or turn it on to the previous level of brightness. Brightness can be set either from the encoder or from a telephone or another Z-Wave switch.



Rotary Dimmer LED Control Code
#define PUSH_BUTTON 23 #define ENCODER_CHA_PIN 19 #define ENCODER_CHB_PIN 20 #define LEV_SHIFT 8 #define ENCODER_DEBONCE 4 #define STATE_IDLE 0xFF #define STATE_SKIP 0xFE ZUNO_SETUP_ISR_GPTIMER(gpt_handler); ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_MULTILEVEL(getter, setter)); byte level = 0; byte last_reported_level = 0; byte g_state = STATE_IDLE; byte g_pins = 0; byte g_debounce_time = 0; byte last_push_button_state = HIGH; byte stored_level = 0; dword last_level_changed_time = 0; // Runs every 128 μs void gpt_handler() { byte pins = 0; pins = !digitalRead(ENCODER_CHA_PIN); if(!digitalRead(ENCODER_CHB_PIN)) pins |= 2; if(g_pins == pins) { // Is the state stable? g_debounce_time++; if(g_debounce_time>ENCODER_DEBONCE) { if(g_state == STATE_IDLE) { g_state = pins; } else if(g_state == STATE_SKIP) { if(pins == 0) g_state = 0; } else { if((g_state == 0 && pins == 1) || (g_state == 1 && pins == 3) || (g_state == 3 && pins == 2) || (g_state == 2 && pins == 0) ) { if (level < 39) { level++; } else if ((level + LEV_SHIFT) <= 255) { level += LEV_SHIFT; } else if ((level + LEV_SHIFT) > 255){ level = 255; } } else if((g_state == 0 && pins == 2) || (g_state == 2 && pins == 3) || (g_state == 3 && pins == 1) || (g_state == 1 && pins == 0) ) { if (level <= 39 && level !=0) { level--; } else if (level >= LEV_SHIFT) { level -= LEV_SHIFT; } else if (level < 0) { level = 0; } } if(g_state != pins) g_state = STATE_SKIP; } g_debounce_time = 0; } } else { g_debounce_time = 0; } g_pins = pins; } void setup() { Serial.begin(); pinMode(PUSH_BUTTON, INPUT_PULLUP); pinMode(ENCODER_CHA_PIN, INPUT); pinMode(ENCODER_CHB_PIN, INPUT_PULLUP); zunoGPTInit(ZUNO_GPT_SCALE1024|ZUNO_GPT_CYCLIC); // 32 MHz/1024 = 31.25 kHz (tick is 32 μs) zunoGPTSet(4); // 32 μs * 4 = 128 μs zunoGPTEnable(1); } void loop() { // Do we need to report the level? if(last_reported_level != level) { if (level > 0) { stored_level = level; } last_reported_level = level; analogWrite(PWM1, level); last_level_changed_time = millis(); Serial.print("Level: "); Serial.println(level); } // Button handler byte current_push_button_state = digitalRead(PUSH_BUTTON); if (current_push_button_state != last_push_button_state) { last_push_button_state = current_push_button_state; // if button pressed if (last_push_button_state == LOW) { // if LED turned ON, turn OFF if (level > 0) { analogWrite(PWM1, 0); level = 0; } // Restore last level else { analogWrite(PWM1, stored_level); level = stored_level; } } } // Send report if 2 seconds level not changed if (last_level_changed_time && millis() > last_level_changed_time + 2000) { last_level_changed_time = 0; zunoSendReport(1); } } void setter(byte value) { if (value > 99) { value = 99; } level = (long)value * 255 / 99; analogWrite(PWM1, level); } byte getter(void) { return last_reported_level * 99 / 255; } 


To change the brightness of the tape using a dimmer, which I used to use, it was necessary to hold the key up or down, this is not very convenient, it is difficult to adjust the desired level of brightness. And the dimmer looks like an ordinary switch, and not like a classic dimmer with a wheel to which many are accustomed.



For the new Z-Wave LED controller, I modified the dimmer housing - I drilled a hole for the encoder and slightly changed the frame attachment to use the frame from another switch. For design, do not kick, made from scrap materials. You can use the finished body from the usual dimmer to look aesthetically pleasing.



LUT decides! For the manufacture of a single copy of the board, I don’t know the technology better than LUT, so I made 2 boards that fit perfectly in the case of the old dimmer. In the lower part there is a Z-Uno, mosfet and a power supply and tape connector, by the way, the mosfets are designed for voltages up to 30V, so the tape can be used as 12V and 24V, without a radiator, it is better not to exceed 5A.



In the upper part is located only the encoder.



Combining a sandwich from the boards and placing it in the case, we have a Z-Wave LED controller.



At the moment, the Z-Wave LED controller is not installed in the plug-in and lies on the TV cabinet. Some time I will still test the work.



But now the convenience of controlling the LED ribbon has greatly increased; when controlled from the wheel or the bedside switch, the brightness changes instantly. In Z-Wave, the dimming scale is in the range from 0 to 99, with the help of the wheel you can select the brightness level from 0 to 255. When rotating by 1 division after 0, the LEDs light up a little, at night it will not wake anyone, but will help not to step on the accidentally forgotten LEGO cube on the floor.

It took 3 evenings to make the device, 1 evening - writing the firmware, 1 evening LUT, 1 evening work with a file.

UPDATED 1/21/2018
There are several ideas for finalizing the design, I would like to receive comments.
Idea 1. I’ll order a nice beautiful dimmer with a glass panel on alik and replace the stuffing, I can handle it.
Idea 2. To use a twirl with a display like the climate control in a car, the display will show the current brightness level. The problem is that I can not find a spinner with a display separately from the climate control.

UPDATED 01/23/2018
In the mounting plate Schneider Electric Odace (80 r in Electrical installation) assembled the LED circuit of the controller.



Frame Odace 90 p stands (which is not in the photo), but the twirl is not sold separately, but I had it in stock. Any additional case is not planned, the device is completely ready.

Source: https://habr.com/ru/post/409727/