Low memory

I know this could be a stupid question but just need to make sure, I have a sketch that complies ok and seem to run ok but only tried for short duration but I have this displayed in the window at the bottom

Sketch uses 28,804 bytes (89%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,906 bytes (93%) of dynamic memory, leaving 142 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

I understand that most of the variables/memory has been sued Would this have any adverse effect in long term operation ?
Or would I need to use a Mega instead ?

Thanks
Steve

I'd look at 1284P or 2560 to get some SRAM margin.

The number shown counts all memory used by global variables - but not local variables, or dynamically allocated stuff (String, and anything using malloc()) - those have to fit in the remaining memory.

If your program doesn't use dynamic memory allocation, and doesn't use so many local variables, nested function calls, etc that the stack would need more memory than it has left, you'll be fine. Otherwise, weird (bad) stuff can happen when it tries to use memory and there isn't any left.

If you use String (capitol S) class, you'll have memory problems with so little memory. Beyond that, it could go either way depending on the code.

Faced with that warning message, I would look over the code to see if there were any places to save some ram (Are you printing string constants without using F(), etc)

I'm using these includes as it's a data logger that writes to SD card and displays the data on a LCD and storing some variables in the EEPROM

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <EEPROMex.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

This is part of the setup

setSyncProvider(RTC.get);   // the function to get the time from the RTC
  lcd.setCursor(0, 0);
  if (timeStatus() != timeSet)
  lcd.print("Unable to sync with the RTC");
  else
  lcd.print("RTC has set the system time");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Initializing SD card...");
  pinMode(CS_pin, OUTPUT);
  // see if the card is present and can be initialized:
  if (!SD.begin(CS_pin)) {
    lcd.setCursor(0, 1);
    lcd.print("Card failed, or not present");
    while (1); //return;
  }
  lcd.print("card initialized.");
  //char filename[16]; // make it long enough to hold your longest file name, plus a null terminator
  snprintf(filename, sizeof(filename), "data%03d.txt", n); // includes a three-digit sequence number in the file name
  while (SD.exists(filename)) {
    n++;
    snprintf(filename, sizeof(filename), "data%03d.txt", n);
  }
  File dataFile = SD.open(filename, FILE_READ);
  dataFile.close();
  //now filename[] contains the name of a file that doesn't exist
  //Write Log File Header
  //Write Log File Header
  dataFile = SD.open(filename, FILE_WRITE);
  String header = " LOGGER,Time,Volts1(Volts),Amps(Amps),Serial Number";
  dataFile.print(n);
  dataFile.println(header);
  read_data();
  delay(100);
   Vresults3 = Vresults0 / (R2 / (volts_scale + R2)); /// This will be removed and replaced only for testing
  Vresults4 = Vresults1 * amps_scale ; //this is wrong 3.75V shows 37.52amps *100 shows 375.2amps
  char timeStamp[26];
  sprintf(timeStamp, "%2d,%02d/%02d/20%02d %02d:%02d:%02d,",
  CS, day(), month(), (year() - 2000), hour(), minute(), second());
  dataFile.print(timeStamp);
  dataFile.print(Vresults3);
  dataFile.print(",");
  dataFile.print(Vresults4);
  dataFile.println(",020002287");
  dataFile.close();
  CS = 2;
  //Read the Configuration information (COMMANDS.txt)
  File commandFile = SD.open("COMMANDS.txt");
  if (commandFile)
  {
    unsigned long decade = pow(10, (commandFile.available() - 1));
    while (commandFile.available())
    {
      unsigned long temp = (commandFile.read() - '0');
      refresh_rate = temp * decade + refresh_rate;
      decade = decade / 10;
    }
  }
  else
  {
    lcd.setCursor(0, 3);
    lcd.print("Could not read command file.");
    return;
  }
  lcd.clear();
}

I think you meant

  lcd.print(F("Unable to sync with the RTC"));

etc, etc.

Steveiboy, It would surprise me, if the Arduino worked at all. You have too little ram left (dynamic memory).

You gave us two pieces of code. There is a website for that : http://snippets-r-us.com/

AWOL is telling you that there is a way to reduce the amount of ram usage with the 'F()' macro. If you do that for every Serial.print and Serial.println and lcd.print and lcd.println you might have enough memory.

Meanwhile, order a Mega. You have already many libraries, and you probably want to add something in the future.

sprintf(timeStamp, "%2d,%02d/%02d/20%02d %02d:%02d:%02d,",

"sprintf_P" etc.

AWOL:

sprintf(timeStamp, "%2d,%02d/%02d/20%02d %02d:%02d:%02d,",

"sprintf_P" etc.

I don't see any reason to use a buffer OR any variation of sprintf to write the date and time to the file.

We do.

Steveiboy uses this: sprintf(timeStamp, "%2d,%02d/%02d/20%02d %02d:%02d:%02d,", CS, day(), month(), (year() - 2000), hour(), minute(), second());

Can that be changed to use less ram memory ? AWOL says yes.

sprintf_P(timeStamp, PSTR("%2d,%02d/%02d/20%02d %02d:%02d:%02d,"), CS, day(), month(), (year() - 2000), hour(), minute(), second());

Tutorial : Gammon Forum : Electronics : Microprocessors : Putting constant data into program memory (PROGMEM)

Am I translating between Arduino users now ? Call me when the aliens have landed.

No, PaulS is quite correct, sprintf (and variants) isn't absolutely necessary (though some of nicer formats like leading zeroes or fixed-width fields are more fiddly without it), but since the OP already has it, I thought I'd point-out some more RAM savings.

AWOL:
...though some of nicer formats like leading zeroes or fixed-width fields are more fiddly without it....

Formatted output isn't a reason to use sprintf or its variant? I think, yes.

sprintf or not, this is just plain silly:

sprintf(timeStamp, "%2d,%02d/%02d/[color=red]20%02d[/color] %02d:%02d:%02d,",
  CS, day(), month(), [color=red](year() - 2000)[/color], hour(), minute(), second());

Formatted output isn't a reason to use sprintf or its variant? I think, yes.

Sometimes, yes. But printing a 1 or 2 digit value as a 2 digit string, so you can avoid an if statement and possibly two calls to print() is not one of the times where sprintf() is worth the overhead.

Thanks Guys
I've made the alterations and now get this

Sketch uses 28,920 bytes (89%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,514 bytes (73%) of dynamic memory, leaving 534 bytes for local variables. Maximum is 2,048 bytes.

Yes I could just use a Meaga256 but would be waist of one, This project will be in place for about a year or 2 and was hoping to use the Uno has I have many of these and would not miss it, I will still go through seeing what I could cut down on.

Once again thanks for the inputs guys

534 bytes available is still scary, because you use many libraries, and I don't know if they allocate buffers or create new classes. Maybe even the String object is used somewhere.

Don't be scared, 534B is quarter of memory, but all the time is there room for improvement, I bet.
:slight_smile: