hamradioshop.ro
Articole > Software pentru radioamatori Litere mici Litere medii Litere mari     Comentati acest articol    Tipariti

ESP32 Serial Monitor cu Display ILI9341 Spy 2.8 inch

Doru Sandu ex. YO9CXY

Intr-un articol anterior am explicat faptul ca informatiile prezente pe internet nu sunt intotdeauna cele pe care le dorim. Fara sa punem la socoteala si situatiile in care sunt nefunctionale sau explicate gresit, am luat hotararea sa folosesc putinul timp liber pentru a lamuri cateva aspecte legate de functionarea unui ESP32 intr-o retea WiFi.

De regula multi dintre noi care incearca sa realizeze o aplicatie soft de la zero sau prin modificarea exemplelor existente, sunt mai mult priceputi in costructiile hardware decat in informatica.

De aceea aceea majoritatea folosim programe de generatie mai veche care se potrivesc sigur cu tehnica din laboratoarele noastre. Eu, de obicei apelez la serviciile suficiente ale lui Arduino IDE 1.8.16, care are o flexibilitate foarte buna si caruia i se poate adauga o varietate larga de Biblioteci si Placi.

In periplul meu printre informatii, am avut nevoie frecvent de monitorizarea functionarii sau a depanarii programelor. Folosirea Serial Monitor-ului prezent in Tools nu este intotdeauna recomandata pentru ca utilizeaza acelasi port pe care se face si incarcarea fisierelor in microcontroller oricare ar fi el, iar rezultatul este o blocare nedorita a intregii lucrari.

Pentru a nu mai avea nevoie de activarea/dezactivarea repetata a Serial Monitor-ului, eventual si pentru o portabilitate sporita,am luat hotararea sa transfer monitorizarea pe un Display ILI 9341 Spy cu o marime medie si usor lizibil care foloseste putine resurse hardware. Exemplificarea o voi face pe un program simplu de manageriere a doua relee publicat de Rui Santos pe pagina: https://randomnerdtutorials.com/esp32-access-point-ap-web-server/

Programul este modificat pentru a folosi conexiunea WiFi AP (fara legatura prin internet), sa controleze doua Led-uri de la distanta asigurata de o comunicatie WiFi, aproximativ 10m. Recomand sa retineti structura acestui program pentru ca imbunatatirile ulterioare vor avea drept punct de plecare acest exemplu fara sa mai revenim de fiecare data cu explicatii suparator repetate.

 

     

Interfata PC Infotmatii monitor

Pentru ca acest proiect reprezinta o ocazie rara sa intelegem functionarea unui Wifi Web Server pe o gama larga de device-uri, am luat hotararea sa adaug tot ce este necesar pentru a-i monitoriza functionarea “pas cu pas”. Schema electronica pe care am abordat-o este una cu putine componente si se alimenteaza fie prin USB-ul computerului, fie de la o sursa externa stabilizata de 3V3 sau 5 Vcc.

Pentru mai multe amanunte recomand studierea cu atentie si in detaliu a documentatiei produsului.

Constructia Hardware este dupa cum am spus, in jurul unui ESP32S sau ESP32U, care are

un numar de 38 de terminale si este usor de recunoscut. Se pot incerca si alte module ESP!

Voi prezenta configuratia Pin Out a componentelor fara a intocmi o schema electronica de conexiuni, cu scopul de a obisnui unilizatorul sa caute in softul utilizat toate amanuntele privind constructia.

  

ESP 32-S Pin Out (Atentie la pinul nr.21!)                                               ESP 32-U Pin Out

 

 

                  ILI9341 2.8inch TFT Spy Display

 

Arhitectura Software:

Softul prezentat in continuare va fi explicat pe larg cu toate amanuntele, in asa fel incat si un incepator va putea intelege modalitatea functionarii unei retele WiFi, a paginilor HTML/CSS folosite, si de ce nu, cum sa reconstruiasca o aplicatie proprie.

