I’m using the WiFi Esp library, using a ESP8266 to give my uno wifi capability. It’s working fine for posting data to my PC, got a bit of an issue on the receive side but am working around it.
Unfortunately, when I lose WiFi connection it blocks my loop. This is problematic because I’m running relays on timers - sometimes the connection will drop while the relay is energised and it’ll stay that way until it reconnects.
Could anyone suggest where I’ve gone wrong? (apologies, theres a fair chunk of code here)
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into digital pin 2
#define ONE_WIRE_BUS 5
#include <SPI.h>
#include "WiFiEsp.h"
#include "SoftwareSerial.h"
#ifndef HAVE_HWSERIAL1
#include <PubSubClient.h>
#include "IPAddress.h"
#include "certs.h"
SoftwareSerial Serial1(4,7); // RX, TX
#endif
//setup a onewire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
//pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);
// Update these with values suitable for your hardware/network
int status = WL_IDLE_STATUS; // the Wifi radio's status
const int fanPin = 11;
WiFiEspClient WiFiclient;
PubSubClient client(WiFiclient);
const int relayPin_1 = 9; //relay output pins
const int relayPin_2 = 10;
long lastReconnectAttempt = 0;
long lastClientLoop = 0;
char pressureData[10];
char tempCStr[10];
int pressureVal;
double pressureBar;
const int pressureSensor = A0;
unsigned long previousPressureMillis = 0;
unsigned long currentMillis = 0;
unsigned long currentMillis_1 = 0;
unsigned long currentMillis_2 = 0;
unsigned long previousRelayMillis_1 = 0;
unsigned long previousRelayMillis_2 = 0;
const int pressureDataDelay = 500;
unsigned long relayInterval = 30000;
const int relayRunTime_1 = 2000;
const int relayRunTime_2 = 1000;
unsigned long tester = 7000;
unsigned long previousTempMillis = 0;
byte relayState_1 = HIGH; // for keeping track of ON/OFF
byte relayState_2 = HIGH;
int deviceCount = 0;
const long interval = 5000;
float tempC;
const char* temps[] = {"temps1", "temps2", "temps3", "temps4"};
void setup()
{
// initialize serial for debugging
Serial.begin(115200);
// initialize serial for ESP module
Serial1.begin(9600);
// initialize ESP module
WiFi.init(&Serial1);
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue
while (true);
}
// attempt to connect to WiFi network
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network
status = WiFi.begin(ssid, pass);
}
Serial.println("You're connected to the network");
pinMode(fanPin, OUTPUT);
pinMode(relayPin_1, OUTPUT); //configuring relay pins
pinMode(relayPin_2, OUTPUT);
analogWrite(fanPin, 150);
deviceCount = sensors.getDeviceCount();
sensors.begin();
client.setServer(server, 1883);
client.setCallback(callback);
client.setKeepAlive( 90 );
lastReconnectAttempt = 0;
}
void loop()
{
currentMillis = millis();
currentMillis_1 = millis();
currentMillis_2 = (currentMillis_1 + relayInterval/2 + relayRunTime_1 - relayRunTime_2);
if (!client.connected()) {
long currentMillis = millis();
if (currentMillis - lastReconnectAttempt > 5000) {
lastReconnectAttempt = currentMillis;
// Attempt to reconnect
if (reconnect()) {
lastReconnectAttempt = 0;
}
}
} else {
// Client connected
client.loop();
}
sendTempData();
sendPressureData();
updateRelayState_1();
updateRelayState_2();
switchRelays();
}
void callback(char* topic, byte *payload, unsigned int length) {
/* if (topic == "interval") {
char buffer [256];
interval = strtoul(buffer, 256, payload);
client.publish("interval", "Interval updated");
Serial.print("Current Interval Value: ");
Serial.println(interval);
} */
unsigned long intervalLong;
byte* p = (byte*)malloc(length);
// Copy the payload to the new buffer
memcpy(p,payload,length);
client.publish("outputs", p, length);
intervalLong = strtoul(p, NULL, 10);
relayInterval = intervalLong;
// Serial.print("Interval is: ");
// Serial.println(relayInterval);
// Serial.print("Tester: ");
// Serial.println(tester);
// Free the memory
free(p);
}
boolean reconnect() {
if (client.connect("arduinoClient")) {
// Once connected, publish an announcement...
client.publish("outputs","hello world");
// ... and resubscribe
client.subscribe("inputs", 1);
client.subscribe("interval", 1);
}
return client.connected();
}
double mapf(double x, double in_min, double in_max, double out_min, double out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void sendPressureData() {
pressureVal = 848; // analogRead(pressureSensor);
pressureBar = mapf(pressureVal, 175, 900, 0.0, 10.00);
dtostrf(pressureBar, 4, 2, pressureData);
if (currentMillis - previousPressureMillis >= pressureDataDelay) {
client.publish("pressureData", pressureData);
// Serial.print("Interval: ");
// Serial.println(interval);
previousPressureMillis = currentMillis;
}
}
void sendTempData() {
// send the command to get temperatur;
if (currentMillis - previousTempMillis >= interval) {
sensors.requestTemperatures();
for(int i = 0; i < 4; i++) {
tempC = sensors.getTempCByIndex(i);
dtostrf(tempC, 4, 2, tempCStr);
client.publish(temps[i], tempCStr);
}
previousTempMillis = currentMillis;
// Serial.println("");
}
}
void updateRelayState_1() {
if (relayState_1 == HIGH) {
if (currentMillis_1 - previousRelayMillis_1 >= relayInterval) {
relayState_1 = LOW;
previousRelayMillis_1 += relayInterval;
}
} else {
if (currentMillis_1 - previousRelayMillis_1 >= relayRunTime_1) {
relayState_1 = HIGH;
previousRelayMillis_1 += relayRunTime_1;
}
}
}
void updateRelayState_2() {
if(relayState_2 == HIGH) {
if(currentMillis_2 - previousRelayMillis_2 >= relayInterval) {
relayState_2 = LOW;
previousRelayMillis_2 += relayInterval;
}
} else {
if (currentMillis_2 - previousRelayMillis_2 >= relayRunTime_2) {
relayState_2 = HIGH;
previousRelayMillis_2 += relayRunTime_2;
}
}
}
void switchRelays() {
digitalWrite(relayPin_1, relayState_1);
digitalWrite(relayPin_2, relayState_2);
}