analogRead() causes Arduino to crash

Hello,

For my job I am using an Arduino Mega 2560 + Ethernet Shield to build a datalogger for logging the voltage on all 16 analog pins.
I've got the timing and storage on microSD working, but now I'm running into some problems with the analogRead().

For those who want to test my problems: just write a program that reads all analog inputs one by one, and directly send the reading using Serial.print(); Run this loop without any delays.
Wire the analog pins to random voltages: GND, 3.3V, 5V, resistor divider, leave unconnected.

Sometimes the analogRead() function causes the Arduino to crash. Sometimes it is pin 0, sometimes 1, 7, no consistency here. Sometimes it hangs in the first loop, sometimes in the second, again no consistency. When I reset, it still hangs on the same pin in the same loop.
The only thing that seems to work is to change the voltage on the pin.

I really hate this, because this means that my datalogger isn't reliable and I will have to use MAXIM analog input to SPI chips.

Does anyone recognise my problems, and have a solution?

Tom

What is the exact code you are using with your example of the issue?

muddy:
For those who want to test my problems: just write a program that reads all analog inputs one by one, and directly send the reading using Serial.print(); Run this loop without any delays.

You write the program. Post it. I'll try it.

It’s the most staightforward code ever. Using the MEGA btw.
If it crashes, it mostly happens right at the beginning or somewhere during the second readcycle.
It happens with inputs tied to 0V, 5V, 3,3V or floating.

#include <SD.h>

const int chipSelect = 4;
const int HWCS = 53;

void setup()
{
  pinMode(HWCS, OUTPUT);
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if(!SD.begin(chipSelect)) 
  {
    Serial.println("Card failed, or not present");
  }
  Serial.println("card initialized.");
}

void loop()
{
  String dataString = "";
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) 
    {
      dataString += ","; 
    }
  }
  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");
  } 
}

Right. First the boilerplate:

Please edit your post, select the code, and put it between [code][/code] tags.

You can do that by hitting the # button above the posting area.

Next. Amend your subject line for the thread from:

analogRead() causes Arduino to crash

to:

String class causes Arduino to crash

In a nutshell that will be your problem. Try rewriting without using the String class.

We've just had a lengthy discussion in another thread (which you can't be expected to realize is related).

There is a bug in the memory allocation used by String. It causes crashes.

Arduino Forum ("String corrupts the heap and crashes")

This is exactly why Nick and I both asked you to post the actual code causing problems.

The example code you described: “just write a program that reads all analog inputs one by one, and directly send the reading using Serial.print(); Run this loop without any delays.

Is this code here:

void setup()
{
  Serial.begin(9600);
  Serial.println("Getting Started...");
  Serial.println("-------------------");
}

void loop()
{
  for (int analogPin = 0; analogPin < analogPins; analogPin++) {
    Serial.print(analogRead(analogPin));
    Serial.print(",");
  }
  Serial.println(".");
}

Which runs with no problems.

Then if I take your code (I expanded to use 5 analog inputs because 3 seemed to work for me and removed SD stuff because I don’t have one attached) which uses “String”:

#define analogPins 6
void setup()
{
  Serial.begin(9600);
  Serial.println("Getting Started...");
  Serial.println("-------------------");
}

void loop()
{
  String dataString = "";
  for (int analogPin = 0; analogPin < analogPins; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < (analogPins-1)) 
    {
      dataString += ","; 
    }
  }
  Serial.println(dataString);
}

That crashes after the first iteration every time I hit reset.

It is String causing your problems, not analogRead().

Also, you would do yourself a favor by wrapping the character strings used by your Serial.print()s in F(). e.g.:
Serial.println(F(“Getting Started…”));

That will keep those string constants from using up RAM.

I didn't even consider that anything else could cause this problem.
Next week, I will apply the changes suggested and hopefully be a happy person!
Thanks

Tom

I didn't even consider that anything else could cause this problem.

When you think that thousands of other people read analogue pins every day without error, dear old William of Ockham's* favourite shaving implement suggests that whatever is causing your problem, it is not analogRead.

  • Good job he wasn't born just the other side of the A3 - he'd have been called Willy Wisley! :stuck_out_tongue_closed_eyes:

I didn't even consider that anything else could cause this problem.

Does this mean that you didn't follow your own advice?

For those who want to test my problems: just write a program that reads all analog inputs one by one, and directly send the reading using Serial.print(); Run this loop without any delays.