Running out of memory

I have an Arduino Nano connected to a RTC and a 0.96" OLED module. I have written a program to convert the date into the Hebrew (lunar-solar) date using Gauss’s Passover formula and calculate the time of sunset (necessary as the Hebrew date changes at nightfall (here defined as 72 minutes after sunset) using the Dusk2Dawn library, which is a port from NOAA’s Solar Calculator.

It also displays a couple of other times which are relevant in Jewish Law.

The problem is that Hebrew dates are generally expressed in Hebrew letters rather than numbers, so I needed to use strings to convert. This has caused me to (I think) run out of memory, as when I comment out either of these two lines:

 u8g2_for_adafruit_gfx.print(hebMonthName[hebMonth - 1]);
  u8g2_for_adafruit_gfx.print(hebDateName[hebDate - 1]);

the code runs perfectly. So I can show either the month, or the date, but not both. If both lines are included, the code appears to upload, but then doesn’t run at all.

I have tried changing

char *  hebMonthName[]  = {" ןסינ ", " רייא ", " ןויס ", " זומת ", " בא " , " לולא ", " ירשת ", " ןושח ", " ולסכ ", " תבט ", " טבש ", " רדא ", " 'א רדא ", " 'ב רדא "};

to

const char mo0[] PROGMEM = " ןסינ ";
const char mo1[] PROGMEM = " רייא ";
const char mo2[] PROGMEM = " ןויס ";
const char mo3[] PROGMEM = " זומת ";
const char mo4[] PROGMEM = " בא ";
const char mo5[] PROGMEM = " לולא ";
const char mo6[] PROGMEM = " ירשת ";
const char mo7[] PROGMEM = " ןושח ";
const char mo8[] PROGMEM = " ולסכ ";
const char mo9[] PROGMEM = " תבט ";
const char mo10[] PROGMEM = " טבש ";
const char mo11[] PROGMEM = " רדא ";
const char mo12[] PROGMEM = " 'א רדא ";
const char mo13[] PROGMEM = " 'ב רדא ";

 const char *  hebMonthName[]  = {mo0,mo1,mo2,mo3,mo4,mo5,mo6,mo7,mo8,mo9,mo10,mo11,mo12,mo13};
 char buffer [9];

and in the loop

 for (int i = 0; i < 14; i++) {
   strcpy_P(buffer, (char *)pgm_read_word(&(hebMonthName[i])));   
 u8g2_for_adafruit_gfx.print(buffer);}

but it just caused the OLED to flash continuously and didn’t show the month at all. Any suggestions? I am somewhat limited in the OLED library I can use as very few contain Hebrew fonts. Using a Mega wouldn’t work, as I need the small size of the Nano.

Complete code attached, as otherwise I’d be over the 9,000 character limit.

hebrewOlcd.ino (9.96 KB)

mon0 through mo13 are being placed in PROGMEM.
The array of pointers to those strings, const char * hebMonthName, is NOT.
Look to me like that requires a PROGMEM as well.

const char *  hebMonthName[] PROGMEM  = {mo0,mo1,mo2,mo3,mo4,mo5,mo6,mo7,mo8,mo9,mo10,mo11,mo12,mo13};

As pcbbc points out, your array is not in program memory but you are accessing PROGMEM when you try to copy.
You have two choices:

  1. use reply#1 and put everything in PROGMEM and it will work
  2. keep your array in regular memory and change how you access it
for (int i = 0; i < 14; i++) {
   strcpy_P(buffer, hebMonthName[i]);   
 u8g2_for_adafruit_gfx.print(buffer);}
const char *  hebMonthName[] PROGMEM  = {mo0,mo1,mo2,mo3,mo4,mo5,mo6,mo7,mo8,mo9,mo10,mo11,mo12,mo13};

gives an error

variable 'hebMonthName' must be const in order to be put into read-only section by means of 'attribute((progmem))'

but

const char * const hebMonthName[] PROGMEM  = {mo0,mo1,mo2,mo3,mo4,mo5,mo6,mo7,mo8,mo9,mo10,mo11,mo12,mo13};

compiles.

I also needed to change

strcpy_P(buffer, (char *)pgm_read_word(&(hebMonthName[hebMonth-1])));

as the for loop wasn't what I wanted.

Many thanks. I have now made the changes to hebDateName, and everything is working nicely!

If the u8g2 library inherits from the print class, then the strcpy and buffer are unnecessary, just cast the pointer to (__FlashStringHelper*)

In reference to my previous post, you might want to try this and eliminate the buffer.

u8g2_for_adafruit_gfx.print((__FlashStringHelper*)pgm_read_word(&(hebMonthName[hebMonth-1])));

If you do want to copy into a buffer, make sure it is large enough, unicode characters can occupy more than one byte per character.

Thanks David. Good pointer about the buffer size.