Zaloguje się
or
Tel +48 698 615 740

Ustawienie wagi przy pomocy wyświetlacza dotykowego LCD 3.2″

01 września, 2022

W artykule zostanie przedstawione menu do wyświetlacza dotykowego za pomocą którego jest możliwość odczytywania aktualnych wartości z wagi (belki tensometrycznej). Na wyświetlaczu również można ustawić wartość do jakiej ma zostać obciążona waga (np. jakimś płynem w połączeniu z pompą).

Spis treści

  • Wykorzystane komponenty
  • Wstęp
  • Zaprogramowanie
  • Pliki do pobrania

Wykorzystane komponenty

  • Arduino Mega
  • Dotykowy Wyświetlacz LCD TFT przekątna 3.2″

Wstęp

Program jak i wyświetlacz można wykorzystać w różnych projektach z wagą, posiada on 3 funkcje: pierwsza to pokazywanie aktualnego obciążenia na wadze, druga to możliwość ustawienia gramów do którego momentu ma zostać obciążona, a trzecia to tarowanie. Po naciśnięciu wyświetlacza w miejscu ustaw wagę, wyświetli się klawiatura na której będziemy mogli wpisać interesującą nas wartość. Program posiada również zabezpieczenie i więcej niż 4 liczby nie wpiszemy. Wszystkie te funkcje można zmodyfikować pod swój projekt albo dodać własne. Niezbędna do zaprogramowania wyświetlacza będzie tutaj wiedza z tego artykułu https://ajmaker.pl/2022/01/20/dotykowe-ekran-lcd-3-2-wykorzystanie-w-praktyce/.

Zaprogramowanie

Na początku deklarujemy wszystkie potrzebne zmienne, definicje, biblioteki oraz najważniejsze ustawienia w funkcji setup.

#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 nam do tworzenia przycisków
/* Definicja poszczególnym 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

#define PWM 3
#define IN1 2
#define IN2 5
/* --------------------------------- */
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

bool mieszanie =  true; //zmienna do silnika
bool pompa = true; //zmienna do pomy
int obroty = 100; //obroty silnika
int value = 255; //wartosc obrotow
bool menu_mierzenie = false; //menu do wazenia

int num_count_A = 0; //liczba wpisanych liczb w menu wagi A
int num_count_B = 0; //liczba wpisanych liczb w menu wagi B

bool wazenie = true; //zadeklarowanie zmiennej wazenie
int once = 0; //zadeklarowanie zmiennej oncet

unsigned long ustawgramy_A = 0; //ustawione gramy wagi A
unsigned long last_number_A = 0; //poprzedni numer wpisany w funkcji ustawGramy()
bool ustaw_wage_A = false; //menu do ustawiania wagi A

unsigned long ustawgramy_B = 0; //ustawione gramy wagi B
unsigned long last_number_B = 0; //poprzedni numer wpisany w funkcji ustawGramy()
bool ustaw_wage_B = false; //menu do ustawiania wagi B

void setup() {
  Serial.begin(9600); // Rozpoczęcie transmisji szeregowej

  pinMode(PWM, OUTPUT); //ustawienie PWM jako wyjście
  pinMode(IN1, OUTPUT); //ustawienie IN1 jako wyjście
  pinMode(IN2, OUTPUT); //ustawienie IN2 jako wyjście

  analogWrite(PWM, 0); //ustawienie prędkości obrotów

  digitalWrite(IN1, LOW); //ustawienie stanu niskiego na IN1
  digitalWrite(IN2, LOW); //ustawienie stanu niskiego na IN2

  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ą
  tft.setTextColor(WHITE); // Ustawienie koloru tekstu na czarny
  BOXSIZE = tft.height() / 3;

  menuWazenie(); // wyświetl menu ważenie
}

Teraz zajmiemy się główną funkcją loop, na początek standardowe ustawienia wyświetlacza oraz niezbędny if.

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

Teraz pozostałe instrukcje warunkowe, które określą gdzie aktualnie dotykamy ekran i przypisujemy do nich odpowiednie działanie.

    if (xpos > 240) // jeżeli składowa x punktu jest większa od 240, czyli znajdujemy się w pierwszym wierszu
    {
      if (ypos > 144 && ypos < 192) // jeżeli składowa y punktu jest większa od 144 i mniejsza od 188, czyli znajdujemy się w obszarze przycisku mieszanie
      {
        once = 0; //wyzerowanie zmiennej once
        ustaw_wage_A = true; //ustaw zmienną ustaw_wage_A na true

        while (ustaw_wage_A) // do póki ustaw_wage_A prawda, wykonuj pentle
        {
          if (once < 1) // jeżeli zmienna once mniejsza od 1 wykonaj poniższe instrukcje
          {
            klawiatura(ustawgramy_A); //wywołanie funkcji klawiatury
            once++; //dodaj 1 do zmiennej once
          }

          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

            if (num_count_A < 1) // jeżeli zmienna once mniejsza od 1 wykonaj poniższe instrukcje
            {
              tft.setCursor(22, 30); //ustawienie kursora
              tft.setTextColor(WHITE, BLACK); //zmiana koloru tekstu
            }

            wpiszGramy(xpos, ypos); //wyświetl menu z ważeniem
          }
        }
        menuWazenie(); //wyświetl menu z ważeniem
      }
      else if (ypos > 192 && ypos < 240)
      {
        Serial.println("taruj wage A");
        //tutaj będzie tarowanie wagi A
      }
    }
    else if (xpos > 120 && xpos < 240)
    {
      if (ypos > 144 && ypos < 192) // jeżeli składowa y punktu jest większa od 144 i mniejsza od 188, czyli znajdujemy się w obszarze przycisku mieszanie
      {
        once = 0; //wyzerowanie zmiennej once
        ustaw_wage_B = true; //ustaw zmienną ustaw_wage_B na true

        while (ustaw_wage_B) // do póki ustaw_wage_B prawda, wykonuj pentle
        {
          if (once < 1) // jeżeli zmienna once mniejsza od 1 wykonaj poniższe instrukcje
          {
            klawiatura(ustawgramy_B); //wywołanie funkcji klawiatury
            once++; //dodaj 1 do zmiennej once
          }

          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

            if (num_count_B < 1)
            {
              tft.setCursor(22, 30); //ustawienie kursora
              tft.setTextColor(WHITE, BLACK); //zmiana koloru tekstu
            }

            wpiszGramy(xpos, ypos); //wywołanie funkcji wpiszGramy
          }
        }
        menuWazenie(); //wyświetl menu z ważeniem
      }
      else if (ypos > 192 && ypos < 240)
      {
        Serial.println("taruj wage B");
        //tutaj będzie tarowanie wagi B
      }
    }
  }
}

Z głównego programu byłoby na tyle, ale zostały jeszcze wykorzystane w nim funkcje. Pierwsza z nich ustawGramy() odpowiada za łączenie wpisywanych liczb z wyświetlacza, wyświetlanie liczby i wysyłanie jej do odpowiedniej zmiennej. Zależy to od tego czy korzystamy z menu A czy B. Funkcja posiada jeden argument w którym przyjmowana jest aktualnie wciskana liczba na wyświetlaczu.

void ustawGramy(int l)
{
  if (ustaw_wage_A)
  {
    if (num_count_A > 0 && num_count_A < 4) //jeżeli ilość liczb jest większa od zera i mniejsza od 4 wykonaj poniższe instrukcje
    {
      ustawgramy_A = last_number_A * 10 + l; //pomnożenie ostatniej liczby przez 10 i dodanie liczby, która została wybrana
      last_number_A = ustawgramy_A; //przypisanie gramów jako ostatnia liczba
    }
    else if (num_count_A < 1) //jeżeli ilość liczb jest mniejszy od 1 wykonaj poniższe instrukcje
    {
      ustawgramy_A = l; //ustawienie gramów wagi A
      last_number_A = ustawgramy_A; //przypisanie gramów jako ostatnia liczba
    }
    num_count_A++; //zwiększenie ilości numerów
    tft.setCursor(22, 30); //ustawienie pozycji kursora
    tft.print(ustawgramy_A); //wyświetlenie tekstu
  }
  else
  {
    if (num_count_B > 0 && num_count_B < 4) //jeżeli ilość liczb jest większa od zera i mniejsza od 4 wykonaj poniższe instrukcje
    {
      ustawgramy_B = last_number_B * 10 + l; //pomnożenie ostatniej liczby przez 10 i dodanie liczby, która została wybrana
      last_number_B = ustawgramy_B; //przypisanie gramów jako ostatnia liczba
    }
    else if (num_count_B < 1) //jeżeli ilość liczb jest mniejszy od 1 wykonaj poniższe instrukcje
    {
      ustawgramy_B = l; //ustawienie gramów wagi B
      last_number_B = ustawgramy_B; //przypisanie gramów jako ostatnia liczba
    }
    num_count_B++; //zwiększenie ilości numerów
    tft.setCursor(22, 30); //ustawienie pozycji kursora
    tft.print(ustawgramy_B); //wyświetlenie tekstu
  }
}

Kolejna funkcja menuWazenie wyświetla całe menu.

void menuWazenie()
{
  tft.fillScreen(BLACK); //wypełnij wyświetlacz czarnym kolorem
  tft.setTextColor(WHITE); //ustaw kolor tekstu na biały
  //pierwsza kolumna
  tft.setTextSize(1); //ustawienie rozmiaru tekstu
  tft.setCursor(10, 35); //ustawienie pozycji kursora
  tft.print("WAGA A"); //wyświetlenie tekstu
  tft.setCursor(10, 115); //ustawienie pozycji kursora
  tft.print("WAGA B"); //wyświetlenie tekstu
  tft.setCursor(10, 195); //ustawienie pozycji kursora
  //pierwszy wiersz
  tft.setCursor(345, 55); //ustawienie pozycji kursora
  tft.print("TARUJ"); //wyświetlenie tekstu
  tft.setCursor(250, 55); //ustawienie pozycji kursora
  tft.print("USTAW WAGE"); //wyświetlenie tekstu
  tft.setTextColor(WHITE); //ustawienie koloru tekstu
  tft.setCursor(159, 55); //ustawienie pozycji kursora
  tft.print("AKT. WAGA"); //wyświetlenie tekstu
  tft.setTextSize(2); //ustawienie rozmiaru tekstu
  tft.setCursor(355, 25); //ustawienie pozycji kursora
  tft.print("X"); //wyświetlenie tekstu
  tft.setCursor(255, 25); //ustawienie pozycji kursora
  tft.print(ustawgramy_A); //wyświetlenie tekstu
  tft.print("g"); //wyświetlenie tekstu
  tft.setCursor(180, 25); //ustawienie pozycji kursora
  tft.print("0"); //wyświetlenie tekstu
  //drugi wiersz
  tft.setTextSize(1); //ustawienie rozmiaru tekstu
  tft.setCursor(345, 130); //ustawienie pozycji kursora
  tft.print("TARUJ"); //wyświetlenie tekstu
  tft.setCursor(250, 130); //ustawienie pozycji kursora
  tft.print("USTAW WAGE"); //wyświetlenie tekstu
  tft.setTextColor(WHITE); //ustawienie koloru tekstu
  tft.setCursor(159, 130); //ustawienie pozycji kursora
  tft.print("AKT. WAGA"); //wyświetlenie tekstu
  tft.setTextSize(2); //ustawienie rozmiaru tekstu
  tft.setCursor(355, 100); //ustawienie pozycji kursora
  tft.print("X"); //wyświetlenie tekstu
  tft.setCursor(255, 100); //ustawienie pozycji kursora
  tft.print(ustawgramy_B); //wyświetlenie tekstu
  tft.print("g"); //wyświetlenie tekstu
  tft.setCursor(180, 100); //ustawienie pozycji kursora
  tft.print("0"); //wyświetlenie tekstu
}

