0

my device stops working when disconnected from Internet
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

my device stops working when disconnected from Internet

by pilobond on Sun Feb 03, 2019 8:19 pm

Hi,
Perhaps this is a simple problem but I tried to search Internet and this forum and couldn't find an answer.

I built a simple thermostat and it's controlled from Adafruit IO. It's working really well. The only problem is that, I noticed one time, the Internet router was turned off somehow (lost power) and the furnace was on all night. I am guessing that the router went off while the furnace was turned on, then the device (NodeMCU) was just looking for the connection and not doing anything else.

I am assuming that in the following code, the flow hangs at io.run(); and stops going anywhere until a connection is established again?

void loop(void){
io.run();
...
}

My questions are:
- Is my assumption correct? (that the code hung at io.run()?)
- If so, is there a way for the code to continue, while waiting for reconnect?
- Does the board usually reconnect when Internet comes back?

pilobond
 
Posts: 4
Joined: Wed Jan 09, 2019 11:03 pm

Re: my device stops working when disconnected from Internet

by franklin97355 on Sun Feb 03, 2019 8:31 pm

What else is your code doing? Could you post your code so we can see if that is the cause?

franklin97355
 
Posts: 19939
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: my device stops working when disconnected from Internet

by pilobond on Sun Feb 03, 2019 8:58 pm

Code: Select all | TOGGLE FULL SIZE
#include "config.h"

#include "DHT.h"

#define DHTPIN 16     // what digital pin the DHT22 is conected to
#define DHTTYPE DHT11   // there are multiple kinds of DHT sensors

DHT dht(DHTPIN, DHTTYPE);

int tempCum=0;  // cumulative temperature readings over multiple readings
int humCum=0;  // cumulative humidity readings over multiple readings
float tempAvg;
float humAvg;
int heatOnTemp=11;
int coolOnTemp=35;
//int forceFanValue=0;
int heatOnValue=0;
int coolOnValue=0;

// wire status
bool W1=false;
bool W2=false;
bool Y=false;
bool G=false;

// actual wire (relay) control pin on NODEMCU
const int W1_pin = D5;
const int W2_pin = D6;
const int Y_pin = D7;
const int G_pin = D8;

// Buttons pins on NODEMCU
const int B1_pin = D3;
const int B2_pin = D4;

const int delayTime = 2000; // dealy value for the main loop in ms
const int updateInterval = 14000; // feed update interval in ms (also determines how often average temperature/humidity is calculated)
const int stage2TrigTempDiff = 2; // difference in current and target temperature that will trigger stage 2 heating

int timeCounter = updateInterval; // setting time counter at updateInterval would allow immediate update on starting
int additionCounter = 1; // counts how many times temp/hum values are read so we can devide by it to obtain average

// set up the feeds
AdafruitIO_Feed *tempFeed = io.feed("temperature");
AdafruitIO_Feed *humFeed = io.feed("humidity");
AdafruitIO_Feed *heatOnTemperatureFeed = io.feed("heat-on-temperature");
AdafruitIO_Feed *coolOnTemperatureFeed = io.feed("cool-on-temperature");
AdafruitIO_Feed *forceFanFeed = io.feed("force-fan");
AdafruitIO_Feed *heatOnFeed = io.feed("heat-on");
AdafruitIO_Feed *coolOnFeed = io.feed("cool-on");

#include <LiquidCrystal_I2C.h>

// Construct an LCD object and pass it the
// I2C address, width (in characters) and
// height (in characters). Depending on the
// Actual device, the IC2 address may change.
//LiquidCrystal_I2C lcd(0x3F, 16, 2);  // for 1602
LiquidCrystal_I2C lcd(0x27, 20, 4);  // for 2004


void setup(void){
  Serial.begin(115200);         // Start the Serial communication to send messages to the computer
 
  // wait for serial monitor to open
  while(! Serial);
  Serial.println('\n');

  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  //initialize LCD
  lcd.begin(16,2);
  lcd.init();
  lcd.backlight(); // Turn on the backlight.
  lcd.setCursor(0, 0);     
  lcd.print("Connecting... ");

  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());

  // set up feed handlers
  heatOnTemperatureFeed->onMessage(handleHOT);
  coolOnTemperatureFeed->onMessage(handleCOT);
  forceFanFeed->onMessage(handleFF);

  // read last values for target temperatures
  heatOnTemperatureFeed->get();
  coolOnTemperatureFeed->get();
  forceFanFeed->get();

  // set relay pins as output:
  pinMode(W1_pin, OUTPUT);
  digitalWrite(W1_pin, LOW);
  pinMode(W2_pin, OUTPUT);
  digitalWrite(W2_pin, LOW);
  pinMode(Y_pin, OUTPUT);
  digitalWrite(Y_pin, LOW);
  pinMode(G_pin, OUTPUT);
  digitalWrite(G_pin, LOW);

  // set button pins
  pinMode(B1_pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(B1_pin), handleB1, FALLING);
  pinMode(B2_pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(B2_pin), handleB2, FALLING);

  lcd.clear();
}

