Hello to all do-it-yourselfers! Today we will look at one of the many applications led strip type WS2812B on addressable RGB LEDs. Such tapes (as well as separately mounted WS2812B LEDs) can be used to illuminate the “Ambilight” background of computer monitors and TVs, dynamic lighting in a car, a picture, a photo frame, an aquarium, and so on. They are widely used in the design of any premises, in the form of New Year's illuminations or light shows. The use of LED strip type WS2812B makes it possible to obtain a large number of interesting projects.

The WS2812B LED is an RGB LED embedded in the same housing with the WS2801 chip.


The WS2812B LED itself is a SMD element designed for surface mounting. Inside, the LED consists of red light (red), green light (green) and blue light (blue) crystals in one package. With this LED, you can get a wide variety of color shades of light radiation.

The RGB LED is controlled via the microcontroller board Arduino.
I received a WS2812B LED strip from the Chinese. It is a 1 meter long segment with 144 LEDs. I have long wanted to try for different experiments. With the help of libraries for Arduino - Adafruit Neopixel and Fast led, you can get a lot of very unusual lighting effects. But then I decided to try to make dynamic turn signals for a car in the so-called “Audi style”. I haven’t put this scheme into practice yet (how will our gibbddeshniks take it?), but the effect turned out to be very attractive.

The Arduino Uno board serves as a controller for controlling the LED strip, other boards can be used - Arduino Nano, Arduino Pro mini).
Watch the whole process in the video:


List of tools and materials.
-Arduino Uno board;
- step-down board 12V \ 5V at 3A;
- resistors 100Kom-4pcs;
-resistors 47Kom-4pcs;
- resistors 500 Ohm-1pc;
-buttons (to simulate the inclusion of signals) -4pcs;
-bread board
-screwdriver;
laboratory power supply
- soldering iron;
- cambric;
-tester.
- connecting wires.

Step one. Schema assembly.


I assembled the circuit using a breadboard (bradboard). Resistors connected to the Arduino digital inputs are needed to convert the car's input signals from 12 to 5 volts. 500 ohm resistor to protect the control line of the WS2812B LED strip.
Board photo


As a converter from 12V to 5V, I used a ready-made board from Aliexpress. Any converter with suitable parameters can be used. The converter is needed for stable power supply of Arduino and LED strip WS2812B.


Step two. Arduino programming.

The digital inputs of the Arduino board No. 3,4 are used to turn on the left and right turns. Pin number 5 - turn on the brake light, pin number 6 - turn on the reverse. Pin number 8 - control signal tape WS2812B.

In the Arduino IDE, upload the sketch (link above). Two sketch options - one for the front of the car, the other for the back. Use whichever you need. At the beginning of the sketch, you can set the number of LEDs you need. You can also adjust the speed of the turn signals according to your auto. You can also change the brightness of the LEDs with the strip.Color(103,31,0) parameter - change the first two digits from 0 to 255. That is, you can experiment a little.

When you press the desired button, we give a signal to enable the desired parameter. With the correct assembly of the circuit, it usually starts working immediately.

Photo in progress.






A good experiment turned out with this weekend design. It was interesting

He said last year "Gop" - it's time to jump :)
Or rather, to do the promised review of running turn signals.
I ordered 1 meter of black tape WS2812B (144 LEDs) in a silicone tube, when ordering, I chose "Black 1m 144led IP67" (perhaps someone will like White color substrates, there is such a choice).

A small caveat

I received a tape soldered from two half-meter pieces. The downside of this is the weak point of the soldering (contacts may break over time) and the increased gap between the LEDs.
Check with the seller before buying

Contact wires were soldered to the tape on both sides for serial connection of several pieces, because I didn’t need it, then I soldered it off on one side of the wire, sealed everything with a neutral sealant and wound some more black electrical tape.



Attached to glass with double-sided transparent adhesive tape, for example,.

Installation details

I degreased the surfaces, first I glued the adhesive tape to the tube (I will call it that, even though the cross section is rectangular), cut off the protruding excess of a wider tape, put the edges of the tube into the gap between the ceiling and the upper parts of the decorative panels of the rear pillars (I hid the contact wires with the connector behind one panel ), centered and began to press against the glass, slowly pulling out the protective layer of the tape.
Unfortunately, there is no video - there were no free hands for shooting, and everyone's cars are different.
If something is not clear - ask in the comments.
The summer heat test was successful - nothing peeled off or floated.
The only negative is that the angle of inclination of the glass is gentle, the LEDs shine more upwards. On a sunny day it is hard to see, but since these are duplicate signals, then

Now let's move on to the electronic stuffing.
I used but recently discovered

For about the same cost, we get more buns

The sketch without any modifications will also work on Wemos when programming in the Arduino IDE, and if you implement a small web server, then when connected to it via Wi-Fi, you can change the values ​​\u200b\u200bof variables such as the delay time between blinks, the amount of deceleration during emergency braking etc.
Here in the future, if someone is interested in implementing a project on ESP8266, I can post an example for changing settings via the web interface, saving them to EEPROM, and then reading.
The launch of the web server can be implemented, for example, by turning on the turn signal and pressing the brake pedal when the ignition is turned on (in the setup procedure, poll the status of the corresponding inputs).

To implement the flashing mode during heavy braking was purchased
The sketch monitors the level of deceleration when the brake pedal is pressed, if it exceeds 0.5G (hard deceleration, but no brake squeal), then a flashing mode is activated for a few seconds to attract additional attention.
Control signals to the Arduino inputs from the "plus" of the stops, turn signals and reverse are fed through galvanic isolation - optocouplers with current limiting resistors, which eventually form the LOW level at the Arduino inputs (constantly pulled to the plus through 10kΩ resistors).
Power - 5 volts through a DC-DC buck converter.
The whole thing is folded like a sandwich and packed in a suitable box, on which I marked the installation direction with an arrow for the correct orientation of the gravity sensor

Scheme and photo



The value of the pull-up (to plus) resistors is standard - 10 kOhm, current-limiting optocoupler resistors - 1 kOhm. Optocouplers dropped out of old boards, two got PC123, two - PC817.


In the first photo you can see two additional pins, I made them for the turn signals. Since in my car, when the steering column lever is turned on, a short to ground occurs, I connected the wires to the lever block and the Arduino inputs. If the steering column switch switches plus or take a signal from the "+" bulbs of the left / right turn signal, then connect them through a galvanic isolation.



Well, now the sketch itself (Arduino IDE)

#include #include //a few general comments // I disabled one of the outer LEDs, because they reflected on decorative panels racks //seen in the example of this loop for (int i=1; i<143; i++) //если отключать не нужно, заменяем на for (int i=0; i<144; i++) //задний ход и аварийка у меня не используются, т.к. в первом случае яркость никакая, во втором надо подключать входы к лампам поворотников //поворотники и стоп-сигнал одновременно не включаются, чтобы это реализовать, нужно переписывать соответствующий код скетча (делить ленту на три секции, подбирать тайминги миганий, менять диапазон переменных циклов). //Дерзайте - все в ваших руках // Пин для подключения управляющего сигнала светодной ленты const int PinLS = 2; //Пины для подключения датчиков //если более удобно будет подключать контакты в другом порядке - просто поменяйте значения переменных const int buttonPinL = 3; const int buttonPinR = 4; const int buttonPinS = 6; const int buttonPinD = 5; //начальные статусы входов (подтянуты к плюсу) int buttonStateS = HIGH; int buttonStateD = HIGH; int buttonStateL = HIGH; int buttonStateR = HIGH; // пауза pause_pov1 (в миллисекундах) нужна, чтобы синхронизировать циклы "пробегания" полоски и включения лампочки поворотника // такое может быть, если используется меньше половины светодиодов // в моем случае паузы нет (pause_pov1 = 0) int pause_pov1 = 1; // этой паузой регулируем длительность состояния, когда все светодиоды выключены //я определял опытным путем - включал поворотник, засекал по отдельности время ста мыргов лампочкой и ста беганий полоски, разницу делил на 100, на полученное время увеличивал или уменьшал значение переменной (в зависимости от того, отставали или убегали вперед лампочки) int pause_pov2 = 62; // переменная для получения значения ускорения int ix; Adafruit_NeoPixel strip = Adafruit_NeoPixel(144, PinLS, NEO_GRB + NEO_KHZ800); Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); void setup() { pinMode(buttonPinS, INPUT); pinMode(buttonPinD, INPUT); pinMode(buttonPinL, INPUT); pinMode(buttonPinR, INPUT); strip.begin(); // гасим ленту for (int i=0; i<144; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); accel.begin(); // ограничиваем измеряемый диапазон четырьмя G (этого хватит с большим запасом) accel.setRange(ADXL345_RANGE_4_G); accel.setDataRate(ADXL345_DATARATE_100_HZ); } void loop() { // СТОПЫ: если включены - высший приоритет //Чтобы сделать меняющуюся по ширине полоску в зависимости от интенсивности торможения //(уточнение - никакой светомузыки, ширина полосы после нажатия на тормоз не меняется!) //от плавного торможения до тапки в пол. //Добавляем еще одну переменную, например, ix2, //присваиваем ей значение ix с коэффициентом умножения, //заодно инвертируем и округляем до целого //ix = event.acceleration.x; //ix2 = -round(ix*10); //ограничиваем для плавного торможения в пробках //(чтобы не менялась при каждом продвижении на 5 метров) //if (ix2<10) ix2 = 0; //и для резкого торможения. //Реальный диапазон изменения переменной ix - от 0 до -5 //для максимальной ширины полосы при G равном или большем 0.5 //if (ix2 >50) ix2 = 50; //then change the cycles in the STOP block for (int i=1; i<143; i++) на for (int i=51-ix2; i<93+ix2; i++) //Получаем минимальную ширину полоски ~30 см (для стояния в пробке) и максимальную для резкого торможения //конец комментария buttonStateS = digitalRead(buttonPinS); if (buttonStateS == LOW) { sensors_event_t event; accel.getEvent(&event); ix = event.acceleration.x; // проверка резкого торможения - мигающий режим // значение 5 - это 0,5G, минус - торможение if (ix < -5) { for (int is=0; is<15; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(240,0,0)); strip.show(); delay(10 + is*10); for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); delay(10 + is*3); buttonStateS = digitalRead(buttonPinS); if (buttonStateS == HIGH) return; } } // помигали - и хватит, включаем постоянный режим, если педаль тормоза еще нажата // или если не было резкого торможения и предыдущее условие не сработало if (buttonStateS == LOW) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(200,0,0)); strip.show(); while(buttonStateS == LOW){ buttonStateS = digitalRead(buttonPinS); delay(50); } // плавно гасим for (int is=0; is<20; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(190 - is*10,0,0)); strip.show(); delay(10); } // СТОПЫ конец } } else // если СТОПЫ выключены { // ЗАДНИЙ ХОД: если включен - средний приоритет buttonStateD = digitalRead(buttonPinD); if (buttonStateD == LOW) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(63,63,63)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(63,63,63)); strip.show(); while(buttonStateD == LOW){ buttonStateD = digitalRead(buttonPinD); delay(50); } //плавно гасим for (int is=0; is<16; is++) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); strip.show(); delay(10); } } buttonStateL = digitalRead(buttonPinL); buttonStateR = digitalRead(buttonPinR); // если включена аварийка if (buttonStateL == LOW && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(63,31,0)); strip.setPixelColor(il+72, strip.Color(63,31,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ЛЕВЫЙ ПОВОРОТНИК if (buttonStateL == LOW && buttonStateR == HIGH) { for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ПРАВЫЙ ПОВОРОТНИК if (buttonStateL == HIGH && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } //правый поворотник конец } //конец условия else Стоп // задержка для следующего опроса датчиков delay(10); }

I tried to comment on it to the maximum, but if there are questions, I will try to add comments (therefore, I place it in the text of the review, and not as an attached file). By the way, this also applies to other points of the review - I will also supplement it if there are significant questions in the comments.

And finally, a demonstration of work (I used a sketch with a demo mode for the video).

Upd. I made a sketch with a demo mode specifically to fit everything into one short video.
The brake light flashes only during heavy braking (this was written above), when it is smooth and standing in traffic jams, it just burns without annoying drivers from behind.
Brightness in the dark is not excessive, because. because of the tilt of the glass, the lights are directed more upwards than backwards.
Regular lights work as usual, this strip duplicates them.

He said last year "Gop" - it's time to jump :)
Or rather, to do the promised review of running turn signals.
I ordered 1 meter of black tape WS2812B (144 LEDs) in a silicone tube, when ordering, I chose “Black 1m 144led IP67” (maybe someone will like the white color of the substrate, there is such a choice).

A small caveat

I received a tape soldered from two half-meter pieces. The downside of this is the weak point of the soldering (contacts may break over time) and the increased gap between the LEDs.
Check with the seller before buying

Contact wires were soldered to the tape on both sides for serial connection of several pieces, because I didn’t need it, then I soldered it off on one side of the wire, sealed everything with a neutral sealant and wound some more black electrical tape.



Attached to glass with double-sided transparent adhesive tape, for example,.

Installation details

I degreased the surfaces, first I glued the adhesive tape to the tube (I will call it that, even though the cross section is rectangular), cut off the protruding excess of a wider tape, put the edges of the tube into the gap between the ceiling and the upper parts of the decorative panels of the rear pillars (I hid the contact wires with the connector behind one panel ), centered and began to press against the glass, slowly pulling out the protective layer of the tape.
Unfortunately, there is no video - there were no free hands for shooting, and everyone's cars are different.
If something is not clear - ask in the comments.
The summer heat test was successful - nothing peeled off or floated.
The only negative is that the angle of inclination of the glass is gentle, the LEDs shine more upwards. On a sunny day it is hard to see, but since these are duplicate signals, then

Now let's move on to the electronic stuffing.
I used but recently discovered

For about the same cost, we get more buns

The sketch without any modifications will also work on Wemos when programming in the Arduino IDE, and if you implement a small web server, then when connected to it via Wi-Fi, you can change the values ​​\u200b\u200bof variables such as the delay time between blinks, the amount of deceleration during emergency braking etc.
Here in the future, if someone is interested in implementing a project on ESP8266, I can post an example for changing settings via the web interface, saving them to EEPROM, and then reading.
The launch of the web server can be implemented, for example, by turning on the turn signal and pressing the brake pedal when the ignition is turned on (in the setup procedure, poll the status of the corresponding inputs).

To implement the flashing mode during heavy braking was purchased
The sketch monitors the level of deceleration when the brake pedal is pressed, if it exceeds 0.5G (hard deceleration, but no brake squeal), then a flashing mode is activated for a few seconds to attract additional attention.
Control signals to the Arduino inputs from the "plus" of the stops, turn signals and reverse are fed through galvanic isolation - optocouplers with current limiting resistors, which eventually form the LOW level at the Arduino inputs (constantly pulled to the plus through 10kΩ resistors).
Power - 5 volts through a DC-DC buck converter.
The whole thing is folded like a sandwich and packed in a suitable box, on which I marked the installation direction with an arrow for the correct orientation of the gravity sensor

Scheme and photo



The value of the pull-up (to plus) resistors is standard - 10 kOhm, current-limiting optocoupler resistors - 1 kOhm. Optocouplers dropped out of old boards, two got PC123, two - PC817.


In the first photo you can see two additional pins, I made them for the turn signals. Since in my car, when the steering column lever is turned on, a short to ground occurs, I connected the wires to the lever block and the Arduino inputs. If the steering column switch switches plus or take a signal from the "+" bulbs of the left / right turn signal, then connect them through a galvanic isolation.



Well, now the sketch itself (Arduino IDE)

