Go Down

Topic: Running out of memory (Read 190 times) previous topic - next topic

1040tax

Jun 25, 2020, 06:02 pm Last Edit: Jun 25, 2020, 06:55 pm by 1040tax
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:


Code: [Select]
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

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

to

Code: [Select]
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
Code: [Select]
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.


pcbbc

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.

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

blh64

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
Code: [Select]

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

1040tax

#3
Jun 25, 2020, 06:54 pm Last Edit: Jun 25, 2020, 07:19 pm by 1040tax
Code: [Select]
const char *  hebMonthName[] PROGMEM  = {mo0,mo1,mo2,mo3,mo4,mo5,mo6,mo7,mo8,mo9,mo10,mo11,mo12,mo13};
 gives an error

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


Code: [Select]
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
Code: [Select]
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!

david_2018

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

david_2018

#5
Jun 26, 2020, 03:33 am Last Edit: Jun 26, 2020, 03:37 am by david_2018
In reference to my previous post, you might want to try this and eliminate the buffer.
Code: [Select]

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.

1040tax

Thanks David. Good pointer about the buffer size.

Go Up