Arduino i LCD?

Wpadł mi taki wyświetlacz LCD do Arduino:
arduino_clone_and_lcdlcd_tft_backlcd_tft_on_arduino
Tyle z opisu:

Technologia LCD z podświetleniem
Dotykowy Tak – TFT rezystancyjny (4 połączenia)
Rozmiar 2.4″
Kolory 18-bit; 262k
Kontroler spfd5408 ???

Uruchomienie go zajęło mi trochę czasu. Mam nadzieję, że z moim opisem Wam pójdzie łatwiej:)

Ślepa uliczka?

(Poniższe instrukcje mogą się Wam przydać, jeżeli traficie na inny ekran niż mój)
Nadruk na płytce (’http://www.mcufriend.com’) przekierował mnie na stronę z różnymi chińskimi ślaczkami – na szczęście słowa kluczowe były po angielsku. Z opisów (znaczy ich części) wynikało, że wyświetlacz ma jednak sterownik „st7781”. Niestety link do repozytorium był martwy.
Po krótkim śledztwie trafiłem tutaj i jeszcze tutaj – na całe repozytoria kodu dla różnych wyświetlaczy, po jakiś 80MB. Dokładniej są to instalki Arduino IDE z dodatkowymi bibliotekami i przykładai. Dalej:

  1. Katalog w archiwum:.\libraries\TFTLCD-7781\TFTLCD\
    przekopiowałem do biblitek na mojej instalce Arduino :c:\Program Files (x86)\Arduino\libraries\TFTLCD\
  2. Używam Arduino IDE 1.6.1; ponieważ się nie kompilowało:
    • W pliku TFTLCD.h zmieniłem:
      virtual void write(uint8_t);
      na
      virtual size_t write(uint8_t);
    • W pliku: TFTLCD.cpp zmieniłem:
      void TFTLCD::write(uint8_t c) {
      na:
      size_t TFTLCD::write(uint8_t c) {
      //...
      return 0;
    • W pliku: glcdfont.h zmieniłem:
      static unsigned char font[] PROGMEM =
      na
      const unsigned char font[] PROGMEM =

Po uruchomieniu przykładu z .\libraries\TFTLCD\examples\tftbmp okazało się, że czip identyfikuje się jako … 0x154. Pokazuje to ten krótki kod:
uint16_t identifier = tft.readRegister(0x0);
Inne kody:

0x9325 ILI9325
0x9328 ILI9328
0x7575 HX8347G
0x9341 ILI9341
0x8357 HX8357D
0x0154 S6D0154

Biblioteki

Znając identyfikator czipu sterującego, okazało się że to układ Samsung S6D0154. Zgodnie z instrukcją na forum Arduino udało mi się wreszcie skompletować biblioteki:

Biblioteki te umieszczone są w repozytoriach git-a; żeby je dodać do Arduino IDE (instrukcje dla Internet Explorera):

  • Otwórzcie podane linki
  • Z prawej strony znajdziecie klawisz 'Download ZIP’; wciśnijcie go, żeby pobrać kod
  • Kliknijcie 'Otwórz’ (nie: 'Zapisz’); otwarte archiwum pojawi się po chwili w eksploratorze, np. katalog TFTLCD-Library-master
  • Przekopiujcie cały rozpakowany katalog do bibliotek Arduino IDE:
    • [CTRL]+[C] na katalogu (skopiowanie do schowka)
    • Przejdźcie do: C:\Program Files (x86)\Arduino\libraries
    • Wklejcie katalog [CTRL]+[V]

Powyższe operacje wykonajcie dla każdej z 3 bibliotek. Możecie do tego potrzebować praw administratora. Po tej operacji katalog 'C:\Program Files (x86)\Arduino\libraries’ powinien zawierać nowe podkatalogi 'Adafruit-GFX-Library-master’, 'TFTLCD-Library-master’ i 'Touch-Screen-Library-master’. Nowe biblioteki pojawią się w Arduino IDE pod Szkic-Importuj bibliotekę

Pierwszy kod

Najlepiej po prostu uruchomić wszystkie załączone przykłady. Są raczej proste, ich analiza nie powinna nastręczyć Wam żadnych trudności. Dodatkowo te do których podałem linki powyżej, zostały już odpowiednio zmodyfikowane do pinów UNO. Chodzi tu głównie o podłączenie LCD:
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

Inicjacja wyświetlacza jest wtedy prosta:

  • Tworzymy instancję obiektu wyświetlacza:
    Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
  • W funkcji setup():
    void setup(){
    //...
    tft.reset();
    tft.begin(0x154);
    //..
    }

Kilka przydatnych poleceń poniżej:

tft.setRotation(i); Kierunek ekranu; i=0..3
tft.fillScreen(z); Wypełnienie całego ekranu; z: kolor w systemie 565, np:
#define RED 0xF800
z = tft.color565(r,g,b) Podaj kod koloru (r,g,b); do wykorzystania z np. fillScreen()
tft.fillRect(x, y, xl, yl, z); Wykreśl na pozycji (x,y) wypełniony kwadrat o bokach (xl, yl) i kolorze z
tft.drawPixel(x,y,c); Zapal piksel na pozycji (x,y) na kolor c
tft.setTextSize(4); Ustaw wielkość czcionki na 4
tft.setCursor(x,y); Ustaw kursor w pozycji (x,y)
tft.println(„a”); Wyświetl napis „a” na ekranie

Dla przykładu, żeby wyświetlić napis „arek” na ekranie:

  • Ustaw wielkość czcionki:tft.setTextSize(4);
  • Ustaw kursor w pozycji 0,20:tft.setCursor(0,20);
  • Wyświetl napis:tft.println("arek");

Naprawienie Adafruit_TFTLCD::pushColors

Funkcja Adafruit_TFTLCD::pushColors ma mały problem. Jego naprawa wymaga przeniesienia znaku końca bloku jak pokazano na tej stronie. Chodzi o zamknięcie klamry ’}’ bloku kodu przed instrukcją CD_DATA i usunięcie dodatkowej ’}’ z końca funkcji. Dzięki temu funkcja pushColors (przykład tftbmo zacznie działać poprawnie).

Dzięki tej poprawce, możecie znacznie szybciej wyświetlać bitmapy. stosujcie tej komendy zamiast tft.drawPixel.

Dotykowo

Jednym z problemów tego wyświetlacza jest to, że dzieli on niektóre piny w maską dotykową. Za każdym razem, gdy użyjecie komendy do zczytania pozycji dotyku:
TSPoint p = ts.getPoint();
musicie z powrotem ustawić kierunek pinów wyświetlacza:
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);

Kolejnym problemem okazała się samo wywołanie TSPoint p = ts.getPoint();. Cokolwiek bym nie zmieniał, dotyk na ekranie reagował strasznie kiepsko, zwłaszcza w niektórych obszarach ekranu. Pewne były po prostu 'nieklikalne’.
IMG_20150317_211621

Sytuacja poprawiła się dopiero, gdy zamieniłem wywołanie ts.getPoint() na funkcje 'readTouch’ i 'readPressure’:
(Elementy kodu na podstawie przykładów Adafruit)

//Ustawienia pinów
#define YP A1
#define XM A2
#define YM 7
#define XP 6

//Ustawienia do skalowania
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 890
#define BOXSIZE 40

void loop(){
//..
//Zle
//TSPoint p = ts.getPoint();
//Dobre
int x = ts.readTouchX();
int y = ts.readTouchY();
int z = ts.pressure();
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
if( z> 0 && z<1000){
//…
//Skalowanie
x = map(x, TS_MINX, TS_MAXX, tft.width(), 0);
y = map(y, TS_MINY, TS_MAXY, tft.height()-BOXSIZE, 0);
}//endif
//…
}//endloop

Zmienna 'z’ przechowuje siłę nacisku (filtrujcie po z> 0 i z < 1000), (x,y) to koordynaty przyciśnięcia. W ten sposób dostaniecie wiele zdarzeń od każdego przyciśnięcia – możecie wstawić mały delay(50), żeby się choć części pozbyć (choć pewnie znajdziecie bardziej wyrafinowane rozwiązania)

Karta SD

Kolejnym fajnym bonusem jest gniazdo kart microSD. Praktyczna sprawa – można na niej trzymać np. obrazki na tło ekranu. Podobnie jak wyświetlacz, czytnik kart komunikuje się z Arduino za pomocą SPI. Jedyne co musicie ustawić, to pin wyboru urządzenia (Chip Select – CS) – tutaj 10.
#define SD_CS 10
Dodajcie bibliotekę SD: 'Szkic/Importuj bibliotekę/SD’. Inicjalizacja (z przykładów Adafruit):
void setup(){
//...
if (!SD.begin(SD_CS)) {
Serial.println("SD card failed!");
return;
}
Serial.println("SD card ok!");
//...
}

Wiele przykładów użycia (np. wczytanie bmp) najdziecie w przykładach 'Adafruit_TFTLCD/examples/tftbmp’. Pełną dokumentację biblioteki do karty SD znajdziecie tutaj. Ja testowałem z 1GB karta i było ok.

Podsumowanie

Keypad na Arduino z wyświetlaczem LCD TFT 2.4 cala
Keypad na Arduino z wyświetlaczem LCD TFT 2.4 cala

Bardzo fajna zabawka:) Oczywiście demon prędkości to to nie jest i trzeba się napracować, żeby wszystko uruchomić, ale generalnie można znaleźć wiele zastosowań do tego modułu.

Źródła

  • http://misc.ws/2013/11/08/touch-screen-shield-for-arduino-uno/
  • http://forum.arduino.cc/index.php?topic=223769
  • http://forum.arduino.cc/index.php?topic=134708
  • http://forum.arduino.cc/index.php?topic=286790
  • https://github.com/samuraijap/TFTLCD-Library/issues/2

