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
-