![]()  | 
|
  | 
O Interfata grafica "buna la orice"!
 De data aceasta revin cu un soft experimentat, construit
dupa exemplele grafice din bibliotecile ESP32, si modelat in asa fel incat sa poata fi usor inteles si
modificat pentru nevoile oricui. Asa cum mi s-a sugerat, incerc sa nu reinventez “apa calda”
dar sper ca articolele mele sa vina in sprijinul celor mai putin priceputi sau
incepatorilor. “Experimentatii” pot interveni cu idei constructive. Aplicatia se vrea o interfata grafica ce poate fi folosita
pentru nevoile radioamatorilor care vor sa-si construiasca un S-metru sau o
tastatura deosebita, sa foloseasca comunicatia WiFi in aplicatii sau sa
controleze parametrii dispozitivelor construite in jurul placilor ESP32-S.
Recomand aceasta placa pentru performantele ei, pentru usurinta programarii cu
Arduino IDE si pentru faptul ca poate folosi o antenna exterioara conectata cu
foarte mare usurinta. Articolul anterior are toate elementele Hardware de
conectare a unui ESP32 cu un Display ILI 9341 SPI. Nu mai revin la acest aspect intrucat scriptul care urmeaza
contine din nou conexiunile pinilor, in schimb voi posta o noua imagine cu Pin Out-ul
microcontrollerului in idea ca studiind-o cu atentie veti constata unele
restrictii in folosirea intarilor si iesirilor GPIO.     Prezentarea Software: Softul prezentat in continuare va fi explicat pe larg cu
toate amanuntele in asa fel incat cu putin efort, va putea fi inteles ca logica
a functionarii. Am folosit si adaptat rutine din exemple publicate in
bibliotecile  ESP32 existente la adresa:   https://github.com/Bodmer/TFT_eSPI Keypad_240x320 si TFT_Meters sunt
sursele de baza pentru Interfata Software prezentata, si care dupa cum
am mai spus, poate fi usor modificata la nevoie. Comentariile sunt scrise in EN cu scopul de a face posibila
intelegerea de catre o categorie mai larga de cititori. Iata fisierul .txt care trebuie redenumit .ino pentru prelucrare in Arduino IDE:   ///*******************************************************************/// ///******************* GOOD INTERFACE TO ANYTHING
********************/// ///*************** by DORU SANDU /
gocomraex@gmail.com****************/// ///************************************ ex.YO9CXY
********************/// ///*******************************************************************/// #include <WiFi.h> #include <SPI.h> #include <TFT_eSPI.h>       // Hardware-specific
library /* // Pin configuration for the ILI9341 display/2.8inch &
ESP32 S Dev Board #define TFT_CS     5    // Pin-29 ESP32 "VSPISS"
(GPIO_05) #define TFT_DC     33   // PIN-8 ESP32 "ADC1_5"
(GPIO_33) //#define TFT_MISO 19     // MISO---> ESP32 pin 31
"VSPI_MISO" (GPIO_19) #define TFT_MOSI   23   // MOSI---> ESP32 pin 37
"VSPI_MOSI" (GPIO_23) #define TFT_SCK    18   // SCLK---> ESP32 pin 30
"VSP_ISCK"  (GPIO_18) #define TFT_RST    32   // PIN-7 ESP32 "ADC1_4"
(GPIO_32) #define TOUCH_CS   27   // PIN-11 ESP32 "ADC2_7"
(GPIO_27) */ TFT_eSPI tft = TFT_eSPI();  // Invoke custom library /* #define ILI9341_BLACK       0x0000 #define ILI9341_NAVY        0x000F  #define ILI9341_DARKGREEN   0x03E0  #define ILI9341_DARKCYAN    0x03EF #define ILI9341_MAROON      0x7800 #define ILI9341_PURPLE      0x780F #define ILI9341_OLIVE       0x7BE0 #define ILI9341_LIGHTGREY   0xC618  #define ILI9341_DARKGREY    0x7BEF  #define ILI9341_BLUE        0x001F #define ILI9341_GREEN       0x07E0 #define ILI9341_CYAN        0x07FF #define ILI9341_RED         0xF800 #define ILI9341_MAGENTA     0xF81F  #define ILI9341_YELLOW      0xFFE0 #define ILI9341_WHITE       0xFFFF #define ILI9341_ORANGE      0xFD20 #define ILI9341_GREENYELLOW 0xAFE5 #define ILI9341_PINK        0xF81F */ #define TFT_GREY            0x5AEB #define TEST_LED 15       // LED const char* wifi_ssid = "Denumirea retelei locale WiFi"; const char* wifi_psw = "Parola retelei locale WiFi"; int16_t previousRSSI = 0; //******************************//   // Keypad start position, key sizes and spacing #define KEY_X 75          // Center of key W #define KEY_Y 230         // Center of key Y #define KEY_W 60          // Width of Keys #define KEY_H 30          // Height of Keys #define KEY_SPACING_X 5   // X gap !!!Used for multiple
columns #define KEY_SPACING_Y 5   // Y gap !!!Used for multiple rows #define KEY_TEXTSIZE 1    // Font size multiplier //******************************//   // Using two fonts since numbers are nice when bold #define LABEL1_FONT &FreeSansOblique12pt7b    // Key
label font 1 #define LABEL2_FONT &FreeSansBold12pt7b       // Key
label font 2   // Create 9 keys for the keypad - Number of Keys / Maxim
Number of Characters char keyLabel[9][5] = {"-sta", "spk+",
"sta+", "   ", "stop", "   ",
"-pwr", "spk-", "pwr+"}; uint16_t keyColor[9] = {TFT_RED, TFT_ORANGE,
TFT_DARKGREEN,TFT_BLACK, TFT_GREY, TFT_BLACK,TFT_BLUE, TFT_MAGENTA, TFT_NAVY};   // Invoke the TFT_eSPI button class and create all the
button objects TFT_eSPI_Button key[9]; WiFiServer server(80); //******************************// /*    Available ESP32 RF power parameters:    For 19.5dBm of output, highest. Supply current ~150mA     WIFI_POWER_19_5dBm    // 19.5dBm  (80)     WIFI_POWER_19dBm      // 19dBm    (78)     WIFI_POWER_18_5dBm    // 18.5dBm  (72)     WIFI_POWER_17dBm      // 17dBm    (66)     WIFI_POWER_15dBm      // 15dBm    (60)     WIFI_POWER_13dBm      // 13dBm    (52)     WIFI_POWER_11dBm      // 11dBm    (44)     WIFI_POWER_8_5dBm     //  8dBm    (34)     WIFI_POWER_7dBm       //  7dBm    (28)     WIFI_POWER_5dBm       //  5dBm    (20)     WIFI_POWER_2dBm       //  2dBm    (8)     WIFI_POWER_MINUS_1dBm // -1dBm    (NEVER USE FOR
PROGRAMMING !!!)    For -1dBm of output, lowest. Supply current ~120mA */ const int wifiPowerValues[] = {   WIFI_POWER_2dBm,   WIFI_POWER_5dBm,   WIFI_POWER_7dBm,   WIFI_POWER_8_5dBm,   WIFI_POWER_11dBm,   WIFI_POWER_13dBm,   WIFI_POWER_15dBm,   WIFI_POWER_17dBm,   WIFI_POWER_18_5dBm,   WIFI_POWER_19dBm,   WIFI_POWER_19_5dBm };   const char* wifiPowerNames[] = {   "WIFI_POWER_2dBm",   "WIFI_POWER_5dBm",   "WIFI_POWER_7dBm",   "WIFI_POWER_8_5dBm",   "WIFI_POWER_11dBm",   "WIFI_POWER_13dBm",   "WIFI_POWER_15dBm",   "WIFI_POWER_17dBm",   "WIFI_POWER_18_5dBm",   "WIFI_POWER_19dBm",   "WIFI_POWER_19_5dBm" };   int IndexPower = 10; // Initial value for wifiPowerTx (0 to
10) //int valueSearched
= wifiPowerValues[IndexPower];     // Display
Power in dBm //const char* ConstPower = wifiPowerNames[IndexPower];  //
Display the name of the constant //******************************// #define LOOP_PERIOD 35 // Display updates every 35 ms   float ltx = 0;    // Saved x coord of bottom of needle uint16_t osx = 120, osy = 120;  // Saved x & y coords uint32_t updateTime = 0;        // Time for next update   int old_analog =  -999;         // Value last displayed   int value[6] = {0, 0, 0, 0, 0, 0}; int old_value[6] = { -1, -1, -1, -1, -1, -1}; int d = 0;   ///***************************** SETUP
*******************************/// void setup() {   Serial.begin(115200);         // For debug   pinMode(TEST_LED, OUTPUT);   tft.init();  // Inițializare ecran   tft.setRotation(0);   digitalWrite(TEST_LED, HIGH);     // Calibrare Touch Screen   uint16_t calibrationData[5];   tft.fillScreen(TFT_WHITE);   tft.setTextColor(TFT_RED);   tft.setTextSize(2);   tft.setCursor(40, 30, 2);   tft.print("Calibration of");   tft.setCursor(40, 70);   tft.print("Display");   tft.setTextColor(TFT_BLACK);   tft.setCursor(40, 130);   tft.print("Touch");   tft.setCursor(40, 170);   tft.print("the indicated");   tft.setCursor(40, 210);   tft.print("corners");   tft.setCursor(40, 250);   tft.print("to calibrate");   tft.calibrateTouch(calibrationData, TFT_GREEN, TFT_RED,
15); //******************************//   tft.fillScreen(TFT_BLACK);   tft.setTextColor(TFT_WHITE);   tft.setCursor(25, 80 ,2); // How many times the text set
in the previous row is enlarged   tft.print("Radio_Receiver");   tft.setTextSize(1);   tft.setCursor(10, 120, 2);   tft.printf("Connecting to '%s'\n" , wifi_ssid,
wifi_psw);   delay(2000);   tft.fillScreen(TFT_BLACK);   tft.setTextColor(TFT_RED);   tft.setTextSize(2);   tft.setCursor(20, 80 ,1);   tft.println("WIFI Connecting!");   delay(1000);   Connect_to_WiFi();   digitalWrite(TEST_LED, HIGH);   delay(3000);   digitalWrite(TEST_LED, LOW);   server.begin();           // Start the HTTP server   delay(2000); //******************************//     tft.fillScreen(TFT_BLACK);     drawCustomKeypad();     analogMeter();          // Draw analogue meter     updateTime = millis();  // Next update time     digitalWrite(TEST_LED, HIGH); }   ///****************************** LOOP
*******************************/// void loop() {   // Print the received signal strength:   long rssi = WiFi.RSSI();   Serial.print("RSSI:");   Serial.println(rssi);     int16_t currentRSSI = WiFi.RSSI();   if (currentRSSI != previousRSSI)   {     if (rssi >= -50)     {tft.setTextColor(TFT_GREEN);}       else     if (rssi >= -70 && rssi < -50)     {tft.setTextColor(TFT_WHITE);}       else     {tft.setTextColor(TFT_RED);}       if (rssi = 0)       {         tft.fillRect(185, 255, 40, 20, TFT_BLACK);         tft.setTextColor(TFT_RED);         tft.setCursor(198, 273);         tft.print("0");       }          tft.fillRect(185, 255, 40, 20, TFT_BLACK);     tft.setCursor(185, 273);   tft.print(WiFi.RSSI()); // Display the signal value of the
correspondent   previousRSSI = currentRSSI;   } //******************************//   if (updateTime <= millis())   {     updateTime = millis() + LOOP_PERIOD;       d += 4; if (d >= 360) d = 0;       //value[0] = map(analogRead(A0), 0, 1023, 0, 100); //
Test with value form Analogue 0       // Create a Sine wave for testing     value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);     value[1] = 50 + 50 * sin((d + 60) * 0.0174532925);     value[2] = 50 + 50 * sin((d + 120) * 0.0174532925);     value[3] = 50 + 50 * sin((d + 180) * 0.0174532925);     value[4] = 50 + 50 * sin((d + 240) * 0.0174532925);     value[5] = 50 + 50 * sin((d + 300) * 0.0174532925);       //unsigned long t = millis();     plotNeedle(value[0], 0);     //Serial.println(millis()-t); // Print time taken for
meter update   } //******************************// // Testing the Touch Screen   uint16_t t_x = 0, t_y = 0; // To store the touch
coordinates      // Pressed will be set true is there is a valid touch on
the screen     bool pressed = tft.getTouch(&t_x, &t_y);       // Check if any key coordinate boxes contain the touch
coordinates     for (uint8_t b = 0; b < 9; b++)     {       if (pressed && key[b].contains(t_x, t_y))     {key[b].press(true);}  // Tell the button it is pressed       else     {key[b].press(false);}  // Tell the button it is NOT
pressed     }     // Add a check to execute the appropriate functions   for (uint8_t b = 0; b < 9; b++)   {     if (key[b].justPressed())     {       if (b == 6) // RED Key       {       tft.fillRect(0, 175, 240, 35, TFT_BLACK);       tft.setTextColor(TFT_BLUE);       tft.setCursor(30, 200);       tft.print("TouchDownButton!");       TouchDownButton();       }         else if (b == 8) // NAVY Key       {       tft.fillRect(0, 175, 240, 35, TFT_BLACK);       tft.setTextColor(TFT_NAVY);       tft.setCursor(30, 200);       tft.print("TouchUpButton!");       TouchUpButton();       }   // The routine can continue with Buttons: 0, 1, 2, 4 and 7     }         else if (key[b].justReleased())       {       tft.fillRect(0, 175, 240, 35, TFT_BLACK);       tft.setTextColor(TFT_WHITE);       tft.setCursor(30, 200);       tft.print("NoTouchButton!");     }   } }   ///***************************** KEYPAD
******************************/// void drawCustomKeypad() {   // Draw the keys   for (uint8_t row = 0; row < 3; row++)   // Single row   {     for (uint8_t col = 0; col < 3; col++) // Two columns     {       uint8_t b = col + row * 3;          // Indexes the
current button         if (b < 9) tft.setFreeFont(LABEL1_FONT);  // Check
the value of "b"       else  tft.setFreeFont(LABEL2_FONT); // If "b >
9", use (LABEL2_FONT) /*     KEY_X: x Coordinate of the center of the first button     KEY_Y: y-coordinate of the center of the first button     KEY_W: Width of the button     KEY_H: Height of the button     KEY_SPACING_X: Horizontal space between buttons     KEY_SPACING_Y: Vertical space between buttons */         key[b].initButton(&tft, KEY_X + col * (KEY_W +
KEY_SPACING_X),                               KEY_Y + row * (KEY_H +
KEY_SPACING_Y), // x, y, w, h, outline, fill, text                               KEY_W, KEY_H, TFT_WHITE,
keyColor[b], TFT_WHITE,                  keyLabel[b], KEY_TEXTSIZE);       key[b].drawButton();     }   }     // Display of WIFI functional parameters   int wifiTxPower = WiFi.getTxPower();  // Read Inscribed
Power       tft.setTextColor(TFT_WHITE);       tft.setCursor(63, 273);       tft.print(wifiTxPower);  // Display WIFI Power        // Other possible data to display ///tft.printf("%dPower:%s\n", IndexPower,
ConstPower); ///tft.printf("%s\n", wifiPowerNames[IndexPower]);
// Displays Constants Name }   ///************************* WIFI CONNECTED
**************************/// void Connect_to_WiFi() {   // Waiting to connect to the WiFi network   WiFi.begin(wifi_ssid, wifi_psw);     for(int i = 0; i < 20 && WiFi.status() !=
WL_CONNECTED; i++)     {       Serial.print(".");       tft.print("*");       delay(500);     }     // Checking if the connection has been made     if (WiFi.status() != WL_CONNECTED)     {       tft.fillScreen(TFT_BLACK);       tft.setTextColor(TFT_RED);       tft.setCursor(10, 80);       tft.print("WIFI not Connected!");       Connect_to_WiFi();     }       else     {     digitalWrite(TEST_LED, LOW);      tft.fillScreen(TFT_BLACK);     tft.setTextColor(TFT_GREEN);     tft.setCursor(20, 80);     tft.println("WIFI Connected!");         // Show local IP       tft.setTextColor(TFT_WHITE);       tft.println(" ");       tft.println("IP local: ");       tft.println(WiFi.localIP());         // Show Correspondent IP       tft.println(" ");       tft.println("Correspondent IP:");       tft.println(WiFi.gatewayIP());         // Show IP P2P       tft.println(" ");       tft.println("Correspondent IP:");       tft.println(WiFi.softAPIP());     } }   ///*************************** WIFI POWER
****************************/// void TouchDownButton() {   digitalWrite(TEST_LED, LOW);   // Check if the WiFi power can be decreased       if (IndexPower > 0)       {         // Attention! Use the button's central coordinates         tft.fillRoundRect(KEY_X - KEY_W/2, KEY_Y + KEY_H*2 -
KEY_SPACING_Y, KEY_W, KEY_H, 5, TFT_LIGHTGREY);               // Explain (fillRoundRect): (X-position_upper
left corner, Y-position,               // width, height, background color, corner
radius, outline color)          tft.drawRoundRect(KEY_X - KEY_W/2, KEY_Y + KEY_H*2 -
KEY_SPACING_Y, KEY_W, KEY_H, 5, TFT_WHITE);               // Explain (drawRoundRect): (X-position_upper
left corner, Y-posi8tion,               // width, height, background color, corner
radius, outline color)           IndexPower--; // Decrease the power of WiFi       }         delay(100);     writePower(); } //******************************//   void TouchUpButton() {   digitalWrite(TEST_LED, HIGH);   // Check if the WiFi power can be increased       if (IndexPower < 10)       {         tft.fillRoundRect(KEY_X + KEY_W + KEY_W/2 +
KEY_SPACING_X*2, KEY_Y + KEY_H*2 - KEY_SPACING_Y, KEY_W, KEY_H, 5,
TFT_LIGHTGREY);         tft.drawRoundRect(KEY_X + KEY_W + KEY_W/2 +
KEY_SPACING_X*2, KEY_Y + KEY_H*2 - KEY_SPACING_Y, KEY_W, KEY_H, 5, TFT_WHITE);             IndexPower++; // Increase the power of WiFi       }         delay(100);     writePower(); } //******************************//   void writePower() {   switch (IndexPower)    // Read (IndexPower) Value   {                      // Write (IndexPower) corresponding
Power     case 0:     WiFi.setTxPower(WIFI_POWER_2dBm);     break;       case 1:     WiFi.setTxPower(WIFI_POWER_5dBm);     break;       case 2:     WiFi.setTxPower(WIFI_POWER_7dBm);     break;       case 3:     WiFi.setTxPower(WIFI_POWER_8_5dBm);     break;       case 4:     WiFi.setTxPower(WIFI_POWER_11dBm);     break;       case 5:     WiFi.setTxPower(WIFI_POWER_13dBm);     break;       case 6:     WiFi.setTxPower(WIFI_POWER_15dBm);     break;       case 7:     WiFi.setTxPower(WIFI_POWER_17dBm);     break;       case 8:     WiFi.setTxPower(WIFI_POWER_18_5dBm);     break;       case 9:     WiFi.setTxPower(WIFI_POWER_19dBm);     break;       case 10:     WiFi.setTxPower(WIFI_POWER_19_5dBm);     break;       default:     WiFi.setTxPower(WIFI_POWER_13dBm);   // Write Power in
case of error     break;     } delay(100); drawCustomKeypad(); }   ///************************** ANALOG METER
***************************/// //
######################################################################### //  Draw the analogue meter on the screen //
######################################################################### void analogMeter() {   // Meter outline   tft.fillRect(0, 0, 239, 126, TFT_GREY);   tft.fillRect(5, 3, 230, 119, TFT_WHITE);     tft.setTextColor(TFT_BLACK);  // Text colour     // Draw ticks every 5 degrees from -50 to +50 degrees (100
deg. FSD swing)   for (int i = -50; i < 51; i += 5)   {     // Long scale tick length     int tl = 15;       // Coodinates of tick to draw     float sx = cos((i - 90) * 0.0174532925);     float sy = sin((i - 90) * 0.0174532925);     uint16_t x0 = sx * (100 + tl) + 120;     uint16_t y0 = sy * (100 + tl) + 140;     uint16_t x1 = sx * 100 + 120;     uint16_t y1 = sy * 100 + 140;       // Coordinates of next tick for zone fill     float sx2 = cos((i + 5 - 90) * 0.0174532925);     float sy2 = sin((i + 5 - 90) * 0.0174532925);     int x2 = sx2 * (100 + tl) + 120;     int y2 = sy2 * (100 + tl) + 140;     int x3 = sx2 * 100 + 120;     int y3 = sy2 * 100 + 140;       // Yellow zone limits     if (i >= -50 && i < 0)     {       tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);       tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);     }       // Green zone limits     if (i >= 0 && i < 25)     {       tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);       tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);     }       // Orange zone limits     if (i >= 25 && i < 50)     {       tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);       tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);     }       // Short scale tick length     if (i % 25 != 0) tl = 8;       // Recalculate coords incase tick lenght changed     x0 = sx * (100 + tl) + 120;     y0 = sy * (100 + tl) + 140;     x1 = sx * 100 + 120;     y1 = sy * 100 + 140;       // Draw tick     tft.drawLine(x0, y0, x1, y1, TFT_BLACK);       // Check if labels should be drawn, with position tweaks     if (i % 25 == 0)     {       // Calculate label positions       x0 = sx * (100 + tl + 10) + 120;       y0 = sy * (100 + tl + 10) + 140;       switch (i / 25)       {         case -2: tft.drawCentreString("0", x0, y0
- 12, 2); break;         case -1: tft.drawCentreString("25", x0, y0
- 9, 2); break;         case 0: tft.drawCentreString("50", x0, y0
- 6, 2); break;         case 1: tft.drawCentreString("75", x0, y0
- 9, 2); break;         case 2: tft.drawCentreString("100", x0, y0
- 12, 2); break;       }     }       // Now draw the arc of the scale     sx = cos((i + 5 - 90) * 0.0174532925);     sy = sin((i + 5 - 90) * 0.0174532925);     x0 = sx * 100 + 120;     y0 = sy * 100 + 140;     // Draw scale arc, don't draw the last part     if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);   }     tft.drawString("dBm", 5 + 230 - 40, 119 - 20,
2); // Units at bottom right   tft.drawCentreString("Level Meter", 120, 70, 2);
// Comment out to avoid font 4   tft.drawRect(5, 3, 230, 119, TFT_BLACK); // Draw bezel
line     plotNeedle(0, 0); // Put meter needle at 0 }   //
######################################################################### // Update needle position // This function is blocking while needle moves, time
depends on ms_delay // 10ms minimises needle flicker if text is drawn within
needle sweep area // Smaller values OK if text not in sweep area, zero for
instant movement but // does not look realistic... (note: 100 increments for full
scale deflection) //
######################################################################### void plotNeedle(int value, byte ms_delay) {   tft.setTextColor(TFT_BLACK, TFT_WHITE);   char buf[8]; dtostrf(value, 4, 0, buf);   tft.drawRightString(buf, 40, 119 - 20, 2);     if (value < -10) value = -10; // Limit value to emulate
needle end stops   if (value > 110) value = 110;     // Move the needle util new value reached   while (!(value == old_analog))   {     if (old_analog < value) old_analog++;     else old_analog--;       if (ms_delay == 0) old_analog = value; // Update
immediately id delay is 0       float sdeg = map(old_analog, -10, 110, -150, -30); //
Map value to angle     // Calcualte tip of needle coords     float sx = cos(sdeg * 0.0174532925);     float sy = sin(sdeg * 0.0174532925);       // Calculate x delta of needle start (does not start at
pivot point)     float tx = tan((sdeg + 90) * 0.0174532925);       // Erase old needle image     tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy,
TFT_WHITE);     tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy,
TFT_WHITE);     tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy,
TFT_WHITE);       // Re-plot text under needle     tft.setTextColor(TFT_BLACK);     tft.drawCentreString("Level Meter", 120, 70,
2); // // Comment out to avoid font 4       // Store new needle end coords for next erase     ltx = tx;     osx = sx * 98 + 120;     osy = sy * 98 + 140;       // Draw the needle in the new postion, magenta makes
needle a bit bolder     // draws 3 lines to thicken needle     tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy,
TFT_RED);     tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy,
TFT_MAGENTA);     tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy,
TFT_RED);       // Slow needle down slightly as it approaches new
postion     if (abs(old_analog - value) < 10) ms_delay +=
ms_delay / 5;       // Wait before next update     delay(ms_delay);   } } ///************************** END OF PROGRAM
*************************///     Logica programului: 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 <WiFi.h>             #include <SPI.h>             #include <TFT_eSPI.h>       //
Hardware-specific library Folositi cele mai noi variante!   2 – Configurarea pinilor pentru display si
initializarea acestuia:  /* // Pin configuration for the ILI9341 display/2.8inch &
ESP32 S Dev Board #define TFT_CS     5    // Pin-29 ESP32 "VSPISS"
(GPIO_05) #define TFT_DC     33   // PIN-8 ESP32 "ADC1_5"
(GPIO_33) //#define TFT_MISO 19     // MISO---> ESP32 pin 31
"VSPI_MISO" (GPIO_19) #define TFT_MOSI   23   // MOSI---> ESP32 pin 37
"VSPI_MOSI" (GPIO_23) #define TFT_SCK    18   // SCLK---> ESP32 pin 30
"VSP_ISCK"  (GPIO_18) #define TFT_RST    32   // PIN-7 ESP32 "ADC1_4"
(GPIO_32) #define TOUCH_CS   27   // PIN-11 ESP32 "ADC2_7"
(GPIO_27) */ Observati ca TFT_MISO nu este folosit! Atrag atentia
ca pinii definiti aici, in program sunt comentati deoarece atribuirea lor se
face intr-un fisier al bibliotecii numit “User_Setup.h”. Asa ca pentru o reusita imediata urmati calea:   Program Files (x86) >> Arduino >> libraries
>>TFT_eSPI-master >>  User_Setup.h,   unde inlocuiti
secventa de cod originala cu aceasta: ======================================================================== // For ESP32 Dev board (only tested with ILI9341 display) // The hardware SPI can be mapped to any pins   //#define TFT_MISO 19 #define TFT_MOSI 23 #define TFT_SCLK 18 #define TFT_CS    5   // Chip select control pin #define TFT_DC   33   // Data Command control pin #define TFT_RST  32   // Reset pin (could connect to RST
pin) //#define TFT_RST  32  // Set TFT_RST to -1 if display
RESET is connected to ESP32 board RST //#define TOUCH_CS 25     // Chip select pin (T_CS) of
touch screen #define TOUCH_CS 27     // Chip select pin (T_CS) of
touch screen // For ESP32 Dev board (only tested with GC9A01 display) // The hardware SPI can be mapped to any pins ========================================================================   Initializare Display: TFT_eSPI tft = TFT_eSPI();  // Invoke custom library   3 – Urmeaza o sectiune comentata unde sunt prezentate
culorile disponibile pentru display-ul ILI9341. /* #define ILI9341_BLACK       0x0000 #define ILI9341_NAVY        0x000F  #define ILI9341_DARKGREEN   0x03E0  #define ILI9341_DARKCYAN    0x03EF #define ILI9341_MAROON      0x7800 #define ILI9341_PURPLE      0x780F #define ILI9341_OLIVE       0x7BE0 #define ILI9341_LIGHTGREY   0xC618  #define ILI9341_DARKGREY    0x7BEF  #define ILI9341_BLUE        0x001F #define ILI9341_GREEN       0x07E0 #define ILI9341_CYAN        0x07FF #define ILI9341_RED         0xF800 #define ILI9341_MAGENTA     0xF81F  #define ILI9341_YELLOW      0xFFE0 #define ILI9341_WHITE       0xFFFF #define ILI9341_ORANGE      0xFD20 #define ILI9341_GREENYELLOW 0xAFE5 #define ILI9341_PINK        0xF81F */ Am incarcat prezentarea cu toate aceste informatii pentru a
face mai usoara modificarea sau dezvoltarea softului in functie de necesitati
si dorintele fiecaruia.     4 – Seria declaratiilor de mai jos au rolul de a pune
la dispozitie programului toate informatiile necesare unei functionari corecte.
Nu insist asupra acestora pentru ca sunt comentate intr-un mod usor de inteles.   #define TFT_GREY            0x5AEB #define TEST_LED 15       // LED const char* wifi_ssid = "Denumirea retelei locale WiFi"; const char* wifi_psw = "Parola retelei locale WiFi"; int16_t previousRSSI = 0; //******************************//   // Keypad start position, key sizes and spacing #define KEY_X 75          // Center of key W #define KEY_Y 230         // Center of key Y #define KEY_W 60          // Width of Keys #define KEY_H 30          // Height of Keys #define KEY_SPACING_X 5   // X gap !!!Used for multiple
columns #define KEY_SPACING_Y 5   // Y gap !!!Used for multiple rows #define KEY_TEXTSIZE 1    // Font size multiplier //******************************//   // Using two fonts since numbers are nice when bold #define LABEL1_FONT &FreeSansOblique12pt7b    // Key
label font 1 #define LABEL2_FONT &FreeSansBold12pt7b       // Key
label font 2   // Create 9 keys for the keypad - Number of Keys / Maxim
Number of Characters char keyLabel[9][5] = {"-sta", "spk+",
"sta+", "   ", "stop", "   ",
"-pwr", "spk-", "pwr+"}; uint16_t keyColor[9] = {TFT_RED, TFT_ORANGE,
TFT_DARKGREEN,TFT_BLACK, TFT_GREY, TFT_BLACK,TFT_BLUE, TFT_MAGENTA, TFT_NAVY};   // Invoke the TFT_eSPI button class and create all the
button objects TFT_eSPI_Button key[9]; WiFiServer server(80); //******************************//   5 – Aceste informatii dau posibilitatea ca programul
sa poata modifica puterea de emisie a dispozitivului WiFi cu care este dotata
placa ESP32. Nu incercati sa folositi: WIFI_POWER_MINUS_1dBm, pentru ca
veti avea surprize extrem de neplacute. /*    Available ESP32 RF power parameters:    For 19.5dBm of output, highest. Supply current ~150mA     WIFI_POWER_19_5dBm    // 19.5dBm  (80)     WIFI_POWER_19dBm      // 19dBm    (78)     WIFI_POWER_18_5dBm    // 18.5dBm  (72)     WIFI_POWER_17dBm      // 17dBm    (66)     WIFI_POWER_15dBm      // 15dBm    (60)     WIFI_POWER_13dBm      // 13dBm    (52)     WIFI_POWER_11dBm      // 11dBm    (44)     WIFI_POWER_8_5dBm     //  8dBm    (34)     WIFI_POWER_7dBm       //  7dBm    (28)     WIFI_POWER_5dBm       //  5dBm    (20)     WIFI_POWER_2dBm       //  2dBm    (8)     WIFI_POWER_MINUS_1dBm // -1dBm    (NEVER USE FOR
PROGRAMMING !!!)    For -1dBm of output, lowest. Supply current ~120mA */ const int wifiPowerValues[] = {   WIFI_POWER_2dBm,   WIFI_POWER_5dBm,   WIFI_POWER_7dBm,   WIFI_POWER_8_5dBm,   WIFI_POWER_11dBm,   WIFI_POWER_13dBm,   WIFI_POWER_15dBm,   WIFI_POWER_17dBm,   WIFI_POWER_18_5dBm,   WIFI_POWER_19dBm,   WIFI_POWER_19_5dBm };   const char* wifiPowerNames[] = {   "WIFI_POWER_2dBm",   "WIFI_POWER_5dBm",   "WIFI_POWER_7dBm",   "WIFI_POWER_8_5dBm",   "WIFI_POWER_11dBm",   "WIFI_POWER_13dBm",   "WIFI_POWER_15dBm",   "WIFI_POWER_17dBm",   "WIFI_POWER_18_5dBm",   "WIFI_POWER_19dBm",   "WIFI_POWER_19_5dBm" };   int IndexPower = 10; // Initial value for wifiPowerTx (0 to
10) //int valueSearched
= wifiPowerValues[IndexPower];     // Display
Power in dBm  //const char* ConstPower = wifiPowerNames[IndexPower];  //
Display the name of the constant //******************************//   6– Urmeaza rutina “void setup()” in care dupa
cateva setari, se propune calibrarea Touch Screen-ului, fara de care pozitia
Butoanelor nu este recunoscuta corect.   void setup() {   Serial.begin(115200);         // For debug   pinMode(TEST_LED, OUTPUT);   tft.init();  // Inițializare ecran   tft.setRotation(0);   digitalWrite(TEST_LED, HIGH);     // Calibrare Touch Screen   uint16_t calibrationData[5];   tft.fillScreen(TFT_WHITE);   tft.setTextColor(TFT_RED);   tft.setTextSize(2);   tft.setCursor(40, 30, 2);   tft.print("Calibration of");   tft.setCursor(40, 70);   tft.print("Display");   tft.setTextColor(TFT_BLACK);   tft.setCursor(40, 130);   tft.print("Touch");   tft.setCursor(40, 170);   tft.print("the indicated");   tft.setCursor(40, 210);   tft.print("corners");   tft.setCursor(40, 250);   tft.print("to calibrate");   tft.calibrateTouch(calibrationData, TFT_GREEN, TFT_RED,
15); //******************************// In continuare se pregatesc cateva mesaje pentru informarea
stadiului diferitelor operatii, cea mai importanta fiind conectarea la reteaua
WiFi.     tft.fillScreen(TFT_BLACK);   tft.setTextColor(TFT_WHITE);   tft.setCursor(25, 80 ,2); // How many times the text set
in the previous row is enlarged   tft.print("Radio_Receiver");   tft.setTextSize(1);   tft.setCursor(10, 120, 2);   tft.printf("Connecting to '%s'\n" , wifi_ssid,
wifi_psw);   delay(2000);   tft.fillScreen(TFT_BLACK);   tft.setTextColor(TFT_RED);   tft.setTextSize(2);   tft.setCursor(20, 80 ,1);   tft.println("WIFI Connecting!");   delay(1000);   Connect_to_WiFi();   digitalWrite(TEST_LED, HIGH);   delay(3000);   digitalWrite(TEST_LED, LOW);   server.begin();           // Start the HTTP server   delay(2000); //******************************//   In finalul functiei setup(), se apeleaza rutina
pentru tiparirea grupului de taste si a VU-metrului cu ac.     tft.fillScreen(TFT_BLACK);     drawCustomKeypad();     analogMeter();          // Draw analogue meter     updateTime = millis();  // Next update time     digitalWrite(TEST_LED, HIGH); }     7 – In continuare se afla rutina “void loop()”
care ruleaza in bucla pentru gestionarea relatiei dintre placa ESP32, display si alte periferice.   ///****************************** LOOP
*******************************/// void loop() {   Acesta este codul care va tipari pe Display nivelul
semnalului receptionat (RSSI) in dBm. Culoarea textului se schimba odata cu pragul conventional de
nivel, in Rosu, Alb si Verde, ceea ce reprezinta: Semnal slab, Semnal bun si Semnal foarte
bun.     // Print the received signal strength:   long rssi = WiFi.RSSI();   Serial.print("RSSI:");   Serial.println(rssi);     int16_t currentRSSI = WiFi.RSSI();   if (currentRSSI != previousRSSI)   {     if (rssi >= -50)     {tft.setTextColor(TFT_GREEN);}       else     if (rssi >= -70 && rssi < -50)     {tft.setTextColor(TFT_WHITE);}       else     {tft.setTextColor(TFT_RED);}       if (rssi = 0)       {         tft.fillRect(185, 255, 40, 20, TFT_BLACK);         tft.setTextColor(TFT_RED);         tft.setCursor(198, 273);         tft.print("0");       }          tft.fillRect(185, 255, 40, 20, TFT_BLACK);     tft.setCursor(185, 273);   tft.print(WiFi.RSSI()); // Display the signal value of the
correspondent   previousRSSI = currentRSSI;   } //******************************//     Urmeaza codul necesar baleajului permanent pentru acul
indicator al Level Metrului. Intr-o aplicatie reala, acest cod trebuie adaptat nevoilor fiecaruia
dintre dumneavoastra. O aplicatie viitoare va incerca constructia unui Walkie
Talkie  cu programare si S-metru, imitand o combinatie retro intre o statii
radio Half Duplex si un telefon mobil.     if (updateTime <= millis())   {     updateTime = millis() + LOOP_PERIOD;       d += 4; if (d >= 360) d = 0;       //value[0] = map(analogRead(A0), 0, 1023, 0, 100); //
Test with value form Analogue 0       // Create a Sine wave for testing     value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);     value[1] = 50 + 50 * sin((d + 60) * 0.0174532925);     value[2] = 50 + 50 * sin((d + 120) * 0.0174532925);     value[3] = 50 + 50 * sin((d + 180) * 0.0174532925);     value[4] = 50 + 50 * sin((d + 240) * 0.0174532925);     value[5] = 50 + 50 * sin((d + 300) * 0.0174532925);       //unsigned long t = millis();     plotNeedle(value[0], 0);     //Serial.println(millis()-t); // Print time taken for
meter update   } //******************************//   Aceasta este cea mai delicata portiune a rutinei “loop”,
intrucat in interiorul ei se asigura verificarea apasatii Touch Screen-ului si
precizia coordonatelor Butoanelor desenate. Contine trimiteri doar catre rutinele de modificare a
puterii de emisie, insa folosind aceste exemple se pot atribui functii
suplimentare Butoanelor ramase libere. Folosirea driverului TFT_eSPI.h este cea mai inspirata alegere pentru controlul
Touch Screen-ului intrucat comparat cu driverul de la Adafruit, acesta are un filtru mai puternic impotriva
erorilor.   // Testing the Touch Screen   uint16_t t_x = 0, t_y = 0; // To store the touch
coordinates      // Pressed will be set true is there is a valid touch on
the screen     bool pressed = tft.getTouch(&t_x, &t_y);       // Check if any key coordinate boxes contain the touch
coordinates     for (uint8_t b = 0; b < 9; b++)     {       if (pressed && key[b].contains(t_x, t_y))     {key[b].press(true);}  // Tell the button it is pressed       else     {key[b].press(false);}  // Tell the button it is NOT
pressed     }     // Add a check to execute the appropriate functions   for (uint8_t b = 0; b < 9; b++)   {     if (key[b].justPressed())     {       if (b == 6) // RED Key       {       tft.fillRect(0, 175, 240, 35, TFT_BLACK);       tft.setTextColor(TFT_BLUE);       tft.setCursor(30, 200);       tft.print("TouchDownButton!");       TouchDownButton();       }         else if (b == 8) // NAVY Key       {       tft.fillRect(0, 175, 240, 35, TFT_BLACK);       tft.setTextColor(TFT_NAVY);       tft.setCursor(30, 200);       tft.print("TouchUpButton!");       TouchUpButton();       }   // The routine can continue with Buttons: 0, 1, 2, 4 and 7     }         else if (key[b].justReleased())       {       tft.fillRect(0, 175, 240, 35, TFT_BLACK);       tft.setTextColor(TFT_WHITE);       tft.setCursor(30, 200);       tft.print("NoTouchButton!");     }   } }   8 – Rutinele folosite sunt bine structurate,
delimitate si au urmatoarele denumiri si functii:             - void drawCustomKeypad()                         * Deseneaza toate Butoanele in
functie de coordonatele centrului butonului “stop”.                            Aceasta abordare face posibila
mutarea pe display a intregii tastaturi, modificand                                      doar
coordonatele acestuia.                                     // Keypad start position, key sizes and spacing                                     #define KEY_X
75          // Center of key W                                     #define KEY_Y
230         // Center of key Y                         * Afiseaza puterea WiFi stabilita
din tastatura sau setata pe maxim la pornire.             - void Connect_to_WiFi()                         * Repeta incercarea de conectare la
retea, in serii de cste 10 sec. pana cand este realizata.                         * Afiseaza pentru cateva secunde
IP-ul local, IP-ul routerului de retea si IP-un P2P.             - void TouchDownButton() si void TouchUpButton()                         * Asigura grafica corespunzatoare
apasarii fiecarui buton si face trimitere catre executia                              functiilor
stabilite prin program.             - void writePower()                         * Modifica Puterea WiFi pentru
fiecare apasare a butoanelor “–pwr” si “pwr+”.             - void analogMeter() si void plotNeedle(int
value, byte ms_delay)                         * Doua rutine care se ocupa cu
grafica VU-metrului, S-metrului, Level Metrului sau cum                         doriti dumneavoastra sa-l denumiti.
Rutinele sunt usor de modificat pentru a acoperi o                              varietate
mare de instrumente. Acul indicator are o miscare identica cu cea a unui                                     instrument
real. Grafica este una dintre cele mai simple si reusite de pana acum.   Obsevatii finale: Viteza de rulare a programului poate fi marita semnificativ
prin comentarea cu doua linii oblice a tuturor instructiunilor din seria “Serial.print();”,
folosite in special pentru debug. Compilarea softului se face prin activarea icoanei  al Arduino IDE. 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…”. La aparitia mesajului:       -         
Este foarte important sa se faca o calibrare corecta pentru ca suprafata
Butoanelor sa fie identificata cu precizie de Touch Screen. -         
Modificarea puterii de emisie WiFi se face prin tastarea “-pwr”
si “pwr+”. -         
In partea superioara a tastaturii este afisata starea Butoanelor intr-un
mod sugestiv si explicit. -         
Forma, culorile si schimbarile de stare sunt atribute care fac aplicatia
placuta ochiului, ceea ce vine in completarea functionalitatii acestora. Oricand cei interesati pot modifica, adapta sau dezvolta
aplicatia de fata printr-o gestionare controlata a codului prezentat.
Informatii deosebite puteti obtine si de la Inteligenta
Artificiala prin Chat GPT : https://chat.openai.com/. Pentru
cei ce vor incerca, fac precizarea ca intrebarile se vor pune punctual. Sprijinul meu poate consta in rezolvarea micilor icidente
aparute pe parcursul incercarilor dumneavoastra sau prin oferta de explicatii
suplimentare, atat cat imi permite experienta. Asistenta se poate face la tel. 0742997202
sau prin e-mail: gocomraex@gmail.com Best regards & 73! 
 Articol aparut la 15-12-2023 2324 Inapoi la inceputul articolului | |
| 
 
 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. 
  | |||||
| 
Copyright © Radioamator.ro. Toate drepturile rezervate. All rights reserved
 Articole | Concursuri | Mica Publicitate | Forum YO | Pagini YO | Call Book | Diverse | Regulamentul portalului | Contact  |