bonjour,

j'ai un code de 3 jeux consécutifs.
Lancement automatique du 1er et le second se déclenche à la réussite du premier et bis repetita.

Lors du 3ème jeu, il s'agit de rentrer le code référence rouge, si ok idem pour un nouveau code où il faut donner la référence bleue.

a la réussite du code rouge,

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
if (color == "Red") {
      Serial.println("Code rouge ok");
      code_tape[4] = {0}; //on réinitialise le code_tape
      choisirCarteBleue();
      return INCHANGE;
    }
Quand je fais un programme avec uniquement le jeu 3, le renvoi carte bleue fonctionne avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
return choisirCarteBleue();
Faut-il créer un tableau du type
t_taskColor ['Red','Blue'];

et remplacer void ChoisirCarteRouge() par t_taskColorRed

Sinon au lancement du jeu3, le decompte s'arrête et ne change que lorsqu'un code est tapé, je suppose que c'est normal, dommage. Peut-on y remédier???

Merci par avance pour votre retour, il y a-t-il un cours pour le renvoi de tâche???

le code complet
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
//***************************
//Bibliotheques, variables...
//***************************
 
 
//initialisation du clavier
#include <Keypad.h> //include keypad library - first you must install library (library link in the video description)
 
//initialisation du LCD I2C
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
 
//Partie tableau des differents jeux
typedef  int16_t t_taskID;
const t_taskID INCHANGE = -1;
 
typedef void (*t_setupFunc)();      // on défint le type t_setupFunc comme pointeur sur fonction retournant rien
typedef t_taskID (*t_loopFunc)();  // on défint le type t_loopFunc comme pointeur sur fonction retournant un N°de tâche
typedef void (*t_cleanupFunc)();    // on défint le type t_cleanupFunc comme pointeur sur fonction retournant rien
 
// une tâche va consister en 3 pointeurs de fonctions
struct t_task {
  t_setupFunc taskSetup;
  t_loopFunc taskLoop;
  t_cleanupFunc taskCleanUp;
};
 
// *********************************************
// pour pouvoir définir le tableau des tâches
// On pré-annonce les fonctions de nos tâches. (forward declaration)
// Leur code viendra plus tard.
 
// le Menu
/*void setupMenu();
  t_taskID loopMenu();
  void finMenu();*/
 
// le jeu 1
void setupJeu1();
t_taskID loopJeu1();
void finJeu1();
 
// le Jeu2
void setupJeu2();
t_taskID loopJeu2();
void finJeu2();
 
// le Jeu3
void setupJeu3();
t_taskID loopJeu3();
void finJeu3();
 
// la fin
void setupEnd();
t_taskID loopEnd();
void finEnd();
 
// *********************************************
 
// définir le tableau des tâches
t_task taskList[] = {
  //{setupMenu, loopMenu, finMenu},
  {setupJeu1, loopJeu1, finJeu1},
  {setupJeu2, loopJeu2, finJeu2},
  {setupJeu3, loopJeu3, finJeu3},
  {setupEnd, loopEnd, finEnd}
};
 
// définir les N° de nos tâches avec un nom parlant, ça simplifie la lecture du code.
enum : t_taskID {JEU1, JEU2,JEU3, END};
 
const byte rows = 4; //number of the keypad's rows and columns
const byte cols = 4;
 
char keyMap [rows] [cols] = { //define the cymbols on the buttons of the keypad
 
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
 
 
byte rowPins [rows] = {13, 12, 11, 10}; //pins of the keypad
byte colPins [cols] = {9, 8, 7, 6};
 
Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);
 
// ****************************
//         UTILITAIRES
// ****************************
 
// on calcule le nombre de tâches définies
uint16_t taskCount = sizeof(taskList) / sizeof(taskList[0]);
t_taskID currentTask;
uint32_t currentTaskStartTime;
 
void etablirNouvelleTache(t_taskID nouvelleTache)
{
  if (nouvelleTache >= taskCount) return;     // nouvelleTache n'existe pas
  currentTaskStartTime = millis();
  currentTask = nouvelleTache;
  taskList[currentTask].taskSetup();
}
 
 
void gestionEtat()
{
  t_taskID nouvelleTache = taskList[currentTask].taskLoop();   // on fait un tour de loop de la tâche
 
  if (nouvelleTache != INCHANGE) {          // demande de changement
    taskList[currentTask].taskCleanUp();   // on termine la tâche en cours  proprement
    etablirNouvelleTache(nouvelleTache);    // on bascule vers la nouvelle tâche
  }
}
 
 
// ****************************
//     TÂCHE GLOBALE
// ****************************
const uint16_t pulsation = 1000U; // mise à jour une fois par seconde
const uint32_t  tempsTotal = 1000UL * 60UL * 60UL; // 60 minutes = 3 600 000 ms
uint32_t chronometre = 0;
 
void gestionGlobale()
{
  //on regarde si la partie est gagnée
  if(currentTask == END) {
    ///Serial.print("stop decompte");
  } else {  //sinon,on affiche le décompte
    // pulsation pour montrer que tout va bien, on fait clignoter la LED
    if (millis() - chronometre >= pulsation) {
      if (millis() < tempsTotal) {  // si on considère que le début du jeu est au boot
        uint32_t tempsRestant = (tempsTotal - millis()) / 1000; // en secondes
        lcd.setCursor(0, 0); lcd.print(F("TEMPS:"));
        if (tempsRestant >= 60) {
          lcd.print(tempsRestant / 60); lcd.print("min");
        }
        lcd.print(tempsRestant % 60); lcd.print("s    ");
        // Serial.print('etablirNouvelleTache(t_taskID)');
      } else {
        // LE TEMPS EST EXPIRE. FAIRE CE QU'IL FAUT !
        lcd.setCursor(0, 0); lcd.print(F("VOUS AVEZ PERDU"));
      }
      chronometre += pulsation;
    }
  }
}
 
 
//je laisse juste le jeu 3
 
 
 
