Hi all,
I have stored all my text descriptions by using PROGMEM and my program is working like a charm.
Later, I thought to save flash space by representing the most commons words as tokens mixed into the text strings.
Here the idea: when the program encounter a token expand it to the corresponding into a word picked from a "vocabulary" (i.e. another array of strings).
In this way I can save a lot of flash space! (I'm very short on space
)
I thought to use ascii codes greater than 127 as tokens. Those values are never used when the string contains pure text chars only.
Unfortunately, above approach seems to not work. Sometimes the tokens were expanded, sometimes not. Why?
After digging for many hours, I discovered that the same byte (one char) is translated in the right numeric value depending on the char following it. Strange, isn't it?
The following example sketch just print out the numeric value of a 4-char string followed by the string terminator:
#define ROWS 5
#define COLS 5
static const unsigned char faultDescriptions[5][18] PROGMEM =
{
"abcd",
"\x87\x86\x85\x84",
"\x87\x86aa",
"\x87\x86bb",
"\x87\x86ii"
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
char descr[COLS];
unsigned char value;
for(int row=0;row<ROWS;row++)
{
Serial.print("row ");
Serial.print(row);
Serial.print(" = ");
memcpy_P (&descr, &faultDescriptions [row], COLS);
// print row (skip last char: NULL terminator))
for(int col=0;col<COLS-1;col++) //
{
value = (unsigned char) descr[col];
Serial.print(value);
Serial.print(',');
}
Serial.println();
}
}
void loop() { }
The produced output is:
row 0 = 97,98,99,100, (Great! This are asci values for the "abcd" string. Computers are better than humans!)
row 1 = 135,134,133,132, (Marvelous! this are exactly the hex-values I typed in the PROGMEM!)
row 2 = 135,170,0,0, (Wait... why the second char has not 134 as value?)
row 3 = 135,187,0,0, (Hey! why the second char has changed again!?)
row 4 = 135,134,105,105, (Now the second char is right, are you kidding me stupid computer???)
I'm going crazy. Maybe the solution is in front of my eyes and I cannot see it. But it is hard to understand why the value of \x86 depends on what character I type after it in the PROGMEM section.
Maybe, for some bscure reason, the memcpy_P copies words not bytes, so the final result is influenced by that?
Or maybe, for some obscure reason, bytes greater than 127 are considered signed values somewhere?
Or maybe... what?
Any idea?