kolorowo – ws2812b

Poznaliśmy bardzo ciekawy układ: 3x LED (kolor czerwony, niebieski i zielony) + sterownik ws2811 – wszystko razem tworzy moduł oświetlenia RGB, który bardzo łatwo się steruje – a uzyskane efekty są bardzo przyjemne ;-)Moduły mogą być sprzedawane osobno (pojedynczo), ale super prezentują się układy połączone w „oczko” lub listwy.

3x RGB

Każdy LED świeci światłem o danej długości (L [nm]), maksymalną jasnością (J [mcd]) i cechuje się też konkretnym spadkiem napięcia (V [V]). Poniżej dane z datasheet.:
Red L=620-625 J=390-420 V=2.0-2.2
Green L=522-525 J=660-720 V=3.0-3.4
Blue L=465-467 J=180-200 V=3.0-3.4

Trzeba uważać, aby zasilając takie paski uważnie dobrze policzyć wymagany MAKSYMALNY prąd pobrany przez układ! Mamy tu 3 LEDy, więc gdy wszystkie będą świecić na 100% to potrzeba ~3x20mA na każdy jeden moduł. Nasze „oczko” ma 12 takich układów, więc daje to około 0.72A prądu –  czyli już uszkodziliśmy Arduino (pamiętamy, że wydajność prądowa płytki Arduino UNO <0.5A ? trzeba na to uważać!). Gdy zasilamy paski/oczka bezpośrednio z Arduino proszę zmniejszyć jasność ledów do 10% albo i niżej (w zależności ile ich mamy).

Przestrzegaj tych reguł (wzięte z /dev/jarzebski)

  • Nie przekraczaj napięcia zasilania powyżej 5V,
  • Dodaj kondensator elektrolityczny o pojemności od 100µF do 1000µF (np.: 6.3V lub wyższy) przy zasilaniu pierwszej diody,
  • Dodaj rezystor o wartości od 300Ω do 1kΩ pomiędzy mikrokontrolerem, a pierwszym pinem DIN. Rezystor ten umieść jak najbliżej diody,
  • Postaraj się możliwie skrócić odległość pomiędzy mikrokontrolerem, a pierwszą diodą,
  • Nie podłączaj diod przy włączonym zasilaniu. Jeśli już musisz, rób to w kolejności: masa, zasilanie, linia sterująca, a odłączaj w odwrotnej kolejności
  • Jeśli diody zasilasz z oddzielnego źródła zasilania, najpierw doprowadź zasilanie do diod, potem do mikrokontrolera,
  • Pamiętaj o zabezpieczeniu antystatycznym 🙂 swetry, polary i inne ubiory łatwo gromadzące ładunek nie są wskazane

Polecam cały wpis o tych układach na /dev/jarzebski.

NeoPixel

Biblioteka do programowania układów WS2812B.

    #include <Adafruit_NeoPixel.h>
     
    #define PIN 7
    #define LICZBADIOD 12
     
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(LICZBADIOD, PIN, NEO_GRB + NEO_KHZ800);
     
    void setup(){
      pixels.begin(); // najpierw inicjalizacja biblioteki
    }
    
    int nr=0;
    void loop(){
        if (nr > LICZBADIOD) nr=0;
        pixels.setPixelColor(nr, random(0,256), random(0,256), random(0,256)); //programujemy LED-a o numerze nr
        pixels.show(); // konieczne, aby zmiany były widoczne
        delay(30);
        pixels.setPixelColor(nr, 0, 0, 0); //kolor czarny dla  LED-a o numerze nr 
        nr++;
    }

Kompilacja zakończona z komunikatem:

Szkic używa 3046 bajtów (9%) pamięci programu. Maksimum to 32256 bajtów. Zmienne globalne używają 46 bajtów (2%) pamięci dynamicznej, pozostawiając 2002 bajtów dla zmiennych lokalnych.

Zmieniamy LICZBEDIOD z 12 na 59 i… ten sam rozmiar zajmowanej pamięci. Ta uwaga do porównania dla kolejnej (popularnej) biblioteki.

FastLed

Kolejna biblioteka do programowania tych układów WS2812B.

#include <FastLED.h>
#define NUM_LEDS 12
#define DATA_PIN 7

