/ESP-NOW-Receiver-BME280-Chart Secret
Created
January 19, 2021 18:48
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <esp_now.h> | |
#include <WiFi.h> | |
#include "ESPAsyncWebServer.h" | |
#include <Arduino_JSON.h> | |
// Replace with your network credentials (STATION) | |
const char* ssid = "REPLACE_WITH_YOUR_SSID"; | |
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; | |
// Structure example to receive data | |
// Must match the sender structure | |
typedef struct struct_message { | |
int id; | |
float temp; | |
float hum; | |
unsigned int readingId; | |
} struct_message; | |
struct_message incomingReadings; | |
JSONVar board; | |
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.temp; | |
board["humidity"] = incomingReadings.hum; | |
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.temp); | |
Serial.printf("h value: %4.2f \n", incomingReadings.hum); | |
Serial.printf("readingID value: %d \n", incomingReadings.readingId); | |
Serial.println(); | |
} | |
const char index_html[] PROGMEM = R"rawliteral( | |
<!DOCTYPE HTML><html> | |
<head> | |
<title>ESP-NOW DASHBOARD</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<script src="https://code.highcharts.com/highcharts.js"></script> | |
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> | |
<link rel="icon" href="data:,"> | |
<style> | |
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; } | |
</style> | |
</head> | |
<body> | |
<div class="topnav"> | |
<h3>ESP-NOW DASHBOARD</h3> | |
</div> | |
<div class="content"> | |
<div class="cards"> | |
<div class="card temperature"> | |
<h4><i class="fas fa-thermometer-half"></i> BOARD #1 - TEMPERATURE</h4><p><span class="reading"><span id="t1"></span> °C</span></p><p class="packet">Reading ID: <span id="rt1"></span></p> | |
</div> | |
<div class="card humidity"> | |
<h4><i class="fas fa-tint"></i> BOARD #1 - HUMIDITY</h4><p><span class="reading"><span id="h1"></span> %</span></p><p class="packet">Reading ID: <span id="rh1"></span></p> | |
</div> | |
<div class="card temperature"> | |
<h4><i class="fas fa-thermometer-half"></i> BOARD #2 - TEMPERATURE</h4><p><span class="reading"><span id="t2"></span> °C</span></p><p class="packet">Reading ID: <span id="rt2"></span></p> | |
</div> | |
<div class="card humidity"> | |
<h4><i class="fas fa-tint"></i> BOARD #2 - HUMIDITY</h4><p><span class="reading"><span id="h2"></span> %</span></p><p class="packet">Reading ID: <span id="rh2"></span></p> | |
</div> | |
</div> | |
</div> | |
<div class="content"> | |
<div class="cards"> | |
<div class="card chart"> | |
<div id="chart-temperature"></div> | |
</div> | |
</div> | |
</div> | |
<script> | |
var chartT = new Highcharts.Chart({ | |
chart:{ renderTo : 'chart-temperature' }, | |
title: { text: 'BME280 Temperature' }, | |
series: [{ | |
showInLegend: false, | |
data: [] | |
}], | |
plotOptions: { | |
line: { animation: false, | |
dataLabels: { enabled: true } | |
}, | |
series: { color: '#059e8a' } | |
}, | |
xAxis: { type: 'datetime', | |
dateTimeLabelFormats: { second: '%H:%M:%S' } | |
}, | |
yAxis: { | |
title: { text: 'Temperature (Celsius)' } | |
//title: { text: 'Temperature (Fahrenheit)' } | |
}, | |
credits: { enabled: false } | |
}); | |
if (!!window.EventSource) { | |
var source = new EventSource('/events'); | |
source.addEventListener('open', function(e) { | |
console.log("Events Connected"); | |
}, false); | |
source.addEventListener('error', function(e) { | |
if (e.target.readyState != EventSource.OPEN) { | |
console.log("Events Disconnected"); | |
} | |
}, false); | |
source.addEventListener('message', function(e) { | |
console.log("message", e.data); | |
}, false); | |
source.addEventListener('new_readings', function(e) { | |
console.log("new_readings", e.data); | |
var obj = JSON.parse(e.data); | |
document.getElementById("t"+obj.id).innerHTML = obj.temperature.toFixed(2); | |
document.getElementById("h"+obj.id).innerHTML = obj.humidity.toFixed(2); | |
document.getElementById("rt"+obj.id).innerHTML = obj.readingId; | |
document.getElementById("rh"+obj.id).innerHTML = obj.readingId; | |
var x = (new Date()).getTime(), | |
y = Number(obj.temperature.toFixed(2)); | |
console.log(y); | |
if(chartT.series[0].data.length > 40) { | |
chartT.series[0].addPoint([x, y], true, true, true); | |
} | |
else { | |
chartT.series[0].addPoint([x, y], true, false, true); | |
} | |
}, false); | |
} | |
</script> | |
</body> | |
</html>)rawliteral"; | |
void setup() { | |
// Initialize Serial Monitor | |
Serial.begin(115200); | |
// 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(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(), 10000); | |
}); | |
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) { | |
events.send("ping",NULL,millis()); | |
lastEventTime = millis(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment