Soucis avec supérieur ou égal

Hello tout le monde , j’ai un petit soucis j’ai créer un code qui fonctionne correctement suivant mes attentes .

Il s’agit d’un monnayeur électronique , avec affichage lcd .

Je m’explique le monnayeur accepte pour mes besoins 5 pièces . 0,1 0,2 0,5 1 et 2 euros

Le programme compte correctement

Il additionne bien les valeurs , j’y est ajouter une condition , quand la valeur est de 2euros ou supérieur et mon bouton est actionner alors il m’effectue une fonction jusque là tout va bien ça fonctionne bien , une fois la fonction terminé il me débite 2 unité . Pour cela tout est ok

Imaginons je met 1 euros puis 2 euros , cela me fait 3 euros , j’appuie sur le bouton m’a fonction de lance ok il me reste 1 euros je remet une pièce de 1 euro , il voit bien 2 euros , j’appuie sur le bouton rien ne se passe ... il me suffit de rajouter 10 centime et cela refonctionne , je ne comprend pas pourquoi .

Merci de votre aide , soyez indulgent si j’ai oublier quelques infos au passage c’est mon 1 er programme avec arduino

Bonjour gosigni

Pas top la photo d'écran, mets ton code en ligne en utilisant les balises
image

Cordialement
jpbbricole

bonjour le voici
cdt

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//Monnayeur GD 1
//int previouscredit=0;
const byte coinSig = A0;
const int Start = 2;
const int Buzz = 12;
bool previousCoinSignal = false;
const float coinValue = 0.1;
float bankValue = 0.00;
float credit = 0.0;
int counter=12;
long temps1=0 ;
unsigned long previousUpdateMillis = 0;
unsigned long updateInterval = 150;
bool printOnceFlag = false;
LiquidCrystal_I2C lcd(0x27, 16, 02);

void setup() {
  Serial.begin(115200);
  lcd.backlight();
  lcd.init();
  pinMode(coinSig, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(13 , OUTPUT);
  pinMode(12 , OUTPUT);
  previousCoinSignal = digitalRead(coinSig);

}
void printBank() {
  Serial.print("Bank Value :");
  Serial.println(bankValue);
  Serial.print("credit :");
  Serial.println(credit);
  lcd.setCursor(6, 01);
  lcd.print(credit); 
}

void Play() 

{
         lcd.clear();
    while (counter > 0){
         Decompte();

       lcd.setCursor(05, 0); 
       lcd.print("START!");

       lcd.setCursor(1, 1); 
       lcd.print("CHOOSE A GAME!");
       digitalWrite(13, HIGH);
    }
       digitalWrite(13, LOW);
       lcd.clear();
       bankValue = bankValue -2;
       credit =  bankValue;
       printBank();
      }

  
void Decompte() {
  if ((millis()-temps1)>=1*1000) {
    temps1=millis();
    counter = counter  -1;
  }

  lcd.setCursor(0, 0);
  lcd.print(counter);
  lcd.print("    ");

}

void loop() {
     byte currentCoinSignal = digitalRead(coinSig);
     lcd.setCursor(02, 0); 
     lcd.print("INSERT COIN!");




  if (currentCoinSignal == LOW) {
      previousUpdateMillis = millis();
      printOnceFlag = true;       
  }

  if (printOnceFlag && (millis() - previousUpdateMillis >= updateInterval)) {
      printBank();
      printOnceFlag = false;
  }    

  if (currentCoinSignal != previousCoinSignal) {
      previousCoinSignal = currentCoinSignal;

   if (currentCoinSignal == LOW) {
       bankValue = bankValue + coinValue;
       credit =  bankValue;
       

}
  }
  if (credit >= 2.00 && digitalRead(Start) == 0) {
      digitalWrite(Buzz, HIGH);
      delay(35);
      digitalWrite(Buzz, LOW);
      counter = 12;
      Play(); 
  }

}    

Vous êtes victime de la faible précision des nombre décimaux (float).

testez ce bout de code qui simule ce que vous expliquez comme scénario:

const float coinValue = 0.1;
float credit = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("On met 1 €");
  for (byte i = 0; i < 10; i++) credit += coinValue; // On met 1 €
  Serial.print("Crédit = "); Serial.println(credit, 9);

  Serial.println("On met 2 €");
  for (byte i = 0; i < 20; i++) credit += coinValue; // On met 2 €
  Serial.print("Crédit = "); Serial.println(credit, 9);

  Serial.println("On joue 2 secondes");
  delay(2000);

  Serial.println("Fin du jeu, on retire 2 crédits");
  credit -= 2;
  Serial.print("Crédit = "); Serial.println(credit, 9);

  Serial.println("On remet 1 €");
  for (byte i = 0; i < 10; i++) credit += coinValue; // On remet 1 €
  Serial.print("Crédit = "); Serial.println(credit, 9);

  if (credit >= 2) {
    Serial.print("Crédit >= 2");
  } else {
    Serial.print("Crédit < 2");
  }
}

void loop() {}

le moniteur série (à 115200 bauds) affichera

On met 1 €
Crédit = 1.000000119
On met 2 €
Crédit = 2.999999237
On joue 2 secondes
Fin du jeu, on retire 2 crédits
Crédit = 0.999999237
On remet 1 €
Crédit = 1.999999523
Crédit < 2

Vous voyez qu'avec des opérations qui semblent banales, on ne tombe pas pile sur des nombres multiples de 10 centimes. Quand vous faites ensuite des opérations vous passez pile sous la barre de 2€ avec 1.999999523 dans votre test.

:arrow_right:︎ Pour résoudre votre souci, comptez votre crédit en centimes avec un long par exemple si maintenant je fais

const long coinValue = 10;
long credit = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("On met 1 €");
  for (byte i = 0; i < 10; i++) credit += coinValue; // On met 1 €
  Serial.print("Crédit = "); Serial.println(credit/100.0, 9);

  Serial.println("On met 2 €");
  for (byte i = 0; i < 20; i++) credit += coinValue; // On met 2 €
  Serial.print("Crédit = "); Serial.println(credit/100.0, 9);

  Serial.println("On joue 2 secondes");
  delay(2000);

  Serial.println("Fin du jeu, on retire 2 crédits");
  credit -= 200;
  Serial.print("Crédit = "); Serial.println(credit/100.0, 9);

  Serial.println("On remet 1 €");
  for (byte i = 0; i < 10; i++) credit += coinValue; // On remet 1 €
  Serial.print("Crédit = "); Serial.println(credit/100.0, 9);

  if (credit >= 200) {
    Serial.print("Crédit >= 2");
  } else {
    Serial.print("Crédit < 2");
  }
}

void loop() {}

le moniteur série (à 115200 bauds) affichera

On met 1 €
Crédit = 1.000000000
On met 2 €
Crédit = 3.000000000
On joue 2 secondes
Fin du jeu, on retire 2 crédits
Crédit = 1.000000000
On remet 1 €
Crédit = 2.000000000
Crédit >= 2

:arrow_right:︎ tout est OK.

Pour votre code donc Un truc du genre

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//Monnayeur GD 1
const byte coinSig = A0;
const byte startPin = 2;
const byte buzzPin = 12;
bool previousCoinSignal = false;
const long coinValue = 10;
long bankValue = 0;
long credit = 0;
int counter = 12;
long temps1 = 0 ;
unsigned long previousUpdateMillis = 0;
unsigned long updateInterval = 150;
bool printOnceFlag = false;
LiquidCrystal_I2C lcd(0x27, 16, 02);

void printBank() {
  Serial.print("Bank Value :");
  Serial.println(bankValue);
  Serial.print("credit :");
  Serial.println(credit);
  lcd.setCursor(6, 01);
  lcd.print(credit / 100.0, 2);
}

void Decompte() {
  if ((millis() - temps1) >= 1000) {
    temps1 = millis();
    counter--;
  }
  lcd.setCursor(0, 0);
  lcd.print(counter);
  lcd.print("    ");
}

void Play() {

  lcd.setCursor(5, 0);
  lcd.print("START!");

  lcd.setCursor(1, 1);
  lcd.print("CHOOSE A GAME!");
  digitalWrite(13, HIGH);

  lcd.clear();
  while (counter > 0) Decompte();
  digitalWrite(13, LOW);

  lcd.clear();
  bankValue -= 200;
  credit =  bankValue;
  printBank();
}

void setup() {
  Serial.begin(115200);
  lcd.backlight();
  lcd.init();
  pinMode(coinSig, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(13 , OUTPUT);
  pinMode(12 , OUTPUT);
  previousCoinSignal = digitalRead(coinSig);
}

void loop() {
  byte currentCoinSignal = digitalRead(coinSig);
  lcd.setCursor(2, 0);
  lcd.print("INSERT COIN!");

  if (currentCoinSignal == LOW) {
    previousUpdateMillis = millis();
    printOnceFlag = true;
  }

  if (printOnceFlag && (millis() - previousUpdateMillis >= updateInterval)) {
    printBank();
    printOnceFlag = false;
  }

  if (currentCoinSignal != previousCoinSignal) {
    previousCoinSignal = currentCoinSignal;

    if (currentCoinSignal == LOW) {
      bankValue = bankValue + coinValue;
      credit =  bankValue;
    }
  }

  if (credit >= 200 && digitalRead(startPin) == 0) {
    digitalWrite(buzzPin, HIGH);
    delay(35);
    digitalWrite(buzzPin, LOW);
    counter = 12;
    Play();
  }

}

(non testé, juste modifié votre code)

super merci je vais tester cela je reviens vers vous
:grinning:

Super ça fonctionne nickel un grand merci

cool :slight_smile:
le diable se cache toujours dans les détails

Une règle générale quand on développe un programme qui gère de l'argent : toujours travailler en nombres entiers. Même les banques font cela car il y a toujours des erreurs d'arrondis quand on travaille avec des nombres décimaux.

c'est noté :wink: encore un grand merci ça faisait 2 jours que je bloqué sans comprendre pourquoi .

avec plaisir. Bonne continuation

Ou plutôt cupronickel puisque l'on parle pièces de monnaie
:wink:

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