Konwerter powstał z potrzeby chwili. Po pozytywnych wrażeniach z taśmami RGB i systemem MiLight postanowiłem zaszaleć i kupiłem taśmę typu WS2811 12V. O ile sterowanie taśmą (uC + soft) nie stanowi dla mnie problemu, to niestety przejechałem się na pilocie. Poniższy projekt stanowi prowizoryczne obejście tego problemu. Oczywiście całość będzie działać z dowolnym sterownikiem taśm LED z wyjściem PWM, MiLight podaję jako przykład.
Krótki wstęp teoretyczny:
Ekosystem MiLight zawiera 3 podstawowe piloty:
1. Mono / CCT - regulacja jasności i temperatury światła białego
2. RGB / RGBW - wybór odcienia i jasności (bez nasycenia) lub jasności światła białego
3. RGB + CCT - wybór temperatury i jasności światła białego lub odcienia i jasności RGB lub możliwość miksowania biały + RGB.
Każdy pilot ma dedykowane odbiorniki (sterownik taśm LED i żarówki) jednak pewne kombinacje pomiędzy sterownikiem a pilotem są dozwolone. O ile odbiorniki RGB+CCT działają wyłącznie z pilotem 3, to eksperymenty pokazują że odbiorniki RGB i RGBW bezproblemowo działają z pilotami 2 i 3, a pilot 3 daje znacznie większe możliwości sterowania niż dedykowany pilot 2.
Ponieważ ceny obu pilotów są zbliżone, wybrałem pilot który daje większe możliwości.
Dlaczego nie użyję pilota MiLight i odbiornika 2.4GHz?
W internecie krąży kilka niezależnych projektów opisujących protokół i schemat ramki danych w systemie MiLight. Większość z nich opiera się na Arduino (AVR) i układach radiowych nRF24L01. Niestety wszystkie projekty obsługują stary standard RGBW a nikomu jeszcze nie udało się rozszyfrować nowego protokołu RGB+CCT.
Oczywiście w najbliższym czasie planuję zająć się hakowaniem tego nowego protokołu. Tymczasem stworzyłem obejście problemu w postaci tego konwertera. Urządzenie pobiera sygnał z wyjść sterownika RGB i przekazuje go dalej na taśmę RGB typu WS2811 lub WS2812.
Zasada działania:
-> Kontroler taśmy RGB posiada 3 wyjścia typu otwarty dren. Wraz z rezystorem 270Ω podciągającym do 5V tworzą 3 wyjścia zbliżone do standardu TTL.
-> Rezystor 2k7 i kondensator 22µF tworzą prosty filtr dolnoprzepustowy wygładzający sygnał.
-> Co kilkadziesiąt milisekund mikrokontroler odczytuje 3 sygnały analogowe i po niewielkiej obróbce wysyła je do układów WS281x umieszczonych na taśmie LED.
Żeby taśma 'pikselowa' odróżniała się od klasycznej RGB, w każdym kroku sygnał jest przesuwany o jeden piksel dalej a odczytane wartości trafiają na początek taśmy. W połączeniu z opóźnieniem generowanym przez obwód RC daje to dodatkowy efekt dynamiczny.
Oto schemat oraz kod programu, napisany na szybko w Arduino.
https://easyeda.com/editor#id=2b9bd79e9 ... cd460c2731
Kod: Zaznacz cały
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 5
#define numOfPx 100
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numOfPx, PIN, NEO_BRG + NEO_KHZ800);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
//Serial.begin(115200);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
/* // serial debug
static const uint8_t analog_pins[] = {A0,A1,A2,A3,A4,A5,A6,A7}; // Setup pins for input
Serial.println(" ");
for (int i = 0; i < sizeof(analog_pins); i++) {
int value = 1023 - analogRead(analog_pins[i]);
if(value<1000) Serial.print(" ");
if(value<100) Serial.print(" ");
if(value<10) Serial.print(" ");
Serial.print(value);
Serial.print(", ");
if(i==0) { R = value/4; }
if(i==1) { G = value/4; }
if(i==2) { B = value/4; }
} // */
for(uint16_t i=numOfPx-1; i>0; --i) {
strip.setPixelColor(i, strip.getPixelColor(i-1));
}
delay(10);
int R = 255-(analogRead(A0)/4);
int G = 255-(analogRead(A1)/4);
int B = 255-(analogRead(A2)/4);
uint32_t colorSelect = strip.Color( R, G, B);;
strip.setPixelColor(0, colorSelect);
strip.show();
}
Prezentacja prototypu:
Oraz film demonstrujący działanie konwertera - porównanie z taśmą RGB i odbiornikiem RGBW.
http://filmy.elektroda.net/93_1492617607.mp4
Możliwości rozwoju:
-> Dodanie buforów wejściowych umożliwiających jednoczesne podłączenie do sterownika zwykłej taśmy RGB 12/24V i konwertera.
-> Przeróbka programu tak by odczytywał wygnały PWM zamiast uśrednionych wartości analogowych.
-> Dodanie odbiornika 2.4GHz i obsługi pilotów MiLight RGBW, a w przyszłości może RGB+CCT.
-> Miniaturyzacja urządzenia i przesiadka na mniejszy mikroprocesor np. ATTiny85 na płytce Digispark lub Trinket.
Ostatnią modyfikację chciałem wykonać ale odpuściłem ponieważ nie mam w zapasach gołego procesora ATTiny85 a płytka prototypowa którą dysponuję ma tylko jeden wolny kanał ADC (jeden zabiera reset, pozostałe dwa są zepsute przez rezystory i diody zenera przyłączone do USB).