Mise en memoire progmem d'un GROS tableau de char !

Bonjour, bonjour,

Je me suis mis a creer une sorte d'émulateur avec arduino, j'ai coder plusieurs jeux et la taille qu'occupe la memoire SRAM dans mon arduino mega est de 40%. Aujourd'hui je me suis mit a coder un nouveau jeu : un quizz sur le tableau periodique des elements !
Alors, dans le bout de code que vous retrouverez ci dessous, tout va pas mal lorsque on met tout en memoire SRAM. Facile et simple d'utilisation, ce n'est pourtant pas l'ideal car je souhaite utiliser l'espace pour d'autres choses. En gros je voudrais mettre mon tableau en memoire flash et bien entendu pouvoir le recuperer. Pour ce faire, vous pouvez voir dans mon code que j'utilise des fonctions pour recuperer les donnees dans des 'char' et les afficher ; mais lorsque j'execute ce programme, le lcd ecrit n'importe quoi, des caracteres bizzards et des points d'interrogations ou tout autres choses similaires. Alors ma question est simple : pourquoi et comment ?

Je vous mets la fonction qui utilise PROGMEM ci dessous, il est un peu compliqué, surtout au niveau des noms de variables (je suis pas très inspiré), si vous avez une question sur le code, n'hésitez SURTOUT pas car je sais qu'il n'est pas très compréhensible… Je precise que mon code entier est juste ENORME (8000 lignes .........) et qu'il est ici VRAIMENT EPURER, juste le necessaire, c'est pourquoi j'ai enlever les fonctions setup et loop et toutes les autres declarations mais je ne doute pas que vous le comprendrez bien ! Le voici justement :


// Ce tableau est un peu complique et ne necessite pas de mise en memoire flash a mon avis
// Description du tableau, lorsque le chiffre est un 1, cela signifie que l'element est solide a 0°c, un 2 : il est gazeux et un 3 : il est liquide !
const int type_elements[118] {
  1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2
};

// Declaration de mon tableau a 3 dimensions, en constante, en char, et en PROGMEM !
// Tableau de données de la table périodique :
const char elements PROGMEM [118][2][15] = {
  {"Hydrogene", "H"},
  {"Helium", "He"},
  {"Lithium", "Li"},
  {"Beryllium", "Be"},
  {"Bore", "B"},
  {"Carbone", "C"},
  {"Azote", "N"},
  {"Oxygene", "O"},
  {"Fluor", "F"},
  {"Neon", "Ne"},
  {"Sodium", "Na"},
  {"Magnesium", "Mg"},
  {"Aluminium", "Al"},
  {"Silicium", "Si"},
  {"Phosphore", "P"},
  {"Soufre", "S"},
  {"Chlore", "Cl"},
  {"Argon", "Ar"},
  {"Potassium", "K"},
  {"Calcium", "Ca"},
  {"Scandium", "Sc"},
  {"Titane", "Ti"},
  {"Vanadium", "V"},
  {"Chrome", "Cr"},
  {"Manganese", "Mn"},
  {"Fer", "Fe"},
  {"Cobalt", "Co"},
  {"Nickel", "Ni"},
  {"Cuivre", "Cu"},
  {"Zinc", "Zn"},
  {"Gallium", "Ga"},
  {"Germanium", "Ge"},
  {"Arsenic", "As"},
  {"Selenium", "Se"},
  {"Brome", "Br"},
  {"Krypton", "Kr"},
  {"Rubidium", "Rb"},
  {"Strontium", "Sr"},
  {"Yttrium", "Y"},
  {"Zirconium", "Zr"},
  {"Niobium", "Nb"},
  {"Molybdene", "Mo"},
  {"Technetium", "Tc"},
  {"Ruthenium", "Ru"},
  {"Rhodium", "Rh"},
  {"Palladium", "Pd"},
  {"Argent", "Ag"},
  {"Cadmium", "Cd"},
  {"Indium", "In"},
  {"Etain", "Sn"},
  {"Antimoine", "Sb"},
  {"Tellure", "Te"},
  {"Iode", "I"},
  {"Xenon", "Xe"},
  {"Cesium", "Cs"},
  {"Baryum", "Ba"},
  {"Lanthane", "La"},
  {"Cerium", "Ce"},
  {"Praseodyme", "Pr"},
  {"Neodyme", "Nd"},
  {"Promethium", "Pm"},
  {"Samarium", "Sm"},
  {"Europium", "Eu"},
  {"Gadolipium", "Gd"},
  {"Terbium", "Tb"},
  {"Dysprosium", "Dy"},
  {"Holmium", "Ho"},
  {"Erbium", "Er"},
  {"Thulium", "Tm"},
  {"Ytterbium", "Yb"},
  {"Lutecium", "Lu"},
  {"Hafnium", "Hf"},
  {"Tantale", "Ta"},
  {"Tungstene", "W"},
  {"Rhenium", "Re"},
  {"Osmium", "Os"},
  {"Iridium", "Ir"},
  {"Platine", "Pt"},
  {"Or", "Au"},
  {"Mercure", "Hg"},
  {"Thallium", "Tl"},
  {"Plomb", "Pb"},
  {"Bismuth", "Bi"},
  {"Polonium", "Po"},
  {"Astate", "At"},
  {"Radon", "Rn"},
  {"Francium", "Fr"},
  {"Radium", "Ra"},
  {"Actinium", "Ac"},
  {"Thorium", "Th"},
  {"Protactinium", "Pa"},
  {"Uranium", "U"},
  {"Neptunium", "Np"},
  {"Plutonium", "Pu"},
  {"Americium", "Am"},
  {"Curium", "Cm"},
  {"Berkelium", "Bk"},
  {"Californium", "Cf"},
  {"Einsteinium", "Es"},
  {"Fermium", "Fm"},
  {"Mendelevium", "Md"},
  {"Nobelium", "No"},
  {"Lawrencium", "Lr"},
  {"Rutherfordium", "Rf"},
  {"Dubnium", "Db"},
  {"Seaborgium", "Sg"},
  {"Bohrium", "Bh"},
  {"Hassium", "Hs"},
  {"Meitnerium", "Mt"},
  {"Darmstadtium", "Ds"},
  {"Roentgenium", "Rg"},
  {"Copernicium", "Cn"},
  {"Nihonium", "Nh"},
  {"Flerovium", "Fl"},
  {"Moscovium", "Mc"},
  {"Livermorium", "Lv"},
  {"Tennessine", "Ts"},
  {"Oganesson", "Og"}
};  


void periodique() {


  char bonne_reponse[15] = "";
  char reponse_fictive[15] = "";
  char reponse_fictive2[15] = "";


  lcd.clear();
  lcd.setCursor(2, 0);
  lcd.print(F("QUIZZ Periodique"));
  lcd.setCursor(1, 1);
  lcd.print(F("Trouvez la reponse"));
  lcd.setCursor(3, 2);
  lcd.print(F("AUX QUESTIONS"));

  // Definir des numeros aleatoires pour les questions
  // le randomSeed(analogRead(A0)); est declaré dans le setup pour des nombres pseudo aleatoire !

  int ordre_reponse = random(0, 3);
  int type_question = random(0, 10);
  int demande_vrai = random(0, 118);
  int demande_fausse = random(0, 118);
  int demande_fausse2 = random(0, 118);

  while (demande_fausse == demande_vrai) {
    // Tourner pour que les propositions soient differentes
    demande_fausse = random(0, 118);
  }

  while (demande_fausse2 == demande_vrai or demande_fausse2 == demande_fausse) {
    // Tourner pour que les propositions soient differentes
    demande_fausse2 = random(0, 118);
  }

  // Declaré les tableaux qui contiendront les infos du quizz periodique
  // Désolé si le nom des variables n'est pas tres parlant :)

  char vraie_nom[15] = "";
  char vraie_symbole[15] = "";
  char faux_nom[15] = "";
  char faux_symbole[15] = "";
  char faux_nom2[15] = "";
  char faux_symbole2[15] = "";
  int vrai_type = 0;
  int faux_type = 0;
  int faux_type2 = 0;

  // Ci dessous, les differentes versions (avec/sans PROGMEM) (Avec char OU String)

  /*
    vraie_nom = elements[demande_vrai][0];
    vraie_symbole = elements[demande_vrai][1];

    faux_nom = elements[demande_fausse][0];
    faux_symbole = elements[demande_fausse][1];

    faux_nom2 = elements[demande_fausse2][0];
    faux_symbole2 = elements[demande_fausse2][1];
  */
/*
  strcpy(vraie_nom, elements[demande_vrai][0]);
  strcpy(vraie_symbole, elements[demande_vrai][1]);
  strcpy(faux_nom, elements[demande_fausse][0]);
  strcpy(faux_symbole, elements[demande_fausse][1]);
  strcpy(faux_nom2, elements[demande_fausse2][0]);
  strcpy(faux_symbole2, elements[demande_fausse2][1]);
*/
  strcpy_P(vraie_nom, (char*)pgm_read_word(&(elements[demande_vrai][0])));
    strcpy_P(vraie_symbole, (char*)pgm_read_word(&(elements[demande_vrai][1])));
    strcpy_P(faux_nom, (char*)pgm_read_word(&(elements[demande_fausse][0])));
    strcpy_P(faux_symbole, (char*)pgm_read_word(&(elements[demande_fausse][1])));
    strcpy_P(faux_nom2, (char*)pgm_read_word(&(elements[demande_fausse2][0])));
    strcpy_P(faux_symbole2, (char*)pgm_read_word(&(elements[demande_fausse2][1])));

  vrai_type = type_elements[demande_vrai - 1];
  faux_type = type_elements[demande_fausse - 1];
  faux_type2 = type_elements[demande_fausse2 - 1];

  Serial.println(elements[demande_fausse2][1]);

  ///////////////////////////////////////////////////

  lcd.clear();

  lcd.setCursor(0, 1);
  lcd.print(F("A =>"));
  lcd.setCursor(0, 2);
  lcd.print(F("B =>"));
  lcd.setCursor(0, 3);
  lcd.print(F("C =>"));

  // Ici, on pose la question sur l'element mais le type de question est definis par un random (plus haut)
  // PS : Si il y a plusieurs conditions pour un meme resultat c'est pout les probabilités, je veux que ca tombe moins de fois sur la question de l'etat a 0°C par exemple...

  if (type_question == 0 or type_question == 1) {

    // symbole de l'element

    strcpy(bonne_reponse, vraie_symbole);
    strcpy(reponse_fictive, faux_symbole);
    strcpy(reponse_fictive2, faux_symbole2);

    lcd.setCursor(0, 0);
    lcd.print(F("Quel symbole : "));
    lcd.print(demande_vrai + 1);

  } else if (type_question == 2 or type_question == 3) {
    // numero de l'element

    strcpy(bonne_reponse, char((demande_vrai + 1)));
    strcpy(reponse_fictive, demande_fausse);
    strcpy(reponse_fictive2, demande_fausse2);
    lcd.setCursor(0, 0);
    lcd.print(F("Quel numero : "));
    lcd.print(vraie_symbole);
  }
  else if (type_question == 4) {
    // Type d'element, gaz, liquide, solide ?

    const char gaz[7] = "Gazeux";
    const char liq[8] = "Liquide";
    const char sol[7] = "Solide";

    if (vrai_type == 1) {
      strcpy(bonne_reponse, gaz);
      strcpy(reponse_fictive, liq);
      strcpy(reponse_fictive2, sol);
    } else if (vrai_type == 2) {
      strcpy(bonne_reponse, liq);
      strcpy(reponse_fictive, gaz);
      strcpy(reponse_fictive2, sol);
    } else if (vrai_type == 3) {
      strcpy(bonne_reponse, sol);
      strcpy(reponse_fictive, gaz);
      strcpy(reponse_fictive2, liq);
    }

    lcd.setCursor(0, 0);
    lcd.print(F("Quel Etat a 0C ? "));
    if (random(2) == 0) {
      lcd.print((demande_vrai + 1));
    } else {
      lcd.print(vraie_symbole);
    }

  } else {

    // nom de l'element

    strcpy(bonne_reponse, vraie_nom );
    strcpy(reponse_fictive, faux_nom);
    strcpy(reponse_fictive2, faux_nom2);
    lcd.setCursor(0, 0);
    lcd.print(F("Quel nom : "));
    if (random(2) == 0) {
      lcd.print((demande_vrai + 1));
    } else {
      lcd.print(vraie_symbole);
    }

  }


  char num_bonne_reponse = 'A';

  if (ordre_reponse == 0) {
    num_bonne_reponse = 'A';
    lcd.setCursor(5, 1);
    lcd.print(bonne_reponse);
    lcd.setCursor(5, 2);
    lcd.print(reponse_fictive);
    lcd.setCursor(5, 3);
    lcd.print(reponse_fictive2);
  } else if (ordre_reponse == 1) {
    num_bonne_reponse = 'B';
    lcd.setCursor(5, 1);
    lcd.print(reponse_fictive);
    lcd.setCursor(5, 2);
    lcd.print(bonne_reponse);
    lcd.setCursor(5, 3);
    lcd.print(reponse_fictive2);
  } else {
    num_bonne_reponse = 'C';
    lcd.setCursor(5, 1);
    lcd.print(reponse_fictive2);
    lcd.setCursor(5, 2);
    lcd.print(reponse_fictive);
    lcd.setCursor(5, 3);
    lcd.print(bonne_reponse);
  }

  char entre_users = presser_clavier(); // Fonction qui attends qu'on appuis sur le keypad et retourne sa valeur.

  lcd.clear();
  lcd.setCursor(0, 0);

  if (entre_users == num_bonne_reponse) {

    lcd.print(F("Bonne reponse !"));
    rgb(0, 255, 0); // Fonction pour une LED rgb
    playVictorySound(); // Fonction pour jouer un son sur un buzzer

  } else {

    lcd.print(F("Mauvaise reponse !"));
    rgb(255, 0, 0); // Fonction pour une LED rgb
    playDefeatSound(); // Fonction pour jouer un son sur un buzzer
  }

  rgb(0, 0, 0); // Fonction pour une LED rgb (eteindre apres le buzzer)

  // Afficher la totalité des infos sur l'element :

  lcd.setCursor(0, 1);
  lcd.print(F("Nom : "));
  lcd.print(vraie_nom);

  lcd.setCursor(0, 2);
  lcd.print(F("Numero ATOMIC : ")); // Ce n'est pas une faute d'orthographe (c'est un jeu de mot mais je vous epargne l'explication :) )
  lcd.print(demande_vrai + 1); // Le + 1 pour ignorer le 0 du tableau



  lcd.setCursor(0, 3);
  lcd.print(F("Symbole : "));
  lcd.print(vraie_symbole );


  presser_clavier(); // Mme fonction decrite plus haut !

  rgb(0, 0, 0);
  periodique(); // Revenir a la fonction pour rejouer

}

