Keep monitoring even when ESP can't connect to wifi?

Hi all.

I have set up a iot server (thingsboard) in my campervan monitoring temperature and humidity. This works.
I also have a voltage monitor running, not connected to thingsboard.
If my leisure battery drops below 12v a buzzer will sound. This works too.

Now i have combined these two together and this works too. Copied the temperature and humidity code from the linke tutorial, edited that and added it to the original code so i also have voltage readings reported on my dashboard.

Here comes the part where i got stuck. If the wifi acces point goes down, the sketch stops and wont go into loop. Thus not measuring my voltage anymore and not warning me when voltage drops to low.

Can any of you point me in the right direction, where do i need to start editing the code to have it report data when online but also monitor my voltage and respond to low voltage when wifi ap is down?

Here is the code i have now. Taken from this tutorial:

And added the voltage monitor code from one of the forum members here.

/*
   temperatuur, vochtigheid en voltage wordt verstuurd naar thingsboard
   poging tot monitoren ook zonder internet verbinding
*/




#include "DHT.h"
#include <WiFiEspClient.h>
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include <PubSubClient.h>
#include "SoftwareSerial.h"

#define WIFI_AP "HUIS"
#define WIFI_PASSWORD "12345678"

#define TOKEN "TEMP_VOLT_HUM"

// DHT
#define DHTPIN 4
#define DHTTYPE DHT11

char thingsboardServer[] = "192.168.4.2";

int buzzer = 11; //BUZZER OP PIN 11

unsigned int total; // holds readings
float voltage; // converted to volt

// Initialize the Ethernet client object
WiFiEspClient espClient;

// Initialize DHT sensor.
DHT dht(DHTPIN, DHTTYPE);

PubSubClient client(espClient);

SoftwareSerial soft(2, 3); // RX, TX

int status = WL_IDLE_STATUS;
unsigned long lastSend;

void setup() {
  // initialize serial for debugging
  pinMode(11, OUTPUT);
  analogReference(INTERNAL); // use the internal ~1.1volt reference | change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(9600);
  dht.begin();
  InitWiFi();
  client.setServer( thingsboardServer, 1883 );
  lastSend = 0;
}

void loop() {
  status = WiFi.status();
  if ( status != WL_CONNECTED) {
    while ( status != WL_CONNECTED) {
      Serial.print("Attempting to connect to WPA SSID: ");
      Serial.println(WIFI_AP);
      // Connect to WPA/WPA2 network
      status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
      delay(500);
    }
    Serial.println("Connected to AP");


  }

  if ( !client.connected() ) {
    reconnect();

  }



  if ( millis() - lastSend > 3000 ) { // Update and send only after 1 seconds
    getAndSendTemperatureAndHumidityData();
    getAndSendVoltageData();
    lastSend = millis();
  }

  client.loop();
}

void getAndSendTemperatureAndHumidityData()
{
  Serial.println("Collecting temperature data.");

  // Reading temperature or humidity takes about 250 milliseconds!
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");

  String temperature = String(t);
  String humidity = String(h);

  // Just debug messages
  Serial.print( "Sending temperature and humidity : [" );
  Serial.print( temperature ); Serial.print( "," );
  Serial.print( humidity );
  Serial.print( "]   -> " );


  // Prepare a JSON payload string
  String payload = "{";
  payload += "\"temperature\":"; payload += temperature; payload += ",";
  payload += "\"humidity\":"; payload += humidity;
  payload += "}";

  // Send payload
  char attributes[100];
  payload.toCharArray( attributes, 100 );
  client.publish( "v1/devices/me/telemetry", attributes );
  Serial.println( attributes );
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////                              DOOR MIJ TOEGEVOEGD                                        ///////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void getAndSendVoltageData()
{
  total = 0; // reset
  analogRead(A0); // one unused reading to clear any ghost charge
  for (int x = 0; x < 64; x++) { // 64 analogue readings for averaging
    total = total + analogRead(A0); // add each value
  }
  voltage = total * 0.0002505; // convert readings to volt | ---calibrate by changing the last three digits---

  //Serial.print("The battery is ");
  Serial.println(voltage, 2); // change to (voltage, 3) for three decimal places
  //Serial.println(" volt");
  if (voltage <= 12  )
  {
    digitalWrite (buzzer, HIGH);
    Serial.println("BEEP");
  }

  else
  {
    digitalWrite (buzzer, LOW);
    Serial.println("NO BEEP");
  }

  delay(200); // readout delay

  // Prepare a JSON payload string
  String payload = "{";

  payload += "\"voltage\":"; payload += voltage;
  payload += "}";

  // Send payload
  char attributes[100];
  payload.toCharArray( attributes, 100 );
  client.publish( "v1/devices/me/telemetry", attributes );
  Serial.println( attributes );

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void InitWiFi()
{
  // initialize serial for ESP module
  soft.begin(9600);
  // initialize ESP module
  WiFi.init(&soft);
  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  Serial.println("Connecting to AP ...");
  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(WIFI_AP);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
    delay(500);
  }
  Serial.println("Connected to AP");
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Connecting to ThingsBoard node ...");
    // Attempt to connect (clientId, username, password)
    if ( client.connect("Arduino Uno Device", TOKEN, NULL) ) {
      Serial.println( "[DONE]" );
    } else {
      Serial.print( "[FAILED] [ rc = " );
      Serial.print( client.state() );
      Serial.println( " : retrying in 5 seconds]" );
      // Wait 5 seconds before retrying
      delay( 5000 );
    }
  }
}

Without seeing what's being output to Serial when your WiFi cuts out, my guess is:

Your problem is in InitWiFi() getting stuck in one of your while loops. Considering you sort of want those checks to happen this way, you don't want to get rid of the idea of them altogether.

I would try moving those checks to loop() as an if statement and use millis() to get the connection when you're ready to use it instead of using while() you'd be using if() but then coming back to it infinitely as long as your sketch is running.

Guess it is time to advance from "copy pasting editing" and start to really look into the millis().....

I have tried to postpone that for as long as possible for some reason. Scared of the dark i geus, and "coding" (copy paste edit in my case) has never been my favourite part.

Might be back in a couple of days with adjustments to the code above :wink: