Placer un tableau en SRAM avec PROGMEM

Bonjour,

Voici un code qui fonctionne bien que je voudrais placer en SRAM .

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print(F("Le mode lance est : "));Serial.println(readModeType(5));
}

void loop() {
  
  // put your main code here, to run repeatedly:

}

char const * readModeType(int mode)
{
  static char const *ModeType[11] ={"Module pret:","Centre Servo1:","Centre Servo2:","Securite Moteur 1&2:","Reponse module:",
                            "Maxi mot., Debut Synchro, Min Max Servos:","Config. canal AUX:","Inversion Servos 1&2:",
                            "Nombre pales & Telemetrie:","Test Servos 1&2:","Debugage Module:"};
                          
  return ModeType[mode];
}

Je pense que je doit déclarer le tableau ainsi:

char const * readModeType(int mode)
{
  static char const * const ModeType[11] PROGMEM ={"Module pret:","Centre Servo1:","Centre Servo2:","Securite Moteur 1&2:","Reponse module:",
                            "Maxi mot., Debut Synchro, Min Max Servos:","Config. canal AUX:","Inversion Servos 1&2:",
                            "Nombre pales & Telemetrie:","Test Servos 1&2:","Debugage Module:"};
                          
  return ModeType[mode];
}

Après, je suis un peu perdu !

Merci de votre aide !

Salut,

Y'a tout ici pourtant : http://arduino.cc/en/Reference/PROGMEM

Oui , j'ai déjà regardé ce lien .

j'ai trouvé ce type d'exemple à partir d'une macro:

#include <avr/pgmspace.h>

//Used to store large strings in progmem.
char p_buffer[30];
#define P(str) (strcpy_P(p_buffer, PSTR(str)), p_buffer)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print(F("Le mode lance est : "));Serial.println(P(readModeType(0)));
}

void loop() {
  
  // put your main code here, to run repeatedly:

}

char const * readModeType(int mode)
{
  static char const *ModeType[11] ={"Module pret:","Centre Servo1:","Centre Servo2:","Securite Moteur 1&2:","Reponse module:",
                            "Maxi mot., Debut Synchro, Min Max Servos:","Config. canal AUX:","Inversion Servos 1&2:",
                            "Nombre pales & Telemetrie:","Test Servos 1&2:","Debugage Module:"};
                          
  return ModeType[mode];
}

Mais ça me génère une erreur !

Par contre si je test cet exemple , le code ce compile mais prend plus de place ce qui n'est pas le but!

#include <avr/pgmspace.h>

//Used to store large strings in progmem.
char p_buffer[30];
#define P(str) (strcpy_P(p_buffer, PSTR(str)), p_buffer)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print(F("Le mode lance est : "));Serial.println(readModeType(0));
}

void loop() {
  
  // put your main code here, to run repeatedly:

}

char const * readModeType(int mode)
{
  static char const *ModeType[11] ={P("Module pret:"),"Centre Servo1:","Centre Servo2:","Securite Moteur 1&2:","Reponse module:",
                            "Maxi mot., Debut Synchro, Min Max Servos:","Config. canal AUX:","Inversion Servos 1&2:",
                            "Nombre pales & Telemetrie:","Test Servos 1&2:","Debugage Module:"};
                          
  return ModeType[mode];
}

En regardant un peu les exemples, j'ai essayé ceci mais sans succés !

#include <avr/pgmspace.h>
char buff[30];
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print(F("Le mode lance est : "));Serial.println(readModeType(0));
}

void loop() {  
  // put your main code here, to run repeatedly:
}

char const * readModeType(int mode)
{

  static char const * const ModeType[11] PROGMEM ={"Module pret:","Centre Servo1:","Centre Servo2:","Securite Moteur 1&2:","Reponse module:",
                            "Maxi mot., Debut Synchro, Min Max Servos:","Config. canal AUX:","Inversion Servos 1&2:",
                            "Nombre pales & Telemetrie:","Test Servos 1&2:","Debugage Module:"};
  strcpy_P(buff, (char*)pgm_read_word(&(ModeType[mode]))); // Necessary casts and dereferencing, just copy.                        
  return buff;
}

Merci de votre aide !!!

Non mais ... Dans le lien il y a exactement ce que tu veux faire ! Je vois pas pourquoi tu te prend la tête

Bon, je me résigne,

