[036] Prawie wszystko o diodach świecących cz. 4

[036] Prawie wszystko o diodach świecących cz. 4

Zróbmy sobie lampki choinkowe. Ale nie tylko, bo moim celem jest takie zorganizowanie łańcucha diod, by można je było swobodnie układać. Muszą być zatem połączone przewodami, a z drugiej strony – muszą być osadzone na płytkach, ponieważ, jak wspominałem już, do diod SMD w praktyce ciężko jest podłączyć przewody w sposób trwały.


Wróćmy do naszej płytki. Tym razem wytniemy inny wzór, a do tego natnę ją teraz pilnikiem w sposób tutaj widoczny. Teraz trzeba połamać płytkę na takie kawałki i na każdej zrobić taką cynową kupkę.

Tym razem przylutujemy mniejsze diody, czyli 3535. Najpierw do pierwszej kupki, a potem – jak poprzednio, do pozostałych trzech pól i na koniec jeszcze poprawimy pierwszy lut.

Teraz będziemy potrzebować nieco cienkich przewodów, by połączyć nimi płytki ze sobą. Zasilanie i masę łączymy na zasadzie „każda z każdą”, a wyjście poprzedniej z wejściem następnej. Można to zrobić tak nieładnie jak tutaj…

Albo przeplatając przewód przez otworki, co sprawi, że będzie to wyglądać lepiej i będzie też trwalsze.

Zrobiłem to niezbyt elegancko, ale dlatego, że teraz na końcówki nałożę ucięte fragmenty koszulki termokurczliwej, tworząc już lepiej wyglądającą całość. Należy tylko wcześniej dokładnie sprawdzić czy nie ma żadnych zwarć. Prawdę mówiąc, przewody jak i koszulka winny być zielone – w końcu ma to trafić na choinkę. Jednak jest to projekt edukacyjny, więc sobie wybaczę.

Przewody dobrze ze sobą skręcić, a ich koniec połączę z goldpinami, bym mógł się podłączyć do mojej płytki. Łańcuch diod jest gotowy i jak widać, pod względem budowy niczym się nie różni od tego, co przedstawiałem w poprzednim artykule. Dlatego od razu możemy podłączyć go do Arduino, które sterowało tamtymi diodami i powinniśmy uzyskać ten sam efekt. Czas najwyższy na eksperymenty programowe.

Zaczniemy od wyrzucenia funkcji delay. Instrukcja ta nie jest złem samym w sobie, jeśli nie koliduje nam z niczym i nie ogranicza mocy drzemiącej w kontrolerze na rzecz bezczynnego czekania. Acz trzeba pamiętać, że Arduino i w ogóle współczesne mikrokontrolery bardzo często są zatrudniane do zadań banalnych i po prostu nie muszą wiele robić. Silenie się wtedy na walkę z delayem na rzecz jakichś bardziej eleganckich rozwiązań, by… nadal głównie nic nie robić, jest bez sensu. No ale o tym nie tym razem.

#include <Adafruit_NeoPixel.h>                                             // Dołącz bibliotekę sterującą diodami WS2812
Adafruit_NeoPixel dioda = Adafruit_NeoPixel(1, 12, NEO_GRB + NEO_KHZ800);  // Ustaw parametry zestawu: jedna dioda na dwunastym porcie.
unsigned long czasObecny = 0;                                              // Aktualnie odczytana wartość czasu od włączenia Arduino, wyrażona w milisekundach.
unsigned long czasPoprzedni = 0;                                           // Poprzednio odczytana wartość czasu od włączenia Arduino, wyrażona w milisekundach.
bool led = true;                                                           // Stan aktywności diody świecącej.

void setup() {
  dioda.begin();  // Przygotuj sterowniki znajdujące się w diodach do inicjalizacji.
  dioda.show();   // Wykonaj powyższe polecenie.
}

void loop() {
  czasObecny = millis();                                   // Zapisz wartość czasu od włączenia Arduino.
  if (czasObecny - czasPoprzedni > 300) {                  // Jeśli różnica między pomiarami przekracza 300 ms, to...
    czasPoprzedni = czasObecny;                            // Przenieść wartość aktualną do poprzedniej.
    led = !led;                                            // Zaprzecz aktywności diody świecącej.
    dioda.setPixelColor(0, dioda.Color(255 * led, 0, 0));  // Wyślij komunikat włączający czerwoną strukturę diody świecącej.
    dioda.show();                                          // Wykonaj powyższe polecenie.
  }
}

Przeróbmy nieco program, którym testowałem diody. Początek jest taki sam: zaczytuję bibliotekę Adafruit_NeoPixel obsługującą diody i deklaruję ich ilość oraz port. Na początku wykorzystam tylko jedną diodę, ponieważ ten program będzie tylko testem. We wstępie szkicu należy jeszcze zainicjować bibliotekę.

Zrealizuję teraz proste mruganie diodą, ale bez wykorzystywania funkcji delay. Do tego będą mi potrzebne dwie zmienne: czasObecny i czasPoprzedni. Oraz jeszcze jeden przełącznik, który nazwę: led.

Istotą tego podejścia do opóźnień jest wykorzystanie pewnej zmiennej, która w Arduino żyje sobie poza naszą świadomością i zwiększa swoją wartość co jedną tysięczną sekundy. By ją wydobyć, należy użyć instrukcji millis. I tu wyjaśnia się, dlaczego czasObecny przyjął tak egzotyczną formę, jak unsigned long: bo w tym formacie istnieje owa zmienna. Po resecie startuje od zera, by po pięćdziesięciu dniach i osiągnięciu wartości ponad 4 miliardy znowu się wyzerować. Dlatego przy przekazywaniu jej do naszych zmiennych potrzeba właśnie tego formatu.

Zaraz na początku głównej pętli wartość ta trafi do zmiennej czasObecny. Następnie odejmiemy od owej wartości zmienną czasPoprzedni. Za pierwszym razem ta druga oczywiście będzie mieć wartość zero. Jeśli wynik będzie większy od 300, czyli 300 milisekund, wykonamy co następuje:

  • Najpierw umieścimy przed chwilą zapisany czas w zmiennej czasPoprzedni.

  • Następnie zaprzeczymy przełącznikowi led, to znaczy że jeśli miał wartość zero, będzie mieć teraz wartość jeden i na odwrót.

  • W końcu znaną z poprzedniego szkicu instrukcją zaświecimy czerwoną strukturę w diodzie z jasnością 255 razy wartość przełącznika. A że przyjmuje on wartości 0 bądź 1, dioda będzie się świecić z jasnością zerową bądź pełną.

Odtąd, w nieskończonej pętli będzie sprawdzany warunek na różnicę między odczytem bezpośrednim czasu, a wartością zapamiętaną podczas gmerania przy diodzie i tylko z chwilą, gdy ta różnica będzie większa od 300 ms, warunek się wypełni. W naszym przypadku nic więcej się nie dzieje, ale poniżej warunku można wstawić bardzo wiele kodu i nie będzie to mieć żadnego wpływu na wydajność. Zatem zróbmy tak.

#include <Adafruit_NeoPixel.h>                                             // Dołącz bibliotekę sterującą diodami WS2812
Adafruit_NeoPixel dioda = Adafruit_NeoPixel(5, 12, NEO_GRB + NEO_KHZ800);  // Ustaw parametry zestawu: pięć diod na dwunastym porcie.
unsigned long czasObecny = 0;                                              // Aktualnie odczytana wartość czasu od włączenia Arduino, wyrażona w milisekundach.
unsigned long czasPoprzedni0 = 0;                                          // Poprzednio odczytana wartość czasu od włączenia Arduino dla diody zerowej.
unsigned long czasPoprzedni1 = 0;
unsigned long czasPoprzedni2 = 0;
unsigned long czasPoprzedni3 = 0;
unsigned long czasPoprzedni4 = 0;
bool led0 = true;  // Stan aktywności diody zerowej.
bool led1 = true;
bool led2 = true;
bool led3 = true;
bool led4 = true;

void setup() {
  dioda.begin();  // Przygotuj sterowniki znajdujące się w diodach do inicjalizacji.
  dioda.show();   // Wykonaj powyższe polecenie.
}

void loop() {
  czasObecny = millis();  // Zapisz wartość czasu od włączenia Arduino.

  if (czasObecny - czasPoprzedni0 > 300) {                  // Jeśli różnica między pomiarami przekracza 300 ms, to...
    czasPoprzedni0 = czasObecny;                            // Przenieść wartość aktualną do poprzedniej.
    led0 = !led0;                                           // Zaprzecz aktywności diody świecącej.
    dioda.setPixelColor(0, dioda.Color(255 * led0, 0, 0));  // Wyślij komunikat włączający czerwoną strukturę diody świecącej.
    dioda.show();                                           // Wykonaj powyższe polecenie.
  }

  if (czasObecny - czasPoprzedni1 > 350) {
    czasPoprzedni1 = czasObecny;
    led1 = !led1;
    dioda.setPixelColor(1, dioda.Color(0, 255 * led1, 0));
    dioda.show();
  }

  if (czasObecny - czasPoprzedni2 > 400) {
    czasPoprzedni2 = czasObecny;
    led2 = !led2;
    dioda.setPixelColor(2, dioda.Color(0, 0, 255 * led2));
    dioda.show();
  }

  if (czasObecny - czasPoprzedni3 > 450) {
    czasPoprzedni3 = czasObecny;
    led3 = !led3;
    dioda.setPixelColor(3, dioda.Color(255 * led3, 255 * led3, 0));
    dioda.show();
  }

  if (czasObecny - czasPoprzedni4 > 500) {
    czasPoprzedni4 = czasObecny;
    led4 = !led4;
    dioda.setPixelColor(4, dioda.Color(255 * led4, 0, 255 * led4));
    dioda.show();
  }
}

Rozmnożymy sobie byty, angażując wszystkie pięć diod. W tym celu rozmnożymy zmienne czasPoprzedni-n oraz przełączniki led-n. Zmienna czasObecny pozostanie jedna, bo ona jest zależna od odczytanego czasu, a nie opóźnień związanych z mruganiem.

Poprzednią procedurę także rozmnożymy pięciokrotnie. W każdym wypadku będziemy testować zmienną czasPoprzedni-n (z numerem kolejnym), związany z kolejną diodą. Dlatego zmienne zacząłem numerować od zera, bo tak trochę nieszczęśliwie numerowane są diody w łańcuchu, co ustalił twórca biblioteki.

Spójrzmy na dwie rzeczy: za każdym razem czasy progowe nieco się różnią. Dzięki temu choinka będzie migać w chaotyczny sposób, co jest ładniejsze niż równe mruganie. No i oczywiście dla każdej z pięciu diod wybrałem inną barwę, manipulując składowymi RGB. Po kompilacji i wysłaniu otrzymamy migającą choinkę. Po chwili jednak wydaje mi się ona zbyt nerwowa. Spróbujmy uczynić pewną modyfikację… ale to już w kolejnym artykule.

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2Sprawdź tutaj

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2024 arduino.pl