I've got an ESP32-POE running a web server as well as publishing MQTT to a broker.
I want to publish MQTT every 60s but sticking that delay into void loop(void){} means server.handleClient(); is also beholden to the same delay.
The web server is just displaying sensor data, so a 1 minute update time isn't a dealbreaker but it's a bit annoying that sometimes my browser times out.
How can I decouple these delays? I've had all sorts of issues trying to use ESPAsyncWebServer, supposedly because there are compatibility issues between AsyncWebServer and both ETH.h and ESP32 Arduino core 3.x. I've also seen millis() recommended instead of delay() in some places.
char title[] = "<location> sensor";
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <DHT.h>
#include "AsyncUDP.h"
#include <PubSubClient.h>
// ETH.h precursors
#ifndef ETH_PHY_TYPE
#define ETH_PHY_TYPE ETH_PHY_LAN8720 // Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_PHY_ADDR 0 // I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_PHY_MDC 23 // Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_PHY_MDIO 18 // Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_PHY_POWER -1
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN // Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#endif
#include <ETH.h>
static bool eth_connected = false;
//Set up DHT11
DHT dht(4, DHT11);
//Start Webserver
WebServer server(80);
//HTML
void handleRoot() {
char msg[1500];
snprintf(msg, 1500,
"<html>\
<head>\
<meta http-equiv='refresh' content='60'/>\
<meta name='viewport' content='width=device-width, initial-scale=1'>\
</head>\
<body>\
<h3> %s </h3>\
<p>\
<span>Temperature</span>\
<span>%.2f</span>\
<sup>°C</sup>\
</p>\
<p>\
<span>Humidity</span>\
<span>%.2f</span>\
<sup>%</sup>\
</p>\
<p>\
<span>Dew Point</span>\
<span>%.2f</span>\
<sup>°C</sup>\
</p>\
</body>\
</html>",
title, readDHTTemperature(), readDHTHumidity(), readDewPoint()
);
server.send(200, "text/html", msg);
}
// Set up ethernet event handler (optional)
void onEvent(arduino_event_id_t event) {
switch (event) {
case ARDUINO_EVENT_ETH_START:
// Serial.println("ETH Started");
// The hostname must be set after the interface is started, but needs
// to be set before DHCP, so set it from the event handler thread.
ETH.setHostname("esp32-ethernet");
break;
case ARDUINO_EVENT_ETH_CONNECTED: Serial.println("ETH Connected"); break;
case ARDUINO_EVENT_ETH_GOT_IP:
// Serial.println("ETH Got IP");
// Serial.println(ETH);
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
// Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
// Serial.println("ETH Disconnected");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_STOP:
// Serial.println("ETH Stopped");
eth_connected = false;
break;
default: break;
}
}
// MQTT info
const char *mqtt_broker = "broker.emqx.io";
char topic_temp[64];
char topic_hum[64];
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
WiFiClient ethClient;
PubSubClient client(ethClient);
void setup() {
//initialise DHT sensor
dht.begin();
// Serial.begin(115200); //Initialise serial for debugging
//Initialise Ethernet
Network.onEvent(onEvent);
ETH.begin();
// //Initialise WiFi for debugging
// const char *ssid = "";
// const char *password = "";
// WiFi.mode(WIFI_STA);
// WiFi.begin(ssid, password);
//Create MQTT topic strings
String MacAsString = ETH.macAddress();
MacAsString.replace(":", ""); //remove colons from default output
snprintf(topic_temp, sizeof(topic_temp), "sensor/%s/1/temperature", MacAsString.c_str());
snprintf(topic_hum, sizeof(topic_hum), "sensor/%s/1/humidity", MacAsString.c_str());
//Initialise web server
server.on("/", handleRoot);
server.begin();
//Connect to the MQTT broker
client.setServer(mqtt_broker, mqtt_port);
reconnectMQTT();
}
char tpayload[10]; //define buffers for client.publish
char hpayload[10];
void loop(void){
//Handle HTTP requests
server.handleClient();
//publish
dtostrf(readDHTTemperature(), 6, 2, tpayload); //convert function outputs to string for client.publish
dtostrf(readDHTHumidity(), 6, 2, hpayload);
client.publish(topic_temp, tpayload);
client.publish(topic_hum, hpayload);
delay(60000);
}
void reconnectMQTT() {
while (!client.connected()) {
// Serial.print("Connecting to MQTT...");
if (client.connect("ESP32_ETH_Client")) {
//Serial.println("connected");
} else {
//Serial.print("failed, rc=");
//Serial.print(client.state());
//Serial.println(" trying again in 2 seconds");
delay(2000);
}
}
}