Reboot aléatoire de l'arduino

Bonjour à tous.

Je suis en train d’essayer de faire un système d’entrainement pour un club d’escrime.

Le principe est d’avoir des boutons équipés de leds rvb, et qui s’allument aléatoirement selon différents types d’exercice.

J’ai pu faire déjà plusieurs exercices qui fonctionnent sans problèmes, mais sur le dernier, j’ai un comportement de l’arduino que je ne comprend pas.

Cet exercice fait s’allumer un premier bouton, qui s’éteint une fois touché, puis un autre s’allume (maxi 10 fois). Si l’un des boutons est raté, l’exercice s’arrête là, on mémorise le score puis c’est le tour de l’escrimeur suivant.

Enfin, ça, c’est dans la théorie, mais en pratique, en plein milieu de l’exercice alors que les boutons sont bien enfoncés, l’arduino reboot sans aucune raison apparente, jamais au même moment (parfois au deuxième allumage, parfois au quatrième ou cinquième, etc …).

Voilà le code de cet exercice :

void Prog8() {
byte Ordre[9];
byte Score = 0;

  for (int h = 1 ; h <= Nb_Assauts ; h++) {
    for (int j = 1 ; j <= Nb_Tireurs ; j++) {         // Boucle sur le nb de tireurs
      for (int i = 0 ; i < 10 ; i++) {                // Tirage de l'ordre des cibles
        if ( i == 0 ) Ordre[i] = random(0, 8);
        if ( i > 0) {
          byte Tmp;
          do { Tmp = random(0, 8); } while ( Tmp == Ordre[i - 1]); // Si le tirage est égal à la cible précédente, on refait le tirage
          Ordre[i] = Tmp;
          Serial.println(Ordre[i]);
        }
      }

      lcd.clear();
      lcd.print("      Tireur ");
      lcd.print(j);
      lcd.setCursor(0,2);
      lcd.print("      Assaut ");
      lcd.print(h);

      Alea_Attente = random(Tps_Mini, Tps_Maxi + 1);

      Memo_Millis = millis();                           // Mémorisation de "l'heure"
      for (int k = 0 ; k < 8 ; k++) {                   // Allumage au rouge de toutes les leds
        digitalWrite(Pin_Leds[k][0], HIGH);
      }

      while (millis() - Memo_Millis < Tps_Pause){ }     // Attente de la fin du temps de mise en place
      for (int k = 0 ; k < 8 ; k++) {                   // Extinction des leds
        digitalWrite(Pin_Leds[k][0], LOW);
      }

      Memo_Millis = millis();                           // Mémorisation de "l'heure"
      while (millis() - Memo_Millis < Alea_Attente){ }  // Attente de la fin du temps aléatoire

      Memo_Millis = millis();                           // Mémorisation de "l'heure"
  
      for (int l = 0 ; l < 10 ; l++) {                  // Boucle sur les 10 cibles
        digitalWrite(Pin_Leds[Ordre[l]][2], HIGH);      // Allumage en bleu de la led

        while (millis() - Memo_Millis <= 1000) {        // Tant qu'on est dans la seconde
          buttons[Ordre[l]].update();                   // On actualise l'état du bouton
          if (buttons[Ordre[l]].fell()) {               // Si le bouton est enfoncé
            ++Score;                                    // On augmente le score de 1 pour ce tireur
            digitalWrite(Pin_Leds[Ordre[l]][2], LOW);   // On passe la led au vert
            digitalWrite(Pin_Leds[Ordre[l]][1], HIGH);
            delay(500);                                 // On attend 1/2 seconde
            break;                                      // On sort du While
          } 
        }
        digitalWrite(Pin_Leds[Ordre[l]][1], LOW);       // Extinction de la led
        digitalWrite(Pin_Leds[Ordre[l]][2], LOW);
        digitalWrite(Pin_Leds[Ordre[l]][3], LOW);
        Memo_Millis = millis();
      }                                                 // Fin de la boucle sur les cibles
      All_Off();  
      if ( Score > Memo_Results[j][0]) Memo_Results[j][0] = Score ; // On mémorise le nombre de touches réussies si c'est le meilleur résultat
      Score = 0;                                        // On remet la variable à 0 pour le tireur suivant
    }                                                   // Fin de la boucle sur les tireurs
  }                                                     // Fin de la boucle des assauts
  Fin_Ex();
  Mode_en_cours = 2;
}

Pour vous donner toutes les infos, c’est sur un clone chinois d’arduino mega, la fonction aléatoire utilise l’algo de Von Neumann (LOCODUINO - Comment gérer l’aléatoire ?) et le tableau Pin_Leds est déclaré comme ça :

// Colonnes : Pin rouge, Pin Vert, Pin Bleu, Pin Cathode, Pin Bouton
byte Pin_Leds[8][5] = {
  {39,52,22,2,37},      // Led/Bouton 0
  {41,50,24,3,35},      // Led/Bouton 1
  {43,48,26,4,33},      // Led/Bouton 2
  {45,46,28,5,31},      // Led/Bouton 3
  {47,44,30,6,29},      // Led/Bouton 4
  {49,42,32,7,27},      // Led/Bouton 5
  {51,40,34,8,25},      // Led/Bouton 6
  {53,38,36,9,23},      // Led/Bouton 7
};

Si quelqu’un a une idée de ce qui peut se passer … Merci d’avance

Dans 95% des cas cela se produit quand on tire trop de courant sur le régulateur de la carte arduino.
Il chauffe trop -> la sécurité se met en route -> le courant est coupé -> il refroidit -> la sécurité de retire et il redémarre -> le micro de nouveau alimenté passe par la phase de reboot conforme à sa datasheet -> jusqu'à ce que la sécurité se réenclenche

Première chose à faire : un bilan des courants
Ensuite fournir un schéma électrique avec les valeurs des composants.

Bonjour.

Merci de ta réponse.

Je suis pas chez moi ce weekend, donc j'ai pas de schéma sous la main, mais j'avoue que je serais surpris que ce soit un prb lié à une surcharge.

Cet exercice allume une seul led à la fois et fais rebooter, alors que d'autres en allument deux ou trois, et il n'y a pas de soucis.

En plus j'ai oublié de préciser, mais les LEDs sont alimentées en 12v, et commandées via uln2803 et udn2981.

C'est donc très probablement lié à mon code ...

Et pour compléter les infos, à la compilation, je ne suis qu'à 11% de la mémoire de stockage, et 9% des variables.

Bonjour,

Difficile de te répondre car tu n’as pas jugé utile de mettre ton code en entier en particulier la définition des tableaux.
Je remarque néanmoins que j varie de 1 à Nb_Tireurs

  for (int j = 1 ; j <= Nb_Tireurs ; j++) {

et tu utilises un tableau avec l’index j

 if ( Score > Memo_Results[j][0]) Memo_Results[j][0] = Score ;

J’espère que ton tableau est bien dimensionné à Nb_Tireurs+1

En C utiliser un index qui varie de 1 à n pour un tableau au lieu de 0 à n-1 est source de problème potentiel.

Bonjour Kamill

Je n'ai pas tout posté car les autres exercices déjà fait fonctionnent bien et comme il y en a 6, ça aurait été beaucoup trop long.

Pour le dimensionnement du tableau, il est prévu pour mémoriser jusqu'à 15 tireurs, mais lors de mes tests, comme la variable Nb_Tireurs est réglable, je la met à 3 ou 4, et ça reboot quand même.