J'ai testé le code suivant et je passe de:
Le croquis utilise 2 146 octets (6%) de l'espace de stockage de programmes. Le maximum est de 32 256 octets.
Les variables globales utilisent 406 octets (19%) de mémoire dynamique, ce qui laisse 1 642 octets pour les variables locales. Le maximum est de 2 048 octets.

à
Le croquis utilise 1 964 octets (6%) de l'espace de stockage de programmes. Le maximum est de 32 256 octets.
Les variables globales utilisent 212 octets (10%) de mémoire dynamique, ce qui laisse 1 836 octets pour les variables locales. Le maximum est de 2 048 octets.

char buff[30];
const char ModeType0[] PROGMEM ="Module pret:";
const char ModeType1[] PROGMEM ="Centre Servo1:";
const char ModeType2[] PROGMEM ="Centre Servo2:";
const char ModeType3[] PROGMEM ="Securite Moteur 1&2:";
const char ModeType4[] PROGMEM ="Reponse module:";
const char ModeType5[] PROGMEM ="Maxi mot., Debut Synchro, Min Max Servos:";
const char ModeType6[] PROGMEM ="Config. canal AUX:";
const char ModeType7[] PROGMEM ="Inversion Servos 1&2:";
const char ModeType8[] PROGMEM ="Nombre pales & Telemetrie:";
const char ModeType9[] PROGMEM ="Test Servos 1&2:";
const char ModeType10[] PROGMEM ="Debugage Module:";

const char * const readModeType[11] PROGMEM = {ModeType0,ModeType1,ModeType2,ModeType3,ModeType4,ModeType5,
                                                ModeType6,ModeType7,ModeType8,ModeType9,ModeType10};
void setup() 
{

  Serial.begin(9600);
  Serial.print(F("Le mode lance est : "));  
  strcpy_P (buff, readModeType[10]); Serial.println(buff); 

  
}

void loop() {  
  // put your main code here, to run repeatedly:
}

Y aurait-il plus simple ? En tout cas cela fonctionne et divise par 2 la place utilisée en mémoire dynamique.

Si y'a plus simple je connais pas la solution xD après bon, c'est pas très esthétique mais ça fait que quelques lignes ...

Ahhh,

Si j'intègre ce code modifié dans mon projet tout ce passe bien jusqu'à ce que je remplace la valeur 0 à 10 par une variable !

En fait le code vient lire a codeur BCD hexa ainsi:

/*
 * Lecture du codeur de reglage.
 * Retourne -1 si aucun mode n'est selectionne et
 * le numero du mode de 0 a 15 si un mode est selectionne
 * Chaque pin doit avoir un pull up de definit (ici en interne)
 * Le commun est cable au GND.
 */
int readModeInStart()
{
  // initialise contacteur rotatif (initialise les pull up internes sur A2 a A5)
  pinMode(switchPin1, INPUT_PULLUP);
  pinMode(switchPin2, INPUT_PULLUP);
  pinMode(switchPin4, INPUT_PULLUP);
//  pinMode(switchPin8, INPUT_PULLUP);
  static int modeSettings =
//    (! digitalRead(switchPin8)) << 3 |
    (! digitalRead(switchPin4)) << 2 | 
    (! digitalRead(switchPin2)) << 1 |
    (! digitalRead(switchPin1));//conversion du code BCD Hexa en une valeur de 0 a 15
//  modeSettings = (modeSettings >= 0 && modeSettings <= 15)?modeSettings=modeSettings:modeSettings=-1; 
  modeSettings = (modeSettings >= 0 && modeSettings <= 7)?modeSettings=modeSettings:modeSettings=-1; 
  return  modeSettings;
}
int switchState=0;
switchState = readModeInStart();//lecture du codeur qui désigne le mode a lancer (mode0 a mode10)

Si je remplace :
strcpy_P (buff, readModeType[10]);
par
strcpy_P (buff, readModeType[switchState]);

Le résultat est illisible !!!

Encore une fois : y'a exactement ce que tu veux dans le lien .... On va pas le réexpliquer 50 fois ....

strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));

Merci B@tto, je vais arrêter de faire mon crétin :slight_smile: !

Ce code :
strcpy_P(buff, (char*)pgm_read_word(&(readModeType[switchState])));Serial.println(buff);

Marche trés bien.

Merci pour votre patience et votre écoute

Pierre