Problema con PROGMEM y variables char

Hola....

Para poder insertar un byte en una variable char, es fácil...

char Var[] = "ejemplo n ";
Var[9]=49;

Pero, ¿cómo podría hacerlo cuando utilizo PROGMEM?

const char Var[] PROGMEM = "ejemplo n ";

Var[9]=49;

Y me saca un error lógico, porque una variable "const" no se puede modificar.

Y mucho menos hacer una de estas 2 cosas:

const char Var[] PROGMEM = "ejemplo n "+ char(49);

const char Var[] PROGMEM = {"ejemplo n ", char(49)};

Es imposible?

gracias...

No ,no puedes.Los valores que guardes con PROGMEM tienen que ser constantes.

El tema es que necesito insertar un byte de la tabla ASCII mayor que 127 decimal (entre 128 y 255) en una cadena....algo similar a esto:

const unsigned char Var[] PROGMEM = "ejemplo n X";//X es el carácter correspondiente a char(128);

Y como no puedo hacer esto:

const unsigned char Var[] PROGMEM = "ejemplo n ";

Var[9]=128;

De que forma lo podría hacer? Como podría insertar esa "X" en esa cadena de texto, siendo X = char(128) ??? Quiero decir, incluir un carácter>127 en el mismo texto, no a posteriori.

Sí se puede. Para ello has de utilizar las “secuencias de escape” que permiten definir caracteres con su valor octal o hexadecimal. En el caso del carácter ‘1’, su valor en decimal es 49, en octal 061 y en hexadecimal 0x31. Nótese que el número en octal lo he puesto empezando por 0, mientras que el hexadecimal empieza por 0x.

Para especificar en la cadena el valor en octal, se ha de empezar con \ y poner a continuación el valor en octal. Para ponerlo en hexadecimal se ha de empezar con \x y poner a continuación el valor en hexadecimal. Veamos varias formas de poner el carácter ‘1’ en la cadena "De 10!".

void setup() {
    Serial.begin(9600);
    Serial.println(F("De 10!"));        // Con caracteres ASCII
    Serial.println(F("De \0610!"));     // Con el octal de 3 dígitos \061 no hace falta separalo del 0
    Serial.println(F("De \61" "0!"));   // Con el octal de 2 dígitos \61 hay que separar el 0. Dos cadenas contínuas es una única cadena
    Serial.println(F("De \x31" "0!"));  // Con un hexadecimal \x31 hay que separar el 0. Dos cadenas contínuas es una única cadena
    Serial.println(F("De \x31\x30!"));  // Con dos hexadecimales \x31 \x30 el cero es el segundo hexadecimal
    Serial.println(F("D" "e" " " "1" "0" "!")); // Concatenando varias "subcadenas"
    Serial.println(F("De 1"             // Con dos "subcadenas" con un salto de línea de por medio
                         "0!"));
}

void loop() {
}

Para saber dónde acaba el valor en octal basta con asegurarse que tiene tres dígitos, ni uno más ni uno menos. En el resto de casos, tanto para el octal como el hexadecimal, el número termina en cuanto aparece un dígito o carácter que no puede formar parte del número. Como no siempre puede ser así, en el ejemplo nos encontramos que después del ‘1’ queremos que se muestre un ‘0’, basta con terminar la cadena con las " y continuarla con otras ". Los espacios, tabuladores o retornos de carro que hay entre esas dos “subcadenas” no se tienen en cuenta,

Recomiendo poner los valores en octal y utilizar siempre tres dígitos, con ceros a la izquierda si el valor octal de de menos de tres dígitos. Nos evitaremos "sustos" si a continuación ha de ir un carácter numérico que se puede "confundir" con el valor en octal (o hexadecimal) que queremos poner.

En el caso de querer el byte ASCII 128 (en decimal):

const unsigned char Var[] PROGMEM = "ejemplo n \200";  //  \200 es en octal el carácter correspondiente a char(128);
const unsigned char Var[] PROGMEM = "ejemplo n \x80";  //  \x80 es en hexadecimal el carácter correspondiente a char(128);

Poniendo esto:

const char Var[] PROGMEM = "ejemplo n ";

Var[9]=49;

entendí que querias hacer una asignacion en tiempo de ejecucion.

Muchas gracias. Lo he probado tal y como me ha dicho IgnoranteAbsoluto y funciona perfectamente. Yo no sabía que “hola” “Pedro” el compilador lo toma como una suma o concatenación de cadenas.

Quiero utilizar los caracteres vocales acentuados y la “Ñ” en un display TFT de 3.5", y no sabía como añadirlas en una cadena PROGMEM.

Parte de mi código es este:

En el archivo de la libreria del display TFT he codificado la forma de los caracteres acentuados y la “ñ”, tanto en mayúsculas como minúsculas. Además he añadido esto:

#define A_TILDE "\x80"
#define E_TILDE "\x81"
#define I_TILDE "\x82"
.......
......
......
#define e_TILDE "\x86"
....
....
#define n_TILDE "\x8b"

Y despues, en el propio programa, hago uso de esos #defines tal que así:

const char Var_1[] PROGMEM = "An" e_TILDE "cdota";  
const char Var_2[] PROGMEM = "Espa" n_TILDE "a";

Gracias!