Sper sa nu fie nimeni acuzat de plagiere, tot este la moda, pentru folosirea unor instructiuni si subrutine care oricum nu pot fi editate si folosite decat intr-un singur mod!

Am lasat totusi comentariile interne in EN intrucat am observat ca revista noastra este citita si comentata in multe alte tari. Iata fisierul .txt care oricand poate fi redenumit .ino pentru prelucrare:

 

/// ESP32_38pin-Serial Monitor with ILI9341 2.8 inch Display ///

#include <Adafruit_GFX.h>       // Version 1.5.3

#include <Adafruit_ILI9341.h>   // Version 1.5.6

#include <SPI.h>                // Version 2.1

#include <WiFi.h>

// ******************************************** //

 

// Pin configuration for the ILI9341 display/2.8inch

const int TFT_CS    = 5;    // Pin-29 ESP32 "VSPISS" (GPIO 05)

const int TFT_RST   = -1;   // It is not used, connected to +Vcc (1K/5V) or directly 3V3

const int TFT_DC    = 21;   // PIN-33 ESP32 "I2CSDA" (GPIO 21)

const int TFT_MOSI  = 23;   // MOSI---> ESP32 pin 37 "VSPIMOSI" (GPIO 23)

const int TFT_SCK   = 18;   // SCLK---> ESP32 pin 30 "VSPISCK"  (GPIO 18)

 

// Initialize the Display

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define ILI9341_GREY 0x5AEB

// ******************************************** //

 

// Replace with your network credentials

const char* ssidAP = "Led_Manager";

const char* passwordAP = "12345678";

 

// Define pin OUT

const int output15 = 15;    // ADC13:GPIO15_Pin-23, OUT LED-1

const int output2 = 2;      // ADC12:GPIO2_Pin-24, OUT LED-2

 

// Variable to store the HTTP request

String currentLine = "";    // Declare the currentLine variable

String header = "";         // This is where we store the entire HTTP request

 

// Auxiliar variables to store the current output state

String output15State = "OFF";

String output2State = "OFF";

 

// Set web server port number to 80

WiFiServer server(80);

///******************************************************************///

 

void setup()

{

  Serial.begin(115200);

  tft.begin();

  tft.setRotation(1);

  tft.fillScreen(ILI9341_GREY);

  // Adding a background color that automatically erases the previous text

  tft.setTextColor(ILI9341_WHITE, ILI9341_GREY);

  tft.setTextSize(3);

 

  // Configurarea variabile IN/OUT

  pinMode(output15, OUTPUT);          // ADC13:GPIO15_Pin-23, OUT LED-1

  pinMode(output2, OUTPUT);           // ADC12:GPIO2_Pin-24, OUT LED-2

 

  // Set outputs to LOW

  digitalWrite(output15, LOW);

  digitalWrite(output2, LOW);

 

  tft.setCursor(20, 20);    // Cursor coordinates: Horizontal, Vertical

  tft.println("ESP32 WiFi AP WS");

  tft.setCursor(55, 60);

  tft.setTextSize(2);

  tft.setTextColor(ILI9341_RED, ILI9341_GREY);

 

  tft.println("Connect to WiFi...");

  WiFi.softAP(ssidAP, passwordAP);

  // Waiting for AP to connect (one second)

  while (WiFi.softAPgetStationNum() == 0)

  {

  delay(1000);  // Wait 1 second

  tft.print(".");

  }

 

  // Use "fillRect" to clear the display

  // tft.fillRect(xStart, yStart, tft.width(), yEnd - yStart, background_color);

  tft.fillRect(0, 80, 320, 160, ILI9341_GREY);

 

  // Get the IP address of the AP

  IPAddress IP = WiFi.softAPIP();

  server.begin();           // Start the HTTP server

  tft.setCursor(20, 85);

  tft.setTextColor(ILI9341_GREEN, ILI9341_GREY);

  tft.print("AP_IPaddress:");

  tft.println(IP);

 

  tft.setCursor(40, 110);

  tft.println("WiFi Connected");

 

      tft.setCursor(105, 165);

      tft.println("GPIO 15 OFF");

      tft.setCursor(105, 185);

      tft.println("GPIO  2 OFF");

    tft.setCursor(20, 210);

    tft.println("Client Disconnected.");

}

