Reset spontané Arduino

a marqué ce sujet comme résolu.

Bonjour tout le monde, j'ai créé une petite minuterie (pas plus de 1'40 hein^^) après avoir lu le tuto de Eskimon sur les afficheurs 7 segments. Cependant, la carte se reset systématiquement toutes les 5 à 30 secondes. Pour une minuterie, ce n'est pas génial… Savez-vous d'où cela peut-il venir? Je vous joins le programme et une photo du montage (vous ne verrez rien, c'est un gros bordel: peut-être que cela vient là?). J'utilise un câble USB tout pourri que j'ai trouvé dans une armoire, mais il semblait bien marcher jusque-là. De plus, j'ai essayé d'upload un programme qui gérait juste l'allumage d'une LED (qui s'allumait bien avec le programme de minuterie), et la LED ne s'allume même pas! De toute façon je vais défaire le montage et tester la carte sur un autre pour voir si c'est bien un défaut de la carte ou du câble.

  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
const int A = 7;
const int B = 5;
const int C = 1;
const int D = 6;
const int seg_1 = 8;
const int seg_2 = 10;
const int btn_1 = 2;
const int btn_2 = 3;
const int inhib = 11;
const int led_1 = 12;
const int led_2 = 9;
char nombre;
char dizaine;
char unite;
char chiffre;
boolean afficheur;
boolean decompte_actif;
int time;
int time2;
int etat_1;
int etat_2;

void setup(){
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(seg_1, OUTPUT);
  pinMode(seg_2, OUTPUT);
  pinMode(inhib, OUTPUT);
  pinMode(led_1, OUTPUT);
  pinMode(led_2, OUTPUT);
  digitalWrite(A, LOW);
  digitalWrite(B, LOW);
  digitalWrite(C, LOW);
  digitalWrite(D, LOW);
  digitalWrite(seg_1, LOW);
  digitalWrite(seg_2, LOW);
  digitalWrite(inhib, LOW);
  digitalWrite(led_1, HIGH);
  digitalWrite(led_2, HIGH);
  nombre = 0;
  afficheur = LOW;
  time = millis();
}

void loop(){
  reglage();
  decompte();
  fin();
}

void reglage(){
  attachInterrupt(0, moins, FALLING);
  attachInterrupt(1, plus, FALLING);

  while(!decompte_actif){
    if(millis() - time >= 10){
      afficheur = !afficheur;
      afficher(nombre, afficheur);
      time = millis();
    }
    etat_1 = digitalRead(btn_1);
    etat_2 = digitalRead(btn_2);
    if(!etat_1 && !etat_2){
      time2 = millis();
      decompte_actif = !decompte_actif;
      attachInterrupt(0, rien, FALLING);
      attachInterrupt(1, rien, FALLING); 
    }
  }
}




void decompte(){
  while(decompte_actif){
    if(millis() - time >= 10){
      afficheur = !afficheur;
      afficher(nombre, afficheur);         
      time = millis();
      }

    if(millis() - time2 >= 1000){
      nombre--;
      time2 = millis();
      if(nombre < 0){
        decompte_actif = !decompte_actif;
        etat_1 = HIGH;
        etat_2 = HIGH;
        digitalWrite(inhib, HIGH);
      }
    }
  }
}




void fin(){
  while(etat_1 && etat_2){
    digitalWrite(led_1, LOW);
    delay(200);
    digitalWrite(led_1, HIGH);
    digitalWrite(led_2, LOW);
    delay(200);
    digitalWrite(led_2, HIGH);
    etat_1 = digitalRead(btn_1);
    etat_2 = digitalRead(btn_2);
  }

  digitalWrite(inhib, LOW);
  time = millis();
}




void afficher(int nombre, boolean afficheur){
  digitalWrite(A, LOW);
  digitalWrite(B, LOW);
  digitalWrite(C, LOW);
  digitalWrite(D, LOW);

  dizaine = nombre / 10;
  unite = nombre - (dizaine * 10);

  if(afficheur){
    chiffre = unite;
    digitalWrite(seg_1, LOW);
    digitalWrite(seg_2, HIGH);
  }
  else{
    chiffre = dizaine;
    digitalWrite(seg_1, HIGH);
    digitalWrite(seg_2, LOW);
  }

  if(chiffre >= 8){
    digitalWrite(D, HIGH);
    chiffre -= 8;
  }
  if(chiffre >= 4){
    digitalWrite(C, HIGH);
    chiffre -= 4;
  }
  if(chiffre >= 2){
    digitalWrite(B, HIGH);
    chiffre -= 2;
  }
  if(chiffre >= 1){
    digitalWrite(A, HIGH);
  }
}