Je note que je ne sais pas si les balises de code se sont mises alors j'espere que ce sera lisible...

En tout cas, merci a vous pour vos futures reponses !!!

ben c'est quand même 2 x 118 octets sur un UNO.. c'est beaucoup.

pourquoi ne pas avoir une struct qui embarque tout d'un coup en progmem?

(la définition du tableau ne va pas)

Bonjour JML, je sais bien que je c'est VRAIMENT beaucoup pour une carte arduino (c'est une MEGA pour ma part), il est vraie que je n'avais pas penser a utiliser 'struct' , a vraie dire je n'en ai que tres rarement entendu parler, pourriez vous m'en dire plus sur comment l'utiliser ?

euh je ne pense pas que l'hydrogène ou l'hélium soient solides à 0°...

essayez cela, ça doit rentrer sans souci sur une UNO et vous avez en plus la masse atomique :slight_smile:

enum Etat : uint8_t {INCONNU, SOLIDE, GAZEUX, LIQUIDE };
const char* EtatText[] = {"INCONNU", "SOLIDE", "GAZEUX", "LIQUIDE"};

struct Element {
  char nom[20];
  char symbole[3];
  Etat etat;
  float masse_atomique;
};

static const Element tablePeriodique[] PROGMEM = {
  {"Hydrogène", "H", GAZEUX, 1.008},
  {"Hélium", "He", GAZEUX, 4.0026},
  {"Lithium", "Li", SOLIDE, 6.94},
  {"Béryllium", "Be", SOLIDE, 9.0122},
  {"Bore", "B", SOLIDE, 10.81},
  {"Carbone", "C", SOLIDE, 12.011},
  {"Azote", "N", GAZEUX, 14.007},
  {"Oxygène", "O", GAZEUX, 15.999},
  {"Fluor", "F", GAZEUX, 18.998},
  {"Néon", "Ne", GAZEUX, 20.18},
  {"Sodium", "Na", SOLIDE, 22.99},
  {"Magnésium", "Mg", SOLIDE, 24.305},
  {"Aluminium", "Al", SOLIDE, 26.982},
  {"Silicium", "Si", SOLIDE, 28.085},
  {"Phosphore", "P", SOLIDE, 30.974},
  {"Soufre", "S", SOLIDE, 32.06},
  {"Chlore", "Cl", GAZEUX, 35.45},
  {"Argon", "Ar", GAZEUX, 39.95},
  {"Potassium", "K", SOLIDE, 39.098},
  {"Calcium", "Ca", SOLIDE, 40.078},
  {"Scandium", "Sc", SOLIDE, 44.956},
  {"Titane", "Ti", SOLIDE, 47.867},
  {"Vanadium", "V", SOLIDE, 50.942},
  {"Chrome", "Cr", SOLIDE, 51.996},
  {"Manganèse", "Mn", SOLIDE, 54.938},
  {"Fer", "Fe", SOLIDE, 55.845},
  {"Cobalt", "Co", SOLIDE, 58.933},
  {"Nickel", "Ni", SOLIDE, 58.693},
  {"Cuivre", "Cu", SOLIDE, 63.546},
  {"Zinc", "Zn", SOLIDE, 65.38},
  {"Gallium", "Ga", SOLIDE, 69.723},
  {"Germanium", "Ge", SOLIDE, 72.63},
  {"Arsenic", "As", SOLIDE, 74.922},
  {"Sélénium", "Se", SOLIDE, 78.971},
  {"Brome", "Br", LIQUIDE, 79.904},
  {"Krypton", "Kr", GAZEUX, 83.798},
  {"Rubidium", "Rb", SOLIDE, 85.468},
  {"Strontium", "Sr", SOLIDE, 87.62},
  {"Yttrium", "Y", SOLIDE, 88.906},
  {"Zirconium", "Zr", SOLIDE, 91.224},
  {"Niobium", "Nb", SOLIDE, 92.906},
  {"Molybdène", "Mo", SOLIDE, 95.95},
  {"Technétium", "Tc", SOLIDE, 98.0},
  {"Ruthénium", "Ru", SOLIDE, 101.07},
  {"Rhodium", "Rh", SOLIDE, 102.91},
  {"Palladium", "Pd", SOLIDE, 106.42},
  {"Argent", "Ag", SOLIDE, 107.87},
  {"Cadmium", "Cd", SOLIDE, 112.41},
  {"Indium", "In", SOLIDE, 114.82},
  {"Étain", "Sn", SOLIDE, 118.71},
  {"Antimoine", "Sb", SOLIDE, 121.76},
  {"Tellure", "Te", SOLIDE, 127.6},
  {"Iode", "I", SOLIDE, 126.9},
  {"Xénon", "Xe", GAZEUX, 131.29},
  {"Césium", "Cs", SOLIDE, 132.91},
  {"Baryum", "Ba", SOLIDE, 137.33},
  {"Lanthane", "La", SOLIDE, 138.91},
  {"Cérium", "Ce", SOLIDE, 140.12},
  {"Praséodyme", "Pr", SOLIDE, 140.91},
  {"Néodyme", "Nd", SOLIDE, 144.24},
  {"Prométhium", "Pm", SOLIDE, 145.0},
  {"Samarium", "Sm", SOLIDE, 150.36},
  {"Europium", "Eu", SOLIDE, 152.0},
  {"Gadolinium", "Gd", SOLIDE, 157.25},
  {"Terbium", "Tb", SOLIDE, 158.93},
  {"Dysprosium", "Dy", SOLIDE, 162.50},
  {"Holmium", "Ho", SOLIDE, 164.93},
  {"Erbium", "Er", SOLIDE, 167.26},
  {"Thulium", "Tm", SOLIDE, 168.93},
  {"Ytterbium", "Yb", SOLIDE, 173.05},
  {"Lutécium", "Lu", SOLIDE, 175.00},
  {"Hafnium", "Hf", SOLIDE, 178.49},
  {"Tantale", "Ta", SOLIDE, 180.95},
  {"Tungstène", "W", SOLIDE, 183.84},
  {"Rhénium", "Re", SOLIDE, 186.21},
  {"Osmium", "Os", SOLIDE, 190.23},
  {"Iridium", "Ir", SOLIDE, 192.22},
  {"Platine", "Pt", SOLIDE, 195.08},
  {"Or", "Au", SOLIDE, 196.97},
  {"Mercure", "Hg", LIQUIDE, 200.59},
  {"Thallium", "Tl", SOLIDE, 204.38},
  {"Plomb", "Pb", SOLIDE, 207.2},
  {"Bismuth", "Bi", SOLIDE, 208.98},
  {"Polonium", "Po", SOLIDE, 209.98},
  {"Astate", "At", SOLIDE, 210.0},
  {"Radon", "Rn", GAZEUX, 222.0},
  {"Francium", "Fr", SOLIDE, 223.0},
  {"Radium", "Ra", SOLIDE, 226.0},
  {"Actinium", "Ac", SOLIDE, 227.0},
  {"Thorium", "Th", SOLIDE, 232.04},
  {"Protactinium", "Pa", SOLIDE, 231.04},
  {"Uranium", "U", SOLIDE, 238.03},
  {"Neptunium", "Np", SOLIDE, 237.0},
  {"Plutonium", "Pu", SOLIDE, 244.0},
  {"Américium", "Am", SOLIDE, 243.0},
  {"Curium", "Cm", SOLIDE, 247.0},
  {"Berkélium", "Bk", SOLIDE, 247.0},
  {"Californium", "Cf", SOLIDE, 251.0},
  {"Einsteinium", "Es", SOLIDE, 252.0},
  {"Fermium", "Fm", SOLIDE, 257.0},
  {"Mendélévium", "Md", SOLIDE, 258.0},
  {"Nobelium", "No", SOLIDE, 259.0},
  {"Lawrencium", "Lr", SOLIDE, 262.0},
  {"Rutherfordium", "Rf", INCONNU, 267.0},
  {"Dubnium", "Db", INCONNU, 270.0},
  {"Seaborgium", "Sg", INCONNU, 271.0},
  {"Bohrium", "Bh", INCONNU, 270.0},
  {"Hassium", "Hs", INCONNU, 277.0},
  {"Meitnérium", "Mt", INCONNU, 278.0},
  {"Darmstadtium", "Ds", INCONNU, 281.0},
  {"Roentgenium", "Rg", INCONNU, 282.0},
  {"Copernicium", "Cn", INCONNU, 285.0},
  {"Nihonium", "Nh", INCONNU, 286.0},
  {"Flerovium", "Fl", INCONNU, 289.0},
  {"Moscovium", "Mc", INCONNU, 289.0},
  {"Livermorium", "Lv", INCONNU, 293.0},
  {"Tennessine", "Ts", INCONNU, 294.0},
  {"Oganesson", "Og", INCONNU, 294.0}
};

