Wyświetlacze 1.4 i 1.8 cala z Arduino – sterownik ILI9163

Dodaliśmy na Nettigo dwa nowe wyświetlacze LCD. Oparte o kontroler ILI9163C posiadają efektywną rozdzielczość 128×128 (1.44 cala przekątnej) oraz 128×160 (1.8 cala przekątnej). W sieci funkcjonuje biblioteka do nich (dostępna nawet przez menedżer bibliotek w Arduino IDE) jednak nie do końca dla nas jest OK. Wyświetlacze w naszej ofercie mają nieco inne parametry i nie pracował poprawnie z tą biblioteką.

Dlatego na szybko sklonowaliśmy bibliotekę na Githubie i dokonaliśmy minimalnych poprawek by wyświetlacze można obsłużyć.

Podłączenie ich jest bardzo proste, korzystają z SPI.

Połączenie wyświetlacz <-> Arduino

  • SCK – D13 (SCK)
  • SDA – D11 (MOSI)
  • A0 – D9 (można zmienić)
  • RESET – RESET
  • CS – D10 (można zmienić)
  • GND – GND
  • VCC – 5V
  • LED – 3.3V

Zasadniczo wyświetlacz razem działa na logice 3.3V. Moduły mają wbudowane stabilizatory napięcia, więc można zasilić bez problemu 5V. Podświetlenie LED ma wbudowany rezystor i niby działa na 5V bez kłopotów, ale sugeruję jednak używanie 3.3V do zasilania LED. Przy zasilaniu LED 3.3V podświetlenie wyświetlacza 1.44″ bierze około 20 mA. Zmiana napięcia LED na 5V powoduje skok prądu do 55 mA. Jasność świecenia prawie się nie zmienia, co sugeruje że już przy napięciu 3.3V diody podświetlenia pracują w dobrym zakresie charakterystyki. Zwiększenie prądu spowoduje tylko skrócenie czasu życia diod. Dlatego zasilajmy LED 5V.

Co do logiki… Nota katalogowa ILI9163 mówi, że napięcie na pinach SPI w takim konfigu nie powinno przekroczyć 3.6V. Jednak u mnie na biurku testowe egzemplarze działają w porządku. Jednak YMMV :) czyli nie daję żadnej gwarancji a wręcz sugeruję jednak użycie konwertera poziomów logicznych. Tym bardziej, że na PCB nie widać rezystorów które mogłyby działać jako dzielnik napięcia/konwerter.

Dobra, podłączyłem już wyświetlacz teraz, przykład. Po pierwsze biblioteka: https://github.com/nettigo/TFT_ILI9163C ściągnąć zip, rozpakować do katalogu z bibliotekami, restart Arduino IDE.

Teraz bez wchodzenia w szczegóły – musisz wybrać właściwy moduł. W bibliotece w pliku _settings/TFT_ILI9163C_settings.h w okolicy linii 7 jest kilka dyrektyw #define. Właściwą dla Twojego modułu zostaw odkomentowaną. I tak __144_NETTIGO__ dotyczy wyświetlacza 1.44 cala a __18_NETTIGO__ wyświetlacza 1.8 cala.

Po podłączeniu wyświetlacza i wybraniu właściwego typu, korzystanie jest bardzo proste. Definiujemy obiekt wyświetlacza:

TFT_ILI9163C display = TFT_ILI9163C(CS,DS);

CS i DS to numery pinów, do których podłączyliśmy wskazane sygnały. Jeśli podłączyłeś wyświetlacz dokładnie jak w opisie powyżej to są to odpowiednio 10 i 9.

W setup inicjalizujemy wyświetlacz: display.begin(); i to wszystko co jest potrzebne, można zacząć pracę. Biblioteka jest zgodna z Adafruit GFX więc składnia powinna być znana. Uwaga, nie wszystkie funkcje z tej biblioteki zostały zaimplementowane. Szczegółowa lista metod jest do znalezienia

Np daj taki kod w setup:

void setup() {
  display.begin();
  display.print(display.width());
  display.print("x");
  display.println(display.height());
}

Na wyświetlaczu pojawi się jego rozdzielczość:

Napisy, podstawowe obiekty – linie, prostokąty, koła to wszystko jest. Również wyświetlanie bitmapy na całym ekranie. Brakowało wyświetlania mniejszych bitmap, dlatego nasz wkład w bibliotkę dotyczy funkcji drawRGBBitmap. Funkcja bierze jako argumenty współrzędne gdzie ma zacząć rysować bitmapę, tablicę z danymi oraz rozmiar bitmapy.

Dane mają być w formie 16-sto bitowych wartości RGB. Skąd takie wziąć? No cóż do biblioteki był dodany konwerter ale działa tylko dla Windows więc popełniliśmy mały skrypt w Pythonie. Testowaliśmy go z pythonem 3.5 ale powinien (chyba) działać ze starszymi wersjami. Do pracy potrzebny jest moduł pillow.

Nazywa się img2hex.py i jako argumenty bierze nazwy pliku/ów. Następnie utworzy plik .h o nazwie wywodzącej się pierwowzoru. Np mam plik nettgio-logo.png Wywołuję skrypt

python3 img2hex.py nettigo-logo.png

W miejscu wywołania pojawi plik nettigo_logo.h z taką zawartością (środek wycięty):

#ifndef _nettigo_logo_h
#define _nettigo_logo_h


/*
File generated from: nettigo-logo.png, size (120, 22)

EXAMPLE:
    tft.displayRGBBitmap(x, y, nettigo_logo, nettigo_logoWidth, nettigo_logoHeight);
*/

const word nettigo_logoWidth = 120;
const word nettigo_logoHeight = 22;
const word PROGMEM nettigo_logo[] = {
0xffff, 0x8000, 0xa043, 0xa043, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xa043, 0xa043, 0xa043, 0x9804, 0xffff, 0xffff,

[.....]

 0xffff, 0xffff, 0xffff, 0xffff, 0x9806, 0xa043, 0xa043, 0xa043, 0xa043, 0xa043, 0xa043, 0xa043, 0xa043, 0xa043, 0xa863, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};

#endif

Wszystkie potrzebne informacje – rozmiar, nazwa tablicy do tego zmienne z końcówką WIidth i Length by automatycznie móc w przyszłości podmienić nieco zmodyfikowaną bitmapę.

Teraz pozostaje przenieść plik .h do katalogu ze szkicem w którym go chcemy użyć i dodać właściwy #include "nettigo_logo.h" Nowa zakładka w Arduino IDE pojawi się dopiero po ponownym uruchomieniu, ale szkic powinien się od razu dać skompilować. No i łatwo zobaczyć finalny obraz:

Sam kod w powyższym przykładzie jest bardzo prosty:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
#include "ntg_small_bmp.h"
#include "ntg_napis.h"

#define __CS 10
#define __DC 9

TFT_ILI9163C display = TFT_ILI9163C(__CS, __DC);


void setup(void) {
  display.begin();
 
  display.fillScreen(WHITE);
  display.drawRGBBitmap(40, 20, ntg_small_bmp, 48, 48 );
  display.drawRGBBitmap((display.width() - ntg_napisWidth) / 2, 80, ntg_napis, ntg_napisWidth, ntg_napisHeight);
}

void loop(){
  
}

Pliki .h przygotowane oczywiście z użyciem img2hex.py. Wyświetlacz to wersja 1.8 cala przekątnej. Jak widać – proste w użyciu. Jedyną wadą, którą możnaby wskazać to fakt, że skoro każdy pixel to 16 bitów, więc tablica z danymi jest spora. Ten szkic powyżej zajmuje 17kB. Nie ze względu na kod ale na bitmapy. Z tych 17k  aż 11 kB zajmują dwie bitmapy o rozmiarze 48×48 i 120×24.

Można zmodyfikować bibliotekę i użyć palety barw by zmniejszyć rozmiar danych. Nasze logo i napis jest tylko w dwóch kolorach, więc każdy pixel można by zapisać z użyciem jednego bita. Ale wymaga to pracy nad biblioteką. W tej chwili tego nie planujemy ale może w przyszłości, jeśli wyświetlacze będą się cieszyły dużą popularnością to kto wie :)