Aaron Ardiri
[Valid RSS] RSS/XML feed
198 entries available (show all)

 

Internet of Things (IoT)
   

PLEASE TAKE A MOMENT TO FOLLOW MY NEW VENTURE:
 
RIoT Secure AB
 
ALL SECURITY RELATED TOPICS ON IoT wILL BE POSTED THERE


2015-11-20
>> TEMPERATURE MONITOR - DEALING WITH A FROZEN ARDUINO

Well; that didn't take long - all of a sudden temperature data stopped arriving from the Arduino.

After working flawlessly for over two days; something happened such that my last recording was received at 09:03am earlier this morning - basically, the Arduino just froze up and did nothing. After a quick reboot the data started streaming over again (at 10:44am) so it was time to put some fail safes into the sketch to deal with unexpected lockups and weird crashes.

I have written about watchdog timers in the past that would allow a device to go into a nice sleep mode to maximize power but now it is time to use them as they were designed. To kick the micro-controller in the backside if the code doesn't check in periodically. The issue could have also been a result of the very long delay call in the sketch - so I also optimized that to work a little better.

  • #include <avr/wdt.h>
    
    unsigned long ts;
    #define COMMUNICATION_PERIOD 50500 // we want to a delay of approx 1 minute
                                       // takes approx 10 seconds for reading

The avr/wdt.h header is the only one we need here - in addition, I recorded the exact amount of time it takes for a reading/upload to occur to make sure the communication to the server occurs almost perfectly on the minute. The time to perform the reading of all four of the DS18B20 and the HTTP POST request was just under ten seconds.

  • // immediately disable the watchdog timer on restart
    wdt_disable(); 
    
    ...
    
    // enable the watchdog timer
    wdt_enable(WDTO_8S);
    
    ...
    
    // we need a reference timestamp
    ts = millis() - COMMUNICATION_PERIOD;

The above is slotted into our setup function; just a little house keeping at first and you can see we set the watchdog timer to activate after eight seconds - there are multiple values you can use, but eight seconds is sufficient for what we need. The last line is to make sure the first time we run the loop function it will perform a reading immediately.

  • // should we be looking at our sensors now?
    if (((millis() - ts) >= COMMUNICATION_PERIOD) ||
        (millis() <  ts)) // overflow - we cannot rely on the value anymore
    {
      ...
    
      // flag the time this was done; so we can ensure we wait 60 secs 
      ts = millis();
    }
    
    // go to sleep for half a second
    else
      delay(500);
    
    // reset the watchdog timer
    wdt_reset(); 

The changes to the loop function are as above. In order to do anything; we want to make sure that the requires amount of time passes - in addition, we are checking if the millis counter overflows; which is documented to happen after approximately fifty days.

It is important to update the ts variable after we transmit the data to the cloud for this to work as well. Otherwise the device sleeps for half a second and resets the watchdog timer. We also need to find all places in the sketch where their can take longer than eight seconds delay or the device will reset.

One such place is when the sketch attempts to connect to the WiFi network - we need to reset the watchdog timer and also lower the delay to anything under eight seconds for this to work correctly. A delay of only five seconds for the network connection was sufficient in the tests I performed.

  •   // reset the watchdog timer
      wdt_reset();
    
      // attempt to connect to Wifi network:
      while (status != WL_CONNECTED)
      {
        Serial.print("Attempting to connect to WiFi SSID: ");
        Serial.println(ssid);
    
        // Connect to WPA/WPA2 network:
        status = WiFi.begin(ssid, pass);
    
        // reset the watchdog timer
        wdt_reset();
    
        // wait 5 seconds for connection:
        delay(5000);
      } 

With this; a new sketch was deployed which hopefully will not freeze up.

A complete updated sketch is available below - time will tell if these changes are sufficient to keep the system stable. It has been reported often that the WiFi and Ethernet shields cause lockup's on the fragile 16Mhz micro-controller - the use of watchdog timers has always proven successful in most of the cases it has happened.

UPDATE 2015-11-24
An additional change is required when the client.connect() function fails; the WiFI environment may need to be reset - the simplest way was to add the following code in the loop function.

  • else
    {
      Serial.println(":: failed to connect to server");
    
      // disconnect manually
      WiFi.disconnect();
      status = WL_DISCONNECTED;
    
      // attempt to connect to Wifi network
      connect_WiFi();
    }

In the existing case; if the function would fail - the watch dog timer would get reset at the end of the loop and as such would never kick in. The above should attempt to reconnect to the WiFI network.

advertisement (self plug):
need assistance in an IoT project? contact us for a free consultation.

 



RF 433Mhz radio communication with an Arduino
 
Arduino WiFiShield101 - available, but is it ready?

DISCLAIMER:
All content provided on this blog is for informational purposes only.
All comments are generated by users and moderated for inappropriateness periodically.
The owner will not be liable for any losses, injuries, or damages from the display or use of this information.