const size_t nombreElements = sizeof tablePeriodique / sizeof * tablePeriodique;

void setup() {
  Serial.begin(115200);
  Serial.print(F("La table contient ")); Serial.print(nombreElements); Serial.println(F(" elements"));
  for (size_t i = 0; i < nombreElements; i++) {
    Serial.print("#"); Serial.print(i+1);
    Serial.write('\t'); Serial.print((__FlashStringHelper*) tablePeriodique[i].nom);
    Serial.write('\t'); Serial.print((__FlashStringHelper*) tablePeriodique[i].symbole);
    Serial.write('\t'); Serial.print(EtatText[pgm_read_byte(&tablePeriodique[i].etat)]);
    Serial.write('\t'); Serial.println(pgm_read_float(&tablePeriodique[i].masse_atomique));
  }
}

void loop() {}

le truc pour tout bien avoir en mémoire flash (PROGMEM) c'est d'avoir une taille max constante pour toutes les chaînes. On perd des octets bien sûr, mais ça simplifie grandement la vie.

sinon dans l'ancien temps j'avais appris

H - He (c'est facile)
Lili Bécha Bien Chez Notre Oncle Ferdinand-Nestor.
Napoléon Mangea Allègrement Six Poulets Sans Claquer d’ Argent
Khrouchtchev Caressa Sciemment Tito. Vorochev Cria Magnianime : Fé pas le Con Nikita, ton Cul en Zinc Galvanisé te Gène AsSez pour Branler des Krevettes
...

Oupss ! Excusez moi, j'ai inversé les numeros, mais je reverifirais tout avant le televersement "final"

Mais votre code est genial JML!!! Merci infiniment, vous avez tout fais, bravo a vous !!!!
Il ne me reste plus qu'a "l'incorporer" dans mon jeu, merci encore ! Mais j'ai une derniere question : vous affichez les elemens du tableau grace a la fonction bien connu : Serial.print(ln) mais moi je souhaiterais stocker ces donnees dans des 'char', comme dans mon code que j'ai mit dans mon premier message, mais un probleme survient lors de la compilation, je comprend le sens mais ne sait pas comment le resoudre : exit status 1 incompatible types in assignment of '__FlashStringHelper*' to 'char [20]' pourriez vous m'aider s'il vous plait a resoudre ce probleme.

Pourquoi les remmener en SRAM alors qu’ils sont déjà en flash ?

Il vous suffit de stocker l’indice dans le tableau si vous voulez retrouver un élément particulier

voici un exemple de tirage aléatoire

le bouton rouge pose une question aléatoire (nom du symbole), le bouton vert affiche la réponse


#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd;

const int nbCols = 20;
const int nbLignes = 4;

#include <OneButton.h>
OneButton question(2);
OneButton reponse(3);

enum Etat : uint8_t {INCONNU, SOLIDE, GAZEUX, LIQUIDE };
const char* EtatText[] = {"Inconu", "Solide", "Gazeux", "Liquide"};

struct Element {
  char nom[20];
  char symbole[3];
  Etat etat;
  float masse_atomique;
};

static const Element tablePeriodique[] PROGMEM = {
  {"Hydrogène", "H", GAZEUX, 1.008},
  {"Hélium", "He", GAZEUX, 4.0026},
  {"Lithium", "Li", SOLIDE, 6.94},
  {"Béryllium", "Be", SOLIDE, 9.0122},
  {"Bore", "B", SOLIDE, 10.81},
  {"Carbone", "C", SOLIDE, 12.011},
  {"Azote", "N", GAZEUX, 14.007},
  {"Oxygène", "O", GAZEUX, 15.999},
  {"Fluor", "F", GAZEUX, 18.998},
  {"Néon", "Ne", GAZEUX, 20.18},
  {"Sodium", "Na", SOLIDE, 22.99},
  {"Magnésium", "Mg", SOLIDE, 24.305},
  {"Aluminium", "Al", SOLIDE, 26.982},
  {"Silicium", "Si", SOLIDE, 28.085},
  {"Phosphore", "P", SOLIDE, 30.974},
  {"Soufre", "S", SOLIDE, 32.06},
  {"Chlore", "Cl", GAZEUX, 35.45},
  {"Argon", "Ar", GAZEUX, 39.95},
  {"Potassium", "K", SOLIDE, 39.098},
  {"Calcium", "Ca", SOLIDE, 40.078},
  {"Scandium", "Sc", SOLIDE, 44.956},
  {"Titane", "Ti", SOLIDE, 47.867},
  {"Vanadium", "V", SOLIDE, 50.942},
  {"Chrome", "Cr", SOLIDE, 51.996},
  {"Manganèse", "Mn", SOLIDE, 54.938},
  {"Fer", "Fe", SOLIDE, 55.845},
  {"Cobalt", "Co", SOLIDE, 58.933},
  {"Nickel", "Ni", SOLIDE, 58.693},
  {"Cuivre", "Cu", SOLIDE, 63.546},
  {"Zinc", "Zn", SOLIDE, 65.38},
  {"Gallium", "Ga", SOLIDE, 69.723},
  {"Germanium", "Ge", SOLIDE, 72.63},
  {"Arsenic", "As", SOLIDE, 74.922},
  {"Sélénium", "Se", SOLIDE, 78.971},
  {"Brome", "Br", LIQUIDE, 79.904},
  {"Krypton", "Kr", GAZEUX, 83.798},
  {"Rubidium", "Rb", SOLIDE, 85.468},
  {"Strontium", "Sr", SOLIDE, 87.62},
  {"Yttrium", "Y", SOLIDE, 88.906},
  {"Zirconium", "Zr", SOLIDE, 91.224},
  {"Niobium", "Nb", SOLIDE, 92.906},
  {"Molybdène", "Mo", SOLIDE, 95.95},
  {"Technétium", "Tc", SOLIDE, 98.0},
  {"Ruthénium", "Ru", SOLIDE, 101.07},
  {"Rhodium", "Rh", SOLIDE, 102.91},
  {"Palladium", "Pd", SOLIDE, 106.42},
  {"Argent", "Ag", SOLIDE, 107.87},
  {"Cadmium", "Cd", SOLIDE, 112.41},
  {"Indium", "In", SOLIDE, 114.82},
  {"Étain", "Sn", SOLIDE, 118.71},
  {"Antimoine", "Sb", SOLIDE, 121.76},
  {"Tellure", "Te", SOLIDE, 127.6},
  {"Iode", "I", SOLIDE, 126.9},
  {"Xénon", "Xe", GAZEUX, 131.29},
  {"Césium", "Cs", SOLIDE, 132.91},
  {"Baryum", "Ba", SOLIDE, 137.33},
  {"Lanthane", "La", SOLIDE, 138.91},
  {"Cérium", "Ce", SOLIDE, 140.12},
  {"Praséodyme", "Pr", SOLIDE, 140.91},
  {"Néodyme", "Nd", SOLIDE, 144.24},
  {"Prométhium", "Pm", SOLIDE, 145.0},
  {"Samarium", "Sm", SOLIDE, 150.36},
  {"Europium", "Eu", SOLIDE, 152.0},
  {"Gadolinium", "Gd", SOLIDE, 157.25},
  {"Terbium", "Tb", SOLIDE, 158.93},
  {"Dysprosium", "Dy", SOLIDE, 162.50},
  {"Holmium", "Ho", SOLIDE, 164.93},
  {"Erbium", "Er", SOLIDE, 167.26},
  {"Thulium", "Tm", SOLIDE, 168.93},
  {"Ytterbium", "Yb", SOLIDE, 173.05},
  {"Lutécium", "Lu", SOLIDE, 175.00},
  {"Hafnium", "Hf", SOLIDE, 178.49},
  {"Tantale", "Ta", SOLIDE, 180.95},
  {"Tungstène", "W", SOLIDE, 183.84},
  {"Rhénium", "Re", SOLIDE, 186.21},
  {"Osmium", "Os", SOLIDE, 190.23},
  {"Iridium", "Ir", SOLIDE, 192.22},
  {"Platine", "Pt", SOLIDE, 195.08},
  {"Or", "Au", SOLIDE, 196.97},
  {"Mercure", "Hg", LIQUIDE, 200.59},
  {"Thallium", "Tl", SOLIDE, 204.38},
  {"Plomb", "Pb", SOLIDE, 207.2},
  {"Bismuth", "Bi", SOLIDE, 208.98},
  {"Polonium", "Po", SOLIDE, 209.98},
  {"Astate", "At", SOLIDE, 210.0},
  {"Radon", "Rn", GAZEUX, 222.0},
  {"Francium", "Fr", SOLIDE, 223.0},
  {"Radium", "Ra", SOLIDE, 226.0},
  {"Actinium", "Ac", SOLIDE, 227.0},
  {"Thorium", "Th", SOLIDE, 232.04},
  {"Protactinium", "Pa", SOLIDE, 231.04},
  {"Uranium", "U", SOLIDE, 238.03},
  {"Neptunium", "Np", SOLIDE, 237.0},
  {"Plutonium", "Pu", SOLIDE, 244.0},
  {"Américium", "Am", SOLIDE, 243.0},
  {"Curium", "Cm", SOLIDE, 247.0},
  {"Berkélium", "Bk", SOLIDE, 247.0},
  {"Californium", "Cf", SOLIDE, 251.0},
  {"Einsteinium", "Es", SOLIDE, 252.0},
  {"Fermium", "Fm", SOLIDE, 257.0},
  {"Mendélévium", "Md", SOLIDE, 258.0},
  {"Nobelium", "No", SOLIDE, 259.0},
  {"Lawrencium", "Lr", SOLIDE, 262.0},
  {"Rutherfordium", "Rf", INCONNU, 267.0},
  {"Dubnium", "Db", INCONNU, 270.0},
  {"Seaborgium", "Sg", INCONNU, 271.0},
  {"Bohrium", "Bh", INCONNU, 270.0},
  {"Hassium", "Hs", INCONNU, 277.0},
  {"Meitnérium", "Mt", INCONNU, 278.0},
  {"Darmstadtium", "Ds", INCONNU, 281.0},
  {"Roentgenium", "Rg", INCONNU, 282.0},
  {"Copernicium", "Cn", INCONNU, 285.0},
  {"Nihonium", "Nh", INCONNU, 286.0},
  {"Flerovium", "Fl", INCONNU, 289.0},
  {"Moscovium", "Mc", INCONNU, 289.0},
  {"Livermorium", "Lv", INCONNU, 293.0},
  {"Tennessine", "Ts", INCONNU, 294.0},
  {"Oganesson", "Og", INCONNU, 294.0}
};

const size_t nombreElements = sizeof tablePeriodique / sizeof * tablePeriodique;

size_t questionChoisie;

void nouveauChoix() {
  questionChoisie = random(0, nombreElements);
  lcd.clear();
  lcd.print("Nom de ");
  lcd.print((__FlashStringHelper*) tablePeriodique[questionChoisie].symbole);
}

void afficheReponse() {
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("Symbole:"); lcd.print((__FlashStringHelper*) tablePeriodique[questionChoisie].symbole);
  lcd.setCursor(0, 1); lcd.print("nom:"); lcd.print((__FlashStringHelper*) tablePeriodique[questionChoisie].nom);
  lcd.setCursor(0, 2); lcd.print("Etat:"); lcd.print(EtatText[pgm_read_byte(&tablePeriodique[questionChoisie].etat)]);
  lcd.setCursor(0, 3); lcd.print("Masse:"); lcd.print(pgm_read_float(&tablePeriodique[questionChoisie].masse_atomique), 3);
}


void setup() {

  question.attachClick(nouveauChoix);
  reponse.attachClick(afficheReponse);

  int result = lcd.begin(nbCols, nbLignes);
  if (result) {
    Serial.print("erreur LCD");
    Serial.println(result);
    hd44780::fatalError(result);
  }

  randomSeed(analogRead(A0));

  nouveauChoix();
}

void loop() {
  question.tick();
  reponse.tick();
}

(attention le LCD ne sait pas afficher les accents, je n'ai pas corrigé les noms des éléments)

Merci JML pour cette derniere reponse, mais j'ai trouvé une autre solution, au lieu de ramener les donnees en SRAM je les "print" directement sur le LCD (j'ai aussi corriger les accents), c'est plus gourmand en lignes de code mais c'est le prix a payer !

je ne sais pas pourquoi vous dites cela

dans mon exemple ci dessus j'affiche sur le LCD les éléments, un par ligne il y a le positionnement du curseur puis le print. c'est pas bien compliqué

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.