void loop(void){
   // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  io.run();

  tempCum = tempCum + dht.readTemperature();
  humCum = humCum + dht.readHumidity();

  if ( timeCounter >= updateInterval ){ // if it has been time to update temp/humidity
   
    if ( (tempCum / additionCounter)  < 45 )  // avoid spuriously high numbers
      tempAvg= tempCum / additionCounter; // get average temperature     
    if ( (humCum / additionCounter) < 100)  // avoid spuriously high numbers
      humAvg = humCum / additionCounter;  // get average humidity

    // determine if heating should be on
    // value of 0-1 considered off; 2-3 considered on. this is so that it takes mutliple measurements difference triggers actual turning on of the furnace
    if ( tempAvg < heatOnTemp ) { // if actual temperature is less than the target temperature
      if ( heatOnValue < 3 ) { // increment up to 3
        heatOnValue++;
      }
    }
    else { // if actual temperature is same or higher than the target temperature
      if ( heatOnValue > 0 ) { // decrement down to 0
        heatOnValue--;
      }
    }

    // determine if cooling should be on
    if ( tempAvg > coolOnTemp ) {
      if ( coolOnValue < 3 ) {
        coolOnValue++;
      }
    }
    else {
      if ( coolOnValue > 0){
        coolOnValue--;
      }
    }

    // report numbers to the feeds (to Adafruit IO)
    tempFeed->save(tempAvg);
    humFeed->save( round(humAvg) );
    heatOnFeed->save(heatOnValue); 
    coolOnFeed->save(coolOnValue);

    // set heating wires
    if ( heatOnValue >= 2 ){
      if ( tempAvg <= (heatOnTemp - stage2TrigTempDiff) ) {
        W1 = true;
        W2 = true;
        digitalWrite(W1_pin, HIGH);
        digitalWrite(W2_pin, HIGH);
      } else {
        W1 = true;
        W2 = false;
        digitalWrite(W2_pin, LOW);
        digitalWrite(W1_pin, HIGH);
      }
    } else {
      W1 = false;
      W2 = false;
      digitalWrite(W1_pin, LOW);
      digitalWrite(W2_pin, LOW);
    }

    // set cooling wires
    if ( coolOnValue >= 2 ){
      Y = true;
      G = true;
      digitalWrite(Y_pin, HIGH);   
      digitalWrite(G_pin, HIGH);     
    }
    else {
      Y = false;
      G = false;
      digitalWrite(Y_pin, LOW);
      digitalWrite(G_pin, LOW);   
    }

    // reset values
    timeCounter = 0;
    additionCounter = 1;
    tempCum = 0;
    humCum = 0;

     
    // clear LCD for a short period to indicate updating with new values
    lcd.clear();
    delay(250);

    // show last average temperature on LCD
    lcd.setCursor(0, 0);     
    lcd.print("Temperature = ");
    lcd.print( tempAvg, 1 ); //print average temperature to 1 decimal place
    lcd.print("C");

    // show last average humidity on LCD
    lcd.setCursor(0, 1);     
    lcd.print("Humidity = ");
    lcd.print( humAvg, 0 ); // print average humidity to 0 decimal place
    lcd.print("%");

/*  // for debugging
    Serial.print("temp =");
    Serial.println(temp);
    Serial.print("hum =");
    Serial.println(hum);
    Serial.print("heatOnTemp =");
    Serial.println(heatOnTemp);
    Serial.print("heatOnValue =");
    Serial.println(heatOnValue);
    Serial.print("coolOnTemp =");
    Serial.println(coolOnTemp);
    Serial.print("coolOnValue =");
    Serial.println(coolOnValue);
    Serial.print("forceFanValue =");
    Serial.println(forceFanValue);
    Serial.println("");
    */
   
  }
  else { // if it hasn't been enought time to udpate temp/humidity, increment the counters
    timeCounter = timeCounter + delayTime;
    additionCounter++;
  }

  /*
  if ( digitalRead(B1_pin) == LOW){ // if Button 1 is pressed, lower the target temp
      heatOnTemp--;
      heatOnTemperatureFeed->save(heatOnTemp);
  }
 
  if ( digitalRead(B2_pin) == LOW){ // if Button 2 is pressed, increase the target temp
      heatOnTemp++;
      heatOnTemperatureFeed->save(heatOnTemp);

      if ( heatOnTemp >= coolOnTemp ) { // if heating target is higher than cooling target, bring cooling target above the new heating target
          coolOnTemp = heatOnTemp + 2;
         coolOnTemperatureFeed->save(coolOnTemp);
      }
  }
  */

  // display current status on LCD
  lcd.setCursor(0, 2);     
  lcd.print("Heat:");
  if ( W1 || W2 ){ // if heat on, blink
    lcd.print("   ");
    delay(500);
    lcd.setCursor(5, 2);
  }

  lcd.print(heatOnTemp);
  lcd.print("C");


  lcd.setCursor(10, 2);     
  lcd.print("Cool:");
  if ( Y ){ // if cool on, blink
    lcd.print("   ");
    delay(500);
    lcd.setCursor(15, 2);
  }
  lcd.print(coolOnTemp);
  lcd.print("C");
 

  delay(delayTime);
}


