Arduino nano stop responding spontaneously after few hours

Hi All,

Im very new to Arduino circuit making and trying out an idea. This code is supposed to read soil moisture and update it to thingspeak to collect some statistical data.

But strangely it stops working spontaneously. even when the data upload part is commented.
After some reading I all the print lines as some mentioned it can overrun the memory and added OB LED to blink just to indicate me that code is runnig, still the same issue it stops after a while.

But if I leave only the OB blink part it seems it runs continuously(i checked only 8 hr as previously it stopped after around 5 hr)

My moisture sensor I2C Soil moisture sensor from Catnip electronics on Tindie . It is powered by a separate voltage regulator[LF33ABPT] which also powers the esp8266 by regulating 5v supply to Arduino to 3.3v.

Please help me to identify the issue?

#include<stdlib.h>
#include <I2CSoilMoistureSensor.h>
#include <Wire.h>

#include <SoftwareSerial.h>
#define SSID "6C32C7"
#define PASS "73"
#define IP "api.thingspeak.com" // thingspeak.com

I2CSoilMoistureSensor sensor;
String GET = "GET /update?key=BPSMM6IF7P&field1=";
SoftwareSerial wifi(8, 9); // RX, TX

double moistVal = 0;
double moistAvg = 0;
int moistStore[30];


double tempVal = 0;
double tempAvg = 0;
int tempStore[30];


double lightVal = 0;
double lightAvg = 0;
int lightStore[30];

int blinker = 0;
int ticker = 0;
int ticker_db = 0;
void setup()  
{
 pinMode(13,OUTPUT);
 Wire.begin();
 wifi.begin(9600);
 Serial.begin(9600);
 sendDebug("AT");
 delay(5000);
 if(wifi.find("OK")){
   Serial.println("RECEIVED: OK");
   connectWiFi();
   Serial.println("WiFi Connected");
 }
 sensor.begin(); // reset sensor
 delay(1000); // give some time to boot up
 Serial.print("I2C Soil Moisture Sensor Address: ");
 Serial.println(sensor.getAddress(),HEX);
 Serial.print("Sensor Firmware version: ");
 Serial.println(sensor.getVersion(),HEX);
 Serial.println();
}

void loop(){

   while (sensor.isBusy()) {
     blinker = 0;
     delay(1000); // available since FW 2.3
     while(blinker==5) //added to indicate stuck in sensor busy loop
     {
        digitalWrite(13,HIGH);
        delay(100);
        digitalWrite(13,LOW);
        blinker++;
     }
   }
   moistAvg = sensor.getCapacitance();
   tempAvg = sensor.getTemperature()/(float)10;
   lightAvg = sensor.getLight(false);
   sensor.sleep();
   updateTemp(String(moistAvg,2),String(tempAvg,2),String(lightAvg,2));

  digitalWrite(13,HIGH); //to indicate main loop is running
  delay(100);
  digitalWrite(13,LOW);
  delay(500);
  digitalWrite(13,HIGH);
  delay(100);
  digitalWrite(13,LOW);
  delay(10000);
}

void updateTemp(String Moist, String Temp, String Light){
 String cmd = "AT+CIPSTART=\"TCP\",\"";
 cmd += IP;
 cmd += "\",80";
 sendDebug(cmd);
 delay(2000);
 if(wifi.find("Error")){
   Serial.print("RECEIVED: Error");
   return;
 }
 cmd = GET;
 cmd += Moist +"&field2=" + Temp + "&field3=" + Light ;
 cmd += "\r\n";
 Serial.println(cmd);

 
 wifi.print("AT+CIPSEND=");
 wifi.println(cmd.length());
 delay(1000);
 if(wifi.find(">")){
   Serial.print("SEND");
   Serial.println(cmd);
   wifi.print(cmd);
 }else{
   sendDebug("AT+CIPCLOSE");
 }
 if(wifi.find("OK")){ 
   Serial.println("RECEIVED: OK");
 }else{
   Serial.println("RECEIVED: Error");
 }
}
void sendDebug(String cmd){
 Serial.print("SEND: ");
 Serial.println(cmd);
 wifi.println(cmd);
} 

boolean connectWiFi(){
 Serial.println("AT+CWMODE=1");
 wifi.println("AT+CWMODE=1");
 delay(2000);
 String cmd="AT+CWJAP=\"";
 cmd+=SSID;
 cmd+="\",\"";
 cmd+=PASS;
 cmd+="\"";
 sendDebug(cmd);
 delay(6000);
 if(wifi.find("OK")){
   Serial.println("RECEIVED: OK");
   return true;
 }else{
   Serial.println("RECEIVED: Error");
   return false;
 }
}

To make it easy for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

Using the String class often results in a problem arising after a program is running for some time.

...R

Hi Robin2,

Thank you, I edited the post.

I change my code and come up with an update. But the main loop stops even if the line which contains String conversion is commented out. That is what troubles me. Even if I have only the below code. Just to read the sensor.

Now I notice that when it stuck if I rest the board it won't start the loop.

Ex:-

void loop(){
    
      while (sensor.isBusy()) {
        blinker = 0;
        delay(1000); // available since FW 2.3
        while(blinker==5)
        {
           digitalWrite(13,HIGH);
           delay(100);
           digitalWrite(13,LOW);
           blinker++;
        }
      }
      moistAvg = sensor.getCapacitance();
      tempAvg = sensor.getTemperature()/(float)10;
      lightAvg = sensor.getLight(false);

      sensor.sleep();

  }
   digitalWrite(13,HIGH);
   delay(100);
   digitalWrite(13,LOW);
   delay(500);
   digitalWrite(13,HIGH);
   delay(100);
   digitalWrite(13,LOW);
   delay(10000);
}

There is a while loop that sets blinker to 0 and then immediately there is another while loop that only executes if blinker == 5. Looks to me like that second while loop will never execute.

my bad it should be "!=". Thank you for pointing out that.

But still what could be the issue? why it stops going through the main loop?

But still what could be the issue?

Use of Strings. See reply #1.

@chapsxs, if you still have a problem please post the latest version of your code in your next Reply.

...R

Hi Robin2

I omitted everything and just stated below, it still stuck. now it seems even before 1 hr

I have no pull-ups on SDA and SCK [ I only use one sensor on the bus ], can that be an issue?

If so wy after some readings?

void loop(){
  
   while (sensor.isBusy()) { digitalWrite(13,HIGH);delay(1000);} // available since FW 2.3
   digitalWrite(13,LOW);
   moistAvg = sensor.getCapacitance();
   tempAvg = sensor.getTemperature()/(float)10;
   lightAvg = sensor.getLight(false);
   sensor.sleep();
   digitalWrite(13,HIGH);
   delay(100);
   digitalWrite(13,LOW);
   delay(500);
   digitalWrite(13,HIGH);
   delay(100);
   digitalWrite(13,LOW);
   delay(10000);
}

Post the entire program.

I have no pull-ups on SDA and SCK

There must be pullups on SDA and SCK somewhere, or I2C communications won't work at all. You could try lowering the values (4.7K or 2.2K).

yesterday night I commented below line and kept nano running. I checked it now after work, To my surprise, it still running.

lightAvg = sensor.getLight(false);

I changed this to false after noticing the value read from light registry keep growing on every read. Thinking that itll reach the max int value.

Now I have uploaded original code with the same mod, lets see what happens :smiley:

Fyi your original post includes your thingspeak API key and Wi-Fi password. So you might want to change those...

Seems that

lightAvg = sensor.getLight(false);

this line was the troublemaker, Now I need to figure out why?

Robin2 Thank you for pointing out " csting " option

chapsxs:
Robin2 Thank you for pointing out " csting " option

I guess that is better than a " bsting " :slight_smile:

...R

Use this function to check the RAM on your nano. It returns the number of free bytes of RAM.

// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;

// function to return the amount of free RAM
int memoryFree()
{
  int freeValue;

  if((int)__brkval == 0)
     freeValue = ((int)&freeValue) - ((int)&__bss_end);
  else
    freeValue = ((int)&freeValue) - ((int)__brkval);

  return freeValue;
}

Came from the Arduino Cookbook by Michael Margolis.

void updateTemp(String Moist, String Temp, String Light){
 String cmd = "AT+CIPSTART=\"TCP\",\"";
 cmd += IP;
 cmd += "\",80";

All those passed Strings are pointers but what about the local String cmd? Does it go on the stack? What happens when a char is added?

Strings "do things for you" that you may not want done in a small RAM environment.

GoForSmoke:
Strings "do things for you" that you may not want done in a small RAM environment.

I used a string once. It wasn't pretty.

Unsigned_Arduino:
I used a string once. It wasn't pretty.

Do you know the difference between C++ String objects and C char array strings besides the upper vs lower case S?

If you don't there's valuable lessons to get right there.