Dzisiaj przedstawię prosty system czcionki dla znaków ASCII przeznaczony na wyświetlacz matrycowy z Arduino Uno R4 WiFi. Przy okazji też zademonstruję jak można zrobić animację przesuwającego się tekstu w oparciu o umieszczone tu kody. Implementacja czcionki będzie 100% DIY, napiszemy ją razem i umieścimy w naszym sketchu, chociaż samą czcionkę będziemy mieli już gotową - zapożyczymy ją z biblioteki MD_Parola.
Hello world LED Matrix
Arduino R4 zawiera gotowe przykłady macierzy LED, z którymi polecam zapoznać się przed czytaniem tematu:
Nie będę ich tu jednak opisywać, bo byłoby to bez sensu. Zrobimy razem coś nowego. Zacznijmy od wyświetlenia tablicy na macierzy:
Kod: C / C++
Rezultat:
jak widać, mamy tu ładnie wszystko zorganizowane w dwuwymiarową tablicę bajtów. Jeden bajt to jeden piksel. Można by to zrobić lepiej, a dokładniej 8-krotnie lepiej, gdzie piksel byłby bitem, ale temat jest dla początkujących, więc nie chciałem aż tak komplikować.
Nowa czcionka dla LED matrix
Przydałby się jakiś system czcionki. Można by samemu tworzyć każdy znak ręcznie z pikseli, ale po co? Mamy do tego gotowe czcionki, przykładowo taką od MAX7219 z biblioteki Parola:
https://github.com/mrWheel/ESP_ticker/blob/master/parola_Fonts_data.h
Spróbujmy ją przeportować z ESP MAX7219 na nasze Arduino.
Najpierw trzeba zwrócić uwagę, że każdy znak może mieć inną szerokość.
Wynika to z formatu zapisu danych:
Czcionka jest tablicą bajtów, gdzie każdy znak poprzedza jego rozmiar w bajtach a potem mamy bajty danych, gdzie każdy bajt określa stan 8 pikseli na danej kolumnie.
Będziemy musieli:
- wyszukać znak w danych czcionki (bo skoro każdy może mieć inną ilość bajtów, to nie policzymy jego offsetu)
- odczytać jego rozmiar
- przekopiować jego piksele z bitów na bajty Arduino
Zacznijmy od wyszukiwania. Bazując na MD_Parola:
Kod: C / C++
Powyższy kod ustawia wskaźnik na poczatku danych czcionki a potem odlicza kolejne znaki ASCII dopóki nie trafi na poszukiwany przez nas, jednocześnie pomijając dane tych znaków, które nas nie interesują. Rezultatem będzie wskaźnik na dane znaku ASCII którego poszukujemy.
Teraz funkcja iterująca napis i drukująca go znak po znaku (ze wsparciem drukowania na danej pozycji):
Kod: C / C++
Funkcja ta przechodzi napis znak po znaku (poprzez wskaźnik na char, koniec znaku oznacza bajtowe zero) i kolejno pobiera czcionką danego znaku i jeśli ona jest dostepna, to najpierw drukuje ten znak a potem dodaje odstęp jednej kolumny.
Funkcja dodatkowo zlicza ile rzeczywiście wyświetlono kolumn, później wyjaśnię czemu to dodałem.
Teraz zobaczmy wyświetlanie jednego znaku:
Kod: C / C++
Powyższa funkcja przechodzi bajty danego znaku (jeden znak może mieć ich kilka, jeden bajt to jedna kolumna), sprawdza zakresy tablicy (by "nie wyjść poza ekran" i nie nadpisywać niepożądanych miejsc w pamięci) a potem rozdziela bity bajtu czcionki i umieszcza je w bajtach ekranu. Dodatkowo zlicza ile kolumn rzeczywiście było na ekranie.
Zasadniczo to wszystko. Pora na główny kod:
Kod: C / C++
Tutaj mamy dwa osobne bloki:
- setup po prostu uruchamia wyświetlacz i port szeregowy
- loop wyświetla tekst Elektroda.com z danym offsetem, jednocześnie sprawdzając ile kolumn rzeczywiście wyświetlono w celu wykrycia momentu gdy tekst opuścił w pełni ekran, offset jest z każdą iteracją zwiększany, co daje efekt przewijania
Rezultatem jest zapętlająca się animacja napisu Elektroda.com:
Podsumowanie
Gotowa czcionka z MD_Parola bardzo ułatwiła sprawę, bo nie musieliśmy od 0 tworzyć wszystkich znaków z ASCII piksel po pikselu. Resztę załatwia naprawdę kilka prostych funkcji, a dzięki temu mamy nawet też scrollowanie.
Oczywiście całość można by usprawnić, np. przesyłać do macierzy piksele jako bity a nie bajty, ale to już nie wpłynęłoby na efekt końcowy, choć byłoby wydajniejsze.
Teraz możemy łatwo wyświetlać wyniki naszych działań i pomiarów. Naprawdę, jeszcze rok temu bym nie pomyślał, że szykuje się nam Arduino z całkiem niezłym LEDowym wyświetlaczem na pokładzie...
Na koniec umieszczam pełny kod:
Spoiler:
Kod: C / C++
Fajne? Ranking DIY Pomogłem? Kup mi kawę.