Problem reading serial from Atmega328P (Uno and Nano) but not Atmega2560(Mega)

Hello,

I am not sure if this is the right place to post this but I have an Arduino Mega which I wrote a program on that pretty much just prints out serial to the arduino serial monitor and takes actions with regards to the input from the monitor.

The program runs flawlessly on the Mega but when we came to the end of the project we decided to use the Uno as the mega was too big.

WHen I run the program on the Uno I get this...

When I ran the code on two seperate arduino nanos i get this...

And here is how the output should look like as I coded it on the arduino Mega...

as you can see I get the exact same garbage text from the nanos and the uno which leads me to believe that the problem might be with the Atmega328P µController since that is what the nano and uno share in common and also do not have in common with the Mega.

My question is this... has anyone else run in to a problem such as this? also is it fixable?

I have tried everything possible from switching to different baudrates to putting delays between the Serial.print functions. I also made sure that I am selecting the right com port and arduino board before programming the device.

Here is the piece of code that is relevant.

void setup(void) 
{
  Serial.begin(115200);  // Initialize the serial communication device at 115200 baud.
  initializeModule();  
}

void initializeModule()
{
  delay(50);
  displayHelp();
  Serial.println();
  displayOptions();
  Serial.println();
}

void displayHelp()
{
  Serial.println();
  Serial.print("[S]can");     Serial.print("      ");    Serial.println(" Scans the data bus identifying any connected probes.");
  Serial.print("[C]hoose");   Serial.print("    ");      Serial.println(" Chooses a probe to calibrate.");
  Serial.print("[R]ead");     Serial.print("      ");    Serial.println(" Reads the calibration data from the probe.");
  Serial.print("[W]rite");    Serial.print("     ");     Serial.println(" Writes calibration data to the probe.");
  Serial.print("[V]iew");     Serial.print("      ");    Serial.println(" Shows the selected probe address.");
  Serial.print("[F]ormat");   Serial.print("    ");      Serial.println(" Formats the selected probe.");  
  Serial.print("[O]ptions");  Serial.print("   ");       Serial.println(" Displays the available options.");
  Serial.println();
}

void displayOptions()
{
  Serial.println();
  Serial.print("[S]can");     Serial.print("   ");
  Serial.print("[C]hoose");   Serial.print("   ");
  Serial.print("[R]ead");     Serial.print("   ");
  Serial.print("[W]rite");    Serial.print("   ");
  Serial.print("[V]iew");     Serial.print("   ");
  Serial.print("[F]ormat");   Serial.print("   ");  
  Serial.print("[O]ptions");  Serial.print("   ");
  Serial.print("[H]elp");     Serial.print("   ");
  Serial.println("[A]bout");    
}

Thanks in advance!

I have already run a code on arduino mega then arduino uno without Serial problem.
Have you choose the good board before compile it ?

If the code runs on a processor with 8K of SRAM but not on a processor with 2K of SRAM, then the most likely conclusion one can draw is that memory is being exhausted. The F() macro would help you immensely.

PaulS:
If the code runs on a processor with 8K of SRAM but not on a processor with 2K of SRAM, then the most likely conclusion one can draw is that memory is being exhausted. The F() macro would help you immensely.

That actually sounds reasonable... It has no problem printing correctly when the function prints out 2 or three lines but with these big lines it seems to mess up... I will take a look in to the F() macro and get back to you

Thanks for the heads up!

When i run this code...

void displayHelp()
{
  Serial.println();
  Serial.print(F("[S]can"));     Serial.print(F("      "));    Serial.println(F(" Scans the data bus identifying any connected probes."));
  Serial.print(F("[C]hoose"));   Serial.print(F("    "));      Serial.println(F(" Chooses a probe to calibrate."));
  Serial.print(F("[R]ead"));     Serial.print(F("      "));    Serial.println(F(" Reads the calibration data from the probe."));
  Serial.print("[W]rite");    Serial.print("     ");     Serial.println(" Writes calibration data to the probe.");
  Serial.print("[V]iew");     Serial.print("      ");    Serial.println(" Shows the selected probe address.");
  Serial.print("[F]ormat");   Serial.print("    ");      Serial.println(" Formats the selected probe.");  
  Serial.print("[O]ptions");  Serial.print("   ");       Serial.println(" Displays the available options.");
  Serial.println();
}

I get this...

which is great and all but then when I try to add more F() macros it starts acting weird again (even with the first part that seemed to work fine after the macro). Then if I push it even further and add more F() macros the whole code just stops executing... I read that a way to debug if your running out of SRAM is to comment out big pieces of Serial.print() functions so I did and ran this code...

void displayHelp()
{
  Serial.println();
  Serial.print("[S]can");     Serial.print("      ");    Serial.println(" Scans the data bus identifying any connected probes.");
  Serial.print("[C]hoose");   Serial.print("    ");      Serial.println(" Chooses a probe to calibrate.");
//  Serial.print("[R]ead");     Serial.print("      ");    Serial.println(" Reads the calibration data from the probe.");
//  Serial.print("[W]rite");    Serial.print("     ");     Serial.println(" Writes calibration data to the probe.");
//  Serial.print("[V]iew");     Serial.print("      ");    Serial.println(" Shows the selected probe address.");
//  Serial.print("[F]ormat");   Serial.print("    ");      Serial.println(" Formats the selected probe.");  
//  Serial.print("[O]ptions");  Serial.print("   ");       Serial.println(" Displays the available options.");
//  Serial.println();
}

and this is what I got...

and it just keeps printing M infinately until I close the hyper terminal

So now I feel that I am back to square one and have no Idea what could be causing this... I am currently testing this on my Uno by the way since I have ruled out that the problem is with the actual arduino and decided that the problem lies within the actual µController and its characteristics.

I read that a way to debug if your running out of SRAM is to comment out big pieces of Serial.print() functions so I did and ran this code...

Perhaps you've heard me mention that Snippets-r-us is down the internet a ways. Here, we need to see ALL of your code. That commenting out stuff, using PROGMEM (that's what the F() macro does), etc. changes the behavior of your program is indicative of different portions of memory being corrupted/overwritten.

There are UNO sized Megas available, from Seeed studio for one. Crossroads has a 1284 based solution, too, in a small size.

Yup, Uno size and a small surface mount 1284 Mini.
16K SRAM, twice what the Mega has, and 10 12 more IO than an Uno.
www.crossroadsfencing.com/BobuinoRev17

PaulS:

I read that a way to debug if your running out of SRAM is to comment out big pieces of Serial.print() functions so I did and ran this code...

Perhaps you've heard me mention that Snippets-r-us is down the internet a ways. Here, we need to see ALL of your code. That commenting out stuff, using PROGMEM (that's what the F() macro does), etc. changes the behavior of your program is indicative of different portions of memory being corrupted/overwritten.

There are UNO sized Megas available, from Seeed studio for one. Crossroads has a 1284 based solution, too, in a small size.

Sorry about posting snippets but when I tried posting the whole code I got "The message exceeds the maximum allowed length (9500 characters)." Can I e-mail it to you?

you are right... The memory is definately being exhausted somewhere else as I commented out everything except the displayHelp and displayOptions functions and they printed out just fine by themselves...

Thanks for the information about Crossroads and I will definately be keeping them in mind for my future projects (and a better eye on SRAM in the µControllers that I choose). That might actually be my solution but I would still like to understand why it is not running and how to fix it if possible so that I may learn from it.

kengineer:
Sorry about posting snippets but when I tried posting the whole code I got "The message exceeds the maximum allowed length (9500 characters)."

Attach it...

• Click Reply
• Click Addition Options (below to the right of the edit box)
• Click Browse
• Select the file and click Open
• Click Post

Thanks! Still new to forums as you can tell

You appear to have some fundamental misconceptions about how serial data is transmitted.

*!   1. There appears to be a problem with the arduino Serial.flush() function. It is required to put it after every serial input otherwise the µController is thrown in to an infinite loop.
*!   2. A 10 millisecond delay is inserted between reading every byte when reading an array to prevent over flow and clashes.

Neither of these statements is even remotely close to true.

Depending on the version of the IDE that you are using, the Serial.flush() function does different things. Prior to 1.0, the Serial.flush() methods threw away random amounts of unread data.

The Arduino does not go into an infinite loop if the serial buffer is full, and more data arrives. That data is simply discarded.

Now, it is possible that your code does something stupid when that happens, but it is not helped by dumping random amounts of unread data.

With the release of 1.0, the purpose of the Serial.flush() function was (mistakenly, in my opinion) changed to block until the outgoing serial data buffer was (nearly) empty. It has absolutely nothing to do with incoming data any more, so flush() after every read() is useless.

Putting a delay after every read will increase the time it takes to empty the serial buffer, increasing the risk of more data arriving than can fit in the incoming buffer, increasing the risk that data will be silently redirected to the bit bucket.

That is hardly something that you application wants, is it?

  Serial.print("[S]can");     Serial.print("      ");    Serial.println(" Scans the data bus identifying any connected probes.");
  Serial.print("[C]hoose");   Serial.print("    ");      Serial.println(" Chooses a probe to calibrate.");
  Serial.print("[R]ead");     Serial.print("      ");    Serial.println(" Reads the calibration data from the probe.");
  Serial.print("[W]rite");    Serial.print("     ");     Serial.println(" Writes calibration data to the probe.");
  Serial.print("[V]iew");     Serial.print("      ");    Serial.println(" Shows the selected probe address.");
  Serial.print("[F]ormat");   Serial.print("    ");      Serial.println(" Formats the selected probe.");  
  Serial.print("[O]ptions");  Serial.print("   ");       Serial.println(" Displays the available options.");

21 statements where 7 would have sufficed. I don't get it.

I think you really need a PC application that deals with the user interface, and a much smaller Arduino sketch that simply responds to commands sent, via the serial port, to it.

Perhaps I worded that incorrectly... I will have to look at that Serial.flush() problem as it was the only way to get the program to work... I actually had to run a flush BEFORE every read not after to get it to work... but perhaps it is temporary so I will need to take a closer look at that.

as for the 10µseconds what I meant was that when I input a 10 byte long string and want to put it in a buffer I had to insert 10 µseconds between each Serial.read() other wise it would read 10 strings that were 1 byte long instead of 1 string with 10 bytes.

at the moment I am disecting the program and just trying to run it piece by piece. I got rid 512 bytes of memory by taking advantage of a function in the OneWire library that I was not aware of. So now the program runs everything correctly as long as I do not have the Writing functions in the program. Now it seems that I need to go through the Write functions and see where I can lower my memory usage.

as for the 10µseconds what I meant was that when I input a 10 byte long string and want to put it in a buffer I had to insert 10 µseconds between each Serial.read() other wise it would read 10 strings that were 1 byte long instead of 1 string with 10 bytes.

That's not how you read replies on the forum, is it? Read a letter. Wait 10 milliseconds, and read another. Repeat for 10 characters.

No, it isn't. You read all available data until a character of interest appears, like a period. That is how written materials are parsed.

You need to make the sender send a specific end-of-packet marker. Then, read the data as fast as possible (in a blocking or non-blocking way) until the end marker arrives. Then, do something with the stored data.

Perhaps I can remedy that by looking for \n as the string needs to terminate when the enter key is pressed

Perhaps I can remedy that by looking for \n as the string needs to terminate when the enter key is pressed

What application is reading the serial data on the PC? If it is the Serial Monitor, then there are options for what to append to the data entered. If it is some other application, the carriage return may be the trigger to send the data, but may not actually be sent.

at the moment it is the normal serial monitor however I am hoping to be able to modify this later to integrate with LabVIEW (in which case I will have the computer take care of all the UI as you suggested and allow the arduino to just do the work).

The thing is that I need to show the client that this works and is all good (which I can just do with the mega no problems) but I am a bit stubborn when it comes to figuring out why something is not working instead of just switching to another more powerful module (if it is not needed).

Well I finally got it working… You were right from the begining Paul about the memory and F() macro… I just put F() around every Serial.print and got rid of a 512KB buffer and instead made it a recursive 32KB buffer and now everything runs as it should.

Lesson learned. Many thanks!