I am trying to put a lookup table in a class, and I "want it all":
The same lookup table can be used by all functions in the class
It's declared static, so even if I have 100 instances of the class, it doesn't take up any more space
It's in PROGMEM, as the target is an Arduino Uno with limited RAM
Here is a very cut-down version of my code. It works properly if I leave out "PROGMEM", but when I put it in, I get blanks instead of the string. I tried some alternatives - see below - and got very strange results.
Thanks for the advice and the page - it was very helpful. It would be great if a link to that page was in the documentation here.
For anyone else who happens upon this post, this line of code worked for me:
Serial.println((__FlashStringHelper*)base64); // suggested by Whandall on the Arduino forum. THIS WORKS!
// Also see https://www.nongnu.org/avr-libc/user-manual/pgmspace.html
Or for character access, as suggested on the page Whandall provided, this worked for me as well:
char c;
for (unsigned char i=0; i<64; i++)
{
c = (char)pgm_read_byte(&(base64[i])); // From https://www.nongnu.org/avr-libc/user-manual/pgmspace.html,
Serial.print(c); // then I added the cast to (char). THIS ALSO WORKS!
}
Serial.println("");
This code was needed for the Arduino Uno ATmega328, but as it is for a library, I wanted the same code to work on the Seeed Studio Xiao SAMD21, Adafruit Feather M4 Express, and the PJRC Teensy 4.1. Suprisingly, it worked the same on all of them, with no compiler preprocessor directives needed.
I am a little skeptical of "pgm_read_byte" working on larger programs, as it is a 16-bit near address in program space. It's working fine now on a small test program, but in larger programs, far might become necessary. So I will use compiler preprocessor directives around everything involving PROGMEM, to avoid the issue entirely.
Maybe these platforms don't use Harvard architecture,
and can access flash with normal instructions.
Then the pgm_read could be mapped to simple accesses.