My sketch stopped working when my ATmega328 ran out of memory for variables. So I'm looking for alternatives to storing some of the data.
One big single chunk of memory is consumed by the following code:
struct soundhdr {
char riff[4]; /* "RIFF" */
long flength; /* file length in bytes */
char wave[4]; /* "WAVE" */
char fmt[4]; /* "fmt " */
long block_size; /* size of FMT chunk in bytes (usually 16) */
short format_tag; /* 1=PCM, 257=Mu-Law, 258=A-Law, 259=ADPCM */
short num_chans; /* 1=mono, 2=stereo */
long srate; /* Sampling rate in samples per second */
long bytes_per_sec; /* bytes per second = srate*bytes_per_samp */
short bytes_per_samp; /* 2=16-bit mono, 4=16-bit stereo */
short bits_per_samp; /* Number of bits per sample */
char data[4]; /* "data" */
long dlength; /* data length in bytes (filelength - 44) */
} wavheader;
void setup()
{
strncpy(wavheader.riff,"RIFF",4);
wavheader.flength = 10000000; // file length in bytes
strncpy(wavheader.wave,"WAVE",4);
strncpy(wavheader.fmt,"fmt ",4);
wavheader.block_size = 16; // Size of above header
wavheader.format_tag = 1; // PCM
wavheader.num_chans = 1; // channels 1=mono, 2=stereo
wavheader.srate = 19500; // Sampling rate in samples per second
wavheader.bytes_per_sec = 19500; // bytes per second = srate*bytes_per_samp
wavheader.bytes_per_samp = 1; // 2=16-bit mono, 4=16-bit stereo
wavheader.bits_per_samp = 8; // Number of bits per sample
strncpy(wavheader.data,"data",4); // "data"
wavheader.dlength = 10000000; // data length in bytes (filelength - 44)
}
(1) I suspect that the wavheader struct itself, AND the setup() lines that fill it with data, BOTH take up about 45 bytes of SRAM memory, thus consuming over 90 bytes of SRAM total? (Or perhaps the lines in setup() are totally in program Flash memory, which isn't as bad.)
(2) This structure is really a constant, not a variable, in that it never changes. It is used as the "header" in creating new .WAV audio files. So I believe there should be a way to store it as one complete 45-byte object, instead of first creating the structure, and then adding the lines of code that fill that structure. Storing as a completed structure should cut memory used in half.
(3) Storing it as part of the program with "PROGMEM" wouldn't be bad, except that requires adding the library
#include <avr/pgmspace.h>
And special functions to store this structure and read it back. All of which sounds like using more memory than I would be saving.
(4) And then there's EEPROM memory, which sounds like maybe the best idea. I've got 1024 bytes of that just waiting to be put to a good use.
So really, I have three questions about all the above:
- What is the best place to store large 'constants' like this?
- How do I make this structure a completed constant I can store, instead of it being an empty structure I reload with data each time?
- How do I place this loaded structure into permanent memory, and retrieve it when needed for new file creation?
Tommy