Did I run out of room on my array?

Hey all! I'm currently working on a fun pet project! I'm making my arduino play the "Still Alive" song while it prints the lyrics in time with the song on my 20x4 LCD.

HOWEVER, I have reached a weird bug and I think it has to do with my string array. You can download the .pde from my dropbox http://dl.dropbox.com/u/12652859/StillAlive/StillAlive2/StillAlive2.pde. I've commented some of the code for my debugging and this is where I get stuck. My LCD prints "But there's no" and it stops printing, but the audio continues.

Any idea what's going on? I'm wondering if my string lyrics[] needs to have the element size declared or something ...

More then likely. You didn't state which board you are using. Th Uno has 2k of SRAM to hold all those arrays and that is probably your problem. The most frequent fix is to force those arrays and strings to be stored into FLASH memory which the Uno has 32K (- bootloader space) using the appropriate commands.

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

An alternative is to use an EEPROM. It's pretty easy to use, and consumes minimal processor resources, unlike sd cards.

You are correct, I am using an arduino with an atmega (the 32k one) which is why I was confused since the sketch says it’s using .8k so can anyone point me to some tutorials so I may get this project done :wink:

Question about Progmem…
Since I have a lot of strings for my song lyrics… do I seriously need to include EACH ONE as it’s own array?
From the progmem example/tutorial

#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0";   // "String 0" etc are strings to store - change to suit.
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";

I have over 100 strings already and this would take a long time (and a lot of space in my code) to implement. Am I missing something or do I seriously have to approach my code this way?

The answer was yes, it's going to be a pain, but I already implemented it and it worked great, plenty of room for my strings on the bootloader section and more room in the SRAM for all my other bytes :) Thanks for everyone's help.

plenty of room for my strings on the bootloader section

How did you do that?

AWOL:

plenty of room for my strings on the bootloader section

How did you do that?

On an ATMEGA 328P there is 32kb of bootloader space (the place where your sketches go). As retrolefty mentioned before, using the PROGMEM you can store data that’s more long term in the bootloader. When I finally finish my project I’m going to post the code and you can take a look then to see how I implemented it.

Hint: It’s not pretty

I think you've misunderstood the term "bootloader". The [u]program memory[/u] is 32kB, but the bootloader section is much smaller, and protected, to prevent people writing over the bootloader.

AWOL: I think you've misunderstood the term "bootloader". The [u]program memory[/u] is 32kB, but the bootloader section is much smaller, and protected, to prevent people writing over the bootloader.

Sorry I was just regurgitating what retrolefty said and I realize now that the PROGMEM stores the data on the Flash (where the bootloader also resides) however the two never interact. It's being stored next to the bootloader but not with the bootloader.

Sorry I was just regurgitating what retrolefty said

the Uno has 32K (- bootloader space)

That's a "minus" sign in there.

lol this is just silly now. We’re arguing semantics.

AWOL: I think you've misunderstood the term "bootloader". The [u]program memory[/u] is 32kB, but the bootloader section is much smaller, and protected, to prevent people writing over the bootloader.

He probably missed my - sign when I told him the program space was 32k (-bootloader space), meaning 32k minus the space taken up by the bootloader, which varies these days depending on if Uno or older board. I could have been a little clearer.

Lefty

lol this is just silly now. We're arguing semantics.

What else is software, but semantics?

No lefty, it was my fault, I misunderstood what you said. It was already clear enough.

and lol AWOL yes I suppose that's true.

How long, in characters is your song's lyric?

liudr: How long, in characters is your song's lyric?

It's hard to say since I'm using over 200 hundred strings (I'm halfway through the song) and each string on average has 3 to 5 characters in it.

So you split the song into small pieces, play one piece at a time? That could explain the 200 arrays. Can you store everything, with comma as separators? You can then read a piece at a time.

This is what I used to do before I ran out of room

String lyrics[] = {
  "This ", "was ", "a ", "tri", "umph.", "", "", "", "", "", 
  "I'm ", "mak", "ing ", "a",
  "note ", "here,", "",
  "HUGE ", "SUC", "CESS!", "", "", "", "",

The reason I'm taking this approach rather than entire strings for each string is quite simple really. I want the words and the sound from the speaker to happen at the same time, meaning the screen is printing words at the same time/rate as the song is making music. However as I mentioned before, I ran out of room quite quickly. So now I need to use PROGMEM and it's a pain to implement in my situation.

char s_1[] PROGMEM = "This ";
char s_2[] PROGMEM = "was ";
char s_3[] PROGMEM = "a ";
char s_4[] PROGMEM = "tri";
char s_5[] PROGMEM = "umph.";
char s_6[] PROGMEM =  "";
char s_7[] PROGMEM = "";
char s_8[] PROGMEM = "";
char s_9[] PROGMEM = "";
char s_10[] PROGMEM = ""; 
char s_11[] PROGMEM = "I'm ";
char s_12[] PROGMEM = "mak";
char s_13[] PROGMEM = "ing ";
char s_14[] PROGMEM = "a";
char s_15[] PROGMEM = "note ";
char s_16[] PROGMEM = "here,";
char s_17[] PROGMEM = "";
char s_18[] PROGMEM = "HUGE "; 
char s_19[] PROGMEM = "SUC"; 
char s_20[] PROGMEM = "CESS!"; 
char s_21[] PROGMEM = "";
char s_22[] PROGMEM = "";
char s_23[] PROGMEM = "";
char s_24[] PROGMEM = "";

AND

PROGMEM const char *lyrics[] = {
 s_1, s_2, s_3, s_4, s_5, s_6, s_7, s_8, s_9, s_10, 
  s_11, s_12, s_13, s_14,
  s_15, s_16, s_17,
  s_18, s_19, s_20, s_21, s_22, s_23, s_24,

all for the same effect as the first code.

Can you do this instead?

PROGMEM char lyric[]="This;was;a;tri;umph.;;;;;;I'm ;mak;ing ;a";

Then define a pointer to the string so when you copy, take note what character you copy and stop at a ";".