Débutant sur un gros projet de b**** d'airsoft

Bonsoir blazerwood

C'est l'accès à ce menu ORGA n'importe où et n'importe à quel moment que tu ne sait pas faire?

A+
Bonne soirée
jpbbricole

non quoi que je code, je n'arrive pas à y avoir accès. Du coup j'avais tout supprimé.

Le problème est que tu veux y accéder depuis n'importe où et n'importe quand, la structure de ton programme ne s'y prête que difficilement.
Je vais regarder ça, demain.

Oui en gros qu'une partie soit lancée, ou que je sois simplement dans le menu,je dois pouvoir accéder à ce menu caché avec cette combinaison de touche. Ou alors si vous avez une meilleure idée pour y accéder sans que les joueurs sachent. C'est sympa merci. La j'ai atteint ma limite de compétence.

Bonjour blazerwood

Pourrais tu mettre ta dernière version en ligne?

Bonne journée
jpbbricole

bonjour jpbbricole

#include <Wire.h>
#include <Keypad.h>
#include <Keypad_I2C.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <MFRC522.h>
#include <SPI.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

const int keybI2cAddress = 0x25;
const byte keybRowsNbr = 4;
const byte keybColsNbr = 4;

char keysMap[keybRowsNbr][keybColsNbr] =
{
  {'D', 'C', 'B', 'A'},
  {'#', '9', '6', '3'},
  {'0', '8', '5', '2'},
  {'*', '7', '4', '1'}
};

byte keybRowPins[keybRowsNbr] = {3, 2, 1, 0};
byte keybColPins[keybColsNbr] = {7, 6, 5, 4};

Keypad_I2C customKeypad(makeKeymap(keysMap), keybRowPins, keybColPins, keybRowsNbr, keybColsNbr, keybI2cAddress);

const int lcdAAddress = 0x26;
const int lcdBAddress = 0x27;

LiquidCrystal_I2C lcdA(lcdAAddress, 20, 4);
LiquidCrystal_I2C lcdB(lcdBAddress, 20, 4);

String gameModes[5] = {
  "Search & destroy",
  "Matchs a Mort",
  "Dominations",
  "Piratage",
  "Decryptage",
};

const int ledColorIndex[] = {5, 6, 7};
const int ledNumber = sizeof(ledColorIndex) / sizeof(ledColorIndex[0]);
const int ledOn = HIGH;

const int servoPin = 8;
Servo myServo;

unsigned long timerDuration;
unsigned long startTime;
bool bombExploded = false;

String disarmCode;  // Variable pour stocker le code de désarmement
String enteredCode = "";  // Variable pour stocker le code entré par l'utilisateur

void displayMessage(LiquidCrystal_I2C& lcd, const String& line1, const String& line2, int delayTime = 1000) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(line1);
  lcd.setCursor(0, 1);
  lcd.print(line2);
  delay(delayTime);
}

bool isRFIDCardPresent() {
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    return true;
  }
  return false;
}

void checkRFIDCard() {
  if (isRFIDCardPresent()) {
    digitalWrite(ledColorIndex[0], HIGH);
    delay(1000);
    digitalWrite(ledColorIndex[0], !ledOn);
  }
}

void disarmCodeSetup() {
  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Entrez le code:");
  delay(1000);

  disarmCode = "";

  while (disarmCode.length() < 4) {
    char key = customKeypad.getKey();
    if (key >= '0' && key <= '9') {
      disarmCode += key;
      lcdA.print('*');
    }
    delay(100);
  }

  delay(1000);
  displayMessage(lcdA, "Code enregistrer:", disarmCode, 2000);
}

void displayDisarmCode(const String& code) {
  lcdB.clear();
  lcdB.setCursor(0, 0);
  lcdB.print("Entrez le code:");
  lcdB.setCursor(0, 1);
  for (size_t i = 0; i < code.length(); ++i) {
    lcdB.print('*');
  }
}

void disarmBomb() {
  static String enteredCode = "";  // Maintenant une variable statique pour préserver sa valeur entre les appels
  static unsigned long lastDisplayTime = 0;

  char key = customKeypad.getKey();

  if (key != NO_KEY && (key >= '0' && key <= '9') && enteredCode.length() < 4 && !bombExploded) {
    enteredCode += key;
    lastDisplayTime = millis();
  }

  // Si la longueur du code est de 4 caractères, vérifier le code
  if (enteredCode.length() == 4 && !bombExploded) {
    if (enteredCode == disarmCode) {
      bombExploded = true;
      digitalWrite(ledColorIndex[2], !ledOn);

      // myServo.write(90); // Comment this line to prevent servo action on correct code entry
      // delay(2000);
      // myServo.write(0);

      lcdB.clear();
      lcdB.setCursor(0, 0);
      lcdB.print("Bombe desamorcee !");
      delay(3000);

      // Attendre la lecture du badge NFC
      waitForNFCCard();

    } else {
      displayMessage(lcdB, "Code incorrect!", "Reessayez.", 2000);
      enteredCode = "";  // Réinitialiser le code après une tentative incorrecte
      lastDisplayTime = millis();
    }
  }

  // Afficher le code pendant une période définie après chaque pression de touche
  if (millis() - lastDisplayTime < 3000) {
    displayDisarmCode(enteredCode);
  } else {
    displayDisarmCode("");  // Effacer le code après la période définie
  }
}

int selectGameMode() {
  int selectedMode = -1;

  for (int i = 0; i < 5; i++) {
    displayMessage(lcdB, "Mode de Jeux (" + String(i + 1) + ")", gameModes[i], 1000);
  }

  displayMessage(lcdB, "Faites votre choix:", "(1-5)", 500);

  while (selectedMode < 1 || selectedMode > 5) {
    char key = customKeypad.getKey();
    if (key != NO_KEY && key >= '1' && key <= '5') {
      selectedMode = key - '0';

      lcdB.clear();
      lcdB.setCursor(0, 0);
      lcdB.print("Mode choisi: ");
      lcdB.print(selectedMode);

      lcdB.setCursor(0, 1);
      lcdB.print(" - ");
      lcdB.print(gameModes[selectedMode - 1]);

      delay(3000);
    }
  }

  return selectedMode;
}

bool waitForNFCCard() {
  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Attente du badge NFC...");

  unsigned long startTime = millis(); // Enregistrez le temps au début

  // Attendez que la carte NFC soit présente
  while (!isRFIDCardPresent()) {
    delay(100);
  }

  // La carte NFC a été détectée
  digitalWrite(ledColorIndex[0], HIGH); // Allumez la LED verte
  delay(1000); // Maintenez la LED allumée pendant 1 seconde

  // Réinitialiser l'état du module RFID
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();

  digitalWrite(ledColorIndex[0], !ledOn); // Éteignez la LED verte

  // Affichez le message de votre choix sur l'écran A
  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Veuillez choisir");
  lcdA.setCursor(0, 1);
  lcdA.print("le mode de jeux.");

  return true; // Si une carte est lue, retournez true
}


