Bonjour à tous

Dans ma discussion

https://www.developpez.net/forums/d2...ours-prevenir/

je rencontre un problème que je ne sais pas encore expliquer. Mes soupçons se portent sur la pile mais, sans avoir de certitude, j'ai pensé qu'il était pertinent de remplacer l'arduino UNO par un MEGA ce qui semblait tout à fait "simple": les bornes placées aux mêmes endroits, les codes identiques, ma maquette pratique pour le faire.

Sauf que rien ne se passe comme dans le livre.

Malgré la programmation des cibles, du port ... aucune réaction d'aucun des périphériques. Même le moniteur série ne répond pas.

Je tente de repartir de zéro, en programmant un clignotement de LED qui lui non plus ne fonctionne pas.

Je repars donc d'un exemple qui attend une frappe clavier PC, qu'il analyse et affiche bien sur le moniteur série. Enfin!

Pas à pas, j'y rajoute mes clignotants, qui fonctionnent, le testeur d'adresses I2C qui fonctionne mais ne trouve rien, même si je ne mets que mon afficheur lcd à quatre lignes de 20 caractères.

Rien à faire, MEGA refuse de parler I2C.

Pensant à une erreur de programme ou de câblage, je teste l'autre MEGA qui fait strictement pareil, je replace la UNO, et avec le même programme (mais les cibles adaptées) mon programme de test fonctionne, mes clignotants aussi, mon afficheur également avec le texte court convenu, et le scanner I2C détecte bien les trois shields connectés avec les bonnes adresses trouvées.


Ceci prouve que le remplacement "pur et simple" d'une version arduino à l'autre n'est pas automatique.

A l'énoncé de mes "aventures", que penser? Qu'ai-je pu oublier passant de UNO à MEGA? Il s'agit de MEGA 2560 R3.

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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
//preliminaire_mega_01.ino 280avril 2021
 
#include <Wire.h> /* Indispensable pour la gestion de l'I2C */
#include <I2C_eeprom.h>
#include "RTClib.h"  // supposé être complété de déclarations
#include "LiquidCrystal_I2C.h"  //librairie lcd
 
I2C_eeprom memoire ( 0x50 , I2C_DEVICESIZE_24LC256 ) ; // AT24C256 en 0x50
 
// il y a les clavier + bouton et affichage 2x20
// il va donne 0, 1, 2, 3.
// les trois bits clavier sur 6, 7 et 8  Ca fonctionne.
 
LiquidCrystal_I2C
lcd ( 0x27 , 20 , 4 ) ; //  afficheur 4 lignes
RTC_DS3231 rtc ;  // version DS3231
 /* Les variables du programme */
  byte adresse;       /* variables de gestion des adresses */
  byte resultat;      /* Variable de retour d'interrogation d'une adresse */
  byte nb_existe = 0; /* compteur de peripheriques trouves */
  byte nb_defaut = 0; /* compteur de peripheriques en defaut */
 
void setup() 
{
  lcd.init () ;
  lcd.backlight () ;
  lcd.setCursor ( 0 , 0 ) ;
  // refreshDisplayDone = 0 ;
  Wire.begin();       /* Initialise le bus i2C */
  // Open serial communications and wait for port to open:
  Serial.begin(19200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 
  // send an intro:
  Serial.println("Je vais commencer à jouer \n");
  Serial.println();
  // essais pour débogage seulement
  pinMode ( 8 , OUTPUT ) ; // borne 8 en sortie LED BLEU
  pinMode ( 11 , OUTPUT ) ; // borne 8 en sortie LED ROUGE
  pinMode ( 12 , OUTPUT ) ; // borne 8 en sortie LED JAUNE
}
 
void loop()
{
  allumeBleu () ;
  delay ( 1000 ) ;
  allumeRouge () ;
  eteintBleu () ;
  delay ( 1000 ) ;
  allumeJaune () ;
  eteintRouge () ;
  delay ( 1500 ) ;
  eteintJaune ();
  Serial.print ( "Je viens de faire un tour de mon travail\n" ) ;
 
  /* Petite banniere en ASII... juste pour le fun
     Veuillez bien recopier les lignes ci-dessous pour un affichage correct
     PS: n'oubliez pas que le \ doit etre precede d'un \ pour son affichage */
  Serial.println("  ____                             ___   ____     ____ ");
  Serial.println(" / ___|    ___    __ _   _ __     |_ _| |___ \\   / ___|");
  Serial.println(" \\___ \\   / __|  / _` | | '_ \\     | |    __) | | |    ");
  Serial.println("  ___) | | (__  | (_| | | | | |    | |   / __/  | |___ ");
  Serial.println(" |____/   \\___|  \\__,_| |_| |_|   |___| |_____|  \\____|");
  Serial.println();
 
  Serial.println("\nDebut du scan"); /* Affiche un saut de ligne puis le debut du scan */
 
  /* Debut de la grille d'affichage ou on simule l'adresse 0 par 4 points (.... )
     car elle est reservee par les fabriquants pour des fonctions speciales.
     PS: le tableau est decale d'une tabulation pour une meilleure lisibilite */
  Serial.print("\t.... ");
 
  /* Demarre le scan */
  for (adresse = 1; adresse < 128; adresse++ )
    /* Il y a 128 adresses disponibles au maximun (de 0 a 127)
        rappel : on ne teste pas l'adresse 0 (voir ci-dessus) */
  {
    Wire.beginTransmission(adresse);    /* Commence une transmission a l'adresse indiquee */
    resultat = Wire.endTransmission();
    /* resultat = statut de la transmission :
        0 : succès (peripherique OK)
        1 : donnée trop longue pour le buffer d'émission (erreur)
        2 : NACK reçu sur l'adresse de transmission (pas de peripherique)
        3 : NACK reçu sur la transmission de donnée (pas de peripherique)
        4 : autre erreur  (erreur donc...) */
 
    /* POUR TEST UNIQUEMENT : (on a pas forcement de peripherique en defaut sous la main)
        Decommenter une ou les lignes ci-dessous pour simuler un ou plusieurs peripherique en defaut
        Adaptez les adresses (de 1 a 127) en fonction de votre configuration
        Adapter les resultats en fonction du traitement que vous envisagez */
    //if (adresse == 17) resultat = 4; /* simule une erreur autre que 1,2 ou 3 */
    //if (adresse == 93) resultat = 1; /* simule une erreur de données */
 
    /* Traitement du resultat */
    if (resultat == 0)  /* Il y a un peripherique OK a cette adresse */
    {
      /* Mise en forme et affichage de l'adresse du peripherique en Hexadecimal */
      if (adresse < 16)Serial.print("0x0");
      else Serial.print("0x");
      Serial.print(adresse, HEX);
      Serial.print(" ");
      nb_existe++; /* Increment le nombre de peripheriques trouves */
    }
    else if ((resultat == 4) || (resultat == 1)) /* Indication d'un peripherique en defaut */
    {
      Serial.print("#### ");
      nb_existe++;  /* Increment le nombre de peripheriques trouves */
      nb_defaut++;  /* Incremente le nombre de peripheriques en defaut */
    }
    else  Serial.print(".... ");/* adresse inoccupee */
    /* resultat = 2 ou 3 (NAK) -> pas de reponse d'un peripherique*/
 
    /* Decommentez la ligne ci-dessous si vous avez des erreurs de lecture */
    //delay(25); /* temps d'attente pour ne pas generer d'erreur de lecture */
 
    if (((adresse + 1) % 8) == 0) /* Pour formatage de l'affichage en 8 colonnes */
      /* le +1 c'est parce que l'on part de l'adresse 1 et non de l'adresse 0 */
    {
      Serial.println();   /* Passage a la ligne apres avoir affiche 8 adresses */
      if (adresse < 127)Serial.print("\t");
      /* tabulation pour la mise en forme de l'affichage sauf apres la derniere adresse */
    }
    /* Fin du traitement du resultat et passage a l'adresse suivante */
  }
 
  /* Fin du scan */
  Serial.println("Fin du Scan\n");
 
  /* Affichage des resultats complementaires **/
  if (nb_existe == 0)Serial.println("Aucun peripherique I2C !"); /* Pas de peripherique I2c */
  else
  {
    /* Affichage d'un resume sous la forme :
        X peripherique(s) reconnu(s).
       ou
        X peripherique(s) reconnu(s) dont X peripherique(s) en defaut.
       avec gestion des pluriels et du point terminal */
 
    Serial.print(nb_existe); /* nombre de peripheriques I2c reconnus */
    if (nb_existe < 2)Serial.print(" peripherique reconnu"); /* affichage pour un seul */
    else Serial.print(" peripheriques reconnus");         /* affichage pour plusieurs */
 
    if (nb_defaut != 0)  /* S'il y a des peripheriques en defaut */
    {
      Serial.print(" dont ");  /* poursuit la phrase de resume */
      Serial.print(nb_defaut); /* Nombre de peripheriques en defaut */
      if (nb_defaut < 2)Serial.println(" peripherique en defaut."); /* affichage pour un seul */
      else Serial.println(" peripheriques en defaut.");             /* affichage pour plusieurs */
    }
    else Serial.println("."); /* Termine la phrase par un point s'il n'y a pas de peripherique en defaut */
  }
  /* Message de fin de scan */
  Serial.println("\nAppuyez sur le bouton Reset de l'Arduino pour recommencer.\n");
  Serial.println(); /* Saut de ligne supplémentaire */
 
  // essai LCD
 
  lcd.setCursor ( 0 , 0 ) ;
  lcd.print ( "   ESSAI LIGNE 1    " ) ;
}
//    ==================== fin du loop  =======
// gestion des voyants de test rouge bleu jaune
//  ==================== Allumage/extinction LED =======================
void allumeRouge ()
{
  digitalWrite ( 11 , HIGH ) ; // allume ROUGE
}
// =========================================
void eteintRouge ()
{
  digitalWrite ( 11 , LOW ) ; // éteint ROUGE
}
// ========================================
void allumeBleu ()
{
  digitalWrite ( 8 , HIGH ) ; // allume BLEU
}
// =========================================
void eteintBleu ()
{
  digitalWrite ( 8 , LOW ) ; // éteint BLEU
}
// ========================================
void allumeJaune ()
{
  digitalWrite ( 12 , HIGH ) ; // allume JAUNE
}
// =========================================
void eteintJaune ()
{
  digitalWrite ( 12 , LOW ) ; // éteint JAUNE
}
// =======================================
/*
  //
  // je pars de 0 avec mega
  #include <Wire.h>
  #include <I2C_eeprom.h>
  #include "RTClib.h"  // supposé être complété de déclarations
  #include "LiquidCrystal_I2C.h"  //librairie lcd
 
  I2C_eeprom memoire ( 0x50 , I2C_DEVICESIZE_24LC256 ) ; // AT24C256 en 0x50
 
  // il y a les clavier + bouton et affichage 2x20
  // il va donne 0, 1, 2, 3.
  // les trois bits clavier sur 6, 7 et 8  Ca fonctionne.
 
  LiquidCrystal_I2C
  lcd ( 0x27 , 20 , 4 ) ; //  afficheur 4 lignes
  RTC_DS3231 rtc ;  // version DS3231
 
  // déclaration des variables Guy certaines à supprimer car deviennent inutiles
  int  minuteDeSemaine ;
  unsigned int clavier ; // lecture hard du clavier sur 3 bits bit à bit
  unsigned int KB ; // clavier converti
  unsigned int lectBouton ; // lecture du bouton
  unsigned int bouton ;  // état status du bouton
  int Heure ; //  heure actuelle
  int Jour ; // jour actuel
  int Minute ; // minute actuelle
  unsigned int sortieRelais ; // la mémoire des relais de sortie
  unsigned int refreshDisplayDone ; // mémoire de refresh visu unique
  int choixManuel ; // voie en réglage manuel. 1 = SBWC par défaut
  int dureeManuelle ; // programmation d'une durée qui sera à affecter supprimé unsigned pour le pb du zéro
  // ==================================Devront être en RAM sauvegardée ===================
  int manuelCuisine ;
  int manuelSbWc ;
  int manuelBalneo ;
  int manuelChristmas ;
  // ========================================================================================
  unsigned int minuteDebutAllumage ; // l'équivalent de minuteDeSemaine mais pour début (allumage) programmation
  unsigned int minuteFinAllumage ;   //  même chose mais pour la fin de séquence.
  int destinataireProgrammation ; // A qui appartient la programmation? 0 = cuisine (int ?)
  unsigned int posCurseurLigneProg ; // positions du curseur
  unsigned int posCurseurColonneProg ;
  long int adressage ;  // contiendra l'adresse à lire ou écrire
  unsigned int boucleDestination ; // je programme la destination
  int boucleAllumage ; // programmation de l'allumage
  int boucleExtinction ; // programmation de l'extinction
  int yyy ; // mémoire temporaire
  int colonneDestination ; // la colonne ???
  int boucleHeureProg ;  // je suis dans une boucle programmation heures (all/ext)
  int boucleMinuteProg ; //  je suis dans une boucle programmation min (all/ext)
 
  char daysOfTheWeek[7][4] = {"DIM", "LUN", "MAR", "MER", "JEU", "VEN", "SAM"}; //dim passé à 4 car 3 car
 
  // essai de structure dateHeure
 
  struct dateHeure  // elle va contenir les membres à extraire et à utiliser pour adresser
  {
  unsigned int Jour ; // le jour de la semaine de 0 à 6
  unsigned int Heure ; // heure du jour de 0 à 23
  unsigned int Minute ; // la minute de 0 à 59
  } maDateHeure ;
 
  // déclarations pour nouvelles fonctions: clavier, ...
  int programmeAEnregistrer ;  // indique qu'il faut enregistrer
  byte octetLu ; // lu sur eeprom à une adresse
  byte octetAEcrire ; // l'octet à recopier en eeprom
  uint8_t   readByte ( const uint16_t memoryAddress ) ; // proto readByte
  long memoryAddress ;  // adresse en eeprom
  char bitRelais ;  // le bit à monter lors des programmations. Dépend de destinataireProgrammation
  int nombreDeMinAProgrammer ; // itération de l'allumage en test
  int cpt ; // compteur de boucle
  //   ================== Déclarations des fonctions  ===============================
  const uint16_t adresseMotMagique = 0 ;
  const uint32_t motMagique = 0xB0CAD0 ;
  const uint16_t adresseDebut = adresseMotMagique + sizeof motMagique ;
  const uint16_t tailleRequise = 10080; // 7 jours * 24 heures * 60 minutes
  int temoinDeBoucle ; // compteur de boucle recherche zone (éluder premier passage)
  enum tJour : byte  { Lundi = 0 , Mardi , Mercredi , Jeudi , Vendredi , Samedi , Dimanche } ;
  const char * jours [] = { "LUN" , "MAR" , "MER" , "JEU" , "VEN" , "SAM" , "DIM" } ;
  //  ====================déclarations des fonctions =================================
  void stockageAllumageExtinction () ;  // place en mémoire le bit relais dans la zone all/ext
  void incrementDateHeure () ; // incrémentation de la structure incrementDateHeure
  void readClavier () ; // lecture clavier non nettoyé
  void displayDateHeure () ;  // affiche DAY XXHYY à la ligne reçue
  void refreshRelais () ;
  void displayLigneUneNormale () ;
  void cycleNormal () ; // reste coincé tant que manuel non validé
  void programmationManuel () ;
  void cycleControle () ;  // lecture du programme
  void displayLigneUneManuel () ;  // commande manuelle
  void readBouton () ;  // lecture du bouton
  void clearLigneZero ( ) ; // effacement de ligne 1 // ces déclarations sont des appels des fonctions? Non!
  void clearLigneUn ( ) ; // effacement de ligne 2
  void clearLigneDeux ( ) ; // effacement de ligne 3
  void clearLigneTrois ( ) ; // effacement de ligne 4
  void affichageDureeManuelle () ; // affichage de la durée en cours de programmation non encore affectée
  void afficheAllumage () ;  // affiche DateHeure à une position demandée
  void afficheChoixVoieManuelle () ; // affiche la voie manuelle en réglage
  void displayDestinataire () ; // affichage en ligne 2 de la voie programmée
  void preparationProgrammation () ; // textes préparatifs
  void curseurClignoteProg () ; // mise en clignotement du curseur pour avertir où on programme
  void afficheProgrammation () ;  /// refraîchit la programmation suite à une modification
  void displayLigneUneProgrammation () ;
  void effaceVingtCaracteres () ;  // envoie 20 espaces à partir du curseur
  void boucleProgrammationDestinataire () ; // ne sortira que programmer allulmage
  void boucleProgrammationAllumage () ;  // pour programmer allumage
  void boucleProgrammationExtinction () ; // à présent, enregistrer
  void programmationJourAllumage () ;  // boucle programmation réservée
  void programmationHeureAllumage () ;  // boucle programmation réservée
  void programmationMinuteAllumage () ;  // boucle programmation réservée
  void programmationJourExtinction () ;  // boucle programmation réservée
  void programmationHeureExtinction () ;  // boucle programmation réservée
  void programmationMinuteExtinction () ;  // boucle programmation réservée
  void afficheDestinAbrege () ;  // txt et pas nb
  void debugClavier () ;  // Débogage clavier
  void TestPositionTroisMiseAuPoint () ;  // phase mise au point lecture eeprom/cde relais/increm
  void allumeRouge () ; // Voyants de test
  void eteintRouge () ;
  void allumeBleu () ;
  void eteintBleu () ;
  void allumeJaune () ;
  void eteintJaune () ;
  void positionTroisVerificationsEeprom () ; // les vérifications eepro
  void dumpAdresseZero () ; // Pour tests eeprom
  void decodageJHM () ;  // décode minuteDebutAllumage en Jour Heure et Minute
 
  void clearEcran () ;  // nettoyage complet d'ecran
  void boucleProgDestinControle () ;  // sortira pour afficher
  void creationBitRelais () ;   // remplissage de la mémoire bitRelais de la valeur destinataire
  void explorationProgrammation () ;  // lecture des programmations en position 3
  void detectionDeProchaineZoneProgramme () ; // trouve les deux limites de prochaine zone
  void afficheProgrammationTrouvee () ;   // affiche LCD des extrémités de zone détectée
 
  //   ========================== SET UP ============================
  void setup ()
  {
  // pour eeprom
  Serial.begin ( 19200 ) ;
  memoire.begin () ;
 
  // essais pour débogage seulement
  pinMode ( 8 , OUTPUT ) ; // borne 8 en sortie LED BLEU
  pinMode ( 11 , OUTPUT ) ; // borne 8 en sortie LED ROUGE
  pinMode ( 12 , OUTPUT ) ; // borne 8 en sortie LED JAUNE
 
  clavier = 0 ;
  KB = 0 ;
  lcd.init(); // nécessaire pour l'afficheur
  lcd.backlight() ;
  lcd.setCursor( 0 , 0 ) ;
  refreshDisplayDone = 0 ; // mémoire de refresh visu unique  initialisée
  destinataireProgrammation = 0 ; // cuisine par défaut. Sera modifié par clavier
 
  // on fixe 5 6 et 7 en entrées pour clavier
  // programmation des pins logiques 6 7 et 8 pour clavier en entrées
 
  pinMode ( 9 , OUTPUT ) ; // les 4 sorties pour les relais
  pinMode ( 2 , OUTPUT ) ;
  pinMode ( 3 , OUTPUT ) ;
  pinMode ( 4 , OUTPUT ) ;
  pinMode ( 5 , INPUT ) ;
  pinMode ( 6 , INPUT ) ;
  pinMode ( 7 , INPUT ) ; // les 3 entrees clavier
  pinMode ( A0 , INPUT ) ; // les entrees bouton b0 2 seuls utilisés
  pinMode ( A1 , INPUT ) ;
 
  #ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
  #endif
 
  if ( ! rtc.begin() )
  {
    abort() ;
  }
  if ( rtc.lostPower() )  // supprimé pour 1307 mais rétablir pour 3231
  {
    rtc.adjust ( DateTime ( F (__DATE__) , F (__TIME__))) ;
  }
  digitalWrite ( 13 , LOW ) ; // sort 0
  digitalWrite ( 8 , LOW ) ;  // les LED éteintes
  digitalWrite ( 11 , LOW ) ;
  digitalWrite ( 9 , LOW ) ;  // 1  // les relais à zéro
  digitalWrite ( 2 , LOW ) ;  // 2
  digitalWrite ( 3 , LOW ) ;  // 3
  digitalWrite ( 4 , LOW ) ;  // 4
  eteintRouge () ;  //tout éteint
  eteintBleu () ;
  eteintJaune () ;
  Serial.println ( "Je vais démarrer\n" ) ;
  }
 
  void loop() {
  // put your main code here, to run repeatedly:
  allumeBleu () ;
  delay ( 1000 ) ;
  allumeRouge () ;
  eteintBleu () ;
  delay ( 1000 ) ;
  allumeJaune () ;
  eteintRouge () ;
  delay ( 1500 ) ;
  eteintJaune ();
  Serial.print ( "Je viens de faire un tour de mon travail\n" ) ;
  }
 
  //// ================================
  void readClavier ()  // lecture du clavier pour appels ponctuels
  {
  clavier = 0 ; // init avant lecture
  clavier = digitalRead ( 5 ); // lecture bit 0
  if ( clavier == 1 ) KB = 1 ; else KB = 0 ; // LSb recopié
  clavier = digitalRead ( 6 ) ; // lecture bit 1
  if ( clavier == 1 ) KB += 2 ; // mise à jour de KB
  clavier = digitalRead ( 7 ) ; // lecture bit 2
  if ( clavier == 1 ) KB += 4 ; // mise à jour de KB
  }
  //  =================================
  //  =============================================
  void readBouton ()  // lecture du bouton
  {
  lectBouton = digitalRead ( A0 ); // lecture bit 0
  if ( lectBouton == 1 ) bouton = 1 ;  else bouton = 0 ; // recopie
  lectBouton = digitalRead ( A1 ) ; // lecture bit 1
  if ( lectBouton == 1 ) bouton += 2 ; // mise à jour de bouton
  }
  ///   ===========================
  // ===========================================================
  void debugClavier ()  // Débogage clavier
  {
  char valeurLue = 0 ; // première valeur relevée à comparer avec une autre
  repriseClavier:  // si valeur non confirmée
  readClavier () ;
  if ( KB != 0 )
  {
    valeurLue = KB ;
    delay ( 15 ) ;
    readClavier () ;
    if ( KB != valeurLue ) goto repriseClavier ;
  }
  }
  // =====================================================
  //  ==========================================================================
  // gestion des voyants de test rouge bleu jaune
  //  ==================== Allumage/extinction LED =======================
  void allumeRouge ()
  {
  digitalWrite ( 11 , HIGH ) ; // allume ROUGE
  }
  // =========================================
  void eteintRouge ()
  {
  digitalWrite ( 11 , LOW ) ; // éteint ROUGE
  }
  // ========================================
  void allumeBleu ()
  {
  digitalWrite ( 8 , HIGH ) ; // allume BLEU
  }
  // =========================================
  void eteintBleu ()
  {
  digitalWrite ( 8 , LOW ) ; // éteint BLEU
  }
  // ========================================
  void allumeJaune ()
  {
  digitalWrite ( 12 , HIGH ) ; // allume JAUNE
  }
  // =========================================
  void eteintJaune ()
  {
  digitalWrite ( 12 , LOW ) ; // éteint JAUNE
  }
  // ========================================
  // characters.ino
  /*
  Character analysis operators
 
  Examples using the character analysis operators.
  Send any byte and the sketch will tell you about it.
 
  created 29 Nov 2010
  modified 2 Apr 2012
  by Tom Igoe
 
  This example code is in the public domain.
 
  http://www.arduino.cc/en/Tutorial/CharacterAnalysis
*/
A tout hasard, voici le code, concaténation de quelques "exemples", épurés et de quelques instructions tirées de mon programme pour clignoter. Je n'ai que trois LED pour aller au plus simple.