Nie jeden, a kilka LEDów i zabawa w wężyki…
(c) K.G. 2021
Nie jeden, a kilka LEDów i zabawa w wężyki…
(c) K.G. 2021
Ustaliliśmy, że spotykamy się w piątki o 12:15 (ale mamy czas tylko do 13:30). Zaczynamy od zera – czyli wyjaśnień, jak działa LED i do czego jest potrzebny rezystor w obwodzie. Znaczy nie wyjaśniłem jak działa LED ale omówiłem jego funkcję w obwodzie elektrycznym. No dobrze, Panowie wiedzieli to i owo, ale te informacje należało podać i wyjaśnić wątpliwości (a były takie! z istotniejszych: czy kolejność opornika i LEDa ma znaczenie? NIE!). Jeszcze bez podłączenia Arduino sprawdziliśmy działanie układu zasilanego akumulatorem żelowym 6V, mierzyliśmy prąd, napięcia… nuda? Może. Ale niezbędna. Sprawdzialiśmy, jak świeci LED z oporikiem 10 000 omów, 470 omów a nawet jak z 22 omami (info na końcu wpisu). Dopiero potem podłączyliśmy płytkę Arduino UNO – dowiedzieliśmy się, co to są piny GND, 3.3V oraz 5V. Sprawdziliśmy multimetrem napięcie (a jakże!). A potem podłączyliśmy LED-a do 5V. Działa!
OK, ale Arduino się programuje… Więc uruchomiliśmy darmowe Arduino IDE i napisaliśmy pierwszy programik – świecący co 5s LEDem podłączonym do pinu cyffrowego numer 7 – dlaczego akurat 7? a dlaczego nie 😉 Mamy do wyboru 14 sztuk pinów cyfrowych (numerowane od 0 do 13), to któryś trzeba było wybrać.
Program wymagał wyjaśnienia, gdzie jest funkcja main() z języka C/C++, co robią funkcje setup() oraz loop() a także co to są pinMode(), digitalWrite() oraz delay(). Mam nadzieję, że było w miarę jasno (choć oczywiście – pytania w głowie buszują, z czasem znajdą się na nie odpowiedzi….).
Następnie bawiliśmy się w zmianę czasu trwania świecenia/nieświecenia LED-a. Ustawiliśmy w funkcjach delay() czas 1000 s (czyli 1 s), potem 100 ms a nawet 10 ms (czyli 100x na sekundę!). Oczywiście w tym ostatnim przypadku nie udało się zaobserwować błysków, a jedynie ciągłe świecenie. Przy tej okazji ponowne wróciliśmy do multimetru i sprawdziliśmy, jaki pomiar wskaże urządzenia. Dowiedzieliśmy się co-nieco o uśrednianiu pomiarów przez multimetr.
Ale ta zabawa w zmianę czasu doprowadziła nas do sprawdzenia zdolności percepcji człowieka – sprawdziliśmy, czy oko rejestruje zmiany częściej niż 24x na sekundę (chyba mamy tu jakiegoś amatora filmów!). Udało się. Nie wiesz o co chodzi? To zapraszam na koło w kolejny piątek 😉
A może dwa LEDy? Spróbowaliśmy świecić na przemian!
Potem każdy ze studentów dostał w prezencie Arduino UNO…. wirtualnie 😉 zachęcam do ponowienia zabawy w TInkerkadzie.
I jeszcze jedno: chciałem spalić LED-a. Podałem opornik 22 omów do zasilania 6.3V i…. spodziewałem się szybkiego BUM! A tu przez ponad godzinę LED nie poddawał się, przyjmował okolo 138 mA prądu i świecił (no dobrze, zmienił barwę na pomarańczową – z żółtej – ale wytrzymał). Temperatura na rezystorze to nawet ponad 100C więc taki układ to zdecydowanie błąd w sztuce – ale o dziwo działał u nas przez godzinę (a może i dłużej, ale go rozłączyłem). Nie róbmy tak zbyt często – pamiętajmy, że LEDy „lubią” prąd do ~20mA, choć i tak polecam <10mA bo już wtedy świecą bardzo wyraźnie.
Zachęcam do zastanowienia się nad powyższym układem: czy wskazania amperomierza się zgadzają z przewidywaniami teoretycznymi? Opornik w obwodzie to 22 ohm, zasilanie 6.3V. Śmiało przelicz sam! Coś się jakby nie zgadza? Może warto kliknąć w obrazek poniżej o poczytać trochę?
(c) K.G. 2021
Budujemy podwozie v0.1.
Mieliśmy robić coś prowizorycznego, jednak do montażu kół wykorzystaliśmy przygotowane mocowanie – zaprojektowane i wydrukowane na Wydziałowej drukarce 3D Zoltrax M200. Prosty projekt w Blenderze:
Wydruk 2 sztuk to ~30min pracy drukarki. Efekt poniżej.
Napęd to dwa serwa pracy ciągłej – Feetech FT90R.
Finalnie wszystko wygląda tak:
Mocowanie silników do podwozia – chwilowo trtytkami. Jednak jest to NAJSŁABSZY element tej konstrukcji. Ale wydawał się wystarczający do sprawdzenia, jak działa.
Miało być szybko i minimalistycznie, jednak trzeba wrócić do mocowania silniczków – trytytki należy zmienić na „dedykowane” trzymaki do serw (ponownie projekt 3D i druk na Zoltraxie M200). Liczymy, że dzięki temu pojazd będzie jeździć prosto!
Pan Bartek wraca do projektu Maskotki i zamierza tam wgrać PID-a do lepszego sterowania kołami. Na razie odgrzebał projekt, połączył przewody (sfajczył jedno Arduino UNO – ale jak, tego nikt nie wie) no i projekt jeździ! Z braku swojego kontrolera wykombinował takie oto zabawnie wyglądające cudo 😉
Słychać ten „piękny” pisk podczas zakrętów? Oj słychać… ale jego źródło zostało już zlokalizowane! To nie silniki (jak nam się pierwotnie wydawało), a… trzecie koło! Będzie trzeba coś z tym zrobić.
Poprzedni semetr zakończyliśmy poznaniem niezbędnych elementów, jakie zamierzamy wykorzystać nad naszym projektem. Teraz przyszedł czas na zebranie tego w całość. Powstał taki oto plan:
Punkt pierwszy jest kluczowy i zarazem problematyczny – zamierzamy zrobić coś prowizorycznego, ze sklejki, gumki recepturki i papieru toaletowego (oraz inne rzeczy „spod ręki” – liczy się kreatywność, i na tym polega problematyczność). Przyświecać nam będzie główny cel – podwozie ma być (w miarę) stabilne i gotowe do realizacji kolejnych punktów. W przyszłości (za semestr?) studenci poznają tajniki druku 3D i stworzą piękne pojazdy, na razie będzie prowizorka.
Rzeczy „spod ręki” nie są takie ubogie – w szafie pracowni znalazł się zestaw kół sportowych o średnicy 56 mm i szerokości 25 mm.
Napęd bazować będzie na dwóch serwach pracy ciągłej – Feetech FT90R. Wybór podyktowany był tym, że nie musimy montować sterownika do silników DC (mostek H) gdyż te mikro-serwa mają sterowanie wbudowane w sobie.
Trzeba „tylko” wykombinować połączenie silniczka z tymi kołami… Tym zajmiemy się za tydzień.
Pracujemy nad ostatnim elementem składowym projektu Wojny robotów – kolorowych wyświetlaczy (do przedstawiania poziomu „życia”, „paliwa” itd). Wszystko okazuje się dziecinnie proste – a to za sprawą gotowych bibliotek dla Arduino (był to właśnie pretekst do poznania instalacji bibliotek w Arduino IDE). Pracowaliśmy ze wcześniejszym materiałem z fi-bot’a – zajrzyj.
Sporo manualnej pracy z tą Maskotką… Czasami elektronik/progamista musi się „urbrudzić” i popracować trochę najprostrzymi narzędziami – śrubokrętem, piłką do metalu lub do drewna (u nas: płyta wiórowa). No tak, ale zadanie poszerzenia otworów na koła bez demontażu obudowy – wykonane!
Nowy projekt – może niekoniecznie duży, ale baaaardzo użyteczny. Fajnie, że ktoś sam się tym zainteresował i zrealizował. Szczegóły na stronie projektu.
Po całogodzinnej zabawie udało się zrealizować Wieloklika – brawo! Pozostał jedynie malutki szczególik do dopracowania, ale to już za tydzień.
(c) K.G. 2019
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!
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
7 października o godzinie 14:15 po zajęciach odbyło się pierwsze oficjalne spotkanie koła Fi-BOT na terenie Wydziału Fizyki. Do naszej skromnej grupy dołączyły 4 nowe osoby, dzięki którym, miejmy nadzieję, będziemy w stanie wykonać więcej projektów opartych na Arduino. Pierwsze zajęcia stanowiły rutynowe zapoznanie się z płytką Arduino Uno, jej elementami składowymi oraz formą programowania. W celu zrozumienia, jak funkcjonuje rdzeń naszej pracy, zostały zaprogramowane w prosty sposób LEDy.
W międzyczasie Panowie Przemek i Bartek kontynuowali pracę nad swoimi projektami. Informacje odnośnie projektu Pana Bartka odnaleźć można na dedykowanej stronie.
(c) J.Ch. 2019
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.
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).
Polecam cały wpis o tych układach na /dev/jarzebski.
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.
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
Ciągle dwa/trzy niezależne projekty. Wygląda na to, że będą jednak trzy, bo Pan Bartek „atakuje” temat line followera (świetnie!)
1) zespół od pojazdu po sukcesie sterowania pojazdem przez człowieka (bluetooth) poznawał temat czujki odległości HC-SR04. Zamontowali już nawet „trzymak” w pojeździe – bez użycia wkrętaki! zuchy! 😉 Tak, tak – to „oklepany” układ, ale każdy od czegoś zaczyna – prawda? Trzymam więc kciuki za poprawne oprogramowanie go w pojeździe i zrobienie autonomicznego robota (poruszającego się bez ingerencji człowieka, w tym przypadku: wykrywającego kolizje i zmieniającego kierunek ruchu).
2) „refleks” przeszedł w stan rozbudowany i teraz składa się z 3 losowo zapalanych LEDów, i łapaniu reakcji przez 3 przyciski. Układ:
oraz program (+dużo komentarzy):
//piny z podlaczonymi przyciskami int btn[]={2,4,6}; //piny z podlaczonymi ledami int led[]={3,5,7}; void setup() { Serial.begin(9600); for (int i=0; i<3; i++){ pinMode(btn[i],INPUT_PULLUP); pinMode(led[i], OUTPUT); } } unsigned int i; unsigned int cr,tstart,tstop; byte bt1, bt2, bt3, LOS; void loop() { //"dysko-mode" informujace o poczatku rozgrywki for(i=0;i<3;i++){ digitalWrite(led[0], HIGH); delay(100); digitalWrite(led[1], HIGH); digitalWrite(led[0], LOW); delay(100); digitalWrite(led[2], HIGH); digitalWrite(led[1], LOW); delay(100); digitalWrite(led[2], LOW); delay(100); }//"dysko-mode" //(pseudo)losowe czekanie: od 1s do 5s delay(random(1000,5000)); //wybor LEDa do zaswiecenia: 1,2 lub 3 LOS=random(1,4); //wersja tylko do testow: wypisywanie na ekran losowania Serial.print("LOS="); Serial.println(LOS); //wlaczenie wylosowanego LEDa //dzieki zapisaniu numerow pin-ow do tablicy jest to teraz bardzo proste! digitalWrite(led[LOS-1], HIGH); //rozpoczecie mierzenia czasu tstart = millis(); //czekanie na rekacje uzytkownika - wcisniecie jednego z trzech pyrzycsikow //zapamietujemy w zmiennych, ktore przyciski sa wcisniete do{ bt1 = digitalRead(btn[0]); bt2 = digitalRead(btn[1]); bt3 = digitalRead(btn[2]); }while(bt1+bt2+bt3==0); //petla wykonuje sie tak dlugo, az przynajmniej jeden z przyciskow zostanie wcisniety //zatrzymanie "stopera" skoro cos zostalo wcisniete tstop = millis(); digitalWrite(led[LOS-1], LOW); //okreslenie poprawnosci wcisniecia przycisku: //zakladamy, ze zle wcisniety przycisk (tak wygodniej) bool ok=false; //czy wygralem? //sprawdzenie, czy moze jednak zostal wcisniety odpowieni przycisk switch(LOS){ case 1: if ((bt1==1)&&(bt2==0)&&(bt3==0)) ok=true;break; case 2: if ((bt2==1)&&(bt1==0)&&(bt3==0)) ok=true;break; case 3: if ((bt3==1)&&(bt1==0)&&(bt2==0)) ok=true;break; }//swicth //jesli wygrales, to stosowny komunikat if (ok){ cr = tstop-tstart; //cr = "czas rekacji" Serial.print("brako! gratulacje! "); Serial.print("czas reakcji:"); Serial.println(cr); }//ok==true else{ Serial.println("pudło! nie ten przycisk!"); } delay(1000); }//loop
Można jeszcze popracować nad tym kodem – można dodać kolejny (inny) „dysko-mode” informujące, że się poprawnie wybrało przycisk, albo zaświecić wszystkimi LED-ami, gdy użytkownik „spudłował”. W przyszłości dodamy do układu wyświetlacz LCD aby tam pojawił się stosowny komunikat, a nie na ekranie podłączonego komputera.
3) na bazie TSOP5000 (kiedyś już ją poznawaliśmy) powstanie czujnik do pojazdu typu line follower – praca się właśnie rozpoczyna. Działa już (podwójny) układ czujników, więc teraz rozpoczął się drugi etap: układ 3/4/5? czujek na własnoręcznej płytce prototypowej + pojazd na sterowniku L298.
Dlaczego własnoręcznie robiona czujka, a nie jedna z „kupnych”, jak te ze zdjęć poniżej?
Odpowiedź jest prosta: bo to fajniejsze i mamy więcej zabawy podczas pracy, a o to właśnie chodzi!
KG, 2018