arduino mega 2560 hanged up

hello,
We have done a project for industrial IOT using arduino mega where there are 11sesnors : 1analog, 10 digital and we have done zigbee communication.
When everything was working, the controller stopped communicating.
I am for sure communication is not the problem because, as i resetted the controller everything worked fine for some few hours but, stopped again.
So the way out was: resetting after every iteration.
Now it's working w/o any interruptions, my question is why was the controller stopping?
What could have been the problem.

dishak:
What could have been the problem.

Memory issues? E.g. use of the String class can be the culprit; recursive calling of functions can be another one. Using malloc / new and not freeing / deleting the memory is also possible cause of trouble.

For proper advise, you will have to post the code.

//4,50==miso,51==mosi,52==sck
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

int f=0;
//String dataString = "";
const int chipSelect = 4;
void sdcar(void);
#include <dht.h>
dht DHT;
#include <SD.h>
float pressure(void);
//const int chipSelect = 4;
#include <SPI.h>
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial( 9,10);
//float f[100];
#define DHT22_PIN 2
#include <XBee.h>
#include <Wire.h>
XBee xbee = XBee();
ZBRxResponse zbRx = ZBRxResponse();
XBeeAddress64 addr64 = XBeeAddress64(0x00000000,0x00000000);
  float cell[100];
  int y=0;
#include <OneWire.h>
String data = "";

float measure(int,int);
//#include <OneWire.h>
float a[100];
void temp(void);
//float temp(void);
//float cell[100];
int u=0;
int j=0;
int count=0;
float k=0;
OneWire  ds(3);  // on pin 3 (a 4.7K resistor is necessary)


void setup(void) {
  Serial.begin(9600);
  pinMode(12,LOW);
   if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
    pinMode(22,OUTPUT);pinMode(24,OUTPUT);pinMode(26,OUTPUT);pinMode(28,OUTPUT);pinMode(2,OUTPUT);pinMode(23,INPUT);pinMode(25,INPUT);pinMode(27,INPUT);
    pinMode(29,INPUT);pinMode(13,OUTPUT);
    //pinMode(A1,INPUT);
    //digitalWrite(trig,LOW);
}


void loop(void)
{
  for(f=0;f<1;f++)
  {
  //---------------------ambient temp&humid------------------------
  Serial.print("DHT22, \t");
 uint32_t start = micros();
 int chk = DHT.read22(DHT22_PIN);
 uint32_t stop = micros();
 float h=DHT.humidity;
float t=DHT.temperature;
Serial.println(h);
Serial.println(t);
//---------------------ambient temp&humid------------------------
//---------------------pressure-------------------------------
  temp();
  for(j=0;j<5;j++)
  {
  Serial.println(cell[j]);
  }
  j=0;
  float pressure1=pressure();                   //find pressure
 //Serial.println(k);
 //---------------------pressure-------------------------------
//---------------------------ultrasound--------------- 
Serial.println("distance in mm");
float shutterleft=measure(23,22);             //shutter position
Serial.println(shutterleft);
float shutterright=measure(25,24);
Serial.println(shutterright);
float lever = measure(27,26);
Serial.println(lever);
float slevegap= measure(29,28);
Serial.println(slevegap);
//---------------------------ultrasound------------------
String Value = "A"+String(cell[j])+"B"+"C"+String(cell[j+1])+"D"+"E"+String(cell[j+2])+"F"+"G"+String(cell[j+4])+"H"+"I"+String(cell[j+3])+"J"
  +"K"+String(shutterleft)+"L"+"M"+String(shutterright)+"N"+"O"+String(lever)+"P"+"Q"+String(slevegap)+"R"+"S"+String(pressure1)+"T"+"U"+String(t)+"V"+"W"+String(h)+"X";
  
  data = String(cell[j])+","+String(cell[j+1])+","+String(cell[j+2])+","+String(cell[j+4])+","+String(cell[j+3])+","
  +String(shutterleft)+","+String(shutterright)+","+String(lever)+","+String(slevegap)+","+String(pressure1)+","+String(t)+","+String(h); 
  
      int a = Value.length();
      uint8_t payload[a];
      ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
   for(int i=0;i<a;i++)
   {payload[i]=Value[i];}
 xbee.send(zbTx);
 sdcar();
 delay(1000);
}
 //---------will resest--------------
    pinMode(12,HIGH);
   //digitalWrite(12,LOW);
   delay(6);
   pinMode(12,LOW);
   //digitalWrite(12,HIGH);
   delay(6); 
   Serial.println("resetting");
   }
   //------------will reset-------------------
 


//--------------------------temp-------------------------------------------------
void temp()
{

  int t=0,count=0;
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  while(count<5)
  {
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
//  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
   // Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
     // Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
     // Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      //Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
     // Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
     // Serial.println("Device is not a DS18x20 family device.");
      return;
  } 
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();

  }
int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
    }
  t++;
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
//Serial.print("t_value:");
//Serial.print(t);
//Serial.print('\t');
cell[y]=celsius;
y++;}
  //return(celsius);
}
//--------------------------temp-------------------------------------------------
//------------------ultrasonic-------------------------------------------------------
float measure(int echo,int trig)
{
  int i=0;
  float distance=0;
  // put your main code here, to run repeatedly:
for(i=0;i<25;i++)
{
  digitalWrite(trig,LOW);
  delayMicroseconds(2);
digitalWrite(trig,HIGH);
delayMicroseconds(11);
digitalWrite(trig,LOW);
//delayMicroseconds(2);
long duration=pulseIn(echo,HIGH);
distance+=duration/58.82;
}
distance=distance/25;
float d1=distance*10;
return(d1);
}

//------------------ultrasonic-------------------------------------------------------
//---------------------------pressure------------------------------------------
float pressure(void)
{
  int a=analogRead(A1);
 float v=a*0.00488;
  //float p=v*0.40355;
  //return(p);
  return(v);
}
//---------------------------pressure-------------------------------------------

//-------------------------------sd-----------------------------------------
void sdcar(void)
{
  tmElements_t tm;
RTC.read(tm);

String Date = String(tm.Day)+"/"+String(tm.Month)+"/"+String(tmYearToCalendar(tm.Year));
String tim = String(tm.Hour)+":"+String(tm.Minute)+":"+String(tm.Second);

String dataString = Date+","+tim+","+data;

  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();

    
    Serial.println(dataString);
  }
  
  else {
    Serial.println("error opening datalog.txt");
  }
}
//--------------------------------------------sd------------------------------------------------------

everything worked fine for some few hours but, stopped again.

Because:

String Value = "A"+String(cell[j])+"B"+"C"+String(cell[j+1])+"D"+"E"+String(cell[j+2])+"F"+"G"+String(cell[j+4])+"H"+"I"+String(cell[j+3])+"J"
  +"K"+String(shutterleft)+"L"+"M"+String(shutterright)+"N"+"O"+String(lever)+"P"+"Q"+String(slevegap)+"R"+"S"+String(pressure1)+"T"+"U"+String(t)+"V"+"W"+String(h)+"X";
  
  data = String(cell[j])+","+String(cell[j+1])+","+String(cell[j+2])+","+String(cell[j+4])+","+String(cell[j+3])+","
  +String(shutterleft)+","+String(shutterright)+","+String(lever)+","+String(slevegap)+","+String(pressure1)+","+String(t)+","+String(h);

...and this:

String Date = String(tm.Day)+"/"+String(tm.Month)+"/"+String(tmYearToCalendar(tm.Year));
String tim = String(tm.Hour)+":"+String(tm.Minute)+":"+String(tm.Second);

You are simply lucky that it is working now. With different values or times, it could hang again. This is the bane of the String class. Soooo easy to use...

To get rid of the String class, let's look at the sdcar routine. You can just write the pieces individually. You don't need to glue them all into one big String. And because you are writing it twice, once to the file and once to Serial, you can make a routine to write the date/time to a Stream. Serial and the SD file are both types of a Stream:

void writeDateTime( Stream & stream, tmElements_t & tm )
{
  stream.print( tm.Day );
  stream.print( '/' );
  stream.print( tm.Month );
  stream.print( '/' );
  stream.print( tm.Year );
  stream.print( ',' );

  stream.print( tm.Hour );
  stream.print( ':' );
  stream.print( tm.Minute );
  stream.print( ':' );
  stream.print( tm.Second );
  stream.print( ',' );

  stream.println( data );
}

Now we can use that routine in sdcar:

void sdcar(void)
{
  tmElements_t tm;
  RTC.read(tm);

  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  
  if (dataFile) {
    writeDateTime( dataFile, tm );
    dataFile.close();

    writeDateTime( Serial, tm );

  } else {
    Serial.println( F("error opening datalog.txt") ); // F macro saves RAM
  }
}

There, String all gone! :slight_smile: I'll write up another post for the first String mess...

And please use the ^T in the editor to auto-indent your code. :stuck_out_tongue:

Cheers,
/dev

This is definitely a problem:

  float cell[100];
  int y=0;
   ...

void temp()
{
   ...

cell[y]=celsius;
y++;}
  //return(celsius);
}

If it were indented properly, it would have been easier to read. Debugging and modifying is mostly reading, so do everything you can to make it readable. White space (spaces, empty lines) is free.

/dev:
Because:
To get rid of the String class, let's look at the sdcar routine. You can just write the pieces individually.

Why not make things EVEN EASIER? Simply define a large enough buffer and do this:

char buffer [64]; // text must be less than 63 chars + null

sprintf (buffer,
    "An int: %d, unsigned: %u, a string: %s, a character: %c\n",
    int d = 3,
    uint8_t = 13,
    char *str = "I'm a string",
    char c = 'A'
);

Serial.print (buffer);

"Assembling" a single line out of several .print() statements is a holdover from the sadistic ways of Java (which had a big influence on Processing... which had a big influence on Arduino).

This is C and C++... do it the right way!

It's an exercise in memory saving :wink:

And your buffer is too small to cater for the largest value of int and byte if I counted correctly 8)

Note: I'm a big fan of sprintf

"Assembling" a single line out of several .print() statements is a holdover from the sadistic ways of Java... This is C and C++... do it the right way!

Well, this actually predates Java by a few decades. :slight_smile: And I'll have to frown on including a few K of program space for sprintf, which does not implement the "%f" float formatter, so there's that...

Most beginners will be more comfortable with a series of prints instead of picking the right buffer size, picking the right formatters, and passing the right arguments. Even you had trouble with this... :smiley: The varargs routines are handy, but not something I would recommend to a beginner.

If you really want to be all modern-ey and up in da C++, then I would recommend the Streaming library (Ssshh! Don't tell anyone, but the template magic resolves to a series of prints, and never requires a "large enough buffer"...)

Cheers,
/dev