0

I am successful putting and retrieving char array into Arduino flash memory using PROGMEM char arrays.

I am building my app using header files with class definition / implementation and would like to keep the strings in same header file.

If I define another PROGMEM char array neither one can be executed. In other words - these PROGMEM are global arrays as far as Arduino compiler is concerned, they compile but won't show up.

Here is my test code

  lcd.clear();
  lcd.print(*strFlashDebug[0]);  // in CDebug 
  lcd.setCursor(0,1);
  lcd.print(*strFlashTrack[0]);  // in CTrack

If I put both definitions in same header file it only works with only one lcd.print enabled, not commented out.

It appears that multiple PROGMEM arrays can be defined and compiled but only one is actually usable. Any comments are appreciated. Cheers Vaclav

1
  • Please post your array definitions as well, or better even, a complete compilable example with just enough code to illustrate the issue.
    – user2973
    Dec 20 '14 at 12:02
2

The important thing to know for PROGMEM is that the AVR chip you’re using does not have a single flat address space. I.e., it does not use a von Neumann architecture; instead, it uses a specific version of what is known as a Harvard architecture: it has separate address spaces for RAM, program memory, and EEPROM. All of them start at 0. Which means that while dereferencing a nullptr is technically still undefined behavior in C++, it can be (and often is) perfectly valid in Arduino code.

The short version is: If you have a PROGMEM pointer, whatever function you pass it to must work on PROGMEM pointers. lcd.print does not, and afaict there is no way the function could possibly detect this is not a RAM pointer. You have to call a different function, assuming there is one in the first place.

See http://arduino.cc/en/Reference/PROGMEM for examples on how to use PROGMEM data.

1
  • To add to this excellent description, you could, as a workaround, temporarily copy to RAM the PROGMEM data you need to pass to lcd.print() and pass it this copy. A wrapper function, say lcd_print_PMEM() could encapsulate the details, and the RAM used would literally only be allocated for the duration of that call.
    – JRobert
    Dec 20 '14 at 16:01
0

PROGMEM variable definition (i.e. declaration) allocate memory in FLASH. You need use extern clause in header file and physical declaration in C code which is linked in your code. It's pays also for potential static class properties.

Also check if lcd.print() accepts PROGMEM array, i.e. if overloaded procedure is defined and called.

Just note I recommend using much more effective string formating via file streams (FILE) and fprintf_P().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.