I have memory stability problem and need to free up some more memory!

I am new to Arduino and C programming. I have been getting a “Low memory available, stability problems may occur. Sketch uses 12,394 bytes and Global uses 1,913 bytes. What changes to the program lines are needed?

I am using an Ardunio Uno R3

SortingHat1.ino (5.06 KB)

Just POST the code

#include <PGMWrap.h>
#include <Brain.h>
#include <ArduinoPins.h>
#include <FatReader.h>
#include <FatStructs.h>
#include <mcpDac.h>
#include <SdInfo.h>
#include <SdReader.h>
#include <WaveHC.h>
#include <Wavemainpage.h>
#include <WavePinDefs.h>
#include <WaveUtil.h>

// Set up the brain reader, pass it the hardware serial object you want to listen on.
Brain brain(Serial);

SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the volumes root directory
FatReader file;   // This object represent the WAV file
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time
long interval = 0;
int hse = 0;

/*
   Define macro to put error messages in flash memory
*/
#define error(msg) error_P(PSTR(msg))

//////////////////////////////////// SETUP
void setup() {
  Serial.begin(9600);

  if (!card.init()) error("card.init");

  // enable optimized read - some cards may timeout
  card.partialBlockRead(true);

  if (!vol.init(card)) error("vol.init");

  if (!root.openRoot(vol)) error("openRoot");

  //playGriffin();
  //playHuffle();
  //playRaven();
  //playSlith();
  //playTnk1();
  //playTnk2();
  //playTryAgain();
}

//////////////////////////////////// LOOP
void loop() {
  brain.update();
  // Make sure we have a signal.
  int signalQual = brain.readSignalQuality();
  Serial.println(signalQual);
  if (signalQual < 50) {
    askAbouthses();
  }
}

void askAbouthses() {
  playTnk2();
  playAskGriffin();
  playAskHuffle();
  playAskRaven();
  playAskSlith();
  playTnk1();
  makeDecision();
  delay(10000);
}

void readMind(int hseIndex) {
  if (brain.update()) {
    if (hseIndex != 0) {
      int currInterval = brain.readAttention();
      if (currInterval > interval) {
        interval = currInterval;
        hse = hseIndex;
      }
    }
  }
}

void makeDecision() {
  if (hse == 1) {
    playGriffin();
  }
  else if (hse == 2) {
    playHuffle();
  }
  else if (hse == 3) {
    playRaven();
  }
  else if (hse == 4) {
    playSlith();
  }
  hse = 0;
  interval = 0;
}

/////////////////////////////////// HELPERS
/*
   print error message and halt
*/
void error_P(const char *str) {
  PgmPrint("Error: ");
  SerialPrint_P(str);
  sdErrorCheck();
  while (1);
}
/*
   print error message and halt if SD I/O error, great for debugging!
*/
void sdErrorCheck(void) {
  if (!card.errorCode()) return;
  PgmPrint("\r\nSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  PgmPrint(", ");
  Serial.println(card.errorData(), HEX);
  while (1);
}

/*
   Play the Griffin Audio Clip
*/
void playGriffin(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF0.WAV"));
  playSound(name, 4100, 0);
}

/*
   Play the Ask Griffin Audio Clip
*/
void playAskGriffin(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF7.WAV"));
  playSound(name, 4100, 1);
}

/*
   Play the Huffle Audio Clip
*/
void playHuffle(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF1.WAV"));
  playSound(name, 4100, 0);
}

/*
   Play the Ask Huffle Audio Clip
*/
void playAskHuffle(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF8.WAV"));
  playSound(name, 4100, 2);
}

/*
   Play the Raven Audio Clip
*/
void playRaven(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF2.WAV"));
  playSound(name, 1500, 0);
}

/*
   Play the Ask Raven Audio Clip
*/
void playAskRaven(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF9.WAV"));
  playSound(name, 5100, 3);
}

/*
   Play the Slith Audio Clip
*/
void playSlith(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF3.WAV"));
  playSound(name, 2100, 0);
}

/*
   Play the Ask Slith Audio Clip
*/
void playAskSlith(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF10.WAV"));
  playSound(name, 4500, 4);
}

/*
   Play the Tnk1 Audio Clip
*/
void playTnk1(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF4.WAV"));
  playSound(name, 7100, 0);
}

/*
   Play the Tnk2 Audio Clip
*/
void playTnk2(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF5.WAV"));
  playSound(name, 19100, 0);
}

/*
   Play the TryAgain Audio Clip
*/
void playTryAgain(void) {
  char name[10];
  // copy flash string to RAM
  strcpy_P(name, PSTR("DTMF6.WAV"));
  playSound(name, 10100, 0);
}

/*
   Play whatever sound file name is passed through, for the duration specified in milliseconds
*/
void playSound(char* name, int millisecs, int hseIndex) {
  // start time
  uint32_t t = millis();
  // open file by name
  if (!file.open(root, name)) error("open by name");
  // create wave and start play
  if (!wave.create(file))error("wave.create");
  wave.play();
  // stop after PLAY_TIME ms
  while ((millis() - t) < millisecs) {
    if (hseIndex != 0) {
      readMind(hseIndex);
    }
  }
  wave.stop();
  // check for play errors
  sdErrorCheck();
  PgmPrintln("Done");
}

It looks like you are using almost all of your RAM in your sketch. Combined with the bootloader your program is most likely using as much or more RAM than your Arduino actually has. I suggest reducing the RAM usage as much as possible in your sketch.

I see no flagrant wastes of ram there. I think it's the libraries doing it, and it looks like you need them....

I think you might want to consider a mega2560 or 1284p based board.

Will the 2560 accept the Adafruit Wave Shield for Arduino.

Wave shield docs say no.

Since I may not be able to use the 2560 with the wave shield, would you suggest what lines in the code I need to change and to what?

  1. Check if all ints need 16 bits, maybe uint8_t is adequate.

  2. you have a dozen functions with the same pattern, e.g

void playAskHuffle(void) {
char name[10];
// copy flash string to RAM
strcpy_P(name, PSTR("DTMF8.WAV"));
playSound(name, 4100, 2);
}

Put the WAV strings in a PROGMEM array and you can handle it with one function with the index as param.
(OK would only save some flash)
possibly just add param to playSound would work.

  1. remove some error handling ?

Thank you. To show my ignorance further I can use some help in setting up the PROGMEM array.