Funkcja klawiatura, wyświetla całą klawiaturę wraz z ustawionymi gramami. Przyjmuje ona jeden argument i wyświetla aktualnie ustawione gramy.

void klawiatura(int g)
{
  tft.fillScreen(BLACK); //wypełnij wyświetlacz czarnym kolorem
  tft.setTextColor(WHITE); //ustaw kolor tekstu na biały

  tft.setTextSize(3); //ustawienie rozmiaru tekstu
  tft.setCursor(22, 30); //ustawienie pozycji kursora
  tft.print(g); //wyświetlenie tekstu
  tft.setCursor(112, 30); //ustawienie pozycji kursora
  tft.print("g"); //wyświetlenie tekstu
  tft.setCursor(192, 30); //ustawienie pozycji kursora
  tft.print("1"); //wyświetlenie tekstu
  tft.setCursor(272, 30); //ustawienie pozycji kursora
  tft.print("2"); //wyświetlenie tekstu
  tft.setCursor(352, 30); //ustawienie pozycji kursora
  tft.print("3"); //wyświetlenie tekstu
  tft.setCursor(22, 110); //ustawienie pozycji kursora
  tft.print("GOTOWE"); //wyświetlenie tekstu
  tft.setCursor(192, 110); //ustawienie pozycji kursora
  tft.print("4"); //wyświetlenie tekstu
  tft.setCursor(272, 110); //ustawienie pozycji kursora
  tft.print("5"); //wyświetlenie tekstu
  tft.setCursor(352, 110); //ustawienie pozycji kursora
  tft.print("6"); //wyświetlenie tekstu
  tft.setCursor(112, 190); //ustawienie pozycji kursora
  tft.print("0"); //wyświetlenie tekstu
  tft.setCursor(32, 190); //ustawienie pozycji kursora
  tft.print("C"); //wyświetlenie tekstu
  tft.setCursor(192, 190); //ustawienie pozycji kursora
  tft.print("7"); //wyświetlenie tekstu
  tft.setCursor(272, 190); //ustawienie pozycji kursora
  tft.print("8"); //wyświetlenie tekstu
  tft.setCursor(352, 190); //ustawienie pozycji kursora
  tft.print("9"); //wyświetlenie tekstu

  tft.drawFastHLine(0, 0, 400, WHITE); //narysowanie linii poziomej
  tft.drawFastHLine(0, 80, 400, WHITE); //narysowanie linii poziomej
  tft.drawFastHLine(0, 160, 400, WHITE); //narysowanie linii poziomej
  tft.drawFastHLine(0, 239, 400, WHITE); //narysowanie linii poziomej

  tft.drawFastVLine(0, 0, 400, WHITE); //narysowanie linii pionowej
  tft.drawFastVLine(80, 160, 400, WHITE); //narysowanie linii pionowej
  tft.drawFastVLine(160, 0, 400, WHITE); //narysowanie linii pionowej
  tft.drawFastVLine(240, 0, 400, WHITE); //narysowanie linii pionowej
  tft.drawFastVLine(320, 0, 400, WHITE); //narysowanie linii pionowej
  tft.drawFastVLine(399, 0, 400, WHITE); //narysowanie linii pionowej
}

Ostatnią i największą funkcją będzie wpiszGramy, odbiera ona wciśnięte przez użytkownika liczby i wysyła do funkcji ustawGramy. Funkcja posiada dwa argumenty, gdzie przyjmuje pozycje ekranu, aby mogła poprawnie działać.

void wpiszGramy(int xpos, int ypos)
{
  if (xpos > 240) // jeżeli składowa x punktu jest większa od 240, czyli znajdujemy się w pierwszym wierszu
  {
    if (ypos > 106 && ypos < 154)
    {
      Serial.println("1"); //wyświetl w monitorze portu szeregowego
      ustawGramy(1); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 154 && ypos <= 202)
    {
      Serial.println("2"); //wyświetl w monitorze portu szeregowego
      ustawGramy(2); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 202 && ypos <= 250)
    {
      Serial.println("3"); //wyświetl w monitorze portu szeregowego
      ustawGramy(3); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
  }
  else if (xpos > 120 && xpos <= 240) // jeżeli składowa x punktu jest większa od 120 i mniejsza od 240, czyli znajdujemy się w drugim wierszu
  {
    if (ypos > 0 && ypos < 106)
    {
      Serial.println("GOTOWE"); //wyświetl w monitorze portu szeregowego
      ustaw_wage_A = false;
      ustaw_wage_B = false;
      delay(500); //opoźnienie
    }
    else if (ypos > 106 && ypos < 154)
    {
      Serial.println("4"); //wyświetl w monitorze portu szeregowego
      ustawGramy(4); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 154 && ypos < 202)
    {
      Serial.println("5"); //wyświetl w monitorze portu szeregowego
      ustawGramy(5); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 202 && ypos < 250)
    {
      Serial.println("6"); //wyświetl w monitorze portu szeregowego
      ustawGramy(6); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
  }
  else if (xpos < 120) //jeżeli składowa x punktu jest mniejsza od 120, czyli znajdujemy się w trzecim wierszu
  {
    if (ypos > 0 && ypos < 48)
    {
      Serial.println("C");
      tft.setCursor(22, 30);
      tft.setTextColor(WHITE, BLACK); //ustawienie koloru tekstu i tła, pierwszy parametr kolor tekstu, drugi tła
      tft.print("0    "); //wyświetlenie 0 ze spacjami, żeby wyczyścić ekran w miejscu wpisywanych liczb

      if (ustaw_wage_A) //jeżeli jesteśmy w menu wagi A zerujemy wartości
      {
        last_number_A = 0; //zerujemy zmienną
        ustawgramy_A = 0; //zerujemy zmienną
        num_count_A = 0; //zerujemy zmienną
      }
      else if (ustaw_wage_B) //jeżeli jesteśmy w menu wagi B zerujemy wartości
      {
        last_number_B = 0; //zerujemy zmienną
        ustawgramy_B = 0; //zerujemy zmienną
        num_count_B = 0; //zerujemy zmienną
      }

      delay(500);
    }
    else if (ypos > 48 && ypos < 106) //zakres zera na wyświetlaczu
    {
      Serial.println("0"); //wyświetl w monitorze portu szeregowego
      ustawGramy(0); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 106 && ypos < 154) //zakres siódemki na wyświetlaczu
    {
      Serial.println("7"); //wyświetl w monitorze portu szeregowego
      ustawGramy(7); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 154 && ypos < 202) //zakres ósemki na wyświetlaczu
    {
      Serial.println("8"); //wyświetl w monitorze portu szeregowego
      ustawGramy(8); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
    else if (ypos > 202 && ypos < 250) //zakres dziewiątki na wyświetlaczu
    {
      Serial.println("9"); //wyświetl w monitorze portu szeregowego
      ustawGramy(9); //wywołanie funkcji ustawGramy
      delay(500); //opoźnienie
    }
  }
}

Wykorzystanie w praktyce

Pliki do pobrania

Sticky
Możliwość komentowania Ustawienie wagi przy pomocy wyświetlacza dotykowego LCD 3.2″ została wyłączona
Adrian Wojtala

Adrian Wojtala

Ma 21 lat. Studiuje informatykę na Uniwersytecie DSW, ukończył technikum o profilu technik-informatyk. Interesuje się programowaniem i w przyszłości ma plan zostać back-end developerem. Swoją przygodę z Arduino rozpoczął podczas praktyk od września 2021 r.

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.