The following code compile fine but I can't test it yet because I've no board.
//#include <avr/pgmspace.h>
// save some unsigned ints
const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};
// save some chars
const char signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};
unsigned int displayInt;
int k; // counter variable
char myChar;
void setup() {
Serial.begin(9600);
while (!Serial);
// put your setup code here, to run once:
// read back a 2-byte int
for (k = 0; k < 5; k++)
{
displayInt = pgm_read_word_near(charSet + k);
Serial.println(displayInt);
}
Serial.println();
// read back a char
int len = strlen_P(signMessage);
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(signMessage + k);
Serial.print(myChar);
}
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
}
The question is whether PROGMEM prevents the constants from being copied from flash memory to SRAM on the ARM processors, as it does on the AVRs?
It's easy to see the effect of PROGMEM on the UNO, as the IDE nowadays displays the available SRAM and there's also the MemoryFree library, but this is not the case with the Zero and Due.
I've tested the Zero, Due and Uno with the above code. It appears as though the Due and Zero access the constant data irrespective of whether it's declared with PROGMEM or not. The Uno on the other hand requires PROGMEM, otherwise the function pgm_read_byte_near() returns garbage.
This suggests that PROGMEM has no effect on the ARM processors and has been included for backwards code compatibility with AVR processors.
As there's no information about PROGMEM for the Due or Zero on the internet, I looked it up for the ARM based Teensy 3.0/3.1 instead. Here's what Paul Stoffregen (creator of the Teensy boards) said:
On Teensy 3.0, all you have to do is use "const" in the variable declaration. Or at least that's all you're supposed to do. Everything that's "const" gets put into flash without consuming any RAM.
PROGMEM, pgm_read_byte() and the other AVR names are defined only so code designed for AVR can compile. But they do absolutely nothing on Teensy 3.0.
I'd recommend adding const to that huge array. If you're not planning to compile on Teensy 2.0 or other AVR boards, you might as well remove the PROGMEM stuff. Accessing the array normally is much nicer and more readable code that using pgm_read_byte().
If the SAMD (Arduino Zero) is anything like the SAM3X (Arduino Due), you can just use the C++ "const" keyword, and forget all about the AVR's PROGMEM keyword. Even better, flash memory is completely mapped to main memory map, meaning no special calls are required to access it. More efficient, and more readable! For instance, you can just do: