REACTION GAME - meilleur score avec EEPROM

Bonjour à tous,

je suis débutant dans la programmation arduino,
j'essais de créer un jeu de rapidité : "réaction de game" mais me voila bloqué ( re re re bloqué)

ce qui marche pour le moment: ( sur une carte arduino uno R3 câblé,+ led + inter...etc)

  • le programme se lance,
  • le texte explicatif s'affiche sur l'écran LCD (16x2)
  • puis les LED (x6) s'allume aléatoirement 1 à une pendant 1minute
  • lorsque l'interrupteur est appuyé - la led allumé s'éteint puis une autre s'allume.
  • ensuite : fin du jeu
  • affichage du temps de réaction moyen
  • Si score supérieur à 0.30 = affichage de félicitation
  • on éteint et on rallume la carte pour relancer le jeu

et du coup!!!
Ce qui marche pas :

1er question:
je souhaite afficher le meilleur score précédent
puis le score de la précédente partie avant que le jeu demarre.
j'ai essayé quelque chose avec EEPROM :

      //ECRIRE LE NOUVEAU MEILLEUR SCORE
      EEPROM.write(2, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
      delay(50);

mais lorsque j'éteint et réallume , j'ai toujours le même score d'écrit ( soit : 0.25)
même lorsque je bat ce score
quelqu'un aurait une suggestion d'écriture?

programme complet ci dessous:
merci d'avance :slight_smile:


// OBJECTIF ALLUMER 6 LED EN DELAY ALEATOIRE;
// AFFICHER LE TEMPS DE REACTION "TOUCHE/LED ALLUME" (SUR 1MIN OU 20 CYCLES).

#include<EEPROM.h>

//BUZZER
int HP = A2;

//PARAMETRAGE LED/BOUTON & DUREE
byte led[6] = {10, 7, 6, 9, 13, A1};
const unsigned long dureeDuJeu = 10000UL; // 60 secondes ( 10sec pour essais)

//SENSOR
int pinBouton = 8;

//PARAMETRAGE ECRAN LCD 16X2
#include <LiquidCrystal.h>      // inclusion de la bibliothèque
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // Initialisation de la bibliothèque par rapport au cablage

void setup() {
  //LEDs comme OUTPUT
  for (byte i = 0; i < 6; i++)
    pinMode(led[i], OUTPUT);

  //Boutontouch comme INPUT
  pinMode(pinBouton, INPUT) ;

  //RECUPERER LES DONNEES MEILLEUR SCORE PRECEDENT
  float f = 0.00f;
  EEPROM.get(2, f);
  //EEPROM.get(3, f);fonctionne pas


  // EXPLICATION TEXTE DU PROGRAMME ................................................

  lcd.begin(16, 2);              // réglage du nombre de ligne et de colonne
  lcd.print("SPEED TEST"); // Affiche un message
  delay(3000);
  lcd.clear();

  lcd.print("MEILLEUR SCORE");
  lcd.setCursor(0, 1);
  lcd.print(f, 2);// AFFICHER MEILLEUR SCORE PRECEDENT
  delay(3000);
  lcd.clear();

  lcd.print("SCORE PRECEDENT");
  lcd.setCursor(0, 1);
  lcd.print(f, 3);// AFFICHER SCORE PRECEDENT
  delay(3000);
  lcd.clear();

  delay(50);
  lcd.print("--PRET--");
  tone(HP, 600, 1000);
  lcd.setCursor(0, 1);
  delay(3000);
  lcd.print("--ALLEZ!!!--");
  tone(HP, 1000, 1000);
  delay(3000);
  lcd.clear();
}

void loop()
{
  int lamp_aleatoire;

  float f = 0.00f;
  EEPROM.get(2, f);
  //EEPROM.get(3, f);

  //Enregistrer le temps de depart ( allumage led1)
  unsigned long tempsDebut;
  unsigned long cumulDesTemps = 0;
  unsigned long nombreDeTentatives = 0;
  unsigned long startLed;

  randomSeed(analogRead(3));

  tempsDebut = millis();
  delay(2000);

  while (millis() - tempsDebut <= dureeDuJeu) {
    unsigned long tempsCourant = 0;
    lamp_aleatoire = random(6);

    // ces lignes remplacent le switch case
    delay(random(180, 1500));    //Attendre un temps aléatoire en chaque led
    startLed = millis();    //Enregistrer le temps de depart ( allumage led1)
    digitalWrite(led[lamp_aleatoire], HIGH);  //Allumer la led
    while (digitalRead(pinBouton) == LOW);
    tempsCourant = millis() - startLed;
    digitalWrite(led[lamp_aleatoire], LOW);
    cumulDesTemps += tempsCourant;
    while (digitalRead(pinBouton) == HIGH);

    //Afficher le temps pendant le jeu
    nombreDeTentatives++;
    lcd.clear();
    lcd.print("Temps : ");
    lcd.print(tempsCourant / 1000.0);
    lcd.print(" s  "); // pour effacer s'il y a des caractères en trop
  }

  //CONDITIONS FIN DU JEU
  //AFFICHER LE TEMPS MOYEN
  //lcd.clear();
  // lcd.print("Temps Moyen :");
  // lcd.setCursor(0, 1);

  // SI PAS DE TOUCHE - ECHEC
  if (nombreDeTentatives == 0) {
    lcd.print("Echec");
  }

  // SI TOUCHE ALORS QUE LED NON ALLUMEE - ECHEC
  if (tempsCourant == 0) {
    lcd.print("Echec");
  }

  //SI TEMPS DE JEU TERMINE
  if (millis() > 1 * dureeDuJeu) {
    digitalWrite(led[6], HIGH);
    lcd.clear();
    lcd.print("FIN  !!");
    tone(HP, 1000, 1000);
    delay(3000);
    digitalWrite(led[6], LOW);
    lcd.clear();
    tone(HP, 1000, 1000);
    lcd.print("Temps Moyen :");
    lcd.setCursor(0, 1);
    lcd.print((cumulDesTemps / (nombreDeTentatives)) / 1000.0 );
    delay(3000);

    //ECRIRE LE NOUVEAU SCORE POUR HISTORIQUE
    EEPROM.write(3, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
    delay(50);

    //CONGRATULATION SI SCORE INF A 0.30
    if (((cumulDesTemps / (nombreDeTentatives)) / 1000.0) < 0.300) {
      lcd.clear();
      lcd.print("NIVEAU:");
      lcd.setCursor(0, 1);
      lcd.print("   EXCELLENT !!!");

      //ECRIRE LE NOUVEAU MEILLEUR SCORE
      EEPROM.write(2, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
      delay(50);
      digitalWrite(10, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(13, HIGH);
      digitalWrite(A1, HIGH);
      delay(3000);
      digitalWrite(10, LOW);
      digitalWrite(9, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      digitalWrite(13, LOW);
      digitalWrite(A1, LOW);
    }
  }

  // FIN DU JEU - ETEINDRE
  lcd.clear();
  lcd.print("FIN DU JEU");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("REDEM. LA CIBLE");
  lcd.setCursor(0, 1);
  lcd.print("POUR REJOUER");
  while (true) {
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(A1, HIGH);
    delay(1000);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(13, LOW);
    digitalWrite(A1, LOW);
    delay(1000);
  }
}

Bonjour manuellinki

Tu lis juste, en EEPROM avec EEPROM.get()
EEPROM.get(2, f);

Par contre pour écrire en EEPROM,
EEPROM.write(2, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
ne sauve que 8 bits.

Il faut faire:
EEPROM.put(2, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));

Cordialement
jpbbricole

Salut,

merci pour ta réponse
ça fonctionne mieux en effet.

pour sauvegarder le score précédent j'écris :

 //ECRIRE LE NOUVEAU SCORE POUR HISTORIQUE
    EEPROM.put(2, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
    delay(50);

pour sauvegarder le meilleur score précédent j'écrit:

 //CONGRATULATION SI SCORE INF A 0.28
    if (((cumulDesTemps / (nombreDeTentatives)) / 1000.0) < 0.280) {
      lcd.clear();
      lcd.print("NIVEAU:");
      lcd.setCursor(0, 1);
      lcd.print("   EXCELLENT !!!");

      //ECRIRE LE NOUVEAU MEILLEUR SCORE
      EEPROM.put(3, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
      delay(50);

puis je lis les précédent scores au debut du jeu comme ci dessous:

// EXPLICATION TEXTE DU PROGRAMME ................................................

  lcd.begin(16, 2);              // réglage du nombre de ligne et de colonne
  lcd.print("SPEED TEST"); // Affiche un message
  delay(3000);
  lcd.clear();

  lcd.print("DERNIER..");
  lcd.setCursor(0, 1);
  delay(2000);
  lcd.clear();
  lcd.print("MEILLEUR SCORE:");
  lcd.setCursor(0, 1);
  EEPROM.get(3, f);
  lcd.print(f, 2);// AFFICHER MEILLEUR SCORE PRECEDENT
  delay(3000);
  lcd.clear();

  lcd.print("SCORE PRECEDENT");
  lcd.setCursor(0, 1);
  EEPROM.get(2, f);
  lcd.print(f, 2);// AFFICHER SCORE PRECEDENT
  delay(3000);
  lcd.clear();

  delay(50);

parcontre, lorsque que je fait un meilleur score : exemple 0.28
et que à la partie précédente j'ai fait un score normal: exemple 0.90

j'ai bien le meilleur score qui s'affiche c-a-d 0.28 quand j'allume le jeu
mais le score normal qui s'affiche ensuite n'est pas 0.90 mais 0.00
( et c'est pareil dans l'autre sens si j'écrie en EEPROM.put(2,....etc) )

comme si le faite d'écrire sur l'un des emplacement de la mémoire effaçait l'autre ?

c'est possible ce que je demande finalement ?

Merci pour ta réponse en tout cas :slight_smile:

ci dessous le programme complet:


// OBJECTIF ALLUMER 6 LED EN DELAY ALEATOIRE;
// AFFICHER LE TEMPS DE REACTION "TOUCHE/LED ALLUME" (SUR 1MIN OU 20 CYCLES).

#include<EEPROM.h>

//BUZZER
int HP = A2;

//PARAMETRAGE LED/BOUTON & DUREE
byte led[6] = {10, 7, 6, 9, 13, A1};
const unsigned long dureeDuJeu = 10000UL; // 60 secondes ( 10sec pour essais)

//SENSOR
int pinBouton = 8;

//PARAMETRAGE ECRAN LCD 16X2
#include <LiquidCrystal.h>      // inclusion de la bibliothèque
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // Initialisation de la bibliothèque par rapport au cablage

void setup() {
  //LEDs comme OUTPUT
  for (byte i = 0; i < 6; i++)
    pinMode(led[i], OUTPUT);

  //Boutontouch comme INPUT
  pinMode(pinBouton, INPUT) ;

  //RECUPERER LES DONNEES MEILLEUR SCORE PRECEDENT
  float f = 0.00f;

  // EXPLICATION TEXTE DU PROGRAMME ................................................

  lcd.begin(16, 2);              // réglage du nombre de ligne et de colonne
  lcd.print("SPEED TEST"); // Affiche un message
  delay(3000);
  lcd.clear();

  lcd.print("DERNIER..");
  lcd.setCursor(0, 1);
  delay(2000);
  lcd.clear();
  lcd.print("MEILLEUR SCORE:");
  lcd.setCursor(0, 1);
  EEPROM.get(3, f);
  lcd.print(f, 2);// AFFICHER MEILLEUR SCORE PRECEDENT
  delay(3000);
  lcd.clear();

  lcd.print("SCORE PRECEDENT");
  lcd.setCursor(0, 1);
  EEPROM.get(2, f);
  lcd.print(f, 2);// AFFICHER SCORE PRECEDENT
  delay(3000);
  lcd.clear();

  delay(50);
  lcd.print("--PRET--");
  tone(HP, 600, 1000);
  lcd.setCursor(0, 1);
  delay(3000);
  lcd.print("--ALLEZ!!!--");
  tone(HP, 1000, 1000);
  delay(3000);
  lcd.clear();
}

void loop()
{
  int lamp_aleatoire;

  float f = 0.00f;

  //Enregistrer le temps de depart ( allumage led1)
  unsigned long tempsDebut;
  unsigned long cumulDesTemps = 0;
  unsigned long nombreDeTentatives = 0;
  unsigned long startLed;

  randomSeed(analogRead(3));

  tempsDebut = millis();
  delay(2000);

  while (millis() - tempsDebut <= dureeDuJeu) {
    unsigned long tempsCourant = 0;
    lamp_aleatoire = random(6);

    // ces lignes remplacent le switch case
    delay(random(180, 1500));    //Attendre un temps aléatoire en chaque led
    startLed = millis();    //Enregistrer le temps de depart ( allumage led1)
    digitalWrite(led[lamp_aleatoire], HIGH);  //Allumer la led
    while (digitalRead(pinBouton) == LOW);
    tempsCourant = millis() - startLed;
    digitalWrite(led[lamp_aleatoire], LOW);
    cumulDesTemps += tempsCourant;
    while (digitalRead(pinBouton) == HIGH);

    //Afficher le temps pendant le jeu
    nombreDeTentatives++;
    lcd.clear();
    lcd.print("Temps : ");
    lcd.print(tempsCourant / 1000.0);
    lcd.print(" s  "); // pour effacer s'il y a des caractères en trop
  }

  //CONDITIONS FIN DU JEU
  // SI PAS DE TOUCHE - ECHEC
  if (nombreDeTentatives == 0) {
    lcd.print("Echec");
  }

  // SI TOUCHE ALORS QUE LED NON ALLUMEE - ECHEC
  // if (tempsCourant == 0) {
  // lcd.print("Echec");
  // }

  //SI TEMPS DE JEU TERMINE
  if (millis() > 1 * dureeDuJeu) {
    digitalWrite(led[6], HIGH);
    lcd.clear();
    lcd.print("FIN  !!");
    tone(HP, 1000, 1000);
    delay(3000);
    digitalWrite(led[6], LOW);
    lcd.clear();
    tone(HP, 1000, 1000);
    lcd.print("Temps Moyen :");
    lcd.setCursor(0, 1);
    lcd.print((cumulDesTemps / (nombreDeTentatives)) / 1000.0 );
    delay(3000);

    //ECRIRE LE NOUVEAU SCORE POUR HISTORIQUE
    EEPROM.put(2, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
    delay(50);

    //CONGRATULATION SI SCORE INF A 0.28
    if (((cumulDesTemps / (nombreDeTentatives)) / 1000.0) < 0.280) {
      lcd.clear();
      lcd.print("NIVEAU:");
      lcd.setCursor(0, 1);
      lcd.print("   EXCELLENT !!!");

      //ECRIRE LE NOUVEAU MEILLEUR SCORE
      EEPROM.put(3, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
      delay(50);
      digitalWrite(10, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(13, HIGH);
      digitalWrite(A1, HIGH);
      delay(3000);
      digitalWrite(10, LOW);
      digitalWrite(9, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      digitalWrite(13, LOW);
      digitalWrite(A1, LOW);
    }
  }

  // FIN DU JEU - ETEINDRE
  lcd.clear();
  lcd.print("FIN DU JEU");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("REDEM. LA CIBLE");
  lcd.setCursor(0, 1);
  lcd.print("POUR REJOUER");
  while (true) {
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(A1, HIGH);
    delay(1000);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(13, LOW);
    digitalWrite(A1, LOW);
    delay(1000);
  }
}

Ça ne peut pas marcher comme ça.
Tu écris le premier score à l'adresse 2 et le second à l'adresse 3.
A chaque fois, tu veux écrire un float. Or, un float est codé sur 4 octets.
L'EEPROM stocke des octets, donc l'adresse que l'on passe en paramètre doit tenir compte de la taille des données que l'on écrit dans l'EEPROM.
Donc, si tu écris le premier score à l'adresse 2, il faut écrire le second 4 octets plus loin soit à l'adresse 6. Et si tu écris encore quelque chose après il faudra le mettre à l'adresse 10.

Pour éviter ces problèmes, tu pourrais faire

const int ADR_NOUVEAU_SCORE 2
const int ADR_MEILLEUR_SCORE (ADR_NOUVEAU_SCORE + sizeof(float))

et ensuite tu fais

 //ECRIRE LE NOUVEAU SCORE POUR HISTORIQUE
    EEPROM.put(ADR_NOUVEAU_SCORE, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));
    delay(50);
....
      //ECRIRE LE NOUVEAU MEILLEUR SCORE
      EEPROM.put(ADR_MEILLEUR_SCORE, ((cumulDesTemps / (nombreDeTentatives)) / 1000.0));

Bonjour,

Parfait!
merci @fdufnews

quand j'ai lu comment utiliser eeprom j'avais pas saisie l'histoire des octets.
merci pour l'explication tout fonctionne correctement maintenant.

le sujet est clos pour moi, (pour le moment...)

bonne continuation :slight_smile: