Out of memory?

Folks,

Newbie here. Running a knock-off Nano. The sketch is about 600 lines long is nothing complex. It's just a clock that displays a happy birthday message on days where there are birthdays. When trying to compile I get an error that I'm out of memory. I wanted to be able to add more folks.

Below is the tail end of the error message.

Sketch uses 11876 bytes (38%) of program storage space. Maximum is 30720 bytes.

Global variables use 2065 bytes (100%) of dynamic memory, leaving -17 bytes for local variables. Maximum is 2048 bytes.data section exceeds available space in board

Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.

Error compiling for board Arduino Nano.

I know my code could use a more sophisticated approach to checking if the day happens to be a birthday. Below is a segment of the code and what I'm doing. Again, I'm new to coding.

#include <Wire.h>                                 // include wire library
#include <RTClib.h>                               // RTC
#include <LiquidCrystal_I2C.h>                    // for LCD
#include "DHT_U.h"
#define Type DHT22

LiquidCrystal_I2C lcd(0x27, 20, 4);               // create LCD, address is 0x27
RTC_DS3231 rtc;                                   // create rtc, address is 0x68

const int sensePin=7;
DHT DHTT(sensePin, Type);

float humidity;
float tempC;
float tempF;

// 0=Sunday, 1=Monday,...6=Saturday
const char dayInWords[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};    

// 0=" ", 1=Jan, 2=Feb, ... 12=Dec
const char monthInWords[13][4] = {" ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", 
                                         "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};

//byte heart[8] = {
//  0b00000,
//  0b01010,
//  0b11111,
//  0b11111,
//  0b11111,
//  0b01110,
//  0b00100,
//  0b00000
//};
//

                                         
void setup()
{
  Serial.begin(9600);                             // start serial monitor for debugging if needed

  lcd.init();                                     // initialize LCD
  lcd.backlight();                                // turn on LCD backlight
    
  rtc.begin();                                    // initialize RTC

  DHTT.begin();

//  lcd.createChar(0, heart);

} //END of setup()


void loop()
{

//  lcd.write(byte(0));                           
  
  
  DateTime rtcTime = rtc.now();                   // get time

  int ss = rtcTime.second();                      // save seconds
  int mm = rtcTime.minute();                      // save minutes
  int hh = rtcTime.twelveHour();                  // etc.
  int DD = rtcTime.dayOfTheWeek();
  int dd = rtcTime.day();
  int MM = rtcTime.month();
  int yyyy = rtcTime.year();                      // save year

  lcd.setCursor(0,0);                             // Set cursor to top left position

  lcd.print(monthInWords[MM]);                    // print date in MMM-dd-yyyy format
  lcd.print("-");                                 // print "-" for formating
  if (dd<10) lcd.print ("0");                     // add 0 before hour if less than 10
  lcd.print(dd);                                  // print day
  lcd.print("-");                                 // print "-" for formatting
  lcd.print(yyyy);                                // print year
  lcd.print("  ");                                // print space for formatting
  lcd.print(dayInWords[DD]);                       // print day in DDD format
  
  lcd.setCursor(0,1);                             // set cursor at beginning of next row

  if (hh<10) lcd.print("0");                      // add 0 before hour if less than 10
  lcd.print(hh);                                  // print hour
  lcd.print(":");                                 // add ":" for formatting
  if (mm<10) lcd.print("0");                      // add 0 before minite if less than 10
  lcd.print(mm);                                  // print minutes
  lcd.print(":");                                 // add ":" for formatting
  if (ss<10) lcd.print("0");                      // add 0 before seconds if less than 10
  lcd.print(ss);                                  // print seconds
  if (rtcTime.isPM()) lcd.print(" PM");           // print PM if PM
  else lcd.print (" AM");                         // else print AM
  
  humidity = DHTT.readHumidity();
  tempC = DHTT.readTemperature();
  tempF = DHTT.readTemperature(true);

  
  if (MM == 1 && dd == 4) {
    lcd.setCursor(0,2);
    lcd.print("Happy Birthday      ");
    lcd.setCursor(0,3);
    lcd.print("Chris H.            ");
  }


  else if (MM == 1 && dd == 7) {
    lcd.setCursor(0,2);
    lcd.print("RIP                 ");
    lcd.setCursor(0,3);
    lcd.print("Ann W.              ");
  }

  else if (MM == 1 && dd == 10) {
    lcd.setCursor(0,2);
    lcd.print("Happy Birthday      ");
    lcd.setCursor(0,3);
    lcd.print("Jim B.              ");
  }


  else if (MM == 1 && dd == 27) {
    lcd.setCursor(0,2);
    lcd.print("Happy Birthday      ");
    lcd.setCursor(0,3);
    lcd.print("William B.          ");
  }


  else if (MM == 2 && dd == 2) {
    lcd.setCursor(0,2);
    lcd.print("Happy Birthday      ");
    lcd.setCursor(0,3);
    lcd.print("Al C.               ");
  }


  else if (MM == 2 && dd == 7) {
    lcd.setCursor(0,2);
    lcd.print("Happy Birthday      ");
    lcd.setCursor(0,3);
    lcd.print("Nick P.             ");
  }

I'm looking for options people. Is my code a big bloated mess? Would some sort of array work better? But again, I'm kinda new to all if this. How about hardware? Does an UNO have more memory? How about a mega?

Thank you.

Best,

Tony

Try out the F macro : lcd.print(F("your string here")); to display your fixed data. This moves the strings to flash memory, which there's a lot more of.

change lines like :

lcd.print("Happy Birthday ");

to 

lcd.print(F("Happy Birthday "));

Would some sort of array work better?

Correct me if I am wrong, but hasn't this already been discussed in your previous threads? Whenever you see repetition like that, it's time for arrays. In this case, arrays of structs. However, since you would want to place those structs in flash, it's not going to be a straightforward matter for a beginner.

If you have 99 places where you print the same thing, "Happy Birthday", you can create a constant string once and reference it 99 times. That way, it will only appear once in memory.

const char* birthdayGreeting = "Happy Birthday ";
...
lcd.print(birthdayGreeting);
...
lcd.print(birthdayGreeting);
...

It's a little bit "Addams Family", but you could assign a boolean to select between greetings and "RIP" depending on whether the person is alive or dead. :confused:

char* toTribute(bool isAlive)
{
const char* greet = "Happy Birthday ";
const char* flowers = "RIP ";
if (isAlive) return greet;
else return flowers;
}
...
lcd.print(toTribute(true));
...

You can get fancier and define constants LIVING and DEAD for true and false, using an enum or #define macros.

Also, it appears to me at a sideways glance at your code, that when it is someones birthday, the LCD will be updated millions of times, rather than just once. That can cause screen flicker.

And ... the Nano Every has more memory if you are still stuck , and is pin compatible

Or you could put your data on an SD card. That would also make it much easier to edit or add people to the database.

Thanks everyone. Changing the code helped a surprising amount.

@aarg I think you might be right about me asking about an array in the past. I still haven't gotten to learning more about them, obviously. I also want to experiment with SD cards. So that might be a nice feature to work on as I finish the clock.

@hammy Thanks for the tip. At some point I will likely something like an Every.

@missdrew The code changes worked.

@dougp The code changes worked.

Thank you everyone!

Best,

Tony

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.