O komputerach jednopłytkowych już raz pisałem. Generalnie nie mam o nich zbyt dobrej opinii, i zdarza mi się często wytykać ich wady. Do tego mocno mnie fascynuje historia techniki, w tym komputerów właśnie. Mam pewne doświadczenie zarówno ze współczesnymi platformami, jak NodeMCU, Raspberry Pi czy Arduino, czy współczesną metodą programowania ich z użyciem C++ dla Arduino i Pythona dla RPi. NodeMCU programowałem z pomocą języków Lua i bodaj Forth. Programowałem też w C, liznąłem troszkę COBOLa, używałem nagiego DOSa i pisałem kod w BASIC i LOGO. Kilka programów skrobnąłem też w Delphi (ktoś to pamięta?) i w Pascalu. Miałem ambitny plan zbudowania sprzętowej emulacji Odry 1305 z użyciem układów CPLD oraz programowej emulacji PDP-8 na PIC24. Tak że myślę, iż mogę odpowiedzieć na pytanie, czy stare komputery były lepsze od współczesnych platform rozwojowych i SBC?
Nie lubię Arduino
I to jest jak najbardziej prawda. Arduino to platforma, która miała dać łatwy dostęp do programowania elektroniki ludziom, którzy nie znają się ani na elektronice, ani na programowaniu. I, szczerze pisząc, nie ma w tym nic złego. Ba, Arduino realizuje ten cel świetnie. Zwłaszcza jego liczne klony, które nie mają cen z kosmosu. Nie lubię Arduino dlatego, że jego użytkownicy zasadniczo stoją w miejscu. Ludzie uczą się Arduino, używają gotowych kawałków kodu i przyjaznych funkcji nie opanowując tego, co kryje się pod spodem. Arduino jest zbyt przyjazne i nie uczy dobrych nawyków programistycznych. Co gorsza, zachęca ludzi do realizacji na tej platformie projektów, które nie powinny być na niej realizowane. Jak na przykład projekt otwartego ECU - modułu sterującego silnikiem spalinowym w ekstremalnie trudnych warunkach. Arduino nie jest zaprojektowane do pracy w takich warunkach, nawet Atmel o tym pisał.
Drugim problemem, równie poważnym, jest nastawienie samych użytkowników Arduino - zawsze i wszędzie bronią swojej platformy nie widząc jej problemów i ograniczeń. Nie ma też kwartału, by Arduino nie próbowało wypuścić kolejnego Arduino-killera, który jest nie tylko drogi, ale też nie oferuje niczego, czego konkurencja już nie zrobiła. A i konkurencja też sobie nie radzi w tej grze.
Raspberry Pi (i inne)
Komputery jednopłytkowe to pewne kuriozum. Obiecywały funkcjonalność komputera stacjonarnego sprzed kilku lat w małym rozmiarze i z możliwością używania w różnych projektach. Moje doświadczenia, gdy miałem awarię komputera stacjonarnego, okazały się kompletnym rozczarowaniem. Przeglądanie Internetu czy oglądanie YouTube było kompletnie niemożliwe. Myślałby kto, że cztery rdzenie i 2GB RAMu wystarczą, zwłaszcza że ponoć jest nawet jakieś bieda-GPU w środku. Może jakbym kupił jakiś SBC oparty o architekturę X86-64, a nie ARM, najlepiej z 4-8GB RAMu i innym nośnikiem systemu, niż karta microSD, to coś by się ugrało. Ale to już kosztuje tyle, co budżetowy laptop czy komputer stacjonarny bez wodotrysków. Tanie SBC nie nadają się do niczego, co można nazwać zwykłym użytkowaniem komputera. I to nie jest ich wina, tylko tego, jak obecnie funkcjonuje Internet i jak wiele wymaga się od przeglądarek. Firefox z czterema otwartymi kartami "zjada mi" teraz prawie 2GB pamięci.
Zatem do czego nadaje się takie Raspberry Pi?
Wbrew pozorom potrafi sporo, jeśli jesteśmy specyficzni. O używaniu na codzień zamiast komputera można zapomnieć - za mało mocy, za mało pamięci. Ale możemy z RPi zrobić emulator starych konsol i platform arcade z systemem RetroPie. Chcemy oglądać strumienie video z Internetu lub słuchać internetowego radia, jest na to odpowiednia wersja systemu, już skonfigurowana pod prostą nawigację i dająca dostęp do wielu bezpłatnych kanałów z całego świata. Dostępnych konfiguracji i dodatkowych modułów jest ogromny, w końcu system operacyjny jest na bazie Debiana.
Wielkim plusem i powodem dominacji RPi jest bardzo dobra dokumentacja i duże wsparcie użytkowników. Bez problemu każdy może kontrolować piny IO na płytce, łatwo łączyć się z urządzeniami po WiFi, postawić i skonfigurować serwer MQTT do domowej automatyzacji i serwer HTTP z automatycznie generowaną stroną internetową pozwalającą na wgląd w bieżący stan i w statystyki. Klejem to wszystko zlepiającym jest Linux (którego kocham nienawidzić) i Python (choć są alternatywy). Jest to dobry i ciekawy start w informatykę bliską sprzętowi, zwłaszcza jak zaczniemy do tego dokładać moduły na ESP8266 i ESP32, jak NodeMCU, czy inne rozwiązania kompatybilne z platformą.
Świat nie kończy się tylko na Raspberry Pi. Po pojawieniu się słynnej "poziomki" nastąpił prawdziwy wysyp takich komputerów jednopłytkowych. 99% z nich jest kompletnie bezużyteczne, bo nie mają ani działającego oprogramowania, ani dokumentacji, i w większości zrobiono je z tych samych komponentów, z których robi się najtańsze tablety i smartfony z Chin. Dlatego właśnie nie ma miesiąca na Elektrodzie, by w newsach nie pojawiły się przynajmniej trzy takie komputery. Warto do nich podchodzić z dużą dozą sceptycyzmu, i sprawdzić poziom wsparcia, zanim wybierze się jakąś alternatywę do RPi.
Jednopłytkowi bracia mniejsi
Między Arduino, a czymś w stylu Raspberry Pi istnieje cały mikroświat mikrokontrolerów ośmio-, szesnasto- i trzydziestodwubitowych. Najpopularniejsze używają układów STM32 albo ESP8266 czy ESP32. Znajdziemy tu też zestawy rozwojowe na bazie układów LPC czy PIC24/dsPIC i PIC32. Oferta jest naprawdę bogata. Ale skutkiem ubocznym jest niewielka popularność mniej znanych rozwiązań. Kto z Was ma ChipKITa? Kto z Was programował układy LPC albo egzotykę od Renesas?
Ogrom opcji, ceny różne, dokumentacja od bardzo dobrej do szczątkowej. Czasem dostaniemy IDE i generator kodu, a czasami dostaniemy tylko garść narzędzi ze szczątkową dokumentacją i wątpliwymi przykładami. Potężne platformy potrafią być ograniczone przez dziwne decyzje projektowe na poziomie sprzętu i oprogramowania, przez co rozwiązania Arduino-podobne są pożądane na początku poznawania nowej platformy. Ważne, by pamiętać, że prawdziwą moc danej platformy można okiełznać sięgając w jej wnętrzności i opanowując niskopoziomową obsługę peryferiów i komponentów danego systemu.
Przykład z życia: potrzebowałem generować strumień losowych bitów w układzie o dużych ograniczeniach RAMu. Domyślna funkcja RAND() w XC8 była zwyczajnie za duża. Napisałem więc własną, używającą nieco mniejszych liczb. W innym programie musiałem znaleźć rozwiązanie, jak emulować EEPROM w mikrokontrolerze bez EEPROMu. Nauczyło mnie to, jak deklarować stałe pod konkretnym adresem i jak przebiega proces samoprogramowania.
Warto też pamiętać, iż platforma nie ma znaczenia. Ba, język programowania to też sprawa wtórna. Liczy się zdolność czytania dokumentacji i pisania sensownych algorytmów. Wiecie, jaka jest najgorsza płytka rozwojowa? Jest to ta, która leży w kącie i zbiera kurz. I piszę to jako winny tego grzechu. Mea culpa...
Dawniej to było... w miarę okej
Na początku był Altair 8800 i IMSAI 8080, czyli pierwsze naprawdę popularne komputery dla hobbystów. Nie dość, że były dość kosztowne, to jeszcze wymagały dużej wiedzy z zakresu elektroniki i programowania, oraz zamiłowania do pstrykania przełącznikami. To przez te komputery, zwłaszcza Atlaira powstały firmy Apple i Microsoft, ta druga stworzyła BASIC dla procesora 8080, i ta wersja pojawiła się w wielu późniejszych komputerach. Lata 80-te to rozpowszechnienie się na zachodzie komputerów ośmiobitowych. Królem był Commodore C64, czyli najlepiej się sprzedający komputer tamtej ery. Oferował 64kb pamięci RAM, dedykowane układy audio i video i bardzo dobry interpreter BASICa. Niejeden twórca gier zaczynał swoją karierę od pisania ich właśnie w BASICu na C64. Jeśli jednak mieszkał w UK, to prędzej używał BBC Micro albo ZX Spectrum. BASIC to język dość prosty, z prostym zadaniem: nauczyć początkujących podstaw programowania. To było Arduino lat 80-tych. I też uczył złych nawyków, jak używanie skoków GOTO. Ale dostęp do bardziej zaawansowanych funkcji komputera nie odbywał się przez przyjazne polecenia BASICa - tu już trzeba było czytać i modyfikować komórki pamięci poleceniami PEEK i POKE lub ich odpowiednikami dla innych komputerów. Ba, podręczniki nie tylko tego nie ukrywały, ale wręcz detalicznie opisywały działanie poszczególnych komórek pamięci. Programiści uczący się na Atari, Commodore czy ZX Spectrum dość szybko odkrywali, że prawdziwą moc z każdej platformy daje dopiero Assembler i programowanie blisko sprzętu. Inaczej po prostu nie dało się manipulować sprite'ami, czy generować dźwięku. Ważnym aspektem też była demoscena na platformach ośmiobitowych, gdzie programiści i hakerzy robili rzeczy, o których nawet projektantom tych komputerów się nie śniło.
Warto też wspomnieć o tym, że ośmiobitowe komputery miały też udokumentowany i przeznaczony do dowolnych zastosowań port rozszerzeń. Eksponował on linie danych i adresowe mikroprocesora, co pozwalało zarówno firmom, jak i zwykłym użytkownikom na dołączanie rozszerzeń, dodatkowych modułów czy nawet cartridgy zawierających programy zapisane w pamięciach ROM. Pozwala to na dużo więcej, niż porty w Arduino czy Raspberry Pi. Choćby na dołożenie więcej RAMu komputerom, które miały 4-16kB.
Największą wadą tych starych komputerów było ładowanie programów. Sam komputer włącza się w mniej niż sekundę, ale jeśli program nie jest zapisany w pamięci (E)EPROM, to jego wczytywanie może trwać 5-10 minut. Współczesne SBC mają problem odwrotny: uruchamianie trwa od 20 sekund do 2-3 minut, ale wczytanie programu z karty microSD trwa ułamki sekundy i można ten proces zautomatyzować. Arduino i inne zestawy oparte o mikrokontrolery startują w ciągu ułamków milisekundy, program ładuje się raz. Niektóre platformy, jak Arduino czy ChipKIT, mają wbudowany bootloader. ESP8266 i ESP-32 mają to realizowane sprzętowo, i płytki w stylu NodeMCU nie potrzebują niczego, a do gołych modułów wystarczy przelotka USB<>UART. "Gołe" mikrokontrolery mogą potrzebować programatora, ale te nie są aż tak drogie. Plus, są i gotowe bootloadery, w które można te mikrokontrolery wyposażyć.
Python - BASIC XXI wieku
Przez ponad dekadę już podstawowym edukacyjnym językiem programowania dla początkujących stał się Python. Jest to język interpretowany, co oznacza że kompilacja następuje "po kawałku" w chwili wykonywania kodu. Działa to podobnie do BASICa, z tą jednak różnicą, iż Python oferuje rzeczy w BASICu niespotykane, jak programowanie obiektowe. To dość nowoczesny język z wieloma gotowymi bibliotekami, ale przez swoją naturę jest raczej powolny. To cecha wielu języków interpretowanych, które pod względem prędkości zawsze przegrywają z językami kompilowanymi. Między programistą Pythona, a programistą BASICa jest jedna, zasadnicza różnica: gdy brakło nocy i możliwości BASICowi, programista sięgał po Assembler, albo na PC po C czy Pascala, albo inny język kompilowany. Gdy programiście Pythona braknie mocy, kupuje potężniejszy komputer/serwer. A wystarczyłoby przerzucić się na C# czy Javę.
Jednym z aspektów Pythona, który osobiście mnie denerwuje jest fakt, iż ten język używa tabulatora jako elementu składni. Przyczyną takiego rozwiązania jest fakt, iż dzięki temu narzucane jest właściwe formatowanie programu. Osobiście preferuję używanie nawiasów klamrowych albo słów kluczowych, jak w C czy Pascalu. Jak ktoś ma problem z brakiem ładnych wcięć, to powinien używać normalnego IDE zamiast notatnika. Serio, to takie proste. Każdy język programowania używający pustych znaków jako elementu składni to zły język.
Używałem kilku dużych aplikacji napisanych w Pythonie, i każda z nich miała jeden problem: była wolna i zasobożerna. Przykład: bCNC, program do sterowania frezarkami CNC opartymi o Arduino. Renderowanie ścieżki, po jakiej będzie poruszał się frez trwa długo, i nie jest pełne, bo narzucono odgórny limit liczby kroków - Python sobie zwyczajnie nie radzi. Ba, dodanie opcjonalnych, zoptymalizowanych i napisanych w C++ bibliotek SciPy i NumPy niewiele pomaga - przy renderowaniu dużych plików gcode bCNC zwyczajnie się wieszał. Dużo starszy program, Mach3, napisany w bodaj Pascalu czy Delphi, nie miał takich problemów. Renderowanie może trochę potrwać, ale zdecydowanie mniej niż w przypadku bCNC, i nigdy przy tym mi się nie zawiesił.
Niestety, Pythona ze względu na prostotę użycia wciska się wszędzie, od backendów wielu serwerów po skomplikowane zadania związane z nauczaniem maszynowym i sieciami neuronowymi. Dlaczego tak się stało? Bo do Pythona jest bibliotek tona. I to jedyna przyczyna. Teraz pomyślcie o tym, że ChatGPT został napisany w Pythonie i jego nauczanie wymagało superkomputera, który był swego czasu w Top100, jak wydajniej i szybciej by pracował, gdyby te algorytmy napisano w C++ albo w Rust. Ba, nawet Go, język stworzony z myślą o przetwarzaniu równoległym, w większości standardowych benchmarków jest 10-60 razy szybszy. ChatGPT jest pisany w Pythonie, bo byłoby za dużo zachodu z przepisaniem go na bardziej optymalny język, zwłaszcza język kompilowany. za to 5-10krotny skok wydajności by ten "zachód" teraz usprawiedliwił, gdyby komuś się chciało to zrobić.
Jednym z miejsc, gdzie Python się zadomowił na stałe są komputery jednopłytkowe, w tym Raspberry Pi. Od lat trwają też prace nad implementacją Pythona dla mikrokontrolerów, ale wyniki są mieszane. Python przez swoją wewnętrzną budowę i sposób działania zwyczajnie jest zasobożerny i słabo sobie radzi na platformach z dużymi ograniczeniami zasobów. Dlatego właśnie NodeMCU na ESP8266 używa języka Lua.
Jedyne, do czego zdarzało mi się użyć języka Python, to było kilka prostych skryptów by coś policzyć iteracyjnie, tj. przechodząc przez wszystkie wartości w zakresach dla trzech zmiennych. Skrypt potrzebował kilkunastu sekund by przeliczyć wartości i wyświetlić wybrane przypadki z ponad 16 milionów.
PEBCAC
Czy zatem stare komputery były lepsze od współczesnych platform rozwojowych?
Odpowiedź brzmi: czasami, ale z innych powodów, niż myślicie.
Współczesne platformy, jak Raspberry Pi i podobne, czy płytki oparte o mikrokontrolery ARM oferują potężne moce obliczeniowe i ogromny przyrost wydajności względem tego, co potrafiły Commodore C64 czy ZX Spectrum. Nawet typowe mikrokontrolery ośmiobitowe mają szybsze zegary i wykonują więcej operacji na sekundę, niż poczciwe procesory MOS 6502 czy Zilog Z80. Ograniczenia starych komputerów wymuszały na programistach dogłębne poznanie architektur i implementacji, oraz wykorzystanie ich do cna. Przykładem niech będzie demoscena, gdzie pisze się specjalne programy robiące rzeczy na pozór niemożliwe na danej platformie. Użyteczność jest mała, bo gdy poczciwy C64 renderuje grafikę 3D z prostą animacją i odtwarzaniem rozbudowanej ścieżki dźwiękowej, nie ma czasu na nic innego. Zatem pod względem surowej mocy obliczeniowej nawet Arduino wygrywa ze starym ośmiobitowcem, ale stary ośmiobitowiec wygrywa możliwościami swoich peryferiów i wyeksponowanymi szynami danych i adresową, co pozwala mu na więcej.
Problemem współczesnych platform nie jest sprzęt, lecz użytkownicy i programiści. Dlaczego Raspberry Pi 3 dławiło mi się, gdy próbowałem użyć go jako tymczasowego komputera stacjonarnego? Ano dlatego, że używał Linuxa i przeglądarki napisanych z myślą o komputerach opartych o procesory Intela i AMD. Architektura ARM jest od nich zupełnie inna. Dla przykładu procesor ARM Cortex A53 ma mniej niż sto instrukcji, wliczając ich warianty. Dla porównania znalazłem listę 336 instrukcji dla IA-32 czyli zestawu instrukcji dla procesorów Intela, przy czym autor tej listy odliczył duplikaty (związane z kompatybilnością wsteczną) i różne warianty. Co ta różnica oznacza w praktyce? To proste, jeśli weźmiemy system operacyjny i oprogramowanie pisane z myślą o komputerach osobistych, a potem skompilujemy go na platformę, gdzie wielu zaawansowanych instrukcji brak (zwłaszcza tych związanych z operacjami na dużych zbiorach danych), to nagle okazuje się, że jedną instrukcję procesora Intel czy AMD kompilator zastępuje dziesiątkami, lub setkami instrukcji procesora ARM. Jedyną, rozsądną metodą na uzyskanie dużej wydajności jest przepisać absolutnie wszystko pod architekturę ARM. Jest to bardzo trudne. Nie wspominając o tajemnicy handlowej producenta układu. Dlatego platforma RPi i jej podobne mają ogromny problem z akceleracją grafiki 3D (kiepskie sterowniki bez dostępu do kodu źródłowego), i często muszą realizować to programowo.
Dodajmy do tego drugi problem, tym razem po stronie użytkowników: używanie niewłaściwych narzędzi, opieranie się na gotowych bibliotekach, które niekoniecznie muszą być dobrze napisane i rozwiązywanie błahych problemów z optymalizacją przez użycie mocniejszego i szybszego układu. Amerykanie mówią: "Gdy jedynym narzędziem, jakie masz jest młotek, wszystko zaczyna wyglądać jak gwoździe". I to jest problem dość poważny, niezwiązany z platformą, lecz znajdujący się między komputerem, a krzesłem. Stare komputery zmuszały programistów do myślenia i szukania optymalizacji. Ba, były one sprzedawane jako platformy edukacyjne, a nie tylko jako maszynki do gier. Dlatego w zestawie był podręcznik użytkownika, którego większość była poświęcona tajnikom programowania i samej platformy. Tego właśnie brakuje współczesnym platformom, które dążą do upraszczania wszystkiego.
Dlatego proponuję wszystkim przywiązanym do Pythona i Arduino, by otworzyli skrzynki narzędziowe i poszukali czegoś więcej, niż młotki. Warto się uczyć czegoś nowego, bo im więcej wiemy, tym łatwiej ta nauka nam idzie i tym łatwiej idzie nam rozwiązywanie problemów. Jasne, to wymaga wysiłku i samozaparcia, ale takie jest życie.
Języki programowania, które warto znać
Skoro piszę, że trzeba uczyć się innych języków, to wypadałoby napisać, które z nich polecam. Pamiętajcie, że to tylko moja opinia, i nie oczekuję, że będziecie się z nią zgadzać. Ba, jeśli się nie zgadzacie, napiszcie, dlaczego i jakie są Wasze propozycje.
Aha, nauka każdego kolejnego języka przychodzi łatwiej, bo w praktyce większość z nich ma wspólne korzenie i podstawy.
C/C++
Języki polecane przeze mnie głównie dla tych, co myślą o programowaniu mikrokontrolerów. Przez dekady C i C++ były językami do pisania systemów operacyjnych, aplikacji i sterowników. Obecnie używane są również do programowania mikrokontrolerów. Arduino używa C++ z pewnymi rozszerzeniami specyficznymi dla tej platformy. Dla ośmiobitowych i szesnastobitowych mikrokontrolerów Microchip ma kompilatory używające C, dla 32-bitowych dostępne są kompilatory C++ oparte o GCC.
Warto opanować C/C++, ale trzeba to robić odpowiednio. Mikrokontrolery nie mają za dużo zasobów, dlatego odpowiednim stylem będzie programowanie funkcjonalne. Odchodzi się już od programowania obiektowego, a dla mikrokontrolerów ten styl może być zbyt zasobożerny, zwłaszcza że jedynym sposobem, by sprawdzić co kompilator robi z tymi obiektami, klasami i metodami, jest sprawdzenie pośredniego kodu w Assemblerze.
Trzy ważne uwagi (nie tylko do pisania w C/C++):
1. Funkcje nie powinny zajmować więcej, niż jeden ekran tekstu. Długie funkcje warto rozbić na mniejsze kawałki. Kompilator to i tak poskłada.
2. Nazwy funkcji, obiektów, metod, klas, zmiennych i stałych powinny być sensowe i czytelne. Dobre IDE i tak zadba o autouzupełnianie długich nazw.
3. Warto nabrać dobrych nawyków komentowania każdej funkcji, zmiennej czy stałej. Wbrew mitom kod nie jest swoją własną dokumentacją. Gdyby był, języki programowania nie miałyby funkcji dodawania komentarzy.
Assembler
Warto wiedzieć, co to jest i jak wygląda, i podejrzeć kawałki kodu by się z nim oswoić. Ale nie ma sensu uczenie się Assemblera i używanie go, nawet dla małych mikrokontrolerów. Tylko raz musiałem po niego sięgać, jak pisałem kod pozwalający na samoprogramowanie się mikrokontrolera - nie było gotowej funkcji w XC8, a sekwencja poleceń była czasowo krytyczna. Kod skopiowałem z noty katalogowej układu jako wstawkę.
Java
Przed Pythonem jednym ze wszędobylskich języków była Java. Java wciąż pozostaje jednym z topowych najpopularniejszych języków programowania. Java była czymś między Pythonem, a C++/C#. Jest wydajna jak języki kompilowane i bezproblemowo wieloplatformowa jak Python. Jak to zrobiono? Prosto: Java kompiluje się do strumienia bitowego, który jest wykonywany na wirtualnej maszynie. Otrzymujemy karę wydajności, ale jest ona niewspółmiernie mniejsza niż w przypadku Pythona. O potędze Javy niech świadczy fakt, iż w latach dwutysięcznych jedno z polskich studiów wydało dwie gry komputerowe napisane w Javie: Chrome i Xpand Rally. Dziesięć lat później powstała inna gra, która zdobyła niewielką popularność w pewnych kręgach. Nosi tytuł Minecraft. Słyszeliście o niej może?
O wszędobylstwie Javy niech świadczy fakt, iż każdy smartfon i telefon komórkowy z ostatnich dwóch dekad z groszami ma ją na pokładzie, i to najczęściej w dwóch różnych wariantach. Każda karta SIM ma okrojoną wirtualną maszynę wykonującą różne małe programy, zgrupowane jako "Usługi Operatora". Drugi silnik to ten, który odpowiada za aplikacje i gry napisane w Javie dla telefonów i smartfonów sprzed dekady lub dwóch. Android wspiera Javę, i nawet iOS może z niej korzystać, choć w opinii developerów to trochę skomplikowane wyzwanie.
Dlatego, moim zdaniem, Java jest lepsza od Pythona, i każdy tworzący programy dla platform w rodzaju Raspberry Pi czy na komputery PC powinien używać Javy zamiast tej powolnej alternatywy. Opcjonalnie sprawdzi się też C++ albo Rust.
Tercet egzotyczny: Lua, Python, Go i Rust
Język skryptowy używany przez NodeMCU. Znajdziemy go też w modzie ComputerCraft do gry Minecraft. Warto go poznać choćby dla łatwego używania ESP8266.
Sporo marudziłem na Pythona, ale mimo wszystko warto się z tym językiem zapoznać. Wiele programów używa go jako języka skryptowego i do pisania wtyczek, ponadto może się przydać do pisania drobnych, prostych skryptów czy małych programów. Ale nie piszcie na nim nic większego, niż 500-1000 linijek kodu. Naprawdę nie warto. To nie jest język do ciężkich i wymagających zadań.
Go, to język uczący przetwarzania równoległego. Nie jest trudny, choć ma swoje drobne dziwactwa. Myślę, że mógłby zastąpić Pythona w wielu bieżących zastosowaniach oferując przy tym lepszą wydajność w zadaniach wielowątkowych. Dlatego warto go poznać choćby przez rzucenie okiem na podręcznik.
Rust to nowy język programowania z nastawieniem na bezpieczeństwo, wydajność i przetwarzanie równoległe. Rust dostępny jest też dla różnych rodzin mikrokontrolerów, głównie ARM i MIPS. Inne mogą wymagać stworzenia własnej implementacji, co nie jest zadaniem dla początkujących. Początkowo Rust miał być językiem do pisania systemów operacyjnych i sterowników, ale obecnie można z nim robić dużo więcej. Warto się go nauczyć właśnie ze względu na powoli rosnącą popularność, wysoką wydajność i możliwość pracy wielowątkowej.
A może po staremu?
Jeśli pragniecie doświadczyć radości i smutków używania starego komputera do programowania, to są dwie sensowne drogi. Kupno starego komputera nie jest żadną z nich. Dlaczego? Z powodu wyjątkowo wysokiej ceny i licznych problemów sprzętowych. Zobaczcie sobie na kanał YT 8-Bit Guy, i obejrzyjcie kilka przykładowych filmów z remontów starych komputerów, by zobaczyć, jak to wygląda.
Pierwsze sensowne rozwiązanie to użycie emulatorów. Każdy zabytkowy komputer ma ich kilka. Można raczej zapomnieć o dostępie do sprzętowych interfejsów, ale i tak można zrobić wiele, w tym napisać własną grę.
Drugą opcją są komputery z serii MicroMite, oparte o mikrokontrolery PIC32 i ARM. Tu już znajdziemy sprzętowe interfejsy do wykorzystania, a program pisany jest w dialekcie BASICa, jak na starym komputerze. Imć 8-Bit Guy pracuje też nad sprzętową emulacją starych komputerów z wykorzystaniem nowych komponentów, co też będzie ciekawą opcją na przyszłość. Oczywiście,. to nie są tanie rzeczy, a ceny spokojnie przekraczają koszt przeciętnego SBC czy zestawu rozwojowego, ale i tak będzie taniej.
Możecie też spróbować samodzielnie stworzyć retrokomputer. Niekoniecznie replikę czy emulację, ale coś swojego. Jak na przykład Big Mess O' Wires. Byłoby ciekawie zobaczyć, co czytelnicy Elektrody są w stanie wymyślić.
A Wy jak myślicie? Lepsze są stare komputery czy współczesne platformy? Czego sami używacie, a czego chcielibyście spróbować? Zapraszam do dyskusji.
Nie lubię Arduino
I to jest jak najbardziej prawda. Arduino to platforma, która miała dać łatwy dostęp do programowania elektroniki ludziom, którzy nie znają się ani na elektronice, ani na programowaniu. I, szczerze pisząc, nie ma w tym nic złego. Ba, Arduino realizuje ten cel świetnie. Zwłaszcza jego liczne klony, które nie mają cen z kosmosu. Nie lubię Arduino dlatego, że jego użytkownicy zasadniczo stoją w miejscu. Ludzie uczą się Arduino, używają gotowych kawałków kodu i przyjaznych funkcji nie opanowując tego, co kryje się pod spodem. Arduino jest zbyt przyjazne i nie uczy dobrych nawyków programistycznych. Co gorsza, zachęca ludzi do realizacji na tej platformie projektów, które nie powinny być na niej realizowane. Jak na przykład projekt otwartego ECU - modułu sterującego silnikiem spalinowym w ekstremalnie trudnych warunkach. Arduino nie jest zaprojektowane do pracy w takich warunkach, nawet Atmel o tym pisał.
Drugim problemem, równie poważnym, jest nastawienie samych użytkowników Arduino - zawsze i wszędzie bronią swojej platformy nie widząc jej problemów i ograniczeń. Nie ma też kwartału, by Arduino nie próbowało wypuścić kolejnego Arduino-killera, który jest nie tylko drogi, ale też nie oferuje niczego, czego konkurencja już nie zrobiła. A i konkurencja też sobie nie radzi w tej grze.
Raspberry Pi (i inne)
Komputery jednopłytkowe to pewne kuriozum. Obiecywały funkcjonalność komputera stacjonarnego sprzed kilku lat w małym rozmiarze i z możliwością używania w różnych projektach. Moje doświadczenia, gdy miałem awarię komputera stacjonarnego, okazały się kompletnym rozczarowaniem. Przeglądanie Internetu czy oglądanie YouTube było kompletnie niemożliwe. Myślałby kto, że cztery rdzenie i 2GB RAMu wystarczą, zwłaszcza że ponoć jest nawet jakieś bieda-GPU w środku. Może jakbym kupił jakiś SBC oparty o architekturę X86-64, a nie ARM, najlepiej z 4-8GB RAMu i innym nośnikiem systemu, niż karta microSD, to coś by się ugrało. Ale to już kosztuje tyle, co budżetowy laptop czy komputer stacjonarny bez wodotrysków. Tanie SBC nie nadają się do niczego, co można nazwać zwykłym użytkowaniem komputera. I to nie jest ich wina, tylko tego, jak obecnie funkcjonuje Internet i jak wiele wymaga się od przeglądarek. Firefox z czterema otwartymi kartami "zjada mi" teraz prawie 2GB pamięci.
Zatem do czego nadaje się takie Raspberry Pi?
Wbrew pozorom potrafi sporo, jeśli jesteśmy specyficzni. O używaniu na codzień zamiast komputera można zapomnieć - za mało mocy, za mało pamięci. Ale możemy z RPi zrobić emulator starych konsol i platform arcade z systemem RetroPie. Chcemy oglądać strumienie video z Internetu lub słuchać internetowego radia, jest na to odpowiednia wersja systemu, już skonfigurowana pod prostą nawigację i dająca dostęp do wielu bezpłatnych kanałów z całego świata. Dostępnych konfiguracji i dodatkowych modułów jest ogromny, w końcu system operacyjny jest na bazie Debiana.
Wielkim plusem i powodem dominacji RPi jest bardzo dobra dokumentacja i duże wsparcie użytkowników. Bez problemu każdy może kontrolować piny IO na płytce, łatwo łączyć się z urządzeniami po WiFi, postawić i skonfigurować serwer MQTT do domowej automatyzacji i serwer HTTP z automatycznie generowaną stroną internetową pozwalającą na wgląd w bieżący stan i w statystyki. Klejem to wszystko zlepiającym jest Linux (którego kocham nienawidzić) i Python (choć są alternatywy). Jest to dobry i ciekawy start w informatykę bliską sprzętowi, zwłaszcza jak zaczniemy do tego dokładać moduły na ESP8266 i ESP32, jak NodeMCU, czy inne rozwiązania kompatybilne z platformą.
Świat nie kończy się tylko na Raspberry Pi. Po pojawieniu się słynnej "poziomki" nastąpił prawdziwy wysyp takich komputerów jednopłytkowych. 99% z nich jest kompletnie bezużyteczne, bo nie mają ani działającego oprogramowania, ani dokumentacji, i w większości zrobiono je z tych samych komponentów, z których robi się najtańsze tablety i smartfony z Chin. Dlatego właśnie nie ma miesiąca na Elektrodzie, by w newsach nie pojawiły się przynajmniej trzy takie komputery. Warto do nich podchodzić z dużą dozą sceptycyzmu, i sprawdzić poziom wsparcia, zanim wybierze się jakąś alternatywę do RPi.
Jednopłytkowi bracia mniejsi
Między Arduino, a czymś w stylu Raspberry Pi istnieje cały mikroświat mikrokontrolerów ośmio-, szesnasto- i trzydziestodwubitowych. Najpopularniejsze używają układów STM32 albo ESP8266 czy ESP32. Znajdziemy tu też zestawy rozwojowe na bazie układów LPC czy PIC24/dsPIC i PIC32. Oferta jest naprawdę bogata. Ale skutkiem ubocznym jest niewielka popularność mniej znanych rozwiązań. Kto z Was ma ChipKITa? Kto z Was programował układy LPC albo egzotykę od Renesas?
Ogrom opcji, ceny różne, dokumentacja od bardzo dobrej do szczątkowej. Czasem dostaniemy IDE i generator kodu, a czasami dostaniemy tylko garść narzędzi ze szczątkową dokumentacją i wątpliwymi przykładami. Potężne platformy potrafią być ograniczone przez dziwne decyzje projektowe na poziomie sprzętu i oprogramowania, przez co rozwiązania Arduino-podobne są pożądane na początku poznawania nowej platformy. Ważne, by pamiętać, że prawdziwą moc danej platformy można okiełznać sięgając w jej wnętrzności i opanowując niskopoziomową obsługę peryferiów i komponentów danego systemu.
Przykład z życia: potrzebowałem generować strumień losowych bitów w układzie o dużych ograniczeniach RAMu. Domyślna funkcja RAND() w XC8 była zwyczajnie za duża. Napisałem więc własną, używającą nieco mniejszych liczb. W innym programie musiałem znaleźć rozwiązanie, jak emulować EEPROM w mikrokontrolerze bez EEPROMu. Nauczyło mnie to, jak deklarować stałe pod konkretnym adresem i jak przebiega proces samoprogramowania.
Warto też pamiętać, iż platforma nie ma znaczenia. Ba, język programowania to też sprawa wtórna. Liczy się zdolność czytania dokumentacji i pisania sensownych algorytmów. Wiecie, jaka jest najgorsza płytka rozwojowa? Jest to ta, która leży w kącie i zbiera kurz. I piszę to jako winny tego grzechu. Mea culpa...
Dawniej to było... w miarę okej
Na początku był Altair 8800 i IMSAI 8080, czyli pierwsze naprawdę popularne komputery dla hobbystów. Nie dość, że były dość kosztowne, to jeszcze wymagały dużej wiedzy z zakresu elektroniki i programowania, oraz zamiłowania do pstrykania przełącznikami. To przez te komputery, zwłaszcza Atlaira powstały firmy Apple i Microsoft, ta druga stworzyła BASIC dla procesora 8080, i ta wersja pojawiła się w wielu późniejszych komputerach. Lata 80-te to rozpowszechnienie się na zachodzie komputerów ośmiobitowych. Królem był Commodore C64, czyli najlepiej się sprzedający komputer tamtej ery. Oferował 64kb pamięci RAM, dedykowane układy audio i video i bardzo dobry interpreter BASICa. Niejeden twórca gier zaczynał swoją karierę od pisania ich właśnie w BASICu na C64. Jeśli jednak mieszkał w UK, to prędzej używał BBC Micro albo ZX Spectrum. BASIC to język dość prosty, z prostym zadaniem: nauczyć początkujących podstaw programowania. To było Arduino lat 80-tych. I też uczył złych nawyków, jak używanie skoków GOTO. Ale dostęp do bardziej zaawansowanych funkcji komputera nie odbywał się przez przyjazne polecenia BASICa - tu już trzeba było czytać i modyfikować komórki pamięci poleceniami PEEK i POKE lub ich odpowiednikami dla innych komputerów. Ba, podręczniki nie tylko tego nie ukrywały, ale wręcz detalicznie opisywały działanie poszczególnych komórek pamięci. Programiści uczący się na Atari, Commodore czy ZX Spectrum dość szybko odkrywali, że prawdziwą moc z każdej platformy daje dopiero Assembler i programowanie blisko sprzętu. Inaczej po prostu nie dało się manipulować sprite'ami, czy generować dźwięku. Ważnym aspektem też była demoscena na platformach ośmiobitowych, gdzie programiści i hakerzy robili rzeczy, o których nawet projektantom tych komputerów się nie śniło.
Warto też wspomnieć o tym, że ośmiobitowe komputery miały też udokumentowany i przeznaczony do dowolnych zastosowań port rozszerzeń. Eksponował on linie danych i adresowe mikroprocesora, co pozwalało zarówno firmom, jak i zwykłym użytkownikom na dołączanie rozszerzeń, dodatkowych modułów czy nawet cartridgy zawierających programy zapisane w pamięciach ROM. Pozwala to na dużo więcej, niż porty w Arduino czy Raspberry Pi. Choćby na dołożenie więcej RAMu komputerom, które miały 4-16kB.
Największą wadą tych starych komputerów było ładowanie programów. Sam komputer włącza się w mniej niż sekundę, ale jeśli program nie jest zapisany w pamięci (E)EPROM, to jego wczytywanie może trwać 5-10 minut. Współczesne SBC mają problem odwrotny: uruchamianie trwa od 20 sekund do 2-3 minut, ale wczytanie programu z karty microSD trwa ułamki sekundy i można ten proces zautomatyzować. Arduino i inne zestawy oparte o mikrokontrolery startują w ciągu ułamków milisekundy, program ładuje się raz. Niektóre platformy, jak Arduino czy ChipKIT, mają wbudowany bootloader. ESP8266 i ESP-32 mają to realizowane sprzętowo, i płytki w stylu NodeMCU nie potrzebują niczego, a do gołych modułów wystarczy przelotka USB<>UART. "Gołe" mikrokontrolery mogą potrzebować programatora, ale te nie są aż tak drogie. Plus, są i gotowe bootloadery, w które można te mikrokontrolery wyposażyć.
Python - BASIC XXI wieku
Przez ponad dekadę już podstawowym edukacyjnym językiem programowania dla początkujących stał się Python. Jest to język interpretowany, co oznacza że kompilacja następuje "po kawałku" w chwili wykonywania kodu. Działa to podobnie do BASICa, z tą jednak różnicą, iż Python oferuje rzeczy w BASICu niespotykane, jak programowanie obiektowe. To dość nowoczesny język z wieloma gotowymi bibliotekami, ale przez swoją naturę jest raczej powolny. To cecha wielu języków interpretowanych, które pod względem prędkości zawsze przegrywają z językami kompilowanymi. Między programistą Pythona, a programistą BASICa jest jedna, zasadnicza różnica: gdy brakło nocy i możliwości BASICowi, programista sięgał po Assembler, albo na PC po C czy Pascala, albo inny język kompilowany. Gdy programiście Pythona braknie mocy, kupuje potężniejszy komputer/serwer. A wystarczyłoby przerzucić się na C# czy Javę.
Jednym z aspektów Pythona, który osobiście mnie denerwuje jest fakt, iż ten język używa tabulatora jako elementu składni. Przyczyną takiego rozwiązania jest fakt, iż dzięki temu narzucane jest właściwe formatowanie programu. Osobiście preferuję używanie nawiasów klamrowych albo słów kluczowych, jak w C czy Pascalu. Jak ktoś ma problem z brakiem ładnych wcięć, to powinien używać normalnego IDE zamiast notatnika. Serio, to takie proste. Każdy język programowania używający pustych znaków jako elementu składni to zły język.
Używałem kilku dużych aplikacji napisanych w Pythonie, i każda z nich miała jeden problem: była wolna i zasobożerna. Przykład: bCNC, program do sterowania frezarkami CNC opartymi o Arduino. Renderowanie ścieżki, po jakiej będzie poruszał się frez trwa długo, i nie jest pełne, bo narzucono odgórny limit liczby kroków - Python sobie zwyczajnie nie radzi. Ba, dodanie opcjonalnych, zoptymalizowanych i napisanych w C++ bibliotek SciPy i NumPy niewiele pomaga - przy renderowaniu dużych plików gcode bCNC zwyczajnie się wieszał. Dużo starszy program, Mach3, napisany w bodaj Pascalu czy Delphi, nie miał takich problemów. Renderowanie może trochę potrwać, ale zdecydowanie mniej niż w przypadku bCNC, i nigdy przy tym mi się nie zawiesił.
Niestety, Pythona ze względu na prostotę użycia wciska się wszędzie, od backendów wielu serwerów po skomplikowane zadania związane z nauczaniem maszynowym i sieciami neuronowymi. Dlaczego tak się stało? Bo do Pythona jest bibliotek tona. I to jedyna przyczyna. Teraz pomyślcie o tym, że ChatGPT został napisany w Pythonie i jego nauczanie wymagało superkomputera, który był swego czasu w Top100, jak wydajniej i szybciej by pracował, gdyby te algorytmy napisano w C++ albo w Rust. Ba, nawet Go, język stworzony z myślą o przetwarzaniu równoległym, w większości standardowych benchmarków jest 10-60 razy szybszy. ChatGPT jest pisany w Pythonie, bo byłoby za dużo zachodu z przepisaniem go na bardziej optymalny język, zwłaszcza język kompilowany. za to 5-10krotny skok wydajności by ten "zachód" teraz usprawiedliwił, gdyby komuś się chciało to zrobić.
Jednym z miejsc, gdzie Python się zadomowił na stałe są komputery jednopłytkowe, w tym Raspberry Pi. Od lat trwają też prace nad implementacją Pythona dla mikrokontrolerów, ale wyniki są mieszane. Python przez swoją wewnętrzną budowę i sposób działania zwyczajnie jest zasobożerny i słabo sobie radzi na platformach z dużymi ograniczeniami zasobów. Dlatego właśnie NodeMCU na ESP8266 używa języka Lua.
Jedyne, do czego zdarzało mi się użyć języka Python, to było kilka prostych skryptów by coś policzyć iteracyjnie, tj. przechodząc przez wszystkie wartości w zakresach dla trzech zmiennych. Skrypt potrzebował kilkunastu sekund by przeliczyć wartości i wyświetlić wybrane przypadki z ponad 16 milionów.
PEBCAC
Czy zatem stare komputery były lepsze od współczesnych platform rozwojowych?
Odpowiedź brzmi: czasami, ale z innych powodów, niż myślicie.
Współczesne platformy, jak Raspberry Pi i podobne, czy płytki oparte o mikrokontrolery ARM oferują potężne moce obliczeniowe i ogromny przyrost wydajności względem tego, co potrafiły Commodore C64 czy ZX Spectrum. Nawet typowe mikrokontrolery ośmiobitowe mają szybsze zegary i wykonują więcej operacji na sekundę, niż poczciwe procesory MOS 6502 czy Zilog Z80. Ograniczenia starych komputerów wymuszały na programistach dogłębne poznanie architektur i implementacji, oraz wykorzystanie ich do cna. Przykładem niech będzie demoscena, gdzie pisze się specjalne programy robiące rzeczy na pozór niemożliwe na danej platformie. Użyteczność jest mała, bo gdy poczciwy C64 renderuje grafikę 3D z prostą animacją i odtwarzaniem rozbudowanej ścieżki dźwiękowej, nie ma czasu na nic innego. Zatem pod względem surowej mocy obliczeniowej nawet Arduino wygrywa ze starym ośmiobitowcem, ale stary ośmiobitowiec wygrywa możliwościami swoich peryferiów i wyeksponowanymi szynami danych i adresową, co pozwala mu na więcej.
Problemem współczesnych platform nie jest sprzęt, lecz użytkownicy i programiści. Dlaczego Raspberry Pi 3 dławiło mi się, gdy próbowałem użyć go jako tymczasowego komputera stacjonarnego? Ano dlatego, że używał Linuxa i przeglądarki napisanych z myślą o komputerach opartych o procesory Intela i AMD. Architektura ARM jest od nich zupełnie inna. Dla przykładu procesor ARM Cortex A53 ma mniej niż sto instrukcji, wliczając ich warianty. Dla porównania znalazłem listę 336 instrukcji dla IA-32 czyli zestawu instrukcji dla procesorów Intela, przy czym autor tej listy odliczył duplikaty (związane z kompatybilnością wsteczną) i różne warianty. Co ta różnica oznacza w praktyce? To proste, jeśli weźmiemy system operacyjny i oprogramowanie pisane z myślą o komputerach osobistych, a potem skompilujemy go na platformę, gdzie wielu zaawansowanych instrukcji brak (zwłaszcza tych związanych z operacjami na dużych zbiorach danych), to nagle okazuje się, że jedną instrukcję procesora Intel czy AMD kompilator zastępuje dziesiątkami, lub setkami instrukcji procesora ARM. Jedyną, rozsądną metodą na uzyskanie dużej wydajności jest przepisać absolutnie wszystko pod architekturę ARM. Jest to bardzo trudne. Nie wspominając o tajemnicy handlowej producenta układu. Dlatego platforma RPi i jej podobne mają ogromny problem z akceleracją grafiki 3D (kiepskie sterowniki bez dostępu do kodu źródłowego), i często muszą realizować to programowo.
Dodajmy do tego drugi problem, tym razem po stronie użytkowników: używanie niewłaściwych narzędzi, opieranie się na gotowych bibliotekach, które niekoniecznie muszą być dobrze napisane i rozwiązywanie błahych problemów z optymalizacją przez użycie mocniejszego i szybszego układu. Amerykanie mówią: "Gdy jedynym narzędziem, jakie masz jest młotek, wszystko zaczyna wyglądać jak gwoździe". I to jest problem dość poważny, niezwiązany z platformą, lecz znajdujący się między komputerem, a krzesłem. Stare komputery zmuszały programistów do myślenia i szukania optymalizacji. Ba, były one sprzedawane jako platformy edukacyjne, a nie tylko jako maszynki do gier. Dlatego w zestawie był podręcznik użytkownika, którego większość była poświęcona tajnikom programowania i samej platformy. Tego właśnie brakuje współczesnym platformom, które dążą do upraszczania wszystkiego.
Dlatego proponuję wszystkim przywiązanym do Pythona i Arduino, by otworzyli skrzynki narzędziowe i poszukali czegoś więcej, niż młotki. Warto się uczyć czegoś nowego, bo im więcej wiemy, tym łatwiej ta nauka nam idzie i tym łatwiej idzie nam rozwiązywanie problemów. Jasne, to wymaga wysiłku i samozaparcia, ale takie jest życie.
Języki programowania, które warto znać
Skoro piszę, że trzeba uczyć się innych języków, to wypadałoby napisać, które z nich polecam. Pamiętajcie, że to tylko moja opinia, i nie oczekuję, że będziecie się z nią zgadzać. Ba, jeśli się nie zgadzacie, napiszcie, dlaczego i jakie są Wasze propozycje.
Aha, nauka każdego kolejnego języka przychodzi łatwiej, bo w praktyce większość z nich ma wspólne korzenie i podstawy.
C/C++
Języki polecane przeze mnie głównie dla tych, co myślą o programowaniu mikrokontrolerów. Przez dekady C i C++ były językami do pisania systemów operacyjnych, aplikacji i sterowników. Obecnie używane są również do programowania mikrokontrolerów. Arduino używa C++ z pewnymi rozszerzeniami specyficznymi dla tej platformy. Dla ośmiobitowych i szesnastobitowych mikrokontrolerów Microchip ma kompilatory używające C, dla 32-bitowych dostępne są kompilatory C++ oparte o GCC.
Warto opanować C/C++, ale trzeba to robić odpowiednio. Mikrokontrolery nie mają za dużo zasobów, dlatego odpowiednim stylem będzie programowanie funkcjonalne. Odchodzi się już od programowania obiektowego, a dla mikrokontrolerów ten styl może być zbyt zasobożerny, zwłaszcza że jedynym sposobem, by sprawdzić co kompilator robi z tymi obiektami, klasami i metodami, jest sprawdzenie pośredniego kodu w Assemblerze.
Trzy ważne uwagi (nie tylko do pisania w C/C++):
1. Funkcje nie powinny zajmować więcej, niż jeden ekran tekstu. Długie funkcje warto rozbić na mniejsze kawałki. Kompilator to i tak poskłada.
2. Nazwy funkcji, obiektów, metod, klas, zmiennych i stałych powinny być sensowe i czytelne. Dobre IDE i tak zadba o autouzupełnianie długich nazw.
3. Warto nabrać dobrych nawyków komentowania każdej funkcji, zmiennej czy stałej. Wbrew mitom kod nie jest swoją własną dokumentacją. Gdyby był, języki programowania nie miałyby funkcji dodawania komentarzy.
Assembler
Warto wiedzieć, co to jest i jak wygląda, i podejrzeć kawałki kodu by się z nim oswoić. Ale nie ma sensu uczenie się Assemblera i używanie go, nawet dla małych mikrokontrolerów. Tylko raz musiałem po niego sięgać, jak pisałem kod pozwalający na samoprogramowanie się mikrokontrolera - nie było gotowej funkcji w XC8, a sekwencja poleceń była czasowo krytyczna. Kod skopiowałem z noty katalogowej układu jako wstawkę.
Java
Przed Pythonem jednym ze wszędobylskich języków była Java. Java wciąż pozostaje jednym z topowych najpopularniejszych języków programowania. Java była czymś między Pythonem, a C++/C#. Jest wydajna jak języki kompilowane i bezproblemowo wieloplatformowa jak Python. Jak to zrobiono? Prosto: Java kompiluje się do strumienia bitowego, który jest wykonywany na wirtualnej maszynie. Otrzymujemy karę wydajności, ale jest ona niewspółmiernie mniejsza niż w przypadku Pythona. O potędze Javy niech świadczy fakt, iż w latach dwutysięcznych jedno z polskich studiów wydało dwie gry komputerowe napisane w Javie: Chrome i Xpand Rally. Dziesięć lat później powstała inna gra, która zdobyła niewielką popularność w pewnych kręgach. Nosi tytuł Minecraft. Słyszeliście o niej może?
O wszędobylstwie Javy niech świadczy fakt, iż każdy smartfon i telefon komórkowy z ostatnich dwóch dekad z groszami ma ją na pokładzie, i to najczęściej w dwóch różnych wariantach. Każda karta SIM ma okrojoną wirtualną maszynę wykonującą różne małe programy, zgrupowane jako "Usługi Operatora". Drugi silnik to ten, który odpowiada za aplikacje i gry napisane w Javie dla telefonów i smartfonów sprzed dekady lub dwóch. Android wspiera Javę, i nawet iOS może z niej korzystać, choć w opinii developerów to trochę skomplikowane wyzwanie.
Dlatego, moim zdaniem, Java jest lepsza od Pythona, i każdy tworzący programy dla platform w rodzaju Raspberry Pi czy na komputery PC powinien używać Javy zamiast tej powolnej alternatywy. Opcjonalnie sprawdzi się też C++ albo Rust.
Tercet egzotyczny: Lua, Python, Go i Rust
Język skryptowy używany przez NodeMCU. Znajdziemy go też w modzie ComputerCraft do gry Minecraft. Warto go poznać choćby dla łatwego używania ESP8266.
Sporo marudziłem na Pythona, ale mimo wszystko warto się z tym językiem zapoznać. Wiele programów używa go jako języka skryptowego i do pisania wtyczek, ponadto może się przydać do pisania drobnych, prostych skryptów czy małych programów. Ale nie piszcie na nim nic większego, niż 500-1000 linijek kodu. Naprawdę nie warto. To nie jest język do ciężkich i wymagających zadań.
Go, to język uczący przetwarzania równoległego. Nie jest trudny, choć ma swoje drobne dziwactwa. Myślę, że mógłby zastąpić Pythona w wielu bieżących zastosowaniach oferując przy tym lepszą wydajność w zadaniach wielowątkowych. Dlatego warto go poznać choćby przez rzucenie okiem na podręcznik.
Rust to nowy język programowania z nastawieniem na bezpieczeństwo, wydajność i przetwarzanie równoległe. Rust dostępny jest też dla różnych rodzin mikrokontrolerów, głównie ARM i MIPS. Inne mogą wymagać stworzenia własnej implementacji, co nie jest zadaniem dla początkujących. Początkowo Rust miał być językiem do pisania systemów operacyjnych i sterowników, ale obecnie można z nim robić dużo więcej. Warto się go nauczyć właśnie ze względu na powoli rosnącą popularność, wysoką wydajność i możliwość pracy wielowątkowej.
A może po staremu?
Jeśli pragniecie doświadczyć radości i smutków używania starego komputera do programowania, to są dwie sensowne drogi. Kupno starego komputera nie jest żadną z nich. Dlaczego? Z powodu wyjątkowo wysokiej ceny i licznych problemów sprzętowych. Zobaczcie sobie na kanał YT 8-Bit Guy, i obejrzyjcie kilka przykładowych filmów z remontów starych komputerów, by zobaczyć, jak to wygląda.
Pierwsze sensowne rozwiązanie to użycie emulatorów. Każdy zabytkowy komputer ma ich kilka. Można raczej zapomnieć o dostępie do sprzętowych interfejsów, ale i tak można zrobić wiele, w tym napisać własną grę.
Drugą opcją są komputery z serii MicroMite, oparte o mikrokontrolery PIC32 i ARM. Tu już znajdziemy sprzętowe interfejsy do wykorzystania, a program pisany jest w dialekcie BASICa, jak na starym komputerze. Imć 8-Bit Guy pracuje też nad sprzętową emulacją starych komputerów z wykorzystaniem nowych komponentów, co też będzie ciekawą opcją na przyszłość. Oczywiście,. to nie są tanie rzeczy, a ceny spokojnie przekraczają koszt przeciętnego SBC czy zestawu rozwojowego, ale i tak będzie taniej.
Możecie też spróbować samodzielnie stworzyć retrokomputer. Niekoniecznie replikę czy emulację, ale coś swojego. Jak na przykład Big Mess O' Wires. Byłoby ciekawie zobaczyć, co czytelnicy Elektrody są w stanie wymyślić.
A Wy jak myślicie? Lepsze są stare komputery czy współczesne platformy? Czego sami używacie, a czego chcielibyście spróbować? Zapraszam do dyskusji.
Fajne? Ranking DIY