///******************************************************************///

 

void loop()

{

 // Check if there is a Client Connection

tft.setCursor(20, 140);

tft.println("Missing Connection    ");

///delay(500);

WiFiClient client = server.available();

 

if (client)

  {

   tft.setCursor(20, 140);

   tft.println("Connection Established");

   ///delay(500);

 

    // Read the HTTP request byte by byte to its end

    while (client.connected())    // Loop "while" the client's connected

    {

      tft.setCursor(20, 210);

      tft.println("Client Connected!   ");

 

      if (client.available())     // If there's bytes to read from the client,

      {

        header += client.readString();

 

        if (header.endsWith("\r\n\r\n"))

        {

          // If you have reached the end of the HTTP request (after two newline characters),

          // can process the request and exit the loop

          if (currentLine.length() == 0)

          {

            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)

            // and a content-type so the client knows what's coming, then a blank line:

            client.println("HTTP/1.1 200 OK");

            client.println("Content-type:text/html");

            client.println("Connection: close");

            client.println();

           

            // Turns the GPIOs ON and OFF

            if (header.indexOf("GET /15/ON") >= 0)

            {

            tft.setCursor(105, 165);

            tft.println("GPIO 15  ON");

            ///Serial.println("GPIO 15 ON");

            output15State = "ON";

            digitalWrite(output15, HIGH);

            }

 

              else

              if (header.indexOf("GET /15/OFF") >= 0)

              {

              tft.setCursor(105, 165);

              tft.println("GPIO 15 OFF");

              ///Serial.println("GPIO 15 OFF");

              output15State = "OFF";

              digitalWrite(output15, LOW);

              }

 

            else

            if (header.indexOf("GET /2/ON") >= 0)

            {

            tft.setCursor(105, 185);

            tft.println("GPIO  2  ON");

            ///Serial.println("GPIO  2 ON");

            output2State = "ON";

            digitalWrite(output2, HIGH);

            }

 

              else

              if (header.indexOf("GET /2/OFF") >= 0)

              {

              tft.setCursor(105, 185);

              tft.println("GPIO  2 OFF");

              ///Serial.println("GPIO  2 OFF");

              output2State = "OFF";

              digitalWrite(output2, LOW);

              }

        

            // Display the HTML web page & CSS to style the ON/OFF buttons

            client.println("<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");

            ///client.println("<link rel=\"icon\" href=\"data:,\">");

            client.println("<style>html{font-family:Helvetica;display:inline-block;margin:0 auto;text-align:center;}");

            client.println(".button{background-color:GREEN;border:none;color:white;padding:16px 40px;text-decoration:none;font-size:30px;margin:2px;cursor:pointer;}");

            client.println(".button2{background-color:RED;}</style></head><body><h1>ESP32 WiFi AP WebServer</h1>");

          

            // Display current state, and ON/OFF buttons for GPIO 15 

            client.println("<p>GPIO 15 - State " + output15State + "</p>");

 

            // If the output15State is OFF, it displays the ON button      

            if (output15State=="OFF")

              {client.println("<p><a href=\"/15/ON\"><button class=\"button\">ON</button></a></p>");}

 

            else

              {client.println("<p><a href=\"/15/OFF\"><button class=\"button button2\">OFF</button></a></p>");}

              

            // Display current state, and ON/OFF buttons for GPIO 2 

            client.println("<p>GPIO 2 - State " + output2State + "</p>");

 

            // If the output2State is OFF, it displays the ON button      

            if (output2State=="OFF")

              {client.println("<p><a href=\"/2/ON\"><button class=\"button\">ON</button></a></p>");}

 

            else

              {client.println("<p><a href=\"/2/OFF\"><button class=\"button button2\">OFF</button></a></p>");}

              client.println("</body></html>");

           

            // The HTTP response ends with another blank line

            client.println();

 

            // Break out of the while loop

            break;

            }

 

          else  // If you got a newline, then clear currentLine

          {currentLine = "";}

        }

      }

    }

 

    // Clear the header variable

    header = "";

 

    // Close the connection

    client.stop();

    tft.setCursor(20, 210);

    tft.println("Client Disconnected!");

    ///Serial.println("Client Disconnected!");

    ///Serial.println("");

    ///delay(500);

  }

}