#include #include //a few general comments // I disabled one of the outer LEDs, because they shone on the decorative panels of the racks //seen in the example of this for loop (int i=1; i<143; i++) //если отключать не нужно, заменяем на for (int i=0; i<144; i++) //задний ход и аварийка у меня не используются, т.к. в первом случае яркость никакая, во втором надо подключать входы к лампам поворотников //поворотники и стоп-сигнал одновременно не включаются, чтобы это реализовать, нужно переписывать соответствующий код скетча (делить ленту на три секции, подбирать тайминги миганий, менять диапазон переменных циклов). //Дерзайте - все в ваших руках // Пин для подключения управляющего сигнала светодной ленты const int PinLS = 2; //Пины для подключения датчиков //если более удобно будет подключать контакты в другом порядке - просто поменяйте значения переменных const int buttonPinL = 3; const int buttonPinR = 4; const int buttonPinS = 6; const int buttonPinD = 5; //начальные статусы входов (подтянуты к плюсу) int buttonStateS = HIGH; int buttonStateD = HIGH; int buttonStateL = HIGH; int buttonStateR = HIGH; // пауза pause_pov1 (в миллисекундах) нужна, чтобы синхронизировать циклы "пробегания" полоски и включения лампочки поворотника // такое может быть, если используется меньше половины светодиодов // в моем случае паузы нет (pause_pov1 = 0) int pause_pov1 = 1; // этой паузой регулируем длительность состояния, когда все светодиоды выключены //я определял опытным путем - включал поворотник, засекал по отдельности время ста мыргов лампочкой и ста беганий полоски, разницу делил на 100, на полученное время увеличивал или уменьшал значение переменной (в зависимости от того, отставали или убегали вперед лампочки) int pause_pov2 = 62; // переменная для получения значения ускорения int ix; Adafruit_NeoPixel strip = Adafruit_NeoPixel(144, PinLS, NEO_GRB + NEO_KHZ800); Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); void setup() { pinMode(buttonPinS, INPUT); pinMode(buttonPinD, INPUT); pinMode(buttonPinL, INPUT); pinMode(buttonPinR, INPUT); strip.begin(); // гасим ленту for (int i=0; i<144; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); accel.begin(); // ограничиваем измеряемый диапазон четырьмя G (этого хватит с большим запасом) accel.setRange(ADXL345_RANGE_4_G); accel.setDataRate(ADXL345_DATARATE_100_HZ); } void loop() { // СТОПЫ: если включены - высший приоритет //Чтобы сделать меняющуюся по ширине полоску в зависимости от интенсивности торможения //(уточнение - никакой светомузыки, ширина полосы после нажатия на тормоз не меняется!) //от плавного торможения до тапки в пол. //Добавляем еще одну переменную, например, ix2, //присваиваем ей значение ix с коэффициентом умножения, //заодно инвертируем и округляем до целого //ix = event.acceleration.x; //ix2 = -round(ix*10); //ограничиваем для плавного торможения в пробках //(чтобы не менялась при каждом продвижении на 5 метров) //if (ix2<10) ix2 = 0; //и для резкого торможения. //Реальный диапазон изменения переменной ix - от 0 до -5 //для максимальной ширины полосы при G равном или большем 0.5 //if (ix2 >50) ix2 = 50; //then change the cycles in the STOP block for (int i=1; i<143; i++) на for (int i=51-ix2; i<93+ix2; i++) //Получаем минимальную ширину полоски ~30 см (для стояния в пробке) и максимальную для резкого торможения //конец комментария buttonStateS = digitalRead(buttonPinS); if (buttonStateS == LOW) { sensors_event_t event; accel.getEvent(&event); ix = event.acceleration.x; // проверка резкого торможения - мигающий режим // значение 5 - это 0,5G, минус - торможение if (ix < -5) { for (int is=0; is<15; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(240,0,0)); strip.show(); delay(10 + is*10); for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); delay(10 + is*3); buttonStateS = digitalRead(buttonPinS); if (buttonStateS == HIGH) return; } } // помигали - и хватит, включаем постоянный режим, если педаль тормоза еще нажата // или если не было резкого торможения и предыдущее условие не сработало if (buttonStateS == LOW) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(200,0,0)); strip.show(); while(buttonStateS == LOW){ buttonStateS = digitalRead(buttonPinS); delay(50); } // плавно гасим for (int is=0; is<20; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(190 - is*10,0,0)); strip.show(); delay(10); } // СТОПЫ конец } } else // если СТОПЫ выключены { // ЗАДНИЙ ХОД: если включен - средний приоритет buttonStateD = digitalRead(buttonPinD); if (buttonStateD == LOW) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(63,63,63)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(63,63,63)); strip.show(); while(buttonStateD == LOW){ buttonStateD = digitalRead(buttonPinD); delay(50); } //плавно гасим for (int is=0; is<16; is++) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); strip.show(); delay(10); } } buttonStateL = digitalRead(buttonPinL); buttonStateR = digitalRead(buttonPinR); // если включена аварийка if (buttonStateL == LOW && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(63,31,0)); strip.setPixelColor(il+72, strip.Color(63,31,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ЛЕВЫЙ ПОВОРОТНИК if (buttonStateL == LOW && buttonStateR == HIGH) { for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ПРАВЫЙ ПОВОРОТНИК if (buttonStateL == HIGH && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } //правый поворотник конец } //конец условия else Стоп // задержка для следующего опроса датчиков delay(10); }

I tried to comment on it to the maximum, but if there are questions, I will try to add comments (therefore, I place it in the text of the review, and not as an attached file). By the way, this also applies to other points of the review - I will also supplement it if there are significant questions in the comments.

And finally, a demonstration of work (I used a sketch with a demo mode for the video).

Upd. I made a sketch with a demo mode specifically to fit everything into one short video.
The brake light flashes only during heavy braking (this was written above), when it is smooth and standing in traffic jams, it just burns without annoying drivers from behind.
Brightness in the dark is not excessive, because. because of the tilt of the glass, the lights are directed more upwards than backwards.
Regular lights work as usual, this strip duplicates them.

I plan to buy +97 Add to favorites Liked the review +89 +191

close