/*
Rui Santos
Complete project details at ESP32: ESP-NOW and Wi-Fi Web Server Dashboard (Arduino) | Random Nerd Tutorials
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <esp_now.h>
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include <Arduino_JSON.h>
#include <HTTPClient.h>
#include <SPI.h>
#include "MCUFRIEND_kbv.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#define ESP32_PARALLEL
#define ILI9486_DRIVER
String temperature;
String humidity;
#define Board ID 1
#define Board ID 2
#define Board ID 3
#define Board ID 4
#define Board ID 5
// Replace with your network credentials (STATION)
const char* ssid = "vivo 1919";
const char* password = "12345678";
//ACCESS POINT credentials
const char* ssidAP = "ESP_E63B4D";
const char* passwordAP = "";
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
int id;
float temperature;
float humidity;
unsigned int readingId;
} struct_message;
struct_message incomingReadings;
struct_message incomingReadings1;
struct_message incomingReadings3;
#define TFT_CD D15
#define TFT_RTS D32
#define TFTWIDTH 480
#define TFTHIGHT 320
#define TFT_BLACK 0x0000 /* 0, 0, 0 /
#define TFT_NAVY 0x000F / 0, 0, 128 /
#define TFT_DARKGREEN 0x03E0 / 0, 128, 0 /
#define TFT_DARKCYAN 0x03EF / 0, 128, 128 /
#define TFT_MAROON 0x7800 / 128, 0, 0 /
#define TFT_PURPLE 0x780F / 128, 0, 128 /
#define TFT_OLIVE 0x7BE0 / 128, 128, 0 /
#define TFT_LIGHTGREY 0xD69A / 211, 211, 211 /
#define TFT_DARKGREY 0x7BEF / 128, 128, 128 /
#define TFT_BLUE 0x001F / 0, 0, 255 /
#define TFT_GREEN 0x07E0 / 0, 255, 0 /
#define TFT_CYAN 0x07FF / 0, 255, 255 /
#define TFT_RED 0xF800 / 255, 0, 0 /
#define TFT_MAGENTA 0xF81F / 255, 0, 255 /
#define TFT_YELLOW 0xFFE0 / 255, 255, 0 /
#define TFT_WHITE 0xFFFF / 255, 255, 255 /
#define TFT_ORANGE 0xFDA0 / 255, 180, 0 /
#define TFT_GREENYELLOW 0xB7E0 / 180, 255, 0 /
#define TFT_PINK 0xFE19 / 255, 192, 203 / //Lighter pink, was 0xFC9F
#define TFT_BROWN 0x9A60 / 150, 75, 0 /
#define TFT_GOLD 0xFEA0 / 255, 215, 0 /
#define TFT_SILVER 0xC618 / 192, 192, 192 /
#define TFT_SKYBLUE 0x867D / 135, 206, 235 /
#define TFT_VIOLET 0x915C / 180, 46, 226 */
JSONVar board;
JSONVar board2;
JSONVar board3;
unsigned long previousMillis = 0;
const long interval = 5000;
AsyncWebServer server(80);
AsyncEventSource events("/events");
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
// Copies the sender mac address to a string
char macStr[18];
Serial.print("Packet received from: ");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(macStr);
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
board["id"] = incomingReadings.id;
board["temperature"] = incomingReadings.temperature;
board["humidity"] = incomingReadings.humidity;
board["readingId"] = String(incomingReadings.readingId);
String jsonString = JSON.stringify(board);
events.send(jsonString.c_str(), "new_readings", millis());
Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len);
Serial.printf("t value: %4.2f \n", incomingReadings.temperature);
Serial.printf("h value: %4.2f \n", incomingReadings.humidity);
Serial.printf("readingID value: %d \n", incomingReadings.readingId);
Serial.println();
}
void OnDataRecv1(const uint8_t *mac_addr1, const uint8_t *incomingData1, int len1) {
// Copies the sender mac address to a string
char macStr1[18];
Serial.print("Packet received from: ");
snprintf(macStr1, sizeof(macStr1), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr1[0], mac_addr1[1], mac_addr1[2], mac_addr1[3], mac_addr1[4], mac_addr1[5]);
Serial.println(macStr1);
memcpy(&incomingReadings1, incomingData1, sizeof(incomingReadings1));
board2["id"] = incomingReadings1.id;
board2["temperature"] = incomingReadings1.temperature;
board2["humidity"] = incomingReadings1.humidity;
board2["readingId"] = String(incomingReadings1.readingId);
String jsonString1 = JSON.stringify(board2);
events.send(jsonString1.c_str(), "new_readings", millis());
Serial.printf("Board ID %u: %u bytes\n", incomingReadings1.id, len1);
Serial.printf("t value: %4.2f \n", incomingReadings1.temperature);
Serial.printf("h value: %4.2f \n", incomingReadings1.humidity);
Serial.printf("readingID value: %d \n", incomingReadings1.readingId);
Serial.println();
}
void OnDataRecv3(const uint8_t *mac_addr3, const uint8_t *incomingData3, int len3) {
// Copies the sender mac address to a string
char macStr3[18];
Serial.print("Packet received from: ");
snprintf(macStr3, sizeof(macStr3), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr3[0], mac_addr3[1], mac_addr3[2], mac_addr3[3], mac_addr3[4], mac_addr3[5]);
Serial.println(macStr3);
memcpy(&incomingReadings3, incomingData3, sizeof(incomingReadings3));
board3["id"] = incomingReadings1.id;
board3["temperature"] = incomingReadings1.temperature;
board3["humidity"] = incomingReadings1.humidity;
board3["readingId"] = String(incomingReadings1.readingId);
String jsonString3 = JSON.stringify(board3);
events.send(jsonString3.c_str(), "new_readings", millis());
Serial.printf("Board ID %u: %u bytes\n", incomingReadings3.id, len3);
Serial.printf("t value: %4.2f \n", incomingReadings3.temperature);
Serial.printf("h value: %4.2f \n", incomingReadings3.humidity);
Serial.printf("readingID value: %d \n", incomingReadings3.readingId);
Serial.println();
}
const char index_html[] PROGMEM = R"rawliteral(
ESP-NOW DASHBOARD html {font-family: Arial; display: inline-block; text-align: center;} p { font-size: 1.2rem;} body { margin: 0;} .topnav { overflow: hidden; background-color: #2f4468; color: white; font-size: 1.7rem; } .content { padding: 20px; } .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); } .cards { max-width: 700px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); } .reading { font-size: 2.8rem; } .packet { color: #bebebe; } .card.temperature { color: #fd7e14; } .card.humidity { color: #1b78e2; }ESP-NOW DASHBOARD
LECP #1 - TEMPERATURE
°C
Reading ID:
LECP #1 - HUMIDITY
%
Reading ID:
LECP #2 - TEMPERATURE
°C
Reading ID:
LECP #2 - HUMIDITY
%
Reading ID:
LECP #3 - TEMPERATURE
°C
Reading ID:
LECP #3 - HUMIDITY
%
Reading ID:
LECP #4 - TEMPERATURE
°C
Reading ID:
LECP #4 - HUMIDITY
%
Reading ID:
LECP #5 - TEMPERATURE
°C
Reading ID:
LECP #5 - HUMIDITY
%
Reading ID:
void setup() {
// Initialize Serial Monitor
tft.begin(0x9486);
Serial.begin(115200);
tft.setRotation(2);
tft.fillScreen(ILI9486_BLACK); // Black Background
tft.fillRect(0,0,40,480,TFT_CYAN); // Upper GREEN Rectange
tft.setRotation(1);
tft.fillRect(0,40,160,140,TFT_MAGENTA); // Upper GREEN Rectange
tft.fillRect(160,40,160,140,TFT_MAGENTA); // Lower RED Rectange
tft.fillRect(320,40,160,140,TFT_MAGENTA); // Upper BLUE Rectange
tft.drawRect(0,40,160,140,TFT_YELLOW); // White borders to the rectangles
tft.drawRect(160,40,160,140,TFT_YELLOW); // White borders to the rectangles
tft.drawRect(320,40,160,140,TFT_YELLOW); // White borders to the rectangles
tft.fillRect(0,180,160,140,TFT_MAGENTA); // Upper GREEN Rectange
tft.fillRect(160,180,160,140,TFT_MAGENTA); // Lower RED Rectange
tft.fillRect(320,180,160,140,TFT_MAGENTA); // Upper BLUE Rectange
tft.drawRect(0,180,160,140,TFT_YELLOW); // White borders to the rectangles
tft.drawRect(160,180,160,140,TFT_YELLOW); // White borders to the rectangles
tft.drawRect(320,180,160,140,TFT_YELLOW);
// Set the device as a Station and Soft Access Point simultaneously
WiFi.mode(WIFI_AP_STA);
// Set device as a Wi-Fi Station
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.print("Wi-Fi Channel: ");
Serial.println(WiFi.channel());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(OnDataRecv1);
esp_now_register_recv_cb(OnDataRecv3);
esp_now_register_recv_cb(OnDataRecv);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 0);
});
server.addHandler(&events);
server.begin();
}
void loop() {
static unsigned long lastEventTime = millis();
static const unsigned long EVENT_INTERVAL_MS = 5000;
if ((millis() - lastEventTime) > EVENT_INTERVAL_MS) {
if(WiFi.status()== WL_CONNECTED ){
events.send("ping",NULL,millis());
lastEventTime = millis();
}
tft.setTextColor(TFT_BLACK); // Set Text Proporties
tft.setTextSize(2);
tft.setCursor(30,10);
tft.println("LOCAL ENGINE CONTROL PANEL (LECP)"); // Write Text on LCD
tft.setTextColor(TFT_BLACK);
tft.setCursor(40,45);
tft.println("LECP 1"); // Write Text on LCD
board["id"] = incomingReadings.id;
board2["id"] = incomingReadings1.id;
board3["id"] = incomingReadings3.id;
Serial.println("Temperature: " + temperature + " *C - Humidity: " + humidity );
tft.setTextSize(2);
tft.setTextColor(TFT_MAGENTA);
tft.setTextColor(TFT_BLACK,TFT_MAGENTA);
tft.setCursor(20,70);
tft.print("T: ");
tft.setTextPadding(120);
tft.print(incomingReadings.temperature);
tft.print(" ");
tft.setTextSize(1);
tft.write(248);
tft.setTextSize(2);
tft.print("C");
// display humidity
tft.setTextSize(2);
tft.setCursor(20,90);
tft.print("H: ");
tft.print(incomingReadings.humidity);
tft.print(" %");
Serial.println("Temperature: " + temperature + " *C - Humidity: " + humidity );
tft.setCursor(200, 45);
tft.println("LECP 2"); // Write Text on LCD
// display temperature
tft.setTextSize(2);
tft.setTextColor(TFT_BLACK,TFT_MAGENTA);
tft.setCursor(190,70);
tft.print("T: ");
tft.setTextPadding(120);
tft.print(incomingReadings1.temperature);
tft.print(" ");
tft.setTextSize(1);
tft.write(248);
tft.setTextSize(2);
tft.print("C");
// display humidity
tft.setTextSize(2);
tft.setCursor(190, 90);
tft.print("H: ");
tft.print(incomingReadings1.humidity);
tft.print(" %");
Serial.println("Temperature: " + temperature + " *C - Humidity: " + humidity );
tft.setCursor(360,45);
tft.println("LECP 3"); // Write Text on LCD
// display temperature
tft.setTextSize(2);
tft.setTextColor(TFT_BLACK,TFT_MAGENTA);
tft.setCursor(350,70);
tft.print("T: ");
tft.setTextPadding(120);
tft.print(incomingReadings3.temperature);
tft.print(" ");
tft.setTextSize(1);
tft.write(248);
tft.setTextSize(2);
tft.print("C");
// display humidity
tft.setTextSize(2);
tft.setCursor(350, 90);
tft.print("H: ");
tft.print(incomingReadings3.humidity);
tft.print(" %");
Serial.println("Temperature: " + temperature + " *C - Humidity: " + humidity );
tft.setCursor(40,185);
tft.println("LECP 4"); // Write Text on LCD
// display temperature
tft.setTextSize(2);
tft.setTextColor(TFT_BLACK,TFT_MAGENTA);
tft.setCursor(30,215);
tft.print("T: ");
tft.setTextPadding(120);
tft.print(incomingReadings.temperature);
tft.print(" ");
tft.setTextSize(1);
// tft._cp437(true);
tft.write(248);
tft.setTextSize(2);
tft.print("C");
// display humidity
tft.setTextSize(2);
tft.setCursor(30, 235);
tft.print("H: ");
tft.print(incomingReadings.humidity);
tft.print(" %");
Serial.println("Temperature: " + temperature + " *C - Humidity: " + humidity );
tft.setCursor(200,185);
tft.println("LECP 5"); // Write Text on LCD
// display temperature
tft.setTextSize(2);
tft.setTextColor(TFT_BLACK,TFT_MAGENTA);
tft.setCursor(190,215);
tft.print("T: ");
tft.setTextPadding(120);
tft.print(incomingReadings.temperature);
tft.print(" ");
tft.setTextSize(1);
// tft._cp437(true);
tft.write(248);
tft.setTextSize(2);
tft.print("C");
// display humidity
tft.setTextSize(2);
tft.setCursor(190, 235);
tft.print("H: ");
tft.print(incomingReadings.humidity);
tft.print(" %");
delay(5000);
// Write Text on LCD
// display temperature
// save the last HTTP GET Request
//previousMillis = currentMillis;
// else {
// Serial.println("WiFi Disconnected");
}
}
/*
String httpGETRequest(const char* serverName)
{
WiFiClient client;
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "--";
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
return payload;
}*/