CRGB leds[NUM_LEDS];

void setup() { 
   FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
   FastLED.setBrightness(10);
}

void loop() { 
      if (nr > NUM_LEDS) nr = 0;
      //leds[nr] = CRGB::Blue; 
      leds[nr].r = random(0, 256);  
      leds[nr].g = random(0, 256);  
      leds[nr].b = random(0, 256);       
      FastLED.show();   //wyswietlamy zaprogramowale kolory LEDow
      leds[nr] = CRGB::Black;
      delay(30);
      nr++;
}

Kompilujemy i widzimy:

Szkic używa 4040 bajtów (12%) pamięci programu. Maksimum to 32256 bajtów. Zmienne globalne używają 139 bajtów (6%) pamięci dynamicznej, pozostawiając 1909 bajtów dla zmiennych lokalnych.

Widzimy, że ten sam kod jest większy z wykorzystaniem FastLed-a. OK. Idziemy krok dalej i zmieniamy NUM_LEDS na 59 i…

Szkic używa 4040 bajtów (12%) pamięci programu. Maksimum to 32256 bajtów. Zmienne globalne używają 280 bajtów (13%) pamięci dynamicznej, pozostawiając 1768 bajtów dla zmiennych lokalnych.

Która biblioteka lepsza – FastLed czy NeoPixel? hmmm… Po pierwsze: obie są proste w użyciu – to zaleta obu. Jednak: FastLed jednak rezerwuje 3 bajty (kolory RGB) dla każdego ws2812b – co jest dość pamięciożerne, tym bardziej, że takie Arduino UNO ma jedynie (aż?) 2kB pamięci. Jednak o wadach i zaletach na razie nie będę się  wypowiadać.

(c) K.G. 2019

RGB LED – PWM (podstawy)

Niby podstawy – ale jakie kolorowe 😉 No i bardzo przyszłościowe – niebawem się okaże, jak barwne mogą być nasze elektroniczne gry zręcznościowe!

Sprawa jest prosta – w tej diodzie RGB są właściwie TRZY diody – czerwona, niebieska i zielona. Dzięki mieszaniu trzech kolorów otrzymujemy każdy inny, dowolny kolor – w tym także biały. Właśnie biały to bardzo ważny kolor – potrzbny nam do codziennego życia – dlatego też właśnie w 2014 r. uchonorowano Japończyków nagrodą Nobla za zrobienie niebieskiego lasera.

RGB LEDy występują z dwoma typami obudowy – matową (polecam) oraz przezroczystą. Ta pierwsza daje światło bardziej rozproszone, trudno nawet zobaczyć te trzy oddzielne LEDy.

Wspólna anoda, wspólna katoda.

RGB LED ma cztery „nóżki” (wyprowadzenia): skoro sa tam trzy LEDy (czerwony, zielony i niebieski) to niepotrzebną rozrzutnością było by mocowanie sześciu nóżek – po dwie dla każdej diody. Oczywiście dioda ma mieć możliwość oddzielnego sterowania (włącznaia), dlatego te trzy nóżki muszą być – natomiast resztę (też 3) można ze sobą uwspólnić – czyli połączyć. Tym oto sposobem zredukowaliśmy nadmiar wyprowadzeń i mamy dwie odmiany RGB LEDa: wspólna katoda (czyli wspólny minus), oraz wspólna anoda (czyli wspólny plus). Wiele mówiący rysunek:

Podłączenie – pamiętaj o oporniku dla KAŻDEGO LEDa!

Niby oczywiste, ale warto o tym przypominać… Wybieramy rezystory 220 Ohma (bo takie mamy pod ręką) – co nie jest idealne, gdyż każdy LED ma inne napięcie przewodzenia… My to świadomie ignorujemy i dla prostoty (czytaj: wygodny) używamy tych samych oporników. Ale coś za coś – nie będziemy mieć tej samej jasności każdego LEDa (płynie przez nie inny prąd!) a więc biały nie będzie taki biały…

(Może znajdę czas i dopiszę tu kiedyś konkretne wartości oporników dla każdego LEDa)

Pierwszy program

Proponuję zdefiniować trzy zmienne (byte, int – jakkolwiek, oczywiście #define będzie też OK) dla każdej nóżki diody RGB (ja swoje podłączyłem do pinów 11,10 i 9). Dzięki temu będziemy wiedzieli, co właściwie robimy.

byte ledR=11;
byte ledG=10;
byte ledB=9;

void setup(){
  pinMode(ledR, OUTPUT);
  pinMode(ledG OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop(){
  digitalWrite(ledR, LOW); //włączamy czerowny kolor
  delay(1000);
  digitalWrite(ledR, HIGH); //wyłączamy czerowny kolor
  delay(1000);
  digitalWrite(ledG, LOW); //włączamy zielony kolor
  delay(1000);
  digitalWrite(ledR, HIGH); //wyłączamy zielony kolor
  delay(1000);
  digitalWrite(leB, LOW); //włączamy niebieski kolor
  delay(1000);
  digitalWrite(ledB, HIGH); //wyłączamy neiebieski kolor
  delay(1000);

  //a teraz mieszamy kolory
  digitalWrite(ledB, LOW); //włączamy niebieski kolor
  digitalWrite(ledR, LOW); //włączamy niebieski kolor... mamy FIOLET!
  delay(1000);
  digitalWrite(ledB, HIGH); 
  digitalWrite(ledR, HIGH); 
  delay(1000);
}

Nie pomyslilem się – włączamy LEDy wyłączając napięcie – komendy digitalWrite(ledX, LOW) – bo program dotyczy RGB LEDa ze wspólną anaodą. Napięcie na wspólnej nóżce wynosi 5V dlatego muszę podać napięcie mniejsze (LOW) na drógą nóżkę, aby prąd płynął (nie płynie, jeśli nie ma różnicy napięć! jak woda, która się nie przelewa gdy tern jest płaski).

Mieszanie kolorów ułatwia poniższa grafika:

Warto trochę pobawić się w rozbudowę programu i uzyskać ciekawe kolorki… to na prawdę fajne!

Drugi program – mieszanie z „czułością” 😉

Pamiętamy działanie cyfrowych pinów PWM? Są one oznaczone tyldą (~, „falką”) i w przypadku LED-a umożliwiają płynną zmienę jasności świecenia. Ja od razu do podłączenia wybrałem właśnie piny PWM więc mogę przystąpić do zabawy w zmienę jasności

byte ledR=11;
byte ledG=10;
byte ledB=9;

void setup(){
  pinMode(ledR, OUTPUT);
  pinMode(ledG OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop(){
  for (i=255; i>0; i--){
     analogWrite(ledR, i); //powoli włączamy czerowny kolor
     delay(10);
  }
  for (i=255; i>0; i--){ 
     analogWrite(ledB, i); //powoli włączamy niebieski kolor 
     delay(10); 
  }   
  delay(1000);
}

Fajna i prosta sprawa, nieprawdaż? Ci, którzy nie pamiętają o co chodzi – zachęcam do uruchomienia Przykłady -> 01 Basics -> Fade z Arduino IDE.

Prąd pobierany z Arduino

Każdy kolor to około 20mA, więc ustawiając światło białe mamy około 60mA prądu. Oznacza to, że nasze Arduino UNO nie pociągnie za dużo takich LEDów (bez kombinowania, ale o tym później).

1 RGB LED = 3 piny PWM !!!

Oczywiście, jeśli chcemy mieć możliwość kontrolowania jansności. To dużo – Arduino UNO ma tylko (aż?) 6 takich pinów. Co więc zrobić, aby świecić 5 RGB LEDami? albo 10? Nie da się? Da się, da. Na kolejnych zajęciach właśnie się tym zajmiemy. Zapraszam! 

Praca domowa

Proponuję poćwiczyć programowanie struktularne – stworzyć funkcję

void rgb(byte red, byte green, byte blue),

która ustawi trzy LEDy na zadane wartości – niech dodatkowo podawane wartości będą z przedziału 0..100, a więc należy dokonać odpowieniej konwersji na liczby z przedziału 0..255. Jeśli tak zrobomy, to wówczas rgb(30,0,0) oznacza lekki kolor czerwony, rgb(0,100,0) to jansy kolor zielony a rgb(77,0,77) jasno-fioletowy. Proszę pobawić się w wirtualnym Arduino!

(c) KG 2018