13 komentarzy do “Arduino i LCD?”

  1. Cześć,
    mam mały problem. Próbuję to ustrojstwo, w sensie wyświetlacz, podłączyć do Arduino Nano. Bibilioteka Adafruit ma zaszyte w pliku pin_magic.h konfiguracje pinów dla poszczególnych płytek Uno, Mega itd. oprócz Nano. Plik jest tak magiczny a moja wiedza tak mała, że nie jestem w stanie rozszyfrować w jaki sposób program odgaduje jakiej płytki używamy. Nie wiem też w jaki sposób dokonać modyfikacji aby ręcznie określić piny LCD_D0, LCD_D1 itd. W sposób dla mnie jawny w kodzie określone są tylko piny LCD_CS, LCD_CD itd.
    Będę wdzięczny za każdą sugestię.

    1. Witaj,
      jaką masz wersję Nano? Jeżeli z 328p to… nie powinno być wielkiej różnicy w porównaniu do UNO – bo to ten sam kontroler. Chyba że masz wersję z AtMega168 – ale te są już teraz rzadkie. Spróbuj podłączyć piny:
      #define LCD_CS A3
      #define LCD_CD A2
      #define LCD_WR A1
      #define LCD_RD A0
      #define LCD_RESET A4
      oraz zasilanie i masę. Powinno zadziałać:)
      Tutaj masz krótszą instrukcję:
      http://uczymy.edu.pl/wp/na-warsztacie/arduino-lcd-krotka-instrukcja/
      Pozdrawiam,
      Arek

  2. W IDE 1.8.5 nie ma katalogu LCD i wczesniejszych zmian nie robilem.
    Po rozpakowaniu bibliotek, u mnie nalezalo jeszcze wyedytowac plik Adafruit_TFTLCD.cpp i idnalezc:

    // #define TFTWIDTH 240
    // #define TFTHEIGHT 320

    #define TFTWIDTH 320
    #define TFTHEIGHT 480

    oraz zamienic na:

    #define TFTWIDTH 240
    #define TFTHEIGHT 320

    // #define TFTWIDTH 320
    // #define TFTHEIGHT 480

    i dzieki za tekst, bez niego bylaby masakra.

  3. I jeszcze mialem odwrocone osie x i y.
    Musialem odnalezc w pliku TouchSscreen.cpp fragment:

    TSPoint::TSPoint(int16_t x0, int16_t y0, int16_t z0) {
    x= x0;
    y = y0;
    z = z0;

    z zamienic na:

    TSPoint::TSPoint(int16_t x0, int16_t y0, int16_t z0) {
    y = x0;
    x = y0;
    z = z0;

    i juz jakos tam dzialalo.

  4. świetny materiał. Ostatnio zakupiłem taki do swojego projektu i mam zgryz bo nie wpinam go w arduino UNO tylko za pośrednictwem przewodów jest połączony. Generalnie chodzi spoko choć mam problem ze współpracą z zegarem RTC DS 1307 na serial monitorze niby gra ale jak przyjdzie do wyświetlenia na TFT to biały ekran i kicha. Nigdzie też nie znalazłem info jakie pliki graficzne można na nim wyświetlać i jak to robić np. gdybym chciał wyświetlić jakieś ikonki (png, gif, ??), czy na karcie mają być katalogi czy bez.

  5. Witam b.dobry materiał.
    Właśnie trafił mi się taki LCD i prawie go opanowałem ale jak zwykle minimum info na sieci. Czy ten wyświetlacz ma możliwość zmiany kroju czcionki? jak wyświetlać np. ikony na ekranie i jakie pliki graficzne obsługuje? Mam z nim jeden problem gdyż nie bardzo współpracuje z RTC DS1307 na serial monitorze data i godzina śmiga ale gdy chcę wyświetlić je na ekranie TFT ekran robi się biały i kicha. I jeszcze jedno pytanko które/ile pinów ma być podłączonych do UNO aby można było czytać dane z SD?

    1. Witaj,
      przyznaję się, że dawno nie bawiłem się tym wyświetlaczem. Ale na pewno wczytywałem obrazki z karty i wyświetlałem je na ekranie. Niestety nie znalazłem kodu – ale sprawdź przykłady dołączone do biblioteki. Z tego co pamiętam (lub raczej niejasno jarzę), obrazki muszą być w odpowiednim formacie – png? tiff? Czcionkę też można było zmieniać… Może to Ci pomoże: https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts. DS1307 to zdaje się i2c? Tutaj nie powinno być konfliktów…
      Niestety tak na szybko to chyba wszystko, co pamiętam…

      Pozdrawiam,
      A

      1. Wooow czcionki śmigają aż miło 🙂 – Wielkie Dzięki.
        LCD mam podłączony przewodami a nie wpięty w UNO i aby nie zajmować wielu pinów podpięte mam wymagane minimum aby LCD śmigał (bez dotyku). Mam jak na razie zgryz gdyż ekran miał być zawieszony w osobnej obudowie ale ilość kabli do podłączenia jest troszkę za duża i zostaje albo zbić do jednej obudowy albo rozważyć inny LCD :-(.
        Jeszcze raz Wielkie Dzięki za podpowiedź.
        Pozdrawiam

Dodaj komentarz