// handle heat on temperature change
void handleHOT(AdafruitIO_Data *data) {
  // convert the data to integer
  heatOnTemp = data->toInt();

  if ( heatOnTemp >= coolOnTemp ) { // if heating target is higher than cooling target, bring cooling target above the new heating target
    coolOnTemp = heatOnTemp + 2;
    coolOnTemperatureFeed->save(coolOnTemp);
  }
}

// handle cool on temperature change
void handleCOT(AdafruitIO_Data *data) {
  // convert the data to integer
  coolOnTemp = data->toInt();

  if ( heatOnTemp >= coolOnTemp ) { // if cooling target is lower than the heating target, bring heating target lower than the new cooling target
    heatOnTemp = coolOnTemp - 2;
    heatOnTemperatureFeed->save(heatOnTemp);
  }
}

// handle force fan input
void handleFF(AdafruitIO_Data *data) {
  if(data->toString() == "ON"){
    //forceFanValue = 1;
    G = true;
    digitalWrite(G_pin, HIGH);   
  }
  else {
    //forceFanValue = 0;
    G = false;
    digitalWrite(G_pin, LOW);
  }
}


void handleB1() {
  heatOnTemp--;
  heatOnTemperatureFeed->save(heatOnTemp);
}

void handleB2() {
heatOnTemp++;
    heatOnTemperatureFeed->save(heatOnTemp);

    if ( heatOnTemp >= coolOnTemp ) { // if heating target is higher than cooling target, bring cooling target above the new heating target
        coolOnTemp = heatOnTemp + 2;
       coolOnTemperatureFeed->save(coolOnTemp);
    }
}
Last edited by franklin97355 on Sun Feb 03, 2019 9:39 pm, edited 1 time in total.
Reason: Please use code tags when posting code or logs to the forums. It preserves formatting and makes it easier for everyone to read the code. Click the code button above the reply box and past your code between the tags created.

pilobond
 
Posts: 4
Joined: Wed Jan 09, 2019 11:03 pm

Re: my device stops working when disconnected from Internet

by franklin97355 on Sun Feb 03, 2019 9:37 pm

This would hold up your code:
Code: Select all | TOGGLE FULL SIZE
// wait for a connection
while(io.status() < AIO_CONNECTED) {
Serial.print(".");
delay(500);
}

franklin97355
 
Posts: 19939
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: my device stops working when disconnected from Internet

by pilobond on Sun Feb 03, 2019 9:55 pm

I am talking about once the program is running (connected to Internet) and doing the loop(void) and then Internet goes down.
I doubt the codes in setup(void) would cause hang up once it has started running properly.

I actually made a simple test. I made a sketch that makes the device connect and then just increment a number every 500ms.

#include "config.h"

AdafruitIO_Feed *tempFeed = io.feed("temperature_IOtest");

int temp=0;

void setup(void){
Serial.begin(115200); // Start the Serial communication to send messages to the computer
delay(10);
Serial.println('\n');

io.connect();

Serial.println("Connecting ...");

// wait for a connection
while(io.status() < AIO_CONNECTED) {
Serial.print(".");
delay(500);
}

}

void loop(void){
Serial.print(temp);
Serial.println(" before io.run");
io.run();
Serial.print(temp);
Serial.println(" after io.run");

temp++;
delay(500);
}

Then I disrupt the Internet. It does seem to confirm my suspicion that it's at io.run() that hangs up the program.
Here is the output of the serial monitor.

Connecting ...
20:49:04.288 -> ....0 before io.run
0 after io.run
1 before io.run
1 after io.run
2 before io.run
2 after io.run
3 before io.run
3 after io.run
4 before io.run
4 after io.run
5 before io.run
5 after io.run
6 before io.run
6 after io.run
7 before io.run
7 after io.run
8 before io.run
8 after io.run
9 before io.run
9 after io.run
10 before io.run
10 after io.run
11 before io.run
11 after io.run
12 before io.run
12 after io.run
13 before io.run
13 after io.run
14 before io.run

20:49:18.797 -> Soft WDT reset
20:49:18.797 ->
20:49:18.797 -> ctx: cont
20:49:18.797 -> sp: 3ffffca0 end: 3fffffd0 offset: 01b0
20:49:18.797 ->
20:49:18.797 -> >>>stack>>>
20:49:18.797 -> 3ffffe50: 40104ab2 00391b90 40205d30 00002710
20:49:18.797 -> 3ffffe60: 3ffef470 00000b42 00000b42 4010020c
20:49:18.797 -> 3ffffe70: fffffffc 00000000 3fff5394 401006dc
20:49:18.797 -> 3ffffe80: 000022b3 40215794 000000a0 402157a8
20:49:18.797 -> 3ffffe90: 00000094 00000040 3fff0536 4020e7de
20:49:18.834 -> 3ffffea0: 3ffef470 0000021b 0000021b 4010020c
20:49:18.834 -> 3ffffeb0: fffffffc 3fff04ec 3fff0a5c 401006dc
20:49:18.834 -> 3ffffec0: 000022b3 00000000 00000030 40205c64
20:49:18.834 -> 3ffffed0: 000022b3 3fff04ec 3fff0a5c 40204433
20:49:18.834 -> 3ffffee0: 3fff5394 3fff04ec 3fff0a5c 40204552
20:49:18.834 -> 3ffffef0: 61ee0534 3fff0514 3fff0538 3ffef3f8
20:49:18.871 -> 3fffff00: 000022b3 3fff04ec 3fff0536 3ffef3f8
20:49:18.871 -> 3fffff10: 000022b3 3fff04ec 3fff0536 4020555b
20:49:18.871 -> 3fffff20: 402068d0 61ee0534 402068d0 61ee0534
20:49:18.871 -> 3fffff30: 0000000b 3fff0536 3fff0514 40203610
20:49:18.871 -> 3fffff40: 3fff0500 00000002 3fff0514 402034e6
20:49:18.871 -> 3fffff50: 3fffdad0 0000000e 3ffef338 4020564c
20:49:18.905 -> 3fffff60: 3fffdad0 3ffef280 3ffef338 3ffef3f8
20:49:18.905 -> 3fffff70: 0000000b 00000002 3ffef288 402035b4
20:49:18.905 -> 3fffff80: 3ffe89b7 3ffef3f8 3ffef338 40202934
20:49:18.905 -> 3fffff90: 00000015 00000000 3ffef288 4020298c
20:49:18.939 -> 3fffffa0: 3fffdad0 3ffef280 3ffef338 40202636
20:49:18.939 -> 3fffffb0: 3fffdad0 00000000 3ffef3f0 40205dbc
20:49:18.939 -> 3fffffc0: feefeffe feefeffe 3ffe854c 40100739
20:49:18.939 -> <<<stack<<<

20:49:18.972 -> ets Jan 8 2013,rst cause:2, boot mode:(1,6)
20:49:18.972 ->

20:49:23.975 -> ets Jan 8 2013,rst cause:4, boot mode:(1,6)
20:49:23.975 ->
20:49:23.975 -> wdt reset

(Here it just stops doing anything.)

pilobond
 
Posts: 4
Joined: Wed Jan 09, 2019 11:03 pm

Re: my device stops working when disconnected from Internet

by pilobond on Sun Feb 03, 2019 10:15 pm

I've done a few more tests with the last code. In my last posting, it seems that somehow the board soft reset, then hard reset to die.

It appears that more common reaction from NODEMCU board is to soft reset after Internet goes down, and then try to reconnect. So perhaps that's what you mean (that it would hang at while(io.status() < AIO_CONNECTED)

21:08:22.009 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6)
21:08:22.009 ->
21:08:22.009 -> load 0x4010f000, len 1384, room 16
21:08:22.009 -> tail 8
21:08:22.009 -> chksum 0x2d
21:08:22.009 -> csum 0x2d
21:08:22.009 -> vbb28d4a3
21:08:22.009 -> ~ld

21:08:22.080 ->
21:08:22.080 -> AdafruitIO::connect()
Connecting ...
21:08:22.294 -> .................................


I wish it would try to reconnect without resetting. When it resets, basically it doesn't do anything it's supposed to do (control the furnace) while trying to connect to Internet.
Is there a way to wait and reconnect to Internet without doing soft reset?

pilobond
 
Posts: 4
Joined: Wed Jan 09, 2019 11:03 pm

Please be positive and constructive with your questions and comments.