void plus(){
  nombre++;
  if(nombre > 99){nombre = 0;}
}

void moins(){
  nombre--;
  if(nombre < 0){nombre = 99;}
}

void rien(){
}

Montage

J'arrive pas à trouver le code de attachInterrupt, mais le plus crédible c'est que l'opération n'est pas atomique, et que tu crash ou obtient un comportement non désiré quand une interruption survient alors que tu es en train de setter le handler. Pour tester si c'est ça, entoure tous tes appels à attachInterrupt avec noInterrupts (); et interrupts ();

J'ai essayé, ça ne marche toujours pas… J'ai testé un programme basique d'allumage d'une LED, la carte ne se reset pas. J'ai alors essayé un programme affichant un chiffre aléatoire avec les afficheurs 7 segments, et la carte se reset comme avec la minuterie. Pourtant, ce programme fonctionnait quand je n'utilisais pas encore de décodeur BCD (avec un programme légèrement différent bien sûr mais identique dans la forme et les fonctions utilisées). Pensez-vous que cela peut venir du décodeur BCD?

Oui je peux tout afficher, le programme marche parfaitement, c'est juste qu'il ne dure pas très longtemps. Je viens de tester sans décodeur BCD, et le problème subsiste. Ca ne vient pas non plus des boutons, j'ai essayé un décompte à partir de 99. De plus, il y a une autre erreur que je n'avais pas signalé, le programme passe d'une étape à une autre sans aucune raison. Par exemple, la fonction fin() s'était déclenchée spontanément. Je pense que ma carte a simplement un problème, elle doit bugger quand elle est confrontée un programme un minimum complexe, enfin je ne sais pas trop…

Je pense que ma carte a simplement un problème, elle doit bugger quand elle est confrontée un programme un minimum complexe

Je ne pense pas non. On est loin du programme complexe encore donc ca devrait aller.

Perso je parierais bien sur un faux contact quelque part, je vois que ca pour expliquer un reboot étrange.

+0 -0

Salut ! Je ne suis pas un expert en arduino mais il me semble que tu stock le retour de millis() dans un int, si tu utilise une arduino uno, un int est codé sur 16 bits donc tu peux stocker 216 millisecondes soit à peu près 65 secondes or tu compte 99 secondes :p. Je sais pas si ça vient de là mais bon…

Sinon (ça a rien à voir mais bon): Tu peux remplacer

1
2
3
4
void plus(){
  nombre++;
  if(nombre > 99){nombre = 0;}
}

par

1
void plus(){ nombre = (nombre+1)%99;}

(idem pour moins) et

1
unite = nombre - (dizaine * 10);

par

1
unite = nombre%10;
+2 -0

Merci pour cette info que j'avais complètement oubliée. Par contre, j'ai essayé, ça ne résout pas le problème de reset… J'ai refait le montage plusieurs fois, donc j'ai du mal à croire au faux contact. Tu es vraiment sûr qu'un défaut de carte est impossible (ou du moins très peu probable)?

