Wojny robotów i programowanie paska z LEDami

Wojny robotów – zbieramy ekipę!

Zajęcia rozpoczęły się od krótkiej rozmowy na temat potencjalnego projektu, pt. „Wojny robotów”, który zaprezentowany zostałby na nadchodzącym „Podlaskim Festiwalu Nauki i Sztuki” (czerwiec 2020). W założeniu projekt opiera się na stworzeniu pary/czwórki robotów-pojazdów ganiających się i starających się zniszczyć. Roboty będą wyposażone w magnesy oraz czujki pola magnetycznego – dzięki temu pojazd, który „oberwał” traci trochę energii. Stan energii przedstawiona będzie jako kolorowe koło utworzone z diod LED. Obudowy mają być wydrukowane w 3D – jeśli uda uzyskać się dofinansowanie, to koło Fi-BOT zyska drukarkę 3D na realizację tego projektu (oraz na kolejne). Potrzebujemy osób do programowania pojazdów, kontrolera, efektów wizualnych, a także do modelowania obudowy – wygląda na to, że sporo osób się zgłosiło!

Ws2812b

Następnie zajęcia prowadzone były jak zwykle – wprowadzenie do robotyki. Tego dnia zajmowaliśmy się programowaniem pasków LEDami WS2812B, do których obsługi potrzebna nam była biblioteka Adafruit NeoPixel. Biblioteka ta umożliwia nam ustawienie koloru każdego poszczególnego LEDa na odpowiednią mieszankę barw RGB.

Prosty przykład wykorzystania biblioteki do zaprogramowania zapalającej się i gasnącej diody LED.

    #include <Adafruit_NeoPixel.h>
     
    #define PIN 7 //Zapisujemy pin, do którego podpięliśmy pasek jako zmienną.
    #define NDIOD 3 //zapisujemy ile diod ma pasek
     
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NDIOD, PIN, NEO_GRB + NEO_KHZ800);
    // Powyżej mamy zapis nowej zmiennej pixels jako typ zmiennej wynikającej z podłączonej biblioteki
    void setup(){
      pixels.begin(); // Tą metodą inicjalizujemy bibliotekę Adafruit NeoPixel
    }
    
    int nr=1;
    void loop(){
        if(nr>NDIOD){
          nr=1;
        }
        pixels.setPixelColor(nr, 200, 0, 0); // LED zaświeci się na czerwono
        pixels.show(); // metoda odpowiada wyświetlaniu się wcześniej zdefiniowanego koloru
        delay(100);
        pixels.setPixelColor(nr, 0, 0, 0); // LED zgaśnie
        pixels.show();
        nr++;
    }

© J.Ch. 2019

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