const y PROGMEM, diferente o igual?

En el intento de reducir al maximo el consumo de ram y flash pase muchas cosas que se repiten a un archivo con constantes

al lo que funciona pero no se si es verdad o casualidad si defino

const char ch_S PROGMEM ='S';

o

const char ch_S ='S';

funciona igual y da el mismo resultado en el consumo de ram y flash, por lo que intuyo que lo aloja en el mismo lugar pero me queda dudas.

Alguien me lo aclaro porfavor

No es lo mismo,con const la variable se trata de un modo parecido a #define y no ocupa ram .progmem guarda la variable en memoria de programa (cuando no son constantes)

Versión PROGMEM

int led = 13;
const char ch_S PROGMEM ='S';
//const char ch_S ='S';


void setup() {
  // put your setup code here, to run once:
  pinMode(led, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)
    delay(100);               // wait for a second
    digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
    delay(100);               // wait for a second
}
El sketch usa 1,068 bytes (3.5%) del espacio de almacenamiento. El máximo es 30,720 bytes.
Las variables globales usan 11 bytes (0.5%) de la memoria dinámica, dejando 2,037 bytes para variables locales. EL máximo es 2,048 bytes.
[Stino - Compilación terminada "Borrar_4" en 11.6s.]

Versión CONST

int led = 13;
//const char ch_S PROGMEM ='S';
const char ch_S ='S';


void setup() {
  // put your setup code here, to run once:
  pinMode(led, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)
    delay(100);               // wait for a second
    digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
    delay(100);               // wait for a second
}
El sketch usa 1,068 bytes (3.5%) del espacio de almacenamiento. El máximo es 30,720 bytes.
Las variables globales usan 11 bytes (0.5%) de la memoria dinámica, dejando 2,037 bytes para variables locales. EL máximo es 2,048 bytes.
[Stino - Compilación terminada "Borrar_4" en 10.3s.]

Leo exactamente lo mismo

Ahora creo un array de 100 bytes y veamos si se ven los cambios

Versión PROGMEM

int led = 13;
const char ch_S[100] PROGMEM = {'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                                'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                                'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                                'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};

//const char ch_S[100] ={ 'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
//                      'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
//                      'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
//                      'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};


void setup() {
  // put your setup code here, to run once:
  pinMode(led, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)
    delay(100);               // wait for a second
    digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
    delay(100);               // wait for a second
}
El sketch usa 1,068 bytes (3.5%) del espacio de almacenamiento. El máximo es 30,720 bytes.
Las variables globales usan 11 bytes (0.5%) de la memoria dinámica, dejando 2,037 bytes para variables locales. EL máximo es 2,048 bytes.
[Stino - Compilación terminada "Borrar_4" en 10.4s.]

VERSION CONST[100]

int led = 13;
//const char ch_S PROGMEM ='S';
const char ch_S[100] ={ 'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                        'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                        'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                        'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};


void setup() {
  // put your setup code here, to run once:
  pinMode(led, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)
    delay(100);               // wait for a second
    digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
    delay(100);               // wait for a second
}
El sketch usa 1,068 bytes (3.5%) del espacio de almacenamiento. El máximo es 30,720 bytes.
Las variables globales usan 11 bytes (0.5%) de la memoria dinámica, dejando 2,037 bytes para variables locales. EL máximo es 2,048 bytes.
[Stino - Compilación terminada "Borrar_4" en 10.4s.]

MI CONCLUSION: Ambas son lo mismo. No ocupan RAM. Solo espacio FLASH.

char ch_S[100] PROGMEM = {'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',                      'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',                                'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',                                'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};

Esto no puede compilarse. Da error.

D:/Dropbox/Arduino/Borrar_4/Borrar_4.ino:2:16: error: variable 'ch_S' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 char ch_S[100] PROGMEM = {'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
                ^

[Stino - Salida con error. Código 1.]

Curioso,con la 1.0.6 si compila sin const.por otro lado supongo que PROGMEM debe servir para algo ,si con PROGMEM o sin el,parece que el resultado es el mismo ,¿que funcion tiene entonces?¿para que ponerlo si supuestamente con anteceder const es lo mismo?

Ahh en tu versión de IDE si puedes hacer asi char ch_S[100] PROGMEM

Con mi version 1.6.0 no.

PROGMEM Store data in flash (program) memory instead of SRAM.

Almacena datos en la memoria flash (de programa) en lugar de SRAM.

Si miras lo que dice el PLAYROUND de PROGMEM, no hay un solo ejemplo sin const para usarlo.

CONST por otro lado const es un calificador de variable que solo lo hace "de lectura solamente"

The const keyword stands for constant. It is a variable qualifier that modifies the behavior of the variable, making a variable "read-only"

Aca hay un buen debate en inglés al respecto.

No vale hacerse trampas al solitario, surbyte ;). Hay que utilizar las variables:

const char ch_S[100] ={ 'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};


void setup() {
	Serial.begin(9600);
	for (int a=0; a<100; a++)
		Serial.println(ch_S[a]);
}

void loop() {
}
Sketch uses 1,890 bytes (5.9%) of program storage space. Maximum is 32,256 bytes.
Global variables use 282 bytes (13.8%) of dynamic memory, leaving 1,766 bytes for local variables. Maximum is 2,048 bytes.
const char ch_S[100] PROGMEM ={ 'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};


void setup() {
	Serial.begin(9600);
	for (int a=0; a<100; a++)
		Serial.println(ch_S[a]);
}

void loop() {
}
Sketch uses 1,890 bytes (5.9%) of program storage space. Maximum is 32,256 bytes.
Global variables use 182 bytes (8.9%) of dynamic memory, leaving 1,866 bytes for local variables. Maximum is 2,048 bytes.

Sin embargo, esto no funcionará correctamente.

Esto sí:

const char ch_S[100] PROGMEM ={ 'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S',
						'S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S'};


void setup() {
	Serial.begin(9600);
	for (int a=0; a<100; a++)
		Serial.println((char)pgm_read_byte_near(ch_S + a));
}

void loop() {
}
Sketch uses 1,894 bytes (5.9%) of program storage space. Maximum is 32,256 bytes.
Global variables use 182 bytes (8.9%) of dynamic memory, leaving 1,866 bytes for local variables. Maximum is 2,048 bytes.

noter: No vale hacerse trampas al solitario, surbyte ;). Hay que utilizar las variables:

Si no las usas el compilador las descarta en la optimizacion.!!

A lo que voy es que si declaro

const char ch_b  ='b';
const char ch_B  ='B';
const char ch_e  ='e';
const char ch_E  ='E';

o

const char ch_b PROGMEM ='b';
const char ch_B PROGMEM ='B';

const char ch_e PROGMEM ='e';
const char ch_E PROGMEM ='E';

De las 2 formas ocupan lo mismo y funciona bien la comparacion en if y switch/case. Que no pasa lo mismo si es un vector

const char TXT_SIGUE[] PROGMEM = "Sigue S/N?";

, al cual hay que accederlo de otra forma, con pgm_read_byte()

Pero me queda esa terrible duda si es casualidad que funcione con PROGMEM y esta bien accederla sin usar pgm_read_byte() y luego falle en algun momento.

Es asunto complicado, porque pertenece a los entresijos de las decisiones que toma el compilador. Por ejemplo, en el caso de una constante tipo char, lo lógico (y no afirmo que sea así) es que cuando el compilador detecta que se va a usar dicha constante, no la rescate ni de flash ni de ram, sino que ponga su valor directamente en la instrucción a realizar (hay muchas instrucciones del atmel que toman un literal como parámetro). En mi caso, una vez comprobé que el uso de memorias es el mismo, para tipos de datos simples suelo utilizar sencillamente const, y PROGMEM en los complejos (arrays, cadenas de caracteres, estructuras...), que es, además, donde realmente se puede economizar RAM en cantidades interesantes.

noter: Es asunto complicado, porque pertenece a los entresijos de las decisiones que toma el compilador. Por ejemplo, en el caso de una constante tipo char, lo lógico (y no afirmo que sea así) es que cuando el compilador detecta que se va a usar dicha constante, no la rescate ni de flash ni de ram, sino que ponga su valor directamente en la instrucción a realizar (hay muchas instrucciones del atmel que toman un literal como parámetro). En mi caso, una vez comprobé que el uso de memorias es el mismo, para tipos de datos simples suelo utilizar sencillamente const, y PROGMEM en los complejos (arrays, cadenas de caracteres, estructuras...), que es, además, donde realmente se puede economizar RAM en cantidades interesantes.

Creo que es asi por como compila y los resultados obtenidos. Pero como siempre hay uno... es mejor estar atento a esto y no reprogramar por un char!!!

Saludos En varios programas he tenido array de mensajes a mostrar y con el uso de const me toma mucha memoria RAM lo que se redujo en gran cantidad al usar PROGMEM.

Pero como dicen es util para array y cosas complejas no solo para un char.

const transforma en READ ONLY una variable que seria de lectura/escritura pero siempre en SRAM.
La corrección que hizo noter de mi ejemplo, usándolo demostró justamente esto.