//*****************************
//        JEU 3
//*****************************
 
const char* password ;
int passwordLength;
char code_secret[] = {0}; //tableau contenant code
String color;
char* carteID;
 
// On définit le type crypto
struct t_crypto {
  const char* ID;
  const char* Red;
  const char* Blue;
};
 
t_crypto Code[] = {
  {"A1C2", "8AA4", "7C9A" },
  {"C312", "651A", "8A52"},
  {"AA98", "74A1", "8C8A"},
  {"7A54", "A35C", "55C2"},
  {"3A3C", "3A3C", "01A5"},
  {"3C5A", "AAAA", "80C4"},
  {"648C", "CC1C", "92C1"},
  {"9761", "C7A4", "3333"}
};
 
void choisirCarteRouge()
{
  long carteCrypto = random(0, 8); //on choisi une carte au hasard
 
  Serial.println(F("Crypto carte ROUGE: "));
  Serial.println(Code[carteCrypto].ID);
  carteID=Code[carteCrypto].ID;
  password = Code[carteCrypto].Red;
  passwordLength = strlen(password);
  Serial.println(F("Tapez le code"));
  lcd.setCursor(0, 1); lcd.print("Crypto");lcd.setCursor(7, 1);lcd.print(Code[carteCrypto].ID);lcd.setCursor(12, 1);lcd.print("Red");
  color = "Red";
}
 
void choisirCarteBleue()
{
  long carteCrypto = random(0, 8);
 
  Serial.println(F("Crypto carte BLEUE: "));
  Serial.println(Code[carteCrypto].ID);
  carteID=Code[carteCrypto].ID;
  password = Code[carteCrypto].Blue;
  passwordLength = strlen(password);
  Serial.println(F("Tapez le code"));
  lcd.setCursor(0, 1); lcd.print("Crypto");lcd.setCursor(7, 1);lcd.print(Code[carteCrypto].ID);lcd.setCursor(12, 1);lcd.print("Blue");
 
  color = "Blue";
 
}
void   setupJeu3 () {
  Serial.begin(115200);
  // Pour activer l'état HOLD
  unsigned int time_hold = 4;
  //anti rebond à calibrer
  //setDebounceTime(unsigned int time)
 
  //Ecran
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  //pinMode(redLED, OUTPUT);  //set the LED as an output
  //pinMode(blueLED, OUTPUT);
  randomSeed(analogRead(A0)); // génération d'un peu d'aléatoire
  choisirCarteRouge();
}
 
t_taskID loopJeu3 () {
 
  char code_tape[passwordLength + 1] = {'\0'};          //tableau contenant la saisie
  uint8_t indice = 0;
 
  while (indice < passwordLength) {
    char whichKey = myKeypad.getKey(); //define which key is pressed with getKey
    if (whichKey) {
      code_tape[indice] = whichKey;
      Serial.print("*");
      lcd.setCursor(7+indice, 1);lcd.print("*");
      indice++;
    }
  }
  code_tape[passwordLength] = '\0'; // pour faire une cString bien formée (superflu car intialisé déjà avec des '\0', donc plus à titre de bonne pratique)
 
  if (strcmp(code_tape, password) == 0) { // on peut utilsier strcmp() car les deux paramètres sont des cStrings bien formées
    Serial.println(F("\ncode OK\n"));
    return INCHANGE;
 
    if (color == "Red") {
      Serial.println("Code rouge ok");
      code_tape[4] = {0}; //on réinitialise le code_tape
      choisirCarteBleue();
      return INCHANGE;
    }
    if (color == "Blue") {
      Serial.println("Code bleu ok");
      Serial.println("Partie terminée");
      lcd.setCursor(0, 1); lcd.print("  Partie finie  ");
      return END;
    }
  }else{
    Serial.println(F("\ncode faux\n"));
    lcd.setCursor(0, 1); lcd.print("Erreur code");
    Serial.print(carteID);
    delay(3000);
  lcd.setCursor(0, 1); lcd.print("Crypto");lcd.setCursor(7, 1);lcd.print(carteID);
  return INCHANGE;
  }
 
 
}
 
void finJeu3()
{
  Serial.println(F("\tFIN JEU #3"));
  // nettoyage éventuel, ici rien de particulier à nettoyer
}
 
//*****************************
//        FIN DU JEU
//*****************************
uint32_t tickEnd;
 
void setupEnd ()
{
  Serial.println(F("Partie terminée"));
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(" VOUS AVEZ GAGNE ");
  lcd.setCursor(0, 1); lcd.print("   Bravo a vous  ");
}
t_taskID loopEnd() {
  return INCHANGE;
}
void finEnd() {}
// ****************************
//     PROGRAMME PRINCIPAL
// ****************************
 
void setup()
{
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
 
  // AUTRES INITIALISATIONS
 
  //decompte
  // Pour activer l'état HOLD
  unsigned int time_hold = 4;
 
  //Ecran
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  // On donne le point d'entrée de notre programme général
  etablirNouvelleTache(JEU3);
 
  //RFID
  SPI.begin();
  mfrc522.PCD_Init();
 
  randomSeed(analogRead(A0)); // génération d'un peu d'aléatoire
}
 
 
void loop()
{
 
  gestionGlobale();
  gestionEtat();
 
}