///******************************************************************///

/// END PROGRAM ///

 

Copiati programul in format .txt, schimbati-i extensia in .ino si prelucrati cu Arduino IDE!

 

Prezentarea programului:

Dupa cum este notat in antet, arhitectura programului este construita in jurul unui microcontroller cu 38 de pini din seria ESP32. Folosirea altui tip este permisa doar dupa verificarea si modificarea pinilor definiti in program!

 

1 – Biblioteci (Librarii) folosite:

            #include <Adafruit_GFX.h>       // Version 1.5.3

#include <Adafruit_ILI9341.h>   // Version 1.5.6

#include <SPI.h>                // Version 2.1

#include <WiFi.h>

Atentie mare la variantele si integritatea acestora, puteti avea surprise.

 

2 – Configurarea pinilor pentru display si initializarea acestuia:

            - // Pin configuration for the ILI9341 display/2.8inch

const int TFT_CS    = 5;    // Pin-29 ESP32 "VSPISS" (GPIO 05)

const int TFT_RST   = -1;   // It is not used, connected to +Vcc (1K/5V) or directly 3V3

const int TFT_DC    = 21;   // PIN-33 ESP32 "I2CSDA" (GPIO 21)

const int TFT_MOSI  = 23;   // MOSI---> ESP32 pin 37 "VSPIMOSI" (GPIO 23)

const int TFT_SCK   = 18;   // SCLK---> ESP32 pin 30 "VSPISCK"  (GPIO 18)

 

// Initialize the Display

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define ILI9341_GREY 0x5AEB

Observati ca TFT_RST este conectat direct la 3V3 sau printr-un resistor la 5V!

 

3 – In continuare urmeaza o sectiune importanta pentru buna functionare:

            - Replace with your network credentials

Aici puteti sa va reintroduceti propria denumire a retelei AP, cu acces direct (ssid),

sau/si propria parola (password) pentru a va proteja de intrusi.

Pentru o retea publica, cum ar fi o statie meteo cu acces pentru aricine, parola poate lipsi, aceasta este o parola vida: const char* passwordAP = "";

            - // Define pin OUT

Definim iesirile pentru cele doua LED-uri.

Atentie! GPIO-urile definite (15 si 2) sunt echivalentul pinilor (23 si 24), nu confundati niciodata adresa GPIO cu denumirea pinului-terminal.

- // Variable to store the HTTP request

Acestea sunt doua variabile gestionate de pagina HTML din program.

            - // Auxiliar variables to store the current output state

Cele doua variabile prezente in aceasta sectiune determina iesirile pentru Led-1 si Led-2 sa fie setate la nivel Low (OFF = stinse) in momentul  pornirii programului.

            - // Set web server port number to 80

Setam in sfarsit un port de comunicatie disponibil in WiFi, 80 in cazul nostru.

Se poate seta oricare alt port disponibil dup ace se consulta atent documentatia microcontrollerui pe care doriti sa-l folositi.

 

4 – Urmeaza rutina “void setup()” in care se fac diverse setari, se afiseaza texte permanente pe display, poitia, marimea si culorile sau se determina  starile initiale ale pinilor de intrare sau iesire.

Sa enumeram cateva:

 

Serial.begin(115200);                          - rata de comunicatie seriala, daca este cazul

            tft.begin();                                           - initializarea displayului

tft.setRotation(1);                               - rotirea afisarii pe display, portrait sau landscape

            tft.fillScreen(ILI9341_GREY);          - culoarea fundalului, grey

            tft.setTextColor(ILI9341_WHITE, ILI9341_GREY);          - culoarea textului si fundalului

            tft.setTextSize(3);                               - marimea textului

            tft.setCursor(20, 20);    // Cursor coordinates: Horizontal, Vertical   - poztiz cursorului

            tft.println("ESP32 WiFi AP WS");     - textul afisat, de exemplu

            ……………………………………

tft.setCursor(105, 165);                       - informatii utile despre starea initiala a iesirilor

            tft.println("GPIO 15 OFF");

            tft.setCursor(105, 185);

            tft.println("GPIO  2 OFF");

            tft.setCursor(20, 210);

   

Tot in aceasta rutina se gestioneaza conexiunea WiFi cu atentionarile de rigoare afisate pe display, inclusiv date despre adresa IP a ESP-ului folosit, din constructie setat cu (192.168.4.1).

Se poate schimba la nevoie.

 

  tft.println("Connect to WiFi...");

  WiFi.softAP(ssidAP, passwordAP);

  // Waiting for AP to connect (one second)

  while (WiFi.softAPgetStationNum() == 0)

  {

  delay(1000);  // Wait 1 second

  tft.print(".");

  }

 

  // Use "fillRect" to clear the display

  // tft.fillRect(xStart, yStart, tft.width(), yEnd - yStart, background_color);

  tft.fillRect(0, 80, 320, 160, ILI9341_GREY);

 

  // Get the IP address of the AP

  IPAddress IP = WiFi.softAPIP();

  server.begin();           // Start the HTTP server

  tft.setCursor(20, 85);

  tft.setTextColor(ILI9341_GREEN, ILI9341_GREY);

  tft.print("AP_IPaddress:");

  tft.println(IP);

 

  tft.setCursor(40, 110);

  tft.println("WiFi Connected");

 

Instructiunea WiFi.softAP(ssidAP, passwordAP); forteaza reteaua inca de la pornirea ESP-ului sa caute un corespondent.

Daca nu este gasit, while (WiFi.softAPgetStationNum() == 0)

la fiecare secunda, delay(1000); tipareste cate un punct, tft.print(".");

De remarcat este faptul ca pentru conexiunea in retea, fiecare device, telefon sau PC, are propriul meniu unde se va active WiFi, identifica Led_Manager si se va introduce manual parola 12345678.

Este posibil ca asteptarea sa fie lunga iar display-ul sa se umple cu puncte, asa ca la identificarea unui corespondent, pentru o afisare normala se face o stergere a tuturor punctelor incepand cu primul rand,

tft.fillRect(0, 80, 320, 160, ILI9341_GREY);

La final, conexiunea fiind efectuata se afiseaza IP-ul 192.168.4.1 apoi mesajul WiFi Connected.

Parcurgerea rutinei void setup() se face o singura data la alimentarea montajului sau de fiecare data cand se executa un RESET prin actionarea butonului de pe placa ESP.

 

5 – Urmeaza rutina “void loop()” care ruleaza permanent pentru gestionarea relatiei Server-Client.

            - WiFiClient client = server.available();

Prima operatie este aceea de verificare a partenerului conectat in retea, daca acesta este unul “agreat”.

In cazul de fata orice conexiune este validate. Chiar mai mult, se admit conexiuni cu 2, 3 sau 4 clienti.

Dupa verificarea stabilitatii conexiunii se confirma reusita operatiei:

while (client.connected())

……

tft.setCursor(20, 140);

            tft.println("Connection Established");

 

Am  ajuns in sfarsit la solicitarea paginii  HTTP care poate procesa datele sau cererea de iesire din buclă:            // Close the connection

            client.stop();

            tft.setCursor(20, 210);

            tft.println("Client Disconnected!");

 

Prelucrarea datelor aferente cererii din pagina HTML se face in codurile de sub eticheta:

- // Turns the GPIOs ON and OFF

 

Complementar, afisarea starii reale a LED-urilor se face in codurile de sub cele doua etichete:

- // Display current state, and ON/OFF buttons for GPIO 15 

                        si

            - // Display current state, and ON/OFF buttons for GPIO 2 

            conform graficii realizate prin codul de sub eticheta:

-          // Display the HTML web page & CSS to style the ON/OFF buttons

 

Consideratii generale:

Viteza de rulare a programului poate fi incetinita semnificativ ptin sterderea clor trei linii oblice din

fata tuturor instructiunilor     ///delay(500);    In cazul in care se doreste utmarirea mesajelor si pe

Serial Monitor-ul din meniul Arduino IDE se face acelasi lucu si cu instructiunile ///Serial.println("..”)

Compilarea softului se face prin activarea icoanei  din meniul principal . Incarcarea fisierului rezultat in mikrocontrollerul ESP32 se face prin conexiunea USB dupa ce portul de comunicatie a fost setat corespunzator pe ruta Tools > Port: “Com…”.

Aceasta operatie incepe la aparitia mesajului:

   si apasarea timp de 3 - 5 sec. a butonului Boot.

Oricand Radioamatorul interesat poate modifica, adapta sau dezvolta aplicatia de fata printr-o gestionare controlata a codului prezentat. Sprijinul meu poate consta in rezolvarea micilor icidente aparute pe parcursul incercarilor dumneavoastra sau prin oferta de explicatii suplimentare, atat cat imi permite experienta. Cererea se poate face la tel. 0742997202 sau prin e-mail: gocomraex @ gmail.com

Best regards from PH

Doru Sandu ex. YO9CXY

Articol aparut la 31-10-2023

1187

Inapoi la inceputul articolului

Comentarii (2)  

  • Postat de Constantin - YO7FWS (yo7fws) la 2023-11-02 10:34:41 (ora Romaniei)
  • Salut Doru. Chiar daca mi se pare complicat sa folosesti pentru depanare un ecran atit de mic, recunosc, in anumite conditii, solutia descrisa de tine este perfect posibila. Spre exemplu, la teste, cind portul serial trebuie sa comunice cu un alt dispozitiv.
    Cu o mica modificare, am simulat proiectul tau pe Wokvi: https://wokwi.com/projects/380214367053795329
    Pina de curind am folosit Arduino 1.8.9. Din curiozitate am testat varianta 2.2.1. A fost o surpriza placuta si am ramas definitiv la ea.
    Succes la proiectele tale in desfasurare! 73, Costi
      Comentariu modificat de autor.

  • Postat de Doru Sandu - YO9CXY (yo9cxy) la 2023-11-04 19:03:27 (ora Romaniei)
  • Multumesc pentru comentariu!
    Asa cum am precizat,articolul se vrea educativ iar pentru incepatori o sursa de inspiratie in realizarea unor lucrari.
    Ca Serial Monitor poate fi oricand modificat si folosit "in portabil" pentru a supraveghea actiuni.Nu mai putin adevarat ca se poate folosi si aplicatii de telefonie mobila dar totusi, practicianul pana nu lipeste el o sarmulita nu se multumeste.
    Toate cele bune!
    73! D.Sandu

    Scrieti un mic comentariu la acest articol!  

    Opinia dumneavoastra va aparea dupa postare sub articolul "ESP32 Serial Monitor cu Display ILI9341 Spy 2.8 inch"
    Comentariul trebuie sa se refere la continutul articolului. Mesajele anonime, cele scrise sub falsa identitate, precum si cele care contin (fara a se limita la) atac la persoana, injurii, jigniri, expresii obscene vor fi sterse iar dupa caz se va ridica dreptul de a posta comentarii.
    Comentariu *
     
    Trebuie sa va autentificati pentru a putea adauga un comentariu.


    Opiniile exprimate în articole pe acest site aparţin autorilor şi nu reflectă neapărat punctul de vedere al redacţiei.

    Copyright © Radioamator.ro. Toate drepturile rezervate. All rights reserved
    Articole | Concursuri | Mica Publicitate | Forum YO | Pagini YO | Call Book | Diverse | Regulamentul portalului | Contact