Go Down

Topic: arduino stops after long time (Read 748 times) previous topic - next topic

prikok

I have made sketch with arduino uno and esp8266 in which i send measures of HC-SR04 to a website. I have two same projects in two different parts with different internet connections. After a month the one of them stop working. Τhe two of them have been operating normally for over seven months and only one of them is causing the problem. Where can the problem arise in one of the two arduino? Is it due to poor internet connection of this part the above problem? My code is:
Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial espSerial =  SoftwareSerial(2,3); 

//Wifi network SSID password
String ssid="ffffff";
String password ="*******";

boolean DEBUG=true;

int echoPin = 12;
int trigPin = 13;

long duration, distance;
int alarm;

String alarms;

String data;
String server = "www.example.com"; // Send data to this site

String uri = "/add2.php";

int error = 0;
int cancel = 0;

void showResponse(int waitTime){
    long t=millis();
    char c;
    while (t+waitTime>millis()){
      if (espSerial.available()){
        c=espSerial.read();
        if (DEBUG) Serial.print(c);
      }
    }
                   
}

void websiteWrite(long value1, int value2){
  if (value2 == 0){
    alarms = "OFF";
  }else{
    alarms = "ON";
  }
 
  data = "distance=" + String(value1) + "&alarm=" + alarms;
 
  espSerial.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.
 
  if( espSerial.find("OK")) {
 
  Serial.println("TCP connection ready"); cancel = 0;
 
  }
  else{
    cancel = cancel + 1;  Serial.println("cancel="); Serial.println(cancel);
  }
  delay(1000);
 
  String postRequest =
 
  "POST " + uri + " HTTP/1.0\r\n" +
 
  "Host: " + server + "\r\n" +
 
  "Accept: *" + "/" + "*\r\n" +
 
  "Content-Length: " + data.length() + "\r\n" +
 
  "Content-Type: application/x-www-form-urlencoded\r\n" +
 
  "\r\n" + data;
 
  String sendCmd = "AT+CIPSEND=";//determine the number of caracters to be sent.
 
  espSerial.print(sendCmd);
 
  espSerial.println(postRequest.length() );
 
  delay(500);
 
  if(espSerial.find(">")) { Serial.println("Sending.."); espSerial.print(postRequest);
 
  if( espSerial.find("SEND OK")) { Serial.println("Packet sent");
 
  while (espSerial.available()) {
 
  String tmpResp = espSerial.readString();
 
  Serial.println(tmpResp);
 
  }
 
  // close the connection
 
  espSerial.println("AT+CIPCLOSE");
 
  }
    error = 0;
  }else{
    error = error + 1;
    Serial.println("error=");
    Serial.println(error);
   
  }
 
  if(cancel >=15 || error >= 15){software_Reset() ;}
 
}

void setup() {
  delay(150000);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
 
  DEBUG=true;           
  Serial.begin(9600);
 
  espSerial.begin(9600); 
 
  //espSerial.println("AT+RST");         
  //showResponse(1000);
 
  //espSerial.println("AT+UART_DEF=9600,8,1,0,0");   
  //showResponse(1000);
 
  espSerial.println("AT+CWMODE=1");   
  showResponse(1000);

  espSerial.println("AT+CWJAP=\""+ssid+"\",\""+password+"\""); 
  showResponse(5000);

  if (DEBUG)  Serial.println("Setup completed"); 
}

void loop() {

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration/58.2;
 
  if (distance<=8){
    alarm=1;
  }else{
    alarm=0;
  }
 
      if (isnan(distance)) {
        if (DEBUG) Serial.println("Failed of calculation the distance");
      }
      else {
          if (DEBUG)  Serial.println("Distance="+String(distance)+" cm");
           websiteWrite(distance,alarm);                                      // Write values to website
      }
 
   
  //Needs 60 sec delay between updates   
  delay(60000);   
}

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile ("  jmp 0"); 



pert

After power cycling the non-working unit, does it start working normally again?

wildbill

Use of Strings (note case) in a sketch on an Arduino with little RAM is risky. Use C style strings instead.

prikok

Disconnecting/connecting the device solved the issue temporarily, but this can't be a solution, as the device is supposed to be used permanently and fully automatically. Αnd since both are the same by code and link because one works normally while the other stops?

Robin2

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. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pert

Disconnecting/connecting the device solved the issue temporarily, but this can't be a solution
I wasn't suggesting it as a solution. I was asking because this can provide helpful diagnostic information. If a power cycle doesn't resolve the problem then it might be caused by faulty hardware, lack of network connectivity, etc. A problem like the memory fragmentation caused by the use of String will always be resolved (temporarily) by a power cycle.

prikok

Do you think there is a problem with using strings or something else?

sterretje

"Stop working" does not say much. What are the symptoms?

I think a first step would be to add some diagnostics ( in the beginning of loop() ).

If you have a PC connected permanently you can add code that sends every N seconds a message over the serial port; you'll need to keep e.g. Serial Monitor open (because opening serial monitor resets the Uno).
If that's not the case, you can implement a blink without delay.

In both cases, you will have an indication if it's just the communication that fails or if your code crashed.

You have two equivalent setups; are they in the same location?

If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

prikok

I can not connect it to a PC and they are in different locations. That is why I am impressed that one works properly and the other stops after some time.

PieterP

Apart from Strings turning your heap into Swiss cheese, this line will mess things up when millis overflows after 49.71 days:
while (t+waitTime>millis())

Pieter

lastchancename

#10
Jan 12, 2019, 09:47 pm Last Edit: Jan 13, 2019, 01:50 am by lastchancename
While not the solution to a faulty implementation... if your project is a low duty-cycle application, you *could* use the WDT to buy some time while you develop a proper solution.

The watchdog *should* be used to catch exceptional failures, not as a band-aid.  But it can help with getting through short term obligations!
Experienced responders have a nose for laziness, (they were beginners once)... Sure, there are trolls, chest-beaters, and pretenders - but the help you'll get here is about as good as it gets - if you try to help youself!.

ChrisTenone

Do you think there is a problem with using strings or something else?
TL/DR: Strings are bad and will crash your program. Use character arrays.

Not strings, but the String class is the problem. Sting is a part of the C libraries. They work just fine on computers with garbage collection (generally any operating system has garbage collection - it cleans up the heap, ie free memory area periodically. But an Arduino has no garbage collection, and it's heap is quite minuscule.

So when you run a sketch using Strings, they slowly, but surely eat up all of the heap, until there are no two consecutive bytes available. At that point you cannot store an integer value, and your program crashes. When it does, the reasons are complex and not usually repeatable. It can crash anywhere from a few hours after starting to several weeks, depending on how often it creates and (incompletely) destroys the Strings.

This matches the circumstances of your issue exactly. Try to re-write your code to use character arrays instead of Strings. There are plenty of functions that manipulate character arrays as strings, however they work differently than do Strings, so you will need to do some additional programming to use them.
What, I need to say something else too?

6v6gt

Strings simply use malloc() and free() (or the new() and delete() c++ equivalents) behind the scenes. Any intense use of such dynamic memory allocation features in c/c++ (and this applies not only to Strings) will lead to potential heap fragmentation. This is not so much an issue of missing garbage collection because this could still happen even all the items in the heap are still wanted and Arduino Strings are anyway cleaned up if they go out of scope etc. I don't believe that any form of automatic heap defragmentation is even possible in c/c++ because the language allows the program to maintain direct pointers into the heap.
The Arduino String class has a reserve() method which creates a dedicated pool of heap space which can help to minimize this problem of fragmentation.

sterretje

So when you run a sketch using Strings, they slowly, but surely eat up all of the heap, until there are no two consecutive bytes available. At that point you cannot store an integer value, and your program crashes. When it does, the reasons are complex and not usually repeatable. It can crash anywhere from a few hours after starting to several weeks, depending on how often it creates and (incompletely) destroys the Strings.
I think you need to rephrase that. They do not necessarily "slowly but surely eat up all the heap" but it might happen.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

sterretje

I did a quick-and-dirty hack of OPs code using global c-strings of sufficient size. I do not think it is as much the use of String as all concatenations are in sequence so there will not be fragmentation. Though I do agree on the comments on the use of String.

But I think that OP is actually running out of memory in the websiteWrite. With the hack, I get a "low on memory" warning.

One reason for the code crashing is that tmpResp can chew away lots of memory depending on the actual response. Looking at the succesfull response in https://developer.mozilla.org/en-US/docs/Web/HTTP/Session, it would be 450 for the header and 650 for the total. As OP does not seem to be interested in the actual result, I would just read and print byte-by-byte instead of using a String variable. I suspect that that will solve the issue but not knowing the exact responses it will be a bit of a guess.

If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up