sterretje:
"The smart solution would be to implement a function which could manipulate the flash variables on a byte-by-byte basis without bufferingWhich is not possible on AVR based Arduinos without modifying the bootloader or other tricks.
He means reading a byte of FLASH and deciding whether it should be passed on to its final destination or not, or with modification. (I see Danois90 has clarified.) For example:
// strings I want to save in flash
const char STR_0[] PROGMEM = "string0_";
const char STR_1[] PROGMEM = "string1_";
const char STR_2[] PROGMEM = "string2_";
const char STR_3[] PROGMEM = "string3_";
const char STR_4[] PROGMEM = "string4_";
const char STR_5[] PROGMEM = "string5_";
const char* const STR[] PROGMEM =
{
STR_0,
STR_1,
STR_2,
STR_3,
STR_4,
STR_5
};
const size_t MAX_STRINGS = sizeof(STR) / sizeof(STR[0]);
// Handy macro for casting the "const char *" to the correct type for printing
#define CF(s) ((const __FlashStringHelper *)s)
void function()
{
uint8_t i=0;
while (i<MAX_STRINGS) {
printUppercaseFLASHstr( STR[i] );
i++;
if (i<MAX_STRINGS)
printUppercaseFLASHstr( STR[i] );
i++;
Serial.println();
}
Serial.println();
}
void printUppercaseFLASHstr( const char *flashPtr )
{
for (;;) {
char c = pgm_read_byte( flashPtr++ );
if (c == '\0')
break;
if (('a' <= c) and (c <= 'z'))
c -= 'a' - 'A'; // offset is 32, so subtracting 32 from 'd' (80) is a 'D' (68)
Serial.write( c );
}
}
void setup() {
Serial.begin(9600);
function();
}
void loop() {
}
This prints the uppercase versions of all those strings without ever copying them to a RAM buffer. The output:
STRING0_STRING1_
STRING2_STRING3_
STRING4_STRING5_
Actually, I suspect the sketch performs everything in registers, so it may not use any RAM.