void setup() {
  Wire.begin();
  customKeypad.begin();
  Serial.begin(115200);

  SPI.begin();
  mfrc522.PCD_Init();
  setupBuzzer();

  myServo.attach(servoPin);
  myServo.write(0);

  for (int l = 0; l < ledNumber; l++) {
    pinMode(ledColorIndex[l], OUTPUT);
    digitalWrite(ledColorIndex[l], !ledOn);
  }

  lcdA.init();
  lcdB.init();
  lcdA.backlight();
  lcdB.backlight();
  lcdA.begin(16, 2);
  lcdB.begin(16, 2);

  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("GEARS AIRSOFT");
  delay(3000);

  lcdB.clear();
  lcdB.setCursor(0, 0);
  lcdB.print("Activation");
  digitalWrite(ledColorIndex[0], HIGH);
  delay(2000);

  lcdB.clear();
  lcdB.setCursor(0, 0);
  lcdB.print("Activation OK");
  delay(3000);
  digitalWrite(ledColorIndex[0], !ledOn); // Éteindre la LED verte
}

void loop() {
  int selectedMode;

  digitalWrite(ledColorIndex[1], HIGH);

  selectedMode = selectGameMode();

  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Temps (min):");

  int selectedTime = 0;
  bool timeSelectionComplete = false;

  while (!timeSelectionComplete) {
    char key = customKeypad.getKey();
    if (key >= '0' && key <= '9') {
      selectedTime = selectedTime * 10 + (key - '0');
      lcdA.print(key);
    } else if (key == '#') {
      timeSelectionComplete = true;
    } else if (key == '*') {
      if (selectedTime > 0) {
        selectedTime = selectedTime / 10;
        lcdA.clear();
        lcdA.setCursor(0, 0);
        lcdA.print("Temps (min):");
        lcdA.print(selectedTime);
      }
    }

    checkRFIDCard();  // Vérifier la carte RFID à chaque itération

    delay(100);
  }

  disarmCodeSetup();  // Appeler la configuration du code de désarmement après la sélection du temps

  digitalWrite(ledColorIndex[1], !ledOn);

  timerDuration = selectedTime * 60L * 1000L;
  startTime = millis();
  bombExploded = false;

  digitalWrite(ledColorIndex[2], HIGH);

  while (millis() - startTime < timerDuration && !bombExploded) {
    unsigned long remainingTime = timerDuration - (millis() - startTime);
    unsigned long remainingMinutes = remainingTime / 1000 / 60;
    unsigned long remainingSeconds = (remainingTime / 1000) % 60;

    lcdB.clear();
    lcdA.clear();
    lcdA.setCursor(0, 0);
    lcdA.print("Temps restant:");
    lcdA.setCursor(0, 1);
    lcdA.print(remainingMinutes);
    lcdA.print(" min ");
    lcdA.print(remainingSeconds);
    lcdA.print(" sec");

    if ((millis() - startTime) % 500 < 250) {
      digitalWrite(ledColorIndex[2], HIGH);
    } else {
      digitalWrite(ledColorIndex[2], LOW);
    }

    disarmBomb();  // Appeler la fonction de désamorçage à chaque itération de la boucle principale

    checkRFIDCard();  // Vérifier la carte RFID à chaque itération

    delay(100);
  }

  if (!bombExploded && millis() - startTime >= timerDuration) {
    myServo.write(90);
    delay(2000);
    myServo.write(0);
  }

  for (int l = 0; l < ledNumber; l++) {
    digitalWrite(ledColorIndex[l], !ledOn);
  }

  if (!bombExploded) {
    digitalWrite(ledColorIndex[2], HIGH);
    lcdB.clear();
    lcdB.setCursor(0, 0);
    lcdB.print("BOOOOM !");
    lcdB.setCursor(0, 1);
    lcdB.print("Bombe Explosée !");
    delay(3000);

    lcdA.clear();
    lcdA.setCursor(0, 0);
    lcdA.print("Veuillez présenter");
    lcdA.setCursor(0, 1);
    lcdA.print("votre badge ORGA.");

    // Attendre la lecture du badge NFC avant de passer à la suite
    waitForNFCCard();

    digitalWrite(ledColorIndex[0], HIGH);
    delay(1000);
    digitalWrite(ledColorIndex[0], !ledOn);
    digitalWrite(ledColorIndex[2], !ledOn);

    lcdA.clear();
    lcdA.setCursor(0, 0);
    lcdA.print("Veuillez choisir");
    lcdA.setCursor(0, 1);
    lcdA.print("le mode de jeux");
    digitalWrite(ledColorIndex[0], !ledOn);
  }
  const int buzzerPin = 4;

void setupBuzzer() {
  pinMode(buzzerPin, OUTPUT);
  digitalWrite(buzzerPin, LOW);
}

void playBuzzerSound(int duration) {
  digitalWrite(buzzerPin, HIGH);
  delay(duration);
  digitalWrite(buzzerPin, LOW);

}

Utilises tu l'IDE Arduino pour développer ?

oui

Bonjour blazerwood

Afin de poursuivre nos investigations, j'ai dû "réaménager", un peu, ton programme, essentiellement du fait que nos entrées/sorties ne sont pas les mêmes. Pour ce faire, j'utilise l'assemblage conditionnel réglé par cette ligne:
#define blazerwood // A mettre en remarque si jpbbricole
Si cette ligne est ainsi, c'est tes paramètres qui sont compilés.
Si elle est ainsi:
//#define blazerwood // A mettre en remarque si jpbbricole
ce sont les miens, donc à contrôler quand je te passe une version corrigée :wink:
Pour choisir les paramètres, la "mécanique" est ainsi, pour exemple:

//------------------------------------- Affichages LCD
#ifdef blazerwood
	const int lcdAadresse = 0x26;     // Adresse du premier écran
	const int lcdBadresse = 0x27;     // Adresse du second écran
#else
	const int lcdAadresse = 0x26;     // Adresse du premier écran
	const int lcdBadresse = 0x3F;     // Adresse du second écran
#endif

Ainsi, je te passe ta version "réaménagée" afin que tu me dises quelle fonctionne comme avant.
La prochaine étape est que tu veux intercepter le code #* afin de lancer le menu ORGE, juste?

J'ai essayé ton programme, pas au complet, tu as fait un super boulot, ti maîtrises :+1:

Le programme:

#include <Wire.h>
#include <Keypad.h>
#include <Keypad_I2C.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <MFRC522.h>
#include <SPI.h>

#define blazerwood     // A mettre en remarque si jpbbricole

//------------------------------------- RFID
#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

//------------------------------------- Clavier
#ifdef blazerwood
	const int keybI2cAddress = 0x25;
#else     // jpbbricole
	const int keybI2cAddress = 0x38;
#endif
const byte keybRowsNbr = 4;
const byte keybColsNbr = 4;

char keysMape[keybRowsNbr][keybColsNbr] =
{
	#ifdef blazerwood
	{'D', '#', '0', '*'},
	{'C', '9', '8', '7'},
	{'B', '6', '5', '4'},
	{'A', '3', '2', '1'}
	#else
	{'1','2','3','A'},
	{'4','5','6','B'},
	{'7','8','9','C'},
	{'*','0','#','D'}
	#endif
};

#ifdef blazerwood
	byte keybRowPins[keybRowsNbr] = {3, 2, 1, 0};
	byte keybColPins[keybColsNbr] = {7, 6, 5, 4};
#else
	byte keybRowPins[keybRowsNbr] = {7, 6, 5, 4};     // Connexion des lignes
	byte keybColPins[keybColsNbr] = {3, 2, 1, 0};     // Connexion des colonnes
#endif

Keypad_I2C customKeypad(makeKeymap(keysMape), keybRowPins, keybColPins, keybRowsNbr, keybColsNbr, keybI2cAddress);

//------------------------------------- Affichages LCD
#ifdef blazerwood
	const int lcdAadresse = 0x26;     // Adresse du premier écran
	const int lcdBadresse = 0x27;     // Adresse du second écran
#else
	const int lcdAadresse = 0x26;     // Adresse du premier écran
	const int lcdBadresse = 0x3F;     // Adresse du second écran
#endif

LiquidCrystal_I2C lcdA(lcdAadresse, 20, 4);
LiquidCrystal_I2C lcdB(lcdBadresse, 20, 4);

String gameModes[5] = {
	"Search & destroy",
	"Matchs a Mort",
	"Dominations",
	"Piratage",
	"Decryptage",
};

const int ledColorIndex[] = {5, 6, 7};
const int ledNumber = sizeof(ledColorIndex) / sizeof(ledColorIndex[0]);
const int ledOn = HIGH;

const int servoPin = 8;
Servo myServo;

unsigned long timerDuration;
unsigned long startTime;
bool bombExploded = false;

String disarmCode;  // Variable pour stocker le code de désarmement
String enteredCode = "";  // Variable pour stocker le code entré par l'utilisateur

const int buzzerPin = 4;
void setup()
{
	Wire.begin();
	customKeypad.begin();
	Serial.begin(115200);

	SPI.begin();
	mfrc522.PCD_Init();
	setupBuzzer();

	myServo.attach(servoPin);
	myServo.write(0);

	for (int l = 0; l < ledNumber; l++) {
		pinMode(ledColorIndex[l], OUTPUT);
		digitalWrite(ledColorIndex[l], !ledOn);
	}

	lcdA.init();
	lcdB.init();
	lcdA.backlight();
	lcdB.backlight();
	lcdA.begin(16, 2);
	lcdB.begin(16, 2);

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("GEARS AIRSOFT");
	delay(3000);

	lcdB.clear();
	lcdB.setCursor(0, 0);
	lcdB.print("Activation");
	digitalWrite(ledColorIndex[0], HIGH);
	delay(2000);

	lcdB.clear();
	lcdB.setCursor(0, 0);
	lcdB.print("Activation OK");
	delay(3000);
	digitalWrite(ledColorIndex[0], !ledOn); // Éteindre la LED verte
}

void loop() 
{
	int selectedMode;

	digitalWrite(ledColorIndex[1], HIGH);

	selectedMode = selectGameMode();

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Temps (min):");

	int selectedTime = 0;
	bool timeSelectionComplete = false;

	while (!timeSelectionComplete) 
	{
		char key = customKeypad.getKey();
		if (key >= '0' && key <= '9') 
		{
			selectedTime = selectedTime * 10 + (key - '0');
			lcdA.print(key);
			} 
				else if (key == '#') 
			{
				timeSelectionComplete = true;
			} 
			else if (key == '*') 
			{
			if (selectedTime > 0) 
			{
				selectedTime = selectedTime / 10;
				lcdA.clear();
				lcdA.setCursor(0, 0);
				lcdA.print("Temps (min):");
				lcdA.print(selectedTime);
			}
		}

		checkRFIDCard();  // Vérifier la carte RFID à chaque itération

		delay(100);
	}

	disarmCodeSetup();  // Appeler la configuration du code de désarmement après la sélection du temps

	digitalWrite(ledColorIndex[1], !ledOn);

	timerDuration = selectedTime * 60L * 1000L;
	startTime = millis();
	bombExploded = false;

	digitalWrite(ledColorIndex[2], HIGH);

	while (millis() - startTime < timerDuration && !bombExploded) 
	{
		unsigned long remainingTime = timerDuration - (millis() - startTime);
		unsigned long remainingMinutes = remainingTime / 1000 / 60;
		unsigned long remainingSeconds = (remainingTime / 1000) % 60;

		lcdB.clear();
		lcdA.clear();
		lcdA.setCursor(0, 0);
		lcdA.print("Temps restant:");
		lcdA.setCursor(0, 1);
		lcdA.print(remainingMinutes);
		lcdA.print(" min ");
		lcdA.print(remainingSeconds);
		lcdA.print(" sec");

		if ((millis() - startTime) % 500 < 250) 
		{
			digitalWrite(ledColorIndex[2], HIGH);
		} 
		else 
		{
			digitalWrite(ledColorIndex[2], LOW);
		}

		disarmBomb();  // Appeler la fonction de désamorçage à chaque itération de la boucle principale

		checkRFIDCard();  // Vérifier la carte RFID à chaque itération

		delay(100);
	}

	if (!bombExploded && millis() - startTime >= timerDuration) 
	{
		myServo.write(90);
		delay(2000);
		myServo.write(0);
	}

	for (int l = 0; l < ledNumber; l++) 
	{
		digitalWrite(ledColorIndex[l], !ledOn);
	}

	if (!bombExploded) 
	{
		digitalWrite(ledColorIndex[2], HIGH);
		lcdB.clear();
		lcdB.setCursor(0, 0);
		lcdB.print("BOOOOM !");
		lcdB.setCursor(0, 1);
		lcdB.print("Bombe Explosée !");
		delay(3000);

		lcdA.clear();
		lcdA.setCursor(0, 0);
		lcdA.print("Veuillez présenter");
		lcdA.setCursor(0, 1);
		lcdA.print("votre badge ORGA.");

		// Attendre la lecture du badge NFC avant de passer à la suite
		waitForNFCCard();

		digitalWrite(ledColorIndex[0], HIGH);
		delay(1000);
		digitalWrite(ledColorIndex[0], !ledOn);
		digitalWrite(ledColorIndex[2], !ledOn);

		lcdA.clear();
		lcdA.setCursor(0, 0);
		lcdA.print("Veuillez choisir");
		lcdA.setCursor(0, 1);
		lcdA.print("le mode de jeux");
		digitalWrite(ledColorIndex[0], !ledOn);
	}
}

void displayMessage(LiquidCrystal_I2C& lcd, const String& line1, const String& line2, int delayTime = 1000) 
{
	lcd.clear();
	lcd.setCursor(0, 0);
	lcd.print(line1);
	lcd.setCursor(0, 1);
	lcd.print(line2);
	delay(delayTime);
}

bool isRFIDCardPresent() 
{
	if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) 
	{
		return true;
	}
	return false;
}

void checkRFIDCard() {
	if (isRFIDCardPresent()) 
	{
		digitalWrite(ledColorIndex[0], HIGH);
		delay(1000);
		digitalWrite(ledColorIndex[0], !ledOn);
	}
}

void disarmCodeSetup() 
{
	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Entrez le code:");
	delay(1000);

	disarmCode = "";

	while (disarmCode.length() < 4) 
	{
		char key = customKeypad.getKey();
		if (key >= '0' && key <= '9') 
		{
			disarmCode += key;
			lcdA.print('*');
		}
		delay(100);
	}

	delay(1000);
	displayMessage(lcdA, "Code enregistrer:", disarmCode, 2000);
}

void displayDisarmCode(const String& code) 
{
	lcdB.clear();
	lcdB.setCursor(0, 0);
	lcdB.print("Entrez le code:");
	lcdB.setCursor(0, 1);
	for (size_t i = 0; i < code.length(); ++i) 
	{
		lcdB.print('*');
	}
}

void disarmBomb() 
{
	static String enteredCode = "";  // Maintenant une variable statique pour préserver sa valeur entre les appels
	static unsigned long lastDisplayTime = 0;

	char key = customKeypad.getKey();

	if (key != NO_KEY && (key >= '0' && key <= '9') && enteredCode.length() < 4 && !bombExploded) 
	{
		enteredCode += key;
		lastDisplayTime = millis();
	}

	// Si la longueur du code est de 4 caractères, vérifier le code
	if (enteredCode.length() == 4 && !bombExploded) 
	{
		if (enteredCode == disarmCode) 
		{
			bombExploded = true;
			digitalWrite(ledColorIndex[2], !ledOn);

			// myServo.write(90); // Comment this line to prevent servo action on correct code entry
			// delay(2000);
			// myServo.write(0);

			lcdB.clear();
			lcdB.setCursor(0, 0);
			lcdB.print("Bombe desamorcee !");
			delay(3000);

			// Attendre la lecture du badge NFC
			waitForNFCCard();
		} 
		else 
		{
			displayMessage(lcdB, "Code incorrect!", "Reessayez.", 2000);
			enteredCode = "";  // Réinitialiser le code après une tentative incorrecte
			lastDisplayTime = millis();
		}
	}

	// Afficher le code pendant une période définie après chaque pression de touche
	if (millis() - lastDisplayTime < 3000) {
		displayDisarmCode(enteredCode);
		} else {
		displayDisarmCode("");  // Effacer le code après la période définie
	}
}

int selectGameMode() 
{
	int selectedMode = -1;

	for (int i = 0; i < 5; i++) 
	{
		displayMessage(lcdB, "Mode de Jeux (" + String(i + 1) + ")", gameModes[i], 1000);
	}

	displayMessage(lcdB, "Faites votre choix:", "(1-5)", 500);

	while (selectedMode < 1 || selectedMode > 5) 
	{
		char key = customKeypad.getKey();
		if (key != NO_KEY && key >= '1' && key <= '5') 
		{
			selectedMode = key - '0';

			lcdB.clear();
			lcdB.setCursor(0, 0);
			lcdB.print("Mode choisi: ");
			lcdB.print(selectedMode);

			lcdB.setCursor(0, 1);
			lcdB.print(" - ");
			lcdB.print(gameModes[selectedMode - 1]);

			delay(3000);
		}
	}

	return selectedMode;
}

bool waitForNFCCard() 
{
	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Attente du badge NFC...");

	unsigned long startTime = millis(); // Enregistrez le temps au début

	// Attendez que la carte NFC soit présente
	while (!isRFIDCardPresent()) 
	{
		delay(100);
	}

	// La carte NFC a été détectée
	digitalWrite(ledColorIndex[0], HIGH); // Allumez la LED verte
	delay(1000); // Maintenez la LED allumée pendant 1 seconde

	// Réinitialiser l'état du module RFID
	mfrc522.PICC_HaltA();
	mfrc522.PCD_StopCrypto1();

	digitalWrite(ledColorIndex[0], !ledOn); // Éteignez la LED verte

	// Affichez le message de votre choix sur l'écran A
	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Veuillez choisir");
	lcdA.setCursor(0, 1);
	lcdA.print("le mode de jeux.");

	return true; // Si une carte est lue, retournez true
}



//------------------------------------- Buzzer
void setupBuzzer() 
{
	pinMode(buzzerPin, OUTPUT);
	digitalWrite(buzzerPin, LOW);
}

void playBuzzerSound(int duration) 
{
	digitalWrite(buzzerPin, HIGH);
	delay(duration);
	digitalWrite(buzzerPin, LOW);

}

A+
Bonne après midi
jpbbricole

Super merci c'est bien compris.

Non, il y a un petit souci. Quand la bombe a déjà fait un cycle, si je relance une partie lors du choix du code de désamorçage, cela me dit 'bombe désamorcée' sans lancer de partie.

Déja oui pour voir comment ton menu est affiché et y intégré les différentes actions.

Merci mais moi, je ne sais pas.... Je ne suis pas satisfait :pensive:

Mon réaménagement n'aurait pas influencer ceci?

Je n'avais pas ce problème auparavant. Je ne sais pas, je ne comprends pas où est l'appel de la fonction.

Quel est le nom de cette fonction?

Est ce que cette version a aussi ce problème?

Pour être franc, à force de faire 500 modifications, je ne m'en souviens plus... Et je n'arrive à rien.

Effectivement, ma version avait ce problème. Je ne comprends pas, car avant je n'avais pas ce souci...

Je vair regarder ça plus tard, pour le moment, je vais "m'imprégner" de ton programme et, par petites touches le modifier afin de le rendre plus facilement modifiable :wink:

C'est super sympa ! Car je commence à m'y perdre à force de modifier toutes les 5 minutes. :sweat_smile:

Nouveau bug et là ehhhhh je ne sais pas :joy:. J'ai oublié de passer le badge pendant 20 minutes, et si je le scanne, il ne le lit pas.

Bonsoir blazerwood

Voici la première mouture réaménagée, je n'ai rien touché à ton code, j'ai ajouté la notion jeuEtat qui indique l'état actuel du jeu, c'est régi par cette partie:

//------------------------------------- Etats du jeu
enum {                         jeuEtatDemarrage, jeuEtatSelMode, jeuEtatSelTime, jeuEtatSelCode, jeuEtatEnCours, jeuEtatBombeBoom, jeuEtatBombeToOff, jeuEtatAttNfc, jeuEtatFin, jeuEtatArrete};
const String jeuEtatLabel [] = {"Demarrage",     "Select mode",   "Select time", "Select code",   "En cours",     "Bombe BOOM",      "Bombe desamorcee",   "Att. NFC",    "Fin",       "Arrete"};	

et dans la console (115200), il y a le déroulement du programme, ce qui te permet, dans la phase de développement, d'y voir plus clair :wink:

Etat Demarrage
	Setup()
Etat Select mode
	selectGameMode()
Etat Select mode
	Search & destroy
Etat Select time
	Loop()
Etat Select time
	1
Etat Select code
	disarmCodeSetup()
Etat Select code
	1111
Etat En cours
	while (millis() - startTime
Etat Bombe BOOM
	if (!bombExploded)
Etat Att. NFC
	waitForNFCCard()

Dis moi ce tu en penses.

Le programme:

//	09.12.2023	Ajout des états #121

#include <Wire.h>
#include <Keypad.h>
#include <Keypad_I2C.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <MFRC522.h>
#include <SPI.h>

#define blazerwood     // A mettre en remarque si jpbbricole

//------------------------------------- RFID
#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

//------------------------------------- Clavier
#ifdef blazerwood
const int keybI2cAddress = 0x25;
#else     // jpbbricole
const int keybI2cAddress = 0x38;
#endif
const byte keybRowsNbr = 4;
const byte keybColsNbr = 4;

char keysMape[keybRowsNbr][keybColsNbr] =
{
	#ifdef blazerwood
	{'D', '#', '0', '*'},
	{'C', '9', '8', '7'},
	{'B', '6', '5', '4'},
	{'A', '3', '2', '1'}
	#else
	{'1','2','3','A'},
	{'4','5','6','B'},
	{'7','8','9','C'},
	{'*','0','#','D'}
	#endif
};

#ifdef blazerwood
byte keybRowPins[keybRowsNbr] = {3, 2, 1, 0};
byte keybColPins[keybColsNbr] = {7, 6, 5, 4};
#else
byte keybRowPins[keybRowsNbr] = {7, 6, 5, 4};     // Connexion des lignes
byte keybColPins[keybColsNbr] = {3, 2, 1, 0};     // Connexion des colonnes
#endif

Keypad_I2C customKeypad(makeKeymap(keysMape), keybRowPins, keybColPins, keybRowsNbr, keybColsNbr, keybI2cAddress);

//------------------------------------- Affichages LCD
#ifdef blazerwood
const int lcdAadresse = 0x26;     // Adresse du premier écran
const int lcdBadresse = 0x27;     // Adresse du second écran
#else
const int lcdAadresse = 0x26;     // Adresse du premier écran
const int lcdBadresse = 0x3F;     // Adresse du second écran
#endif

LiquidCrystal_I2C lcdA(lcdAadresse, 20, 4);
LiquidCrystal_I2C lcdB(lcdBadresse, 20, 4);

String gameModes[5] = {
	"Search & destroy",
	"Matchs a Mort",
	"Dominations",
	"Piratage",
	"Decryptage",
};

//------------------------------------- LED
const int ledColorIndex[] = {5, 6, 7};
const int ledNumber = sizeof(ledColorIndex) / sizeof(ledColorIndex[0]);
const int ledOn = HIGH;

//------------------------------------- Servo
const int servoPin = 8;
Servo myServo;

//------------------------------------- Etats du jeu
enum {                         jeuEtatDemarrage, jeuEtatSelMode, jeuEtatSelTime, jeuEtatSelCode, jeuEtatEnCours, jeuEtatBombeBoom, jeuEtatBombeToOff, jeuEtatAttNfc, jeuEtatFin, jeuEtatArrete};
const String jeuEtatLabel [] = {"Demarrage",     "Select mode",   "Select time", "Select code",   "En cours",     "Bombe BOOM",      "Bombe desamorcee",   "Att. NFC",    "Fin",       "Arrete"};	

int jeuEtat;

//------------------------------------- Divers
unsigned long timerDuration;

unsigned long startTime;
bool bombExploded = false;

String disarmCode;  // Variable pour stocker le code de désarmement
String enteredCode = "";  // Variable pour stocker le code entré par l'utilisateur

const int buzzerPin = 4;
void setup()
{
	Wire.begin();
	customKeypad.begin();
	Serial.begin(115200);
	jeuEtatSet(jeuEtatDemarrage, F("Setup()"));

	SPI.begin();
	mfrc522.PCD_Init();
	setupBuzzer();

	myServo.attach(servoPin);
	myServo.write(0);

	for (int l = 0; l < ledNumber; l++) {
		pinMode(ledColorIndex[l], OUTPUT);
		digitalWrite(ledColorIndex[l], !ledOn);
	}

	lcdA.init();
	lcdB.init();
	lcdA.backlight();
	lcdB.backlight();
	lcdA.begin(16, 2);
	lcdB.begin(16, 2);

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("GEARS AIRSOFT");
	delay(3000);

	lcdB.clear();
	lcdB.setCursor(0, 0);
	lcdB.print("Activation");
	digitalWrite(ledColorIndex[0], HIGH);
	delay(2000);

	lcdB.clear();
	lcdB.setCursor(0, 0);
	lcdB.print("Activation OK");
	delay(3000);
	digitalWrite(ledColorIndex[0], !ledOn); // Éteindre la LED verte
}

void loop()
{
	int selectedMode;

	digitalWrite(ledColorIndex[1], HIGH);

	selectedMode = selectGameMode();

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Temps (min):");

	int selectedTime = 0;
	bool timeSelectionComplete = false;

	jeuEtatSet(jeuEtatSelTime, "Loop()");

	while (!timeSelectionComplete)
	{
		char key = customKeypad.getKey();
		if (key >= '0' && key <= '9')
		{
			selectedTime = selectedTime * 10 + (key - '0');
			lcdA.print(key);
		}
		else if (key == '#')
		{
			timeSelectionComplete = true;
		}
		else if (key == '*')
		{
			if (selectedTime > 0)
			{
				selectedTime = selectedTime / 10;
				lcdA.clear();
				lcdA.setCursor(0, 0);
				lcdA.print("Temps (min):");
				lcdA.print(selectedTime);
			}
		}

		checkRFIDCard();  // Vérifier la carte RFID à chaque itération

		delay(100);
	}
	jeuEtatSet(jeuEtatSelTime, String(selectedTime));
	
	disarmCodeSetup();  // Appeler la configuration du code de désarmement après la sélection du temps

	digitalWrite(ledColorIndex[1], !ledOn);

	timerDuration = selectedTime * 60L * 1000L;
	startTime = millis();
	bombExploded = false;

	digitalWrite(ledColorIndex[2], HIGH);

	jeuEtatSet(jeuEtatEnCours, F("while (millis() - startTime"));

	while (millis() - startTime < timerDuration && !bombExploded)
	{
		unsigned long remainingTime = timerDuration - (millis() - startTime);
		unsigned long remainingMinutes = remainingTime / 1000 / 60;
		unsigned long remainingSeconds = (remainingTime / 1000) % 60;

		lcdB.clear();
		lcdA.clear();
		lcdA.setCursor(0, 0);
		lcdA.print("Temps restant:");
		lcdA.setCursor(0, 1);
		lcdA.print(remainingMinutes);
		lcdA.print(" min ");
		lcdA.print(remainingSeconds);
		lcdA.print(" sec");

		if ((millis() - startTime) % 500 < 250)
		{
			digitalWrite(ledColorIndex[2], HIGH);
		}
		else
		{
			digitalWrite(ledColorIndex[2], LOW);
		}

		disarmBomb();  // Appeler la fonction de désamorçage à chaque itération de la boucle principale

		checkRFIDCard();  // Vérifier la carte RFID à chaque itération

		delay(100);
	}

	if (!bombExploded && millis() - startTime >= timerDuration)
	{
		myServo.write(90);
		delay(2000);
		myServo.write(0);
	}

	for (int l = 0; l < ledNumber; l++)
	{
		digitalWrite(ledColorIndex[l], !ledOn);
	}

	if (!bombExploded)
	{
		jeuEtatSet(jeuEtatBombeBoom, F("if (!bombExploded)"));

		digitalWrite(ledColorIndex[2], HIGH);
		lcdB.clear();
		lcdB.setCursor(0, 0);
		lcdB.print("BOOOOM !");
		lcdB.setCursor(0, 1);
		
		lcdB.print("Bombe Explosee !");
		delay(3000);

		lcdA.clear();
		lcdA.setCursor(0, 0);
		lcdA.print("Veuillez présenter");
		lcdA.setCursor(0, 1);
		lcdA.print("votre badge ORGA.");

		// Attendre la lecture du badge NFC avant de passer à la suite
		waitForNFCCard();

		digitalWrite(ledColorIndex[0], HIGH);
		delay(1000);
		digitalWrite(ledColorIndex[0], !ledOn);
		digitalWrite(ledColorIndex[2], !ledOn);

		lcdA.clear();
		lcdA.setCursor(0, 0);
		lcdA.print("Veuillez choisir");
		lcdA.setCursor(0, 1);
		lcdA.print("le mode de jeux");
		digitalWrite(ledColorIndex[0], !ledOn);
	}
}

void displayMessage(LiquidCrystal_I2C& lcd, const String& line1, const String& line2, int delayTime = 1000)
{
	lcd.clear();
	lcd.setCursor(0, 0);
	lcd.print(line1);
	lcd.setCursor(0, 1);
	lcd.print(line2);
	delay(delayTime);
}

bool isRFIDCardPresent()
{
	if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
	{
		return true;
	}
	return false;
}

void checkRFIDCard() {
	if (isRFIDCardPresent())
	{
		digitalWrite(ledColorIndex[0], HIGH);
		delay(1000);
		digitalWrite(ledColorIndex[0], !ledOn);
	}
}

void disarmCodeSetup()
{
	jeuEtatSet(jeuEtatSelCode, F("disarmCodeSetup()"));

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Entrez le code:");
	delay(1000);

	disarmCode = "";

	while (disarmCode.length() < 4)
	{
		char key = customKeypad.getKey();
		if (key >= '0' && key <= '9')
		{
			disarmCode += key;
			lcdA.print('*');
		}
		delay(100);
	}

	jeuEtatSet(jeuEtatSelCode, String(disarmCode));
	delay(1000);
	displayMessage(lcdA, "Code enregistrer:", disarmCode, 2000);
}

void displayDisarmCode(const String& code)
{
	lcdB.clear();
	lcdB.setCursor(0, 0);
	lcdB.print("Entrez le code:");
	lcdB.setCursor(0, 1);
	for (size_t i = 0; i < code.length(); ++i)
	{
		lcdB.print('*');
	}
}

void disarmBomb()
{
	static String enteredCode = "";  // Maintenant une variable statique pour préserver sa valeur entre les appels
	static unsigned long lastDisplayTime = 0;

	char key = customKeypad.getKey();

	if (key != NO_KEY && (key >= '0' && key <= '9') && enteredCode.length() < 4 && !bombExploded)
	{
		enteredCode += key;
		lastDisplayTime = millis();
	}

	// Si la longueur du code est de 4 caractères, vérifier le code
	if (enteredCode.length() == 4 && !bombExploded)
	{
		if (enteredCode == disarmCode)
		{
			bombExploded = true;
			digitalWrite(ledColorIndex[2], !ledOn);

			// myServo.write(90); // Comment this line to prevent servo action on correct code entry
			// delay(2000);
			// myServo.write(0);
			jeuEtatSet(jeuEtatBombeToOff, F("disarmBomb()"));

			lcdB.clear();
			lcdB.setCursor(0, 0);
			lcdB.print("Bombe desamorcee !");
			delay(3000);
	
			// Attendre la lecture du badge NFC
			waitForNFCCard();
		}
		else
		{
			displayMessage(lcdB, "Code incorrect!", "Reessayez.", 2000);
			enteredCode = "";  // Réinitialiser le code après une tentative incorrecte
			lastDisplayTime = millis();
		}
	}

	// Afficher le code pendant une période définie après chaque pression de touche
	if (millis() - lastDisplayTime < 3000) {
		displayDisarmCode(enteredCode);
		} else {
		displayDisarmCode("");  // Effacer le code après la période définie
	}
}

int selectGameMode()
{
	jeuEtatSet(jeuEtatSelMode, F("selectGameMode()"));	

	int selectedMode = -1;

	for (int i = 0; i < 5; i++)
	{
		displayMessage(lcdB, "Mode de Jeux (" + String(i + 1) + ")", gameModes[i], 1000);
	}

	displayMessage(lcdB, "Faites votre choix:", "(1-5)", 500);

	while (selectedMode < 1 || selectedMode > 5)
	{
		char key = customKeypad.getKey();
		if (key != NO_KEY && key >= '1' && key <= '5')
		{
			selectedMode = key - '0';

			lcdB.clear();
			lcdB.setCursor(0, 0);
			lcdB.print("Mode choisi: ");
			lcdB.print(selectedMode);

			lcdB.setCursor(0, 1);
			lcdB.print(" - ");
			lcdB.print(gameModes[selectedMode - 1]);

			delay(3000);
		}
	}

	jeuEtatSet(jeuEtatSelMode, gameModes[selectedMode - 1]);
	return selectedMode;
}

bool waitForNFCCard()
{
	jeuEtatSet(jeuEtatAttNfc, F("waitForNFCCard()"));

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Attente du badge NFC...");

	unsigned long startTime = millis(); // Enregistrez le temps au début

	// Attendez que la carte NFC soit présente
	while (!isRFIDCardPresent())
	{
		delay(100);
	}

	// La carte NFC a été détectée
	digitalWrite(ledColorIndex[0], HIGH); // Allumez la LED verte
	delay(1000); // Maintenez la LED allumée pendant 1 seconde

	// Réinitialiser l'état du module RFID
	mfrc522.PICC_HaltA();
	mfrc522.PCD_StopCrypto1();

	digitalWrite(ledColorIndex[0], !ledOn); // Éteignez la LED verte

	// Affichez le message de votre choix sur l'écran A
	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Veuillez choisir");
	lcdA.setCursor(0, 1);
	lcdA.print("le mode de jeux.");
	
	jeuEtatSet(jeuEtatArrete, F("waitForNFCCard()"));

	return true; // Si une carte est lue, retournez true
}



//------------------------------------- Buzzer
void setupBuzzer()
{
	pinMode(buzzerPin, OUTPUT);
	digitalWrite(buzzerPin, LOW);
}

void playBuzzerSound(int duration)
{
	digitalWrite(buzzerPin, HIGH);
	delay(duration);
	digitalWrite(buzzerPin, LOW);

}

//------------------------------------- Etats du jeu
void jeuEtatSet(int etat, String remarque)
{
	jeuEtat = etat;

	Serial.println("Etat " + jeuEtatLabel[etat]);

	if (remarque != "")
	{
		Serial.println("\t" + remarque);
	}
}

A+
Bonne soirée
jpbbricole

1 Like

bonjour jpbbricole
Franchement, merci ! Grâce à tout ce que tu as fait, j'ai bien débugué mon script. Voici une version fonctionnelle. Il faudrait juste l'optimiser pour réduire la charge mémoire de l'Arduino si possible.
Voici la version fonctionnel.

#include <Wire.h>
#include <Keypad.h>
#include <Keypad_I2C.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <MFRC522.h>
#include <SPI.h>

#define blazerwood     // A mettre en remarque si jpbbricole

//------------------------------------- RFID
#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

//------------------------------------- Clavier
#ifdef blazerwood
const int keybI2cAddress = 0x25;
#else     // jpbbricole
const int keybI2cAddress = 0x38;
#endif
const byte keybRowsNbr = 4;
const byte keybColsNbr = 4;

char keysMape[keybRowsNbr][keybColsNbr] =
{
  #ifdef blazerwood
  {'D', 'C', 'B', 'A'},
  {'#', '9', '6', '3'},
  {'0', '8', '5', '2'},
  {'*', '7', '4', '1'}
  #else
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
  #endif
};

#ifdef blazerwood
byte keybRowPins[keybRowsNbr] = {3, 2, 1, 0};
byte keybColPins[keybColsNbr] = {7, 6, 5, 4};
#else
byte keybRowPins[keybRowsNbr] = {7, 6, 5, 4};     // Connexion des lignes
byte keybColPins[keybColsNbr] = {3, 2, 1, 0};     // Connexion des colonnes
#endif

Keypad_I2C customKeypad(makeKeymap(keysMape), keybRowPins, keybColPins, keybRowsNbr, keybColsNbr, keybI2cAddress);

//------------------------------------- Affichages LCD
#ifdef blazerwood
const int lcdAadresse = 0x26;     // Adresse du premier écran
const int lcdBadresse = 0x27;     // Adresse du second écran
#else
const int lcdAadresse = 0x26;     // Adresse du premier écran
const int lcdBadresse = 0x3F;     // Adresse du second écran
#endif

LiquidCrystal_I2C lcdA(lcdAadresse, 20, 4);
LiquidCrystal_I2C lcdB(lcdBadresse, 20, 4);

String gameModes[5] = {
  "Search & destroy",
  "Matchs a Mort",
  "Dominations",
  "Piratage",
  "Decryptage",
};

//------------------------------------- LED
const int ledColorIndex[] = {5, 6, 7};
const int ledNumber = sizeof(ledColorIndex) / sizeof(ledColorIndex[0]);
const int ledOn = HIGH;

//------------------------------------- Servo
const int servoPin = 8;
Servo myServo;

//------------------------------------- Etats du jeu
enum {                         jeuEtatDemarrage, jeuEtatSelMode, jeuEtatSelTime, jeuEtatSelCode, jeuEtatEnCours, jeuEtatBombeBoom, jeuEtatBombeToOff, jeuEtatAttNfc, jeuEtatFin, jeuEtatArrete};
const String jeuEtatLabel [] = {"Demarrage",     "Select mode",   "Select time", "Select code",   "En cours",     "Bombe BOOM",      "Bombe desamorcee",   "Att. NFC",    "Fin",       "Arrete"};

int jeuEtat;

//------------------------------------- Divers
unsigned long timerDuration;

unsigned long startTime;
bool bombExploded = false;

String disarmCode;  // Variable pour stocker le code de désarmement
int disarmCodeLength = 4;  // Longueur par défaut du code

const int buzzerPin = 4;

void setup()
{
  Wire.begin();
  customKeypad.begin();
  Serial.begin(115200);
  jeuEtatSet(jeuEtatDemarrage, F("Setup()"));

  SPI.begin();
  mfrc522.PCD_Init();
  setupBuzzer();

  myServo.attach(servoPin);
  myServo.write(0);

  for (int l = 0; l < ledNumber; l++) {
    pinMode(ledColorIndex[l], OUTPUT);
    digitalWrite(ledColorIndex[l], !ledOn);
  }

  lcdA.init();
  lcdB.init();
  lcdA.backlight();
  lcdB.backlight();

  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("GEARS AIRSOFT");
  delay(3000);

  lcdB.clear();
  lcdB.setCursor(0, 0);
  lcdB.print("Activation");
  delay(2000);

  lcdB.clear();
  lcdB.setCursor(0, 0);
  lcdB.print("Activation OK");
  digitalWrite(ledColorIndex[0], HIGH);
  delay(3000);
  digitalWrite(ledColorIndex[0], !ledOn); // Éteindre la LED verte
}

void loop()
{
  int selectedMode;

  digitalWrite(ledColorIndex[1], HIGH);

  selectedMode = selectGameMode();

  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Temps (min):");

  int selectedTime = 0;
  bool timeSelectionComplete = false;

  jeuEtatSet(jeuEtatSelTime, "Loop()");

  while (!timeSelectionComplete)
  {
    char key = customKeypad.getKey();
    if (key >= '0' && key <= '9')
    {
      selectedTime = selectedTime * 10 + (key - '0');
      lcdA.print(key);
    }
    else if (key == '#')
    {
      timeSelectionComplete = true;
    }
    else if (key == '*')
    {
      if (selectedTime > 0)
      {
        selectedTime = selectedTime / 10;
        lcdA.clear();
        lcdA.setCursor(0, 0);
        lcdA.print("Temps (min):");
        lcdA.print(selectedTime);
      }
    }

    checkRFIDCard();  // Vérifier la carte RFID à chaque itération

    delay(100);
  }
  jeuEtatSet(jeuEtatSelTime, String(selectedTime));

  disarmCodeSetup();  // Appeler la configuration du code de désarmement après la sélection du temps

  digitalWrite(ledColorIndex[1], !ledOn);

  timerDuration = selectedTime * 60L * 1000L;
  startTime = millis();
  bombExploded = false;

  digitalWrite(ledColorIndex[2], HIGH);

  jeuEtatSet(jeuEtatEnCours, F("while (millis() - startTime"));

  while (millis() - startTime < timerDuration && !bombExploded)
  {
    unsigned long remainingTime = timerDuration - (millis() - startTime);
    unsigned long remainingMinutes = remainingTime / 1000 / 60;
    unsigned long remainingSeconds = (remainingTime / 1000) % 60;

    lcdB.clear();
    lcdA.clear();
    lcdA.setCursor(0, 0);
    lcdA.print("Temps restant:");
    lcdA.setCursor(0, 1);
    lcdA.print(remainingMinutes);
    lcdA.print(" min ");
    lcdA.print(remainingSeconds);
    lcdA.print(" sec");

    if ((millis() - startTime) % 500 < 250)
    {
      digitalWrite(ledColorIndex[2], HIGH);
    }
    else
    {
      digitalWrite(ledColorIndex[2], LOW);
    }

    disarmBomb();  // Appeler la fonction de désamorçage à chaque itération de la boucle principale

    checkRFIDCard();  // Vérifier la carte RFID à chaque itération

    delay(100);
  }

  if (!bombExploded && millis() - startTime >= timerDuration)
  {
    myServo.write(90);
    delay(2000);
    myServo.write(0);
  }

  for (int l = 0; l < ledNumber; l++)
  {
    digitalWrite(ledColorIndex[l], !ledOn);
  }

  if (!bombExploded)
  {
    jeuEtatSet(jeuEtatBombeBoom, F("if (!bombExploded)"));

    digitalWrite(ledColorIndex[2], HIGH);
    lcdB.clear();
    lcdB.setCursor(0, 0);
    lcdB.print("BOOOOM !");
    lcdB.setCursor(0, 1);

    lcdB.print("Bombe Explosee !");
    delay(3000);

    lcdA.clear();
    lcdA.setCursor(0, 0);
    lcdA.print("Veuillez contacter");
    lcdA.setCursor(0, 1);
    lcdA.print("votre ORGA.");

    // Attendre la lecture du badge NFC avant de passer à la suite
    waitForNFCCard();

    digitalWrite(ledColorIndex[0], HIGH);
    delay(1000);
    digitalWrite(ledColorIndex[0], !ledOn);
    digitalWrite(ledColorIndex[2], !ledOn);

    lcdA.clear();
    lcdA.setCursor(0, 0);
    lcdA.print("Veuillez choisir");
    lcdA.setCursor(0, 1);
    lcdA.print("le mode de jeux");
    digitalWrite(ledColorIndex[0], !ledOn);
  }
}

void displayMessage(LiquidCrystal_I2C& lcd, const String& line1, const String& line2, int delayTime = 1000)
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(line1);
  lcd.setCursor(0, 1);
  lcd.print(line2);
  delay(delayTime);
}

bool isRFIDCardPresent()
{
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
  {
    return true;
  }
  return false;
}

void checkRFIDCard() {
  if (isRFIDCardPresent())
  {
    digitalWrite(ledColorIndex[0], HIGH);
    delay(1000);
    digitalWrite(ledColorIndex[0], !ledOn);
  }
}

void disarmCodeSetup()
{
  jeuEtatSet(jeuEtatSelCode, F("disarmCodeSetup()"));

  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Longueur du code (4-8):");

  int selectedLength = 0;
  while (selectedLength < 4 || selectedLength > 8)
  {
    char key = customKeypad.getKey();
    if (key >= '4' && key <= '8')
    {
      selectedLength = key - '0';
      lcdA.clear();
      lcdA.setCursor(0, 0);
      lcdA.print("Longueur choisie:");
      lcdA.print(selectedLength);
      delay(1000);
    }
  }

  disarmCodeLength = selectedLength;

  lcdA.clear();
  lcdA.setCursor(0, 0);
  lcdA.print("Entrez le code:");
  delay(1000);

  disarmCode = "";

  while (disarmCode.length() < disarmCodeLength)
  {
    char key = customKeypad.getKey();
    if (((key >= '0' && key <= '9') || (key >= 'A' && key <= 'F')) && key != NO_KEY)
    {
      disarmCode += key;
      lcdA.print('*');
    }
    else if (key == '#')
    {
      if (disarmCode.length() == disarmCodeLength)
      {
        // Code complet, sortir de la boucle
        break;
      }
    }
    delay(100);
  }

  jeuEtatSet(jeuEtatSelCode, String(disarmCode));
  delay(1000);
  displayMessage(lcdA, "Code valide:", disarmCode, 2000);
}


void displayDisarmCode(const String& code)
{
  lcdB.clear();
  lcdB.setCursor(0, 0);
  lcdB.print("Entrez le code:");
  lcdB.setCursor(0, 1);
  for (size_t i = 0; i < code.length(); ++i)
  {
    lcdB.print('*');
  }
}

void disarmBomb()
{
  static String enteredCode = "";  // Variable statique pour conserver sa valeur entre les appels
  static unsigned long lastDisplayTime = 0;

  char key = customKeypad.getKey();

  if (key != NO_KEY && ((key >= '0' && key <= '9') || (key >= 'A' && key <= 'F')) && enteredCode.length() < disarmCodeLength && !bombExploded)
  {
    enteredCode += key;
    lastDisplayTime = millis();
  }

  // Afficher le code pendant une période définie après chaque pression de touche
  if (millis() - lastDisplayTime < 3000)
  {
    displayDisarmCode(enteredCode);
  }
  else
  {
    displayDisarmCode("");  // Effacer le code après la période définie
    enteredCode = ""; // Réinitialiser le code pour la nouvelle partie
  }

  // Vérifier si le code a atteint la longueur spécifiée
  if (enteredCode.length() == disarmCodeLength)
  {
    if (!bombExploded) // Vérifier si la bombe n'a pas encore explosé
    {
      if (enteredCode == disarmCode)
      {
        bombExploded = true;
        digitalWrite(ledColorIndex[2], !ledOn);

        jeuEtatSet(jeuEtatBombeToOff, F("disarmBomb()"));

        lcdB.clear();
        lcdB.setCursor(0, 0);
        lcdB.print("Bombe desamorcee !");
        delay(3000);

        // Attendre la lecture du badge NFC
        waitForNFCCard();
      }
      else
      {
        displayMessage(lcdB, "Code incorrect !", "Reessayez.", 2000);
        enteredCode = "";  // Réinitialiser le code après une tentative incorrecte
        lastDisplayTime = millis();
      }
    }
  }
}


int selectGameMode()
{
	jeuEtatSet(jeuEtatSelMode, F("selectGameMode()"));	

	int selectedMode = -1;

	for (int i = 0; i < 5; i++)
	{
		displayMessage(lcdB, "Mode de Jeux (" + String(i + 1) + ")", gameModes[i], 1000);
	}

	displayMessage(lcdB, "Faites votre choix:", "(1-5)", 500);

	while (selectedMode < 1 || selectedMode > 5)
	{
		char key = customKeypad.getKey();
		if (key != NO_KEY && key >= '1' && key <= '5')
		{
			selectedMode = key - '0';

			lcdB.clear();
			lcdB.setCursor(0, 0);
			lcdB.print("Mode choisi: ");
			lcdB.print(selectedMode);

			lcdB.setCursor(0, 1);
			lcdB.print(" - ");
			lcdB.print(gameModes[selectedMode - 1]);

			delay(3000);
		}
	}

	jeuEtatSet(jeuEtatSelMode, gameModes[selectedMode - 1]);
	return selectedMode;
}

bool waitForNFCCard()
{
	jeuEtatSet(jeuEtatAttNfc, F("waitForNFCCard()"));

	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Veuillez contacter");
  lcdA.setCursor(0, 1);
lcdA.print("votre ORGA...");
	unsigned long startTime = millis(); // Enregistrez le temps au début

	// Attendez que la carte NFC soit présente
	while (!isRFIDCardPresent())
	{
		delay(100);
	}

	// La carte NFC a été détectée
	digitalWrite(ledColorIndex[0], HIGH); // Allumez la LED verte
	delay(1000); // Maintenez la LED allumée pendant 1 seconde

	// Réinitialiser l'état du module RFID
	mfrc522.PICC_HaltA();
	mfrc522.PCD_StopCrypto1();

	digitalWrite(ledColorIndex[0], !ledOn); // Éteignez la LED verte

	// Affichez le message de votre choix sur l'écran A
	lcdA.clear();
	lcdA.setCursor(0, 0);
	lcdA.print("Veuillez choisir");
	lcdA.setCursor(0, 1);
	lcdA.print("le mode de jeux.");
	
	jeuEtatSet(jeuEtatArrete, F("waitForNFCCard()"));

	return true; // Si une carte est lue, retournez true
}



//------------------------------------- Buzzer
void setupBuzzer()
{
	pinMode(buzzerPin, OUTPUT);
	digitalWrite(buzzerPin, LOW);
}

void playBuzzerSound(int duration)
{
	digitalWrite(buzzerPin, HIGH);
	delay(duration);
	digitalWrite(buzzerPin, LOW);

}

//------------------------------------- Etats du jeu
void jeuEtatSet(int etat, String remarque)
{
	jeuEtat = etat;

	Serial.println("Etat " + jeuEtatLabel[etat]);

	if (remarque != "")
	{
		Serial.println("\t" + remarque);
	}
}

Bonjour blazerwood

Joli boulot :clap:

les prints dans le moniteur, sont quasiment indispensable, au cours du développement, je les inclus dès le départ d'un projet, quitte à les mettre en remarque ou les supprimer, le programme au point.

Pour ce faire, déjà modifier les affichages "simples" comme celui-ci
lcdA.print("GEARS AIRSOFT");
en
lcdA.print(F("GEARS AIRSOFT"));

Dans les déclarations de variables ou tableaux, les déclarer en const comme
char keysMape[
en
const char keysMape[
pour autant que faire se peut :wink:
Le meilleur moyen de le savoir est d'essayer, si ce n'est pas possible le compilateur te le dira assez rapidement :wink:

A+
Bonne après midi, ici beau soleil
jpbbricole

1 Like