Zaloguje się
or
Tel +48 698 615 740

Dotykowy ekran LCD 3.2″, wykorzystanie w praktyce

20 stycznia, 2022

W tym artykule pokażemy jak podłączyć i zaprogramować zamontowany na shieldzie dotykowy wyświetlacz LCD 3.2″. Do zaprezentowania działania ekranu posłuży prosty program realizujący obsługę zapalania i gaszenia trzech diod poprzez naciśnięcie na ekranie odpowiedniego przycisku.

Brak opisu.

Spis treści

  • Krótki opis
  • Specyfikacja
  • Kod programu
  • Pliki źródłowe

Krótki opis

Program będzie działał w oparciu o trzy przyciski znajdujące się na wyświetlaczu, każdy odpowiadający za inną diodę. Wraz z naciśnięciem przycisku dioda zapala się, a ponowne wciśnięcie sprawia że gaśnie. Stan diody sygnalizują odpowiednio napisy “ON” oraz “OFF”. Istotą dobrego zaprojektowania interfejsu jest odpowiednie zrozumienie w jaki sposób podzielony jest ekran. Rozmieszczenie punktów na ekranie działa na zasadzie układu współrzędnych, co szerzej zostanie omówione podczas opisywania kodu programu. Do poprawnego uruchomienia ekranu niezbędne będzie wykorzystanie dodatkowych bibliotek, do których link znajduje się na końcu artykułu.

Specyfikacja

Użyte komponenty
  • arduino leonardo
  • 3.2″ TFT LCD SHIELD
  • 3 diody LED
  • 3 rezystory 230 Ω
  • 20 kabli typu męsko-żeńskiego
  • płytka stykowa
Schemat połączeń

Diody łączymy kolejno do pinów D1, D2 oraz D3 naszego mikrokontrolera.

Podłączenie naszego wyświetlacza jest znacznie bardziej skomplikowane i wymaga aż 16 połączeń. Sposób podłączenia danych pinów przedstawia poniższa tabela.

Ze względu na to, że nie korzystamy z czytnika kart SD, cztery ostatnie połączenia możemy pominąć. Również pin oznaczony jako RESET jest nam zbędny.

Brak opisu.

Kod programu

Na początku dodajemy niezbędne do obsługi wyświetlacza biblioteki oraz definiujemy potrzebne zmienne. Dodatkowo tworzymy obiekty umożliwiające obsługę ekranu, funkcji dotykowej oraz wyświetlania aktualnego położenia po naciśnięciu na ekran. Zdefiniowanie nazw kolorów znacznie poprawia czytelność kodu.

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>
MCUFRIEND_kbv tft; // Stworzenie obiektu pełniącego rolę wyświetlacza
/* Zmienne do obsługi ekranu dotykowego */
uint8_t YP = A1; 
uint8_t XM = A2; 
uint8_t YM = 7;   
uint8_t XP = 6; 
/* --------------------------------- */  
int16_t BOXSIZE; // Zainicjowanie zmiennej służącej do tworzenia przycisków
/* Definicja poszczególnych boków ekranu */
uint16_t TS_LEFT = 880;
uint16_t TS_RT  = 170;
uint16_t TS_TOP = 950;
uint16_t TS_BOT = 180;
/* --------------------------------- */  
#define MINPRESSURE 20 // Minimalna wartość jaką może odczytać program aby uznać, że dotknęliśmy ekranu
#define MAXPRESSURE 500 // Maksymalna wartość jaką może odczytać program aby uznać, że dotknęliśmy ekranu
/* Zdefiniowanie nazwy diody do odpowiadającej jej pinowi */
#define Dioda_jeden 1
#define Dioda_dwa 2
#define Dioda_trzy 3
/* --------------------------------- */  
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 250); // Stworzenie obiektu pełniącego rolę ekranu dotykowego
TSPoint tp; // Stworzenie obiektu do ustalania aktualnego punktu na ekranie
/* Przypisanie do nazw kolorów odpowiadających im wartości w systemie szesnastkowym*/
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
/* --------------------------------- */ 
/* Zmienne pomocnicze do zmiany stanu diody */
  bool flaga_jeden = true;
  bool flaga_dwa = true;
  bool flaga_trzy = true;
/* --------------------------------- */ 

W funkcji setup() ustawiamy stan diod na wyjście. Rozpoczynamy transmisję szeregową oraz uruchamiamy ekran o zadanym id. Istotą zrozumienia działania wyświetlacza jest zobrazowanie jego wielkości na układzie współrzędnych. Znając długość i szerokość ekranu (możemy wyświetlić korzystając z funkcji tft.height() oraz tft.width()), możemy określić położenie wszystkich punktów.

Ustawienie kursora w celu wyświetlenia napisów zostało dobrane metodą prób i błędów. W przypadku bloków funkcjonujących jako przyciski możemy łatwo określić ich wielkość. Wiedząc, że każdy z nich jest równy 1/3 wysokości, łatwo obliczyć że długość ich boku jest równa 80. Z odpowiednimi marginesami równymi 20, na całej długości ekranu mieści się idealnie 5 takich bloków. Łatwo wywnioskować, że odstępy między przyciskami są równe długości ich boków.

void setup() {
/* ustawienie stanu diody na wyjście */
  pinMode(Dioda_jeden,OUTPUT);
  pinMode(Dioda_dwa,OUTPUT);
  pinMode(Dioda_trzy,OUTPUT);
/* --------------------------------- */ 
  Serial.begin(9600); // Rozpoczęcie transmisji szeregowej
  tft.begin(0x9327); // Rozpoczęcie pracy ekranu o id 0x9327 ( odpowiada naszemu modelowi ekranu)
  tft.fillScreen(BLACK); // Wypełnienie ekranu kolorem czarnym
  tft.setRotation(1); // ustawienie rotacji ekranu na poziomą
  BOXSIZE = tft.height() / 3; // przypisanie do zmiennej BOXSIZE wartości odpowiadającej 1/3 wysokości ekranu ( w pozycji poziomej wysokość ekranu jest równa jego szerokości)
   tft.fillRect(0, 0, BOXSIZE, BOXSIZE, YELLOW);// stworzenie w punkcie (0,0) żółtego kwadratu o bokach równych 1/3 wysokości ekranu
   tft.setTextColor(BLACK); // Ustawienie koloru tekstu na czarny
   tft.setCursor(20,10); // ustawienie pozycji kursora na (20,10)
   tft.setTextSize(3); // ustawienie wielkości liter na 3
   tft.print("1.");   // wypisanie na ekranie liczby 1
   tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, MAGENTA);// stworzenie w punkcie odległym od poczatku ekranu o dwókrotną długość boku kwadratu BOXSIZE, różowego kwadratu o bokach równych 1/3 wysokości ekranu
   tft.setCursor(180,10);  // ustawienie pozycji kursora na (180,10)
   tft.print("2.");// wypisanie na ekranie  liczby 2
   tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE); // stworzenie w punkcie odległym od poczatku ekranu o czterokrotną długość boku kwadratu BOXSIZE, różowego kwadratu o bokach równych 1/3 wysokości ekranu
   tft.setCursor(340,10);  // ustawienie pozycji kursora na (340,10)
   tft.print("3."); // wypisanie na ekranie liczby 3
   tft.setTextColor(GREEN);// Ustawienie koloru tekstu na zielony
   tft.setCursor(tft.width()/2-100,BOXSIZE+20); // zmiana pozycji kursora
   tft.println("WYBIERZ DIODE"); // wypisanie tekstu
   tft.setCursor(tft.width()/2-170,BOXSIZE+60);
   tft.println("KTORA CHCESZ ZAPALIC");
   tft.setTextSize(4); // zmiana wielkości tekstu na 4
   tft.setCursor(20,50); // ustawienie pozycji kursora na (20,50)
   tft.setTextSize(3);
   tft.setTextColor(RED);
   tft.print("OFF");
   tft.setCursor(180,50); // ustawienie pozycji kursora na (180,50)
   tft.print("OFF");
   tft.setCursor(340,50);  // ustawienie pozycji kursora na (340,50)
   tft.print("OFF");
}

Dzieląc nasz punkt na składowe x i y przy pomocy funkcji mapowania, możemy precyzyjnie określić w którym miejscu aktualnie znajduje się nasz punkt po naciśnięciu na ekran.

void loop() {

   uint16_t xpos, ypos; // inicjacja zmiennych służących do ustalenia składowych x i y pozycji kursora
   tp = ts.getPoint(); // przypisanie do zmiennej tp aktualnego punktu na ekranie
   /*ustawienie na wyjście pinów służących do obsługi ekranu dotykowego*/
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
    pinMode(XP, OUTPUT);
    pinMode(YM, OUTPUT); 
   /* --------------------------------- */  
       if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) { // sprawdzanie czy punkt znajduje się w granicach ustalonych na początku programu
        xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width()); // rozdzielenie zmiennej tp na składową x poprzez funkcję mapowania
        ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height()); // rozdzielenie zmiennej tp na składową y poprzez funkcję mapowania

Warunki sprawdzające aktualną pozycję zostały dobrane z uwzględnieniem znajomości wartości szerokości i długości ekranu. Wiedząc że wysokość ekranu w pozycji pionowej jest równa 360, a przycisk zajmuje 1/3 szerokości, łatwo wywnioskować że aby znaleźć się w obszarze przycisku składowa y punktu musi być większa od 2/3 wysokości czyli 240. Kolejno sprawdzamy czy znajdujemy się w obszarze każdego z przycisków. Wiedząc, że szerokość ekranu w pozycji pionowej jest równa 240, a przycisków zmieści się równo 5 i każdy z nich jest kwadratem, to każdy z przycisków zajmuje obszar 1/5 szerokości czyli 48 na 48. Odstęp między przyciskami jest taki sam jak ich wymiary, wobec tego łatwo stworzyć instrukcje warunkowe sprawdzające czy punkt znajduje się w obszarze danego przycisku.

 if(xpos>240) // jeżeli składowa x punktu jest większa od 240, czyli znajdujemy się w obszarze przycisków
    {
      if(ypos<48) // jeżeli składowa y punktu jest mniejsza od 48, czyli znajdujemy się w obszarze przycisku nr 1.
      { 
      else if(ypos<144&&ypos>96) // jeżeli składowa y punktu jest mniejsza od 144 i większa od 96, czyli znajdujemy się w obszarze przycisku nr 2.
      {
      }
      else if(ypos<240&&ypos>192) // jeżeli składowa y punktu jest mniejsza od 240 i większa od 192, czyli znajdujemy się w obszarze przycisku nr 2.
      {
      }
    }

Jeżeli punkt odpowiada któremuś z warunków, to następuje obsługa zapalenia i zgaszenia diody. To jaki stan ma posiadać dioda po naciśnięciu przycisku definiuje zmienna stanu logicznego flaga. Jeżeli jej wartość jest równa true, to dioda się zapala a na ekranie przy odpowiednim przycisku pojawia się napis ON . Następnie zmieniamy wartość “flagi” na przeciwną i odczekujemy 500 ms w celu uniknięcia kilkukrotnego wychwycenia pojedynczego naciśnięcia. Podobnie postępujemy w przypadku obsługi warunku na gaszenie diodę. Ustawienie koloru tła tekstu na kolor odpowiadający danemu przyciskowi umożliwia jego podmianę. Biblioteka której używamy nie posiada funkcji bezpośredniej podmiany tekstu, wobec tego tekst nadal się wyświetla, ale jest zamazany dzięki zastosowaniu odpowiedniego koloru tła.

if(flaga_dwa==true)
        {
          digitalWrite(Dioda_dwa, HIGH);
          tft.setTextColor(GREEN,MAGENTA);
          tft.setCursor(180,50);
          tft.println("ON ");
          flaga_dwa=false;
           delay(500);
        }
        else
       {
        digitalWrite(Dioda_dwa,LOW);
          tft.setTextColor(RED,MAGENTA);
          tft.setCursor(180,50);
          tft.println("OFF");
          flaga_dwa=true;
           delay(500);
       }

Pliki źródłowe

Sticky
Możliwość komentowania Dotykowy ekran LCD 3.2″, wykorzystanie w praktyce została wyłączona
Mateusz Pacia

Mateusz Pacia

Skończyłem studia na politechnice Wrocławskiej na kierunku Mechatronika. Zajmuje się tworzeniem i programowaniem układów z wykorzystaniem mikrokontrolerów STM32 i Arduino. W wolnych chwilach programuje w języku PHP i Java.

Comments are closed.

Strona korzysta z plików cookies w celu realizacji usługi i zgodnie z Polityką Plików Cookies. Możesz określić warunki przechowywania lub dostępu do plików cookies w Twojej przeglądarce.