Pages: [1] 2   Go Down
Author Topic: Memory issue?  (Read 1646 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

as an exercise I've written a sketch to take ascii data in on the serial port on an Arduino Uno and convert it to Morse code.  I'm finding that if I comment out some of the code in a routine producing help text it works, if not commented out, it does not.  The code is here:

http://petezilla.webdev.fire/public/embedded/arduino/morse

(too long to sensibly post in the forum).

The block of code I've commended out runs from lines 256 - 278.

I'm wondering if the micro-controller is running out of memory?  I've produced the sketch with no particular regard for memory useage.  However, the code resides in program memory, not SRAM, so I'm not certain it is a SRAM issue.

Thoughts?

Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Link is broken/incomplete
Logged

Per Arduino ad Astra

Netherlands
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you in the default arduino environment programming?
If so, you can see in the bottom of the screen how large your sketch is and how much memory available is.

Are you dynamically allocating memory with malloc functions?
Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you have any large tables that aren't defined as being in PROGMEM, then they will use RAM.
Logged

Per Arduino ad Astra

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8531
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

To find out what RAM is being used

open a DOS window
navigate to the build folder, (to find this hold SHIFT while compiling your code). The path will be something like

C:\Users\<yourname>\AppData\Local\Temp\build3014820664802798593.tmp

run

avr-size <yourprogname>.cpp.elf

You'll get a result like this

   text    data     bss     dec     hex filename
   1010       0       9    1019     3fb <yourprogname>.cpp.elf

If data and bss add up to anything like maybe 1800 (hard to tell what, it depends on the program) you're in trouble

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Link is broken/incomplete

Sorry, I'm an idiot, that link was to the off-line (dev) version of my website.  Correct link is:

http://www.petezilla.co.uk/public/embedded/arduino/morse

Specifically:

http://www.petezilla.co.uk/public/embedded/arduino/morse/morse7.pde
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8531
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

With the code commented out

 text    data     bss     dec     hex filename
 9656     760     201   10617    2979 blink.cpp.elf

with code included

 text    data     bss     dec     hex filename
 9860    1550     201   11611    2d5b blink.cpp.elf

That's 1751 bytes of RAM used not counting the stack. It's getting in the dodgy area.

Try just removing a few lines to see if that fixes the probem.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you have any large tables that aren't defined as being in PROGMEM, then they will use RAM.

I have used a number of strings, using the string object.   They are not especially large, but on the other hand there is not a lot of SRAM.  The code I comment out to make things work is in the serial routines, with fixed strings.

Given that my variables are altered during the course of running the program it would not be a good idea to use PROGMEM I would have thought.   I wonder however whether putting the help information below into a variable stored in program memory might help.  Another solution, probably the best, would be to put it into the EEPROM.  However, I'm not sure if there is a way that data could be included in the sketch.  I assume I'd have to upload it separately.  

However, I'm assuming it is a memory issue - am I right?

Routine below:

Code:
void help() {
  Serial.println("~");
  Serial.println("~USB ASCII to Morse converter.");
  Serial.println("~");
  Serial.println("~Help:");
  Serial.println("~ ##H: Print help (upper case H).");
  Serial.println("~ ##1: Rate 5 words per minute");
  Serial.println("~ ##2: Rate 10 words per minute");
  Serial.println("~ ##3: Rate 15 words per minute");
  Serial.println("~ ##4: Rate 20 words per minute");
  Serial.println("~ ##5: Rate 40 words per minute");
  
  
  /*
  If the following is not commented out then the arduino produces no
  output.
  */
  
  /*
  Serial.println("~");
  Serial.println("~Add # to the end of a line to repeat message.");
  Serial.println("~A # before any letter omits spaces to they can be run-");
  Serial.println("~together to generate prosigns, e.g. #CT (start of message).");
  Serial.println("~Carriage return (13) causes message to be transmitted.");
  Serial.println("~");
  Serial.println("~Commands and Messages:");
  Serial.println("~Lines beginning in tilde ~ are information");
  Serial.println("~Prompt for user input is >");
  Serial.println("~Messages:");
  Serial.println("~    <Ready    =    Awaiting commands or data.");
  Serial.println("~    <Sending  =    Sending morse.");
  Serial.println("~    <Wait     =    Please do not send data, buffers near full.");
  Serial.println("~    <Overrun  =    Too much information in buffers.  Contents ");
  Serial.println("~                   deleted without being sent.  Send data again");
  Serial.println("~                   in smaller chunks.");
  Serial.println("~");
  Serial.println("~Basic idea is you send data, when a <Wait is received then");
  Serial.println("~continue passing current word then hit return to send chunk");
  Serial.println("~before sending more data.");
  Serial.println("");
  */
  
  
}
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

With the code commented out

 text    data     bss     dec     hex filename
 9656     760     201   10617    2979 blink.cpp.elf

with code included

 text    data     bss     dec     hex filename
 9860    1550     201   11611    2d5b blink.cpp.elf

That's 1751 bytes of RAM used not counting the stack. It's getting in the dodgy area.

Try just removing a few lines to see if that fixes the probem.

______
Rob


Interesting, with the help commented out as below I can send 10 characters but with 20 it hangs.  I suspect that this is it running out of memory - perhaps a buffer over-run type problem, not that I have a fixed length buffer, but I do have finite ram.

Code:
void help() {
  Serial.println("~");
  Serial.println("~USB ASCII to Morse converter.");
  Serial.println("~");
  Serial.println("~Help:");
  Serial.println("~ ##H: Print help (upper case H).");
  Serial.println("~ ##1: Rate 5 words per minute");
  Serial.println("~ ##2: Rate 10 words per minute");
  Serial.println("~ ##3: Rate 15 words per minute");
  Serial.println("~ ##4: Rate 20 words per minute");
  Serial.println("~ ##5: Rate 40 words per minute");
 
 
  /*
  If the following is not commented out then the arduino produces no
  output.
  */
 
 
  Serial.println("~");
  Serial.println("~Add # to the end of a line to repeat message.");
  Serial.println("~A # before any letter omits spaces to they can be run-");
  Serial.println("~together to generate prosigns, e.g. #CT (start of message).");
  Serial.println("~Carriage return (13) causes message to be transmitted.");
  Serial.println("~");
  Serial.println("~Commands and Messages:");
  Serial.println("~Lines beginning in tilde ~ are information");
  Serial.println("~Prompt for user input is >");
 
  /*
 
  Serial.println("~Messages:");
  Serial.println("~    <Ready    =    Awaiting commands or data.");
  Serial.println("~    <Sending  =    Sending morse.");
  Serial.println("~    <Wait     =    Please do not send data, buffers near full.");
  Serial.println("~    <Overrun  =    Too much information in buffers.  Contents ");
  Serial.println("~                   deleted without being sent.  Send data again");
  Serial.println("~                   in smaller chunks.");
 
 
 
  Serial.println("~");
  Serial.println("~Basic idea is you send data, when a <Wait is received then");
  Serial.println("~continue passing current word then hit return to send chunk");
  Serial.println("~before sending more data.");
  Serial.println("");
  */
 
 
}
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If so, you can see in the bottom of the screen how large your sketch is and how much memory available is.

This is not the case.  This message is the amount of Flash (or program) storage being used and what is left.  It has nothing to do with the RAM at Runtime.

It is entirely possible to have a sketch that takes up 15k of Flash/Program Memory and only use a couple hundred bytes of RAM. 
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 303
Posts: 26354
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All those Serial.print strings are wasting RAM - move them to PROGMEM.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All those Serial.print strings are wasting RAM - move them to PROGMEM.

You mean something  like the string demo in:

http://www.arduino.cc/en/Reference/PROGMEM

From what you are suggesting then, if I have a line:

Serial.println("Hello world!");

then the complied program puts "Hello world!" in RAM, uses it and does not release it?  Just curious.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 303
Posts: 26354
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
then the complied program puts "Hello world!" in RAM, uses it and does not release it? 
How could it "release it"?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
then the complied program puts "Hello world!" in RAM, uses it and does not release it? 
How could it "release it"?

Perhaps a bad choice of words.  However, the implication that my many Serial.println command consume RAM implies that those RAM locations are not reused. I.e.

Say "Hello World" is written to memory locations say 100-110 (decimal).  These are now output to serial.
Now I want to send to the serial port "Hello  world again" that implies that instead of writing from program memory to RAM "Hello World Again" in memory locations say 100-116 that it is writing them in locations 111-127.  100-110 is not being re-used.  Seems odd to me.

Pete
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It would stand to reason that the complier would only store one copy of a constant, but I do not know if this is the case.  In your code each of your string constants are different.

The complier does not know how many times a constant (string or otherwise) will be used (what if there was a loop?), so the constant has to be stored in RAM at all times.

By moving the (string) constants into PROGMEM, you never actually copy the constant into RAM.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Pages: [1] 2   Go Up
Jump to: