Arduino oraz jego klony, to jedna z najpopularniejszych platform programistycznych, chętnie wykorzystywana przez elektroników-amatorów. Całość oparta o popularne produkty firmy Atmel (konkretnie produkty z rodziny AVR firmy Atmel) łeb w łeb konkurujące z rozwiązaniami produkcji MikroTik. Co więc jest tutaj na tyle złego, by spisywać płytkę Arduino na straty już na starcie?
Pomysł i marketing
Idea jak zwykle jest podniosła i szczytna.
Sprzedać (przeważnie) młodym ludziom obietnicę ograniczonych jedynie własną wyobraźnią możliwości. Dać szansę zbudowania i zaprogramowania układu, którego zakres prac będzie się ograniczał zarówno do podlewania kwiatków, jak i zarządzania naszym domem. Tanią platformę programistyczną dla ambitnych elektroników żądnych całkowitej kontroli nad swoim projektem.
Co nam jednak z Arduino, jeśli nawet nie potrafimy napisać na niego prostego programu?
Tutaj ponownie projekt wyciąga do nas pomocną dłoń swoim dumnie i donośnie zachwalanym IDE, w którym pisanie można porównać do relaksującego wąchania lawendy.
Dumnie określany językiem C ze zbiorem gotowych do pracy, elastycznych funkcji, które każdy programista może wykorzystać wedle potrzeb oraz upodobań. Wszystko podane na tacy w postaci lekkostrawnego dania przyjaznego nawet najmłodszym i rozpoczynającym swoją przygodę z mikrokontrolerami AVR.
Dlaczego więc nie mogę cieszyć się sukcesem tej platformy razem z innymi? Czemu tak silnie sprzeciwiam się, by to ją wybierać na swój pierwszy kontakt z zagadnieniem? Na Boga… Czemu tyle soli przechodzi przez mój organizm?
Nauka i przyszłościowe myślenie
Mimo bycia otwartą i przyjazną platformą dla amatorów, Arduino wymaga przynajmniej podstaw z zakresu elektroniki i programowania. O ile to pierwsze załatwia tok nauczania okolic drugiej klasy gimnazjum, tak polepszyć się w programowaniu możemy najszybciej za pomocą odpowiednich wzorców. A o to jest wybitnie trudno.
Nie ma co ukrywać – zaczynając naukę od prostych skatchy za pomocą firmowego IDE nigdzie nie zajdziemy. Owszem, takie rozwiązanie ma swoje zalety, ale są on przytłoczone wadami, które tylko pogrążają cały projekt.
Dla totalnego amatora, który nie jest pewien swoich umiejętności czy zapału może to być ciekawe, proste oraz pasjonujące. Ale taki człowiek po miesiącu rzuci płytkę w kąt i raczej za prędko do niej nie wróci.
Każda inna osoba, którą to pociąga na tyle, by zająć się tym na poważnie tylko straci i zmarnuje czas.
Owszem, sam próg wejścia jest znacznie niższy, ale co nam przyjdzie pożytecznego z nauki ichniejszej składni? Gdzie będziemy mogli wykorzystać to hermetyczne środowisko? Głupi PIC 16F628A totalnie nas nie zrozumie. A to zamyka nam możliwość komunikacji z bardzo prostym i podobnym czipem, co Atmega.
Dlaczego nie zacząć od razu od prawdziwego, czystego C? Dlaczego to na nim nie oprzeć swojej wiedzy, która w przyszłości spotęguje i zapewni nam same zyski? Dlaczego mamy zaprzątać sobie głowę bezużyteczną składnią, skoro od samego początku możemy uczyć się rzeczy pożytecznych?
Jaka jest różnica dla amatora, co będzie musiał zapamiętać, skoro wszystko na starcie będzie równie niezrozumiałe?
Nauka C owocuje bardzo szybko. Po początkowym zagubieniu nadchodzą chwile łączenia faktów, najbardziej rozwijający nas samych okres. To tutaj zaczynamy widzieć korelacje pomiędzy kolejnymi rozwiązaniami, funkcjami czy innymi pętlami.
Sama nota katalogowa jest skarbnicą wiedzy dokładnie i bardzo szczegółowo opisującą nasz mikrokontroler. To na niej i przykładach w niej zawartych można oprzeć swoje pierwsze projekty! Mimo pozornego skomplikowania są to najbardziej uporządkowane informacje, jakie można znaleźć o naszym sprzęcie.
Wracając jeszcze do elektroniki, to jest to temat tak szeroko i obszernie opisany, że nie ma najmniejszego problemu, by znaleźć interesujące nas informacje. Najlepszym przykładem polskiej sceny YouTube jest kanał Reduktor Szumu oraz RS Elektronika, obydwa prowadzone przez Pana Krzysztofa Bielewicza.
Ogrom pożytecznych informacji, klarowne opisy zagadnień i przyjazna użytkownikowi forma sprawiają, że po chwili obycia i zrozumieniu podstawowych pojęć, każdy znajdzie coś dla siebie.
Budowa i ograniczenia
Punkt widzenia zależy od punktu siedzenia – maksyma, która pasuje niemalże do każdej sprzecznej sytuacji.
Ogromną zaletą gotowej płytki jest oczywiście to, że jest… Gotowa. Jedynym zadaniem postawionym przed użytkownikiem jest pobranie Arduino IDE. Reszta jest już tylko i wyłącznie kwestią naszej wyobraźni.
Jednak podstawowa zaleta bardzo szybko obraca się w jedną z głównych wad.
Dlaczego mamy się ograniczać? Czemu musimy godzić się na rozwiązania przygotowane przez kogoś innego? A jakby zrobić to po swojemu?
Tutaj kolejny raz przychodzi z odsieczą czysta AVR.
Razem z wiedzą o podstawach elektroniki, notą katalogową oraz własną wyobraźnią jesteśmy w stanie idealnie do swoich potrzeb i możliwości dostosować płytkę, którą samą zrobimy.
To tutaj mamy możliwość rozwinąć skrzydła, rzucić wodze fantazji i zrobić projekt idealnie pod nas samych.
Lutownica w dłoni, trochę wolnego czasu i programator (który także możemy sobie sami zrobić) – to narzędzia pozwalające przekuć ideę w interesujący nas końcowy produkt.
Porównanie
Warto na własne oczy przekonać się o podstawowych różnicach w kodzie dla Arduino oraz czystego AVR. Wykorzystam do tego celu jeden z najbardziej podstawowych programów – “Blink”, którego jedynym zadaniem jest zapalać i gasić diodę co dany okres czasu.
Kod dla Arduino
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
Idąc od samej góry, tak jak nasz program, pasuje wyjaśnić poszczególne jego sekcje i linie.
void setup() jest główną funkcją programu. To tutaj możemy określić kierunek naszych pinów, zadeklarować stałe czy też inne zmienne.
Jej naturalnym odpowiednikiem w języku C jest funkcja main().
void loop() to zaś nieskończona pętla programu. To właśnie tutaj wpisujemy instrukcje, jakie ma wykonać nasze Arduino. W C wykorzystuje się do tego celu nieskończoną pętlę while(1) lub for(;;).
pinMode(LED_BUILTIN, OUTPUT);
DDRB |= (1<<PB5);
Pierwszy zgrzyt – jakie znowu DDRB? Co do cholery znaczy |= ? Czemu muszę pisać jakieś (1<<PB5)? Człowieku, z czym Ty do mnie wyskakujesz? I Ty twierdzisz, że to jest lepsze od Arduino?
Ludzie z natury boją się rzeczy, których nie rozumieją. Wiem o tym z doświadczenia. Pierwszy kontakt z takim zapisem również był dla mnie szokiem. Lecz w trakcie poznawania tajników samych AVR zaczęły mi się zaświecać kolejne lampki. Więc pozwólcie, że Wam to opiszę:
DDRB – jest to rejestr kierunku. Określa, czy dany pin ma być wejściem (logiczne 0), czy wyjściem (logiczne 1). Litera B wzięła się z tego, że Atmega 328P posiada trzy takie rejestry z odpowiadającymi im pinami – B, C i D.
|= – operator logiczny “or-równa się“, można go zapisać także w formie DDRx = DDRx | (1<<PBx), jest on po prostu skróconą formą zapisu. Wykorzystuje operator bitowy OR ( | ). Co jest znaną nam bramką logiczną i na takiej zasadzie właśnie działa.
(1<<PB5) – jest to przesunięcie bitowe. Czyli prosto mówiąc – przesuwa jedynkę do bitu, który odpowiada 5 pinowi portu B (czyli pin 13 Arduino). Daje nam to stan wysoki (logiczne 1) na danym pinie.
Dlatego łącząc wszystko w całość otrzymujemy jasny przekaz – pin 5 portu B staje się wyjściem.
Ale wcale nie musimy tak tego zapisywać! Spróbujmy jeszcze na 3 inne sposoby:
DDRB = 32 – bardzo krótki zapis. Ale co on tak właściwie oznacza? Ano to, że do bitu o wadze 5 przypisujemy 1 (2^5 daje nam w końcu 32).
DDRB = 0x05 – o Jezu, jakieś iksy nam się tutaj pojawiają! Ale oznacza to jedynie zapis w systemie szesnastkowym. Zasada działania jest identyczna, jak wyżej. Różnica jest w liczeniu, bo w końcu nie zatrzymujemy się na 9, a na F.
DDRB = 0b00100000 – jakby komuś było mało, zawsze można zapisywać to w postaci binarnej!
Język C daje nam wolność na niespotykaną w Arduino skalę. Czy jest trudniej? Wcale że nie, sami widzicie! Kwestia tylko zapamiętania zapisu oraz powolnego trawienia tej informacji, by w końcu to wszystko zrozumieć. W Arduino proces jest szybszy, ale przecież i tak musimy się nauczyć wykorzystywać dane nam funkcje.
Co z resztą? Ze wstrzymaniem pracy na sekundę, z zaświecaniem i gaszeniem diody?
Sprawa jest analogiczna i wykorzystujemy te same schematy.
digitalWrite(13, HIGH);
PORTB |= (1<<PB5); /* można stosować także trzy pozostałe metody, tak samo jak przy DDRx */
Hej, to przecież znany nam już zapis! Wystarczyło tylko zmienić DDRB na PORTB, by już nie określać kierunku, a po prostu wysłać sygnał!
delay(1000);
_ms_delay(1000);
Za pomocą #include <util/delay.h> możemy w bardzo prosty sposób zaimplementować do naszego programu obsługę opóźnień. Do tego nie musimy ograniczać się do milisekund, bo możemy także zapisać to jako _us_delay(1000), dla znacznie dokładniejszych pomiarów.
digitalWrite(13, LOW);
PORTB &= ~(1<<PB5);
Matko Boska! Co to nam się pojawiło? Znowu jakieś udziwnienia!
Wcale nie, jest to prosty zapis oparty na bramce AND oraz NOT, umożliwiający nam wysłanie na PB5 stanu niskiego. Analogia działania jest taka sama jak przy bramce OR.
Podsumowanie
To bardzo mały wycinek i dosyć pobieżnie opisane wprowadzenie do języka C dla AVR. Chciałem jedynie w kilku prostych słowach przybliżyć, dlaczego nie lubię Arduino (chociaż ma pewne zalety, takie jak to, że bootloader można pominąć, kompilując kod innymi programami) i jego kupno uważam za strzał w stopę. Moim celem było także pokazanie, że strach przed składnią ma tylko wielkie oczy. Poświęcając chwilę na jego zrozumienie, zyskamy o rząd wielkości więcej, niż ucząc się uproszczonego zapisu.
Do tego wpis w CV o języku C jest zawsze i wszędzie mile widziany!
Żeby jednak być sprawiedliwym – nie umniejszam wartości samej platformy. Cieszy mnie, że ktoś próbuje przekonać szersze grono odbiorców do elektroniki i programowania. Proszę mnie nie palić żywcem!
Cheers!
WARTO PRZECZYTAĆ: