Data Logging Sketch Locking Up (Arduino MEGA1280 w/Official Ethernet Shield)

Hi Guys,

I’ve quite literally spent all day going through this code but cannot for the life of me figure out what’s going on. It seems to simply lock up, I’ve tried multiple Arduino’s and ethernet shields so I’m certain it is a code issue.

The idea is that one Arduino logs sensors and transmits the data to this second arduino via TWI for logging to an SD Card and live (give or take a few seconds) submission to a PHP server via ethernet.

However, for some reason this second sketch keeps locking up. Can anybody shed any light on this for me, I really can’t seem to find any reason nor pattern for it. It seems that the main loop stops running, sometimes when this happens the Wire interrupt will still work and log the data to SD, other times nothing happens at all.

#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <avr/wdt.h>
#include <MemoryFree.h>

byte mac[] = {  
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
char server[] = "my.web.server"; // self explanatory!
char siteid[] = "1"; // this is the arduino identifier, if I decide to have several.
char sitepw[] = "password"; // this is a 'password' that could be unique for each site

EthernetClient client;
unsigned long timer;
String dataString;
String sendstring;
int fileindex = 0;
char itoabuffer[12];
String ServerResponse = "";
////////////////////////////////////////////////////////////////////////////
void setup ()
{
  Serial.begin(57600);
  Serial.println("Setting up ethernet");
  if(Ethernet.begin(mac) == 0)
  {
    Serial.println("*** Failed to configure Ethernet using DHCP");
    software_Reboot(3);
  }
  else
  {
    for (byte thisByte = 0; thisByte < 4; thisByte++) {
      Serial.print(Ethernet.localIP()[thisByte], DEC);
      Serial.print("."); 
    }
    Serial.println();
    delay(1000);
  }
  Serial.println("Setting up SD Card");
  if (!SD.begin(4))
  {
    Serial.println("*** Unable to setup SD Card");
    software_Reboot(4);
  }
  Serial.println("Checking for files on SD card");
  while(SD.exists(itoa(fileindex, itoabuffer, 10)))
  {
    Serial.print("Found file ");
    Serial.println(fileindex);
    fileindex++;
  }
  if(fileindex > 0)
  {
    fileindex--; 
  }
  Serial.println("Starting TWI");
  Wire.begin(4);
  Wire.onReceive(receiveEvent);
  Serial.println("Setup complete");
}
////////////////////////////////////////////////////////////////////////////
void loop ()
{
  if (millis() > timer)
  {
    Serial.print("Free Memory:");
    Serial.println(freeMemory());
    Serial.println("Timer up");
    timer = millis() + 3000;
    char sdreading[15];
    char sendchar[35];
    Serial.println("Checking if SD files exist");
    if(SD.exists(itoa(fileindex, itoabuffer, 10)))
    {
      Serial.println("Found file, reading file");
      File MyFile = SD.open(itoa(fileindex, itoabuffer, 10), FILE_READ);
      for(byte i = 0; MyFile.available() || i < 12; i++)
      {
        Serial.print("1");
        if(i < sizeof(sdreading))
        { 
          Serial.print("2");
          sdreading[i] = MyFile.read();
          Serial.print(sdreading[i]);
        }
        else
        { 
          Serial.print("3");
          MyFile.read();
        }
      }
      MyFile.close();
      Serial.println("Closing file");
      byte DataEnd = 0;
      byte x = 0;
      for(x = 0; x < (sizeof(sdreading) + 1); x++)
      {
        Serial.print("4");
        if(sdreading[x] == '.')
        {
          Serial.print("5");
          DataEnd = x;
          x = sizeof(sdreading) + 1;
        }
      }
      sendstring = "";
      for(x = 0; x < DataEnd; x++)
      { 
        Serial.print("6");
        sendstring += sdreading[x];
      }
      SubmitToServer(sendstring);
    }
    else
    {
      Serial.println("No files found");
    }
  }
}
////////////////////////////////////////////////////////////////////////////
void receiveEvent(int howMany)
{
  dataString = "";
  while(0 < Wire.available())
  {
    Serial.print("7");
    byte sensor = Wire.read();
    int z = 0;
    z = Wire.read() << 8;
    z |= Wire.read();
    dataString += String(sensor);
    dataString += ",";
    dataString += String(z);
    dataString += ".";
    while(SD.exists(itoa(fileindex, itoabuffer, 10)))
    {
      Serial.print("8");
      fileindex++;
    }
    File dataFile = SD.open(itoa(fileindex, itoabuffer, 10), FILE_WRITE);
    if(dataFile)
    {
      Serial.print("Writing ");
      Serial.print(dataString);
      Serial.print(" to file ");
      Serial.println(fileindex);
      dataFile.println(dataString);
      dataFile.close();
      Serial.println("... done");
      Serial.print("Free Memory:");
      Serial.println(freeMemory());
      Serial.print("Timer: ");
      Serial.println(timer);
      Serial.print("Millis: ");
      Serial.println(millis());
    }
  }
}
////////////////////////////////////////////////////////////////////////////
void SubmitToServer(String sitedata)
{
  Serial.print("9");
  client.stop();
  Serial.print("10");
  client.flush();
  Serial.print("11");
  ServerResponse = "";
  String sendurl = "";
  if(client.connect(server, 80))
  {
    Serial.println("Connected");
    sendurl += "GET /ard/srv.php?d=";
    sendurl += siteid;
    sendurl += "&p=";
    sendurl += sitepw;
    sendurl += "&v=";
    sendurl += sitedata;
    sendurl += " HTTP/1.1";
    Serial.println(sendurl);
    client.println(sendurl);
    client.println("Host: htpour.forumcomputers.co.uk");
    client.println("Connection: close");
    client.println();
  } 
  else
  {
    Serial.println("Connection Failed");
    software_Reboot(2);
  }
  while(client.connected())
  {
    while(client.available())
    {
      char c = client.read();
      Serial.print(c);
      if (c == '<')
      {
        c = client.read();
        ServerResponse += c;
        c = client.read();
        ServerResponse += c;
        c = client.read();
        ServerResponse += c;
        c = client.read();
        ServerResponse += c;
        Serial.print("Server responded: ");
        Serial.println(ServerResponse);
        Serial.println("Disconnecting");
        client.stop();
      }
    }
  }
  if(ServerResponse == "OKOK")
  {
    if(fileindex > 0)
    {
      Serial.print("Removing file ");
      Serial.println(fileindex);
      if(SD.exists(itoa(fileindex, itoabuffer, 10)))
      {
        Serial.print("a");
        SD.remove(itoa(fileindex, itoabuffer, 10));
      }
      fileindex--;
    } 
    else
    {
      if(SD.exists(itoa(fileindex, itoabuffer, 10)))
      {
        Serial.print("Removing last file ");
        Serial.println(fileindex);
        SD.remove(itoa(fileindex, itoabuffer, 10));
        Serial.println("Last file removed");
      }
    }
    ServerResponse = "";
  }
}
////////////////////////////////////////////////////////////////////////////
void software_Reboot(byte count)
{
  Serial.print("*** Error: ");
  Serial.println(count);
  Serial.println("Rebooting...");
  while(count != 0)
  {
    digitalWrite(13,HIGH);
    delay(1000);
    digitalWrite(13,LOW);
    delay(500);
    count--;
  }
  //cli();
  //wdt_enable(WDTO_15MS);
  //while(1)
  //{
  //}
}

Many thanks in advance!

What is software_reboot() supposed to be doing?

I suggest you simplify your sketch as far as you can to eliminate functionality unrelated to the problem, and add print statements to show which code is executing when the sketch locks up. If you're putting trace statements very close to the lock-up, I suggest you also call Serial.flush() to ensure the trace message gets sent before your sketch locks up.

Thanks PeterH,

The idea behind software_Reboot() is that if I detect an error of some description this function can be called to force a reset of the Arduino and reinitialise the ethernet, SD, etc. This worked with the Mega 32u4, however I have commented it out on the troubleshooting sketch which is being uploaded to a Mega 1280 where the watchdog doesn’t work for me. This isn’t an issue at this point in time as I intend for the final product to run on a 32u4, I’m simply exploiting the 1280 for it’s huge sketch size to put in as much debugging as I like!

I wasn’t familiar with Serial.flush() but that looks very useful indeed! I’ll see what that can tell me and report back.

Thanks for your help!