[119] Arduino i telewizor cz. 2

[119] Arduino i telewizor cz. 2

Skoro już opanowaliśmy wyświetlanie znaków na ekranie telewizora, czas na obrazki. To aż takie proste nie jest, ponieważ potrzebny jest tutaj konwerter – biblioteka nie rozumie żadnych bitmap, plików GIF i tego typu znanych nam elementów. I tutaj z pomocą przychodzi coś, o czym już kiedyś pisałem: strona konwertująca obrazy do postaci zrozumiałej przez bibliotekę. Jednak zanim zajmiemy się tworzeniem własnych grafik, przetestujmy program na gotowcu dostarczonym z biblioteką. Będzie zresztą niezbędny, by stworzyć własną wersję.


#include <TVout.h>    // Biblioteka tworząca obraz telewizyjny.
#include "obraz.h"    // Plik z obrazkiem.
TVout telewizor;      // Definicja obiektu.

void setup() {
  telewizor.begin(PAL, 120, 96);  // Szerokość i wysokość obrazu.
  telewizor.bitmap(0, 0, obraz);  // Wyświetlenie obrazka.
}
void loop() {
}

Tym razem całość sprowadzi się do dwóch nowych elementów: dołączenia pliku obraz.h oraz wywołania rysowania bitmapy. Druga z komend dysponuje także współrzędnymi prawego górnego roku – tak więc obrazem można umieścić w dowolnym miejscu. Zmieniłem tutaj nazwy na bardziej nam przyjazne, ale to nie wszystko. W katalogu ze szkicem musimy mieć dwa takie pliki: w cpp siedzi treść samego obrazu, a w h – dane konfiguracyjne. W każdym wypadku musimy zmienić domyślną nazwę na naszą, lokalną.

// obraz. cpp
#include "obraz.h"
PROGMEM const unsigned char obraz[] = {
120,96,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFE,
0x08,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x02,
0x08,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x02,
// Dalsze linie z treścią obrazu.
};
// obraz.h
#include <avr/pgmspace.h>
#ifndef obraz_H
#define obraz_H
extern const unsigned char obraz[];
#endif

Po skompilowaniu ujrzymy grafikę, którą widzieliśmy na początku, w wersji demonstracyjnej. Czas na coś własnego. Najpierw oczywiście musimy znaleźć dawcę: najlepiej prostego, kontrastowego, który przeżyje redukcję do jednobitowej przestrzeni 120x96 pikseli.

Wybrałem nieco niezgodne z tym, co właśnie powiedziałem zdjęcie z Tatr, by zobaczyć jak się obroni w tak skromnych warunkach.

Wchodzimy na stronę o adresie https://javl.github.io/image2cpp i kolejno: wrzucamy nasz plik, ustawiamy docelową rozdzielczość i sposób emulacji pośrednich tonów. Mamy kilka algorytmów do wyboru oraz współczynnik szarości. Dobieramy parametry do własnego widzimisię, które podziwiamy piętro niżej. Jeśli obrazek będzie zadowalający, generujemy kod.

Teraz już dane z widocznej ramki musimy wkleić w plik obraz.cpp, który poprzednio zawierał obrazek demo. Możemy skompilować szkic i… cóż, nie wygląda to rewelacyjnie, ale w czasach ośmiobitowców nikt nie grymasiłby.

Można pokusić się w tym wypadku o zwiększenie rozdzielczości. W moim wypadku udało się dobić do 151x103 piksele i obrazek zyskał nieco. Jednak sztuka nie uda się, jeśli użyjemy trybu tekstowego, gdyż – jak wspominałem wcześniej – zasoby skończą się przy niższej rozdzielczości. Na koniec przedstawię komendy związane z rysowaniem prostych grafik.

#include <TVout.h>  // Biblioteka tworząca obraz telewizyjny.
TVout telewizor;    // Definicja obiektu.

void setup() {
  telewizor.begin(PAL, 120, 96);  // Szerokość i wysokość obrazu.
}
void loop() {
  telewizor.clear_screen();  // Czyść ekran.

  telewizor.draw_circle(59, 47, 47, WHITE);  // Rysuj okrąg: środek X, środek Y, promień.
  telewizor.delay(1000);                     // Zmodyfikowany delay dla szkiców z biblioteką TVout.
  telewizor.draw_circle(59, 47, 27, WHITE, INVERT);
  telewizor.delay(1000);

  telewizor.draw_rect(0, 0, 119, 94, WHITE);  // Rysuj prostokąt: górny lewy, dolny prawy.
  telewizor.delay(1000);
  telewizor.draw_rect(10, 10, 99, 74, WHITE, INVERT);
  telewizor.delay(1000);

  telewizor.draw_line(0, 0, 119, 95, WHITE);  // Rysuj linię: górny lewy, dolny prawy.
  telewizor.delay(1000);
  telewizor.draw_line(0, 95, 119, 0, WHITE);
  telewizor.delay(1000);
  telewizor.draw_line(59, 0, 59, 95, INVERT);
  telewizor.delay(1000);
  telewizor.draw_line(0, 47, 119, 47, INVERT);
  telewizor.delay(2000);
}

I tak: draw_circle kreśli okręgi, albo raczej elipsy, ze względu na mocne zniekształcenie. Pierwsze dwa parametry to środek koła, trzeci – promień, ostatni może przybierać wartość BLACK, WHITE albo INVERT. Pierwsze – nie muszę wyjaśniać, ostatni sprawia, że kolor jest zamieniany z tym, co było namalowane pod spodem. W ten sposób można zamiast okręgów malować koła, co zastosowałem w kolejnej linii.

draw_rect rysuje prostokąty o współrzędnych górnego lewego i dolnego prawego rogu, a line – odcinki, gdzie cztery parametry parami oznaczają początek i koniec. Należy pamiętać, że piksele liczymy od górnego lewego rogu i od zera. Stąd ostatnia kolumna jest sto dziewiętnasta. Trzeba też uważać przy kreśleniu figur i starać się pozostawiać jednopikselowy margines, inaczej fragmenty na obrzeżach będą cieńsze albo w ogóle nie będą rysowane.

Procedury są bardzo szybkie. Proste demo praktycznie natychmiast zamalowuje ekran szumem i dopiero sztuczne zwolnienie do 50 ms na odcinek pokazuje o co chodziło.

#include <TVout.h>  // Biblioteka tworząca obraz telewizyjny.
TVout telewizor;    // Definicja obiektu.

void setup() {
  telewizor.begin(PAL, 120, 96);  // Szerokość i wysokość obrazu.
}
void loop() {
  telewizor.draw_line(random(119), random(95), random(119), random(95), INVERT);
  //  telewizor.delay(50);
}

Pozwala to na tworzenie emulacji 3D, jak w fabrycznym przykładzie demonstracyjnym, a trzeba wiedzieć, że mimo programowego tworzenia obrazu zużycie zasobów w tym wypadku to 16% pamięci flash i tylko 56 bajtów RAM-u. Tak więc zapasu jest dość, potrzeba tylko wyobraźni i czasu na zabawę. Zachęcam też do analizy fabrycznych przykładów, jest tam jeszcze kilka ciekawych komend.

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

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2025 arduino.pl