Voilà mon schéma (désolé pour l'attente). Par contre, je n'avais pas de logiciel pour faire des schémas, donc j'ai fait un truc à l'arrache sur Paint (si vous avez des noms de logiciels, ça m'intéresse). Ne vous inquiétez pas pour les liaisons entre les afficheurs et le décodeur, c'est parfait pour ça, j'ai même vérifié les data sheets. Et je précise, mes afficheurs sont à cathodes communes et non anodes.

Schéma

Et voilà le code:

  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
const char A = 7;
const char B = 9;
const char C = 10;
const char D = 8;
const char seg_1 = 2;
const char seg_2 = 1;
const char btn_1 = 3;
const char btn_2 = 4;
const char inhib = 6;
const char led_1 = 11;
const char led_2 = 12;
char nombre;
char dizaine;
char unite;
char chiffre;
boolean afficheur;
boolean decompte_actif;
long time;
long time2;
boolean etat_1;
boolean etat_2;
boolean memoire_1;
boolean memoire_2;

void setup(){
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(seg_1, OUTPUT);
  pinMode(seg_2, OUTPUT);
  pinMode(inhib, OUTPUT);
  pinMode(led_1, OUTPUT);
  pinMode(led_2, OUTPUT);
  pinMode(btn_1, INPUT);
  pinMode(btn_2, INPUT);
  digitalWrite(A, LOW);
  digitalWrite(B, LOW);
  digitalWrite(C, LOW);
  digitalWrite(D, LOW);
  digitalWrite(seg_1, LOW);
  digitalWrite(seg_2, LOW);
  digitalWrite(inhib, LOW);
  digitalWrite(led_1, HIGH);
  digitalWrite(led_2, HIGH);
  nombre = 0;
  afficheur = LOW;
  time = millis();
  memoire_1 = HIGH;
  memoire_2 = HIGH;
}

void loop(){
  reglage();
  decompte();
  fin();
}

void reglage(){  
  while(!decompte_actif){
    if(millis() - time >= 10){
      afficheur = !afficheur;
      afficher(nombre, afficheur);
      time = millis();
    }
    etat_1 = digitalRead(btn_1);
    etat_2 = digitalRead(btn_2);
    if(!etat_1 && !etat_2){
      time2 = millis();
      decompte_actif = !decompte_actif; 
    }
    if((!etat_1)&&(etat_1 != memoire_1)){moins();}
    if((!etat_2)&&(etat_2 != memoire_2)){plus();}
    memoire_1 = etat_1;
    memoire_2 = etat_2;
  }
}




void decompte(){
  while(decompte_actif){
    if(millis() - time >= 10){
      afficheur = !afficheur;
      afficher(nombre, afficheur);         
      time = millis();
      }

    if(millis() - time2 >= 1000){
      nombre--;
      time2 = millis();
      if(nombre < 0){
        decompte_actif = !decompte_actif;
        etat_1 = HIGH;
        etat_2 = HIGH;
        digitalWrite(inhib, HIGH);
      }
    }
  }
}




void fin(){
  while(etat_1 && etat_2){
    digitalWrite(led_1, LOW);
    delay(200);
    digitalWrite(led_1, HIGH);
    digitalWrite(led_2, LOW);
    delay(200);
    digitalWrite(led_2, HIGH);
    etat_1 = digitalRead(btn_1);
    etat_2 = digitalRead(btn_2);
  }

  digitalWrite(inhib, LOW);
  time = millis();
}




void afficher(int nombre, boolean afficheur){
  digitalWrite(A, LOW);
  digitalWrite(B, LOW);
  digitalWrite(C, LOW);
  digitalWrite(D, LOW);

  dizaine = nombre / 10;
  unite = nombre % 10;

  if(afficheur){
    chiffre = unite;
    digitalWrite(seg_1, LOW);
    digitalWrite(seg_2, HIGH);
  }
  else{
    chiffre = dizaine;
    digitalWrite(seg_1, HIGH);
    digitalWrite(seg_2, LOW);
  }

  if(chiffre >= 8){
    digitalWrite(D, HIGH);
    chiffre -= 8;
  }
  if(chiffre >= 4){
    digitalWrite(C, HIGH);
    chiffre -= 4;
  }
  if(chiffre >= 2){
    digitalWrite(B, HIGH);
    chiffre -= 2;
  }
  if(chiffre >= 1){
    digitalWrite(A, HIGH);
  }
}




void plus(){nombre = (nombre + 1) % 100;}

void moins(){
  nombre--;
  if(nombre < 0){nombre = 99;}
}

Voilà, j'ai pas modifié grand chose, sauf les int pour les millis(), j'ai enlevé les interruptions qui servaient à rien et qui étaient des potentielles sources d'erreurs, et j'ai changé quelques trucs anodins. Et désolé pour l'attente :)

Vraiment je pense que ce problème vient de ma carte, peut-être qu'elle ne supporte pas de changer l'état de ses sorties toutes les 10 ms. Après je suis sûrement pas un expert, mais je ne comprends pas d'où autre cela pourrait-il venir, puisque j'ai testé le montage sans LED, puis sans bouton, puis j'ai refait le montage. D'autant plus que j'avais déjà constaté quelques bugs de ce genre, comme un petit reset ou un petit temps de latence, mais ça ne gênait pas puisque c'était avec des programmes simplissimes. A part si quelqu'un trouve la solution à mon problème, je pense que je vais racheter une nouvelle carte, au pire ça me servira toujours d'en avoir deux, et j'avais envie de m'acheter une Mega parce que je sens que je vais être vite limité par le nombre d'entrées/sorties disponibles.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte