Ws2812b oraz potencjometr

Kolejne spotkanie z kolorowymi paskami LEDów WS2812B – tym razem sterowane potencjometrem.

UWAGA: TinkerCAD (czyli „wirtualne Arduino”) został wzbogacony właśnie o omawiane moduły RGB. Trzeba przyznać, że działają całkiem fajnie — dlatego zachęcam do zabawy nawet dla osób, które nie mają ich w realu!

Zadanie do wykonania

Zaświecić LEDem o numerze zgodnym z ustawioną wartością na potencjometrze. Inne LEDy mają być wyłączone. Kręcimy potencjometrem – „przesuwamy” LEDa. Kolor LEDa? Twój ulubiony 😉

Pozycję potencjometru odczytujemy przez funkcję analogRead(A0) – o ile środkowy pin potencjometru został podłączony do pinu A0 właśnie. W potencjometrze podłączone są także piny do GND i 5V w Arduino – zgodnie z powyższym rysunkiem.

Numer LEDa – dzielenie całkowite!

analogRead(a) zwraca wartość z przedziału 0..1023, natomiast my mamy tylko (aż?) 16 LEDów. Należy więc przeliczyć wartość a analogRead() na numer pinu… w prosty sposób:

nr = analogRead(A0)*16/1024;    //dobrze!

Ważna jest tutaj kolejność obliczeń, bo gdy napiszemy

nr = 16/1024*analogRead(A0);   //źle :-(

to choć z matematycznego punktu widzenia oba wyrażenia są równoważne, to jednak w drugim przypadku najpierw wykonuje się dzielenie – a jest tutaj dzielenie całkowite (bo zarówno 16 jak i 1024 są liczbami całkowitymi) więc wynosi zero. A zero mnożone przez cokolwiek da zawsze zero. Pierwszy wzorek jest poprawny, bo najpierw wykonamy mnożenie analogRead(A0)*16 a dopiero potem wynik tego iloczynu dzielimy (dzielenie całkowite, ale teraz nie przeszkadza) – i otrzymujemy liczbę z przedziału 0..15.

Dyskoteka – czyli efekt stroboskopu

Skoro mamy już ustalony numer LEDa, to teraz możemy zgasić wszystkie inne, a potem zaświecić tego konkretnego – o numerze nr właśnie. Ale ale… za chwilkę ponownie ustalimy położenie potencjometru, ponownie wyliczmy nr LEDa i co – ponownie zgasimy wszystkie, aby włączyć ten o numerze nr? Obawiam się, że w związku z wyłączaniem i włączaniem otrzymamy efekt „dyskoteka” (stroboskopu). Poza tym to nieprofesjonalne 😛

#include <Adafruit_NeoPixel.h>
     
#define PIN 7 
#define NDIOD 16 
int delta=1024/NDIOD;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NDIOD, PIN, NEO_GRB + NEO_KHZ800);

int nr,poprzedni;

void setup() {
    Serial.begin(9600);
    pixels.begin(); 

    nr=analogRead(A0)/delta;
    pixels.setPixelColor(nr, 10, 0, 0);
    pixels.show();
    poprzedni = nr;
}

void loop() {
    nr=analogRead(A0)/delta;
//    Serial.println(nr); 
        
    if(nr != poprzedni){
      //AKCJA!
      Serial.print("zmiana! nr="); 
      Serial.println(nr); 
      pixels.setPixelColor(poprzedni, 0, 0, 0);
      poprzedni = nr;
      pixels.setPixelColor(nr, 10, 0, 0);
      pixels.show();
    }
}

Powyższy kod rozwiązuje efekt stroboskopu – dzięki dodatkowej zmiennej poprzedni zapamiętujemy, który LED był ostatnio włączony. W głównej pętli programu ustalamy numer LEDa zgodnego z ustawieniami potencjometru, ale „akcja” dzieje się tylko wówczas, gdy zmieniliśmy ustawienia potencjometra. Dobrze dodać wypisywanie na monitor szeregowy informacji tylko wóczas, gdy dzieje się „akcja” – dzięki temu mamy pewność, że napisy (a tym samym i sama „akcja”) wykonuje się jedynie w przypadku zmian ustawień potencjometru.

Uwaga #1 – int VS float

Proszę zwrócić uwagę, że zarówno zmienna nr jak i zmienna poprzedni są zadeklarowane jako int, co w zupełności wystarczy – nie ma potrzeby używać arytmetyki liczb rzeczywistych (powolnych, szczególnie na Arduino).

Uwaga #2 – być bardziej PRO 😛

Zwróć uwagę, że wywołuję funkcję pixels.show() tylko wówczas, gdy coś się zmieniło – niby po co miałbym wołać tą funkcję za każdym razem w loop()-ie, niezależnie od tego, czy coś się zmieniło czy nie? W końcu pixels.show() programuje LEDy zgodnie ze wcześniejszymi ustawieniami pixels.setPixelColor(), więc nie ma senesu wołać ją bez potrzeby.

Zadanie #2 (także tinkercad)

Zmienić kod tak, by świeciły się LEDy od pierwszego do tego konkretnego, zgodnego z ustawieniami potencjometru. Unikać efektu „dysko”.

Zadanie #3

Joystick to dwa potencjometry – można tu go wykorzystać i oprogramować tak, by ruch na osi X zmieniał numer LEDa (jak dotychczas), a ruch na osi Y zmieniał kolor – w jakiś zabawny sposób (może tęcza?). Proszę się pochwalić wynikami!

(c) K.G. 2019

Posted in FiBot and tagged , , .