Reset arduino nano avec broche RST

Bonjour à tous!

Voila je viens par ici quémander une solution à mon problème que je ne comprend pas :

je souhaite utilisé une fonction millis et pour éviter que l'overflow me foute le bazar je voudrais reset l’Arduino régulièrement.

jusque la tout me parait clair et je vois bien la procédure, sauf que dans la pratique, une fois un reset effectué j'ai l'impression que l'arduino reset en boucle et ne démarre donc jamais le programme.

J'ai suivi la première méthode de cet exemple : https://www.instructables.com/id/two-ways-to-reset-arduino-in-software/

j'ai pourtant bien mis en tout début de programme le pin 13 ( celui qui commande le reset) sur HIGH.

J'ai l'impression que malgré ça il démarre sur LOW et donc me fait reset en boucle.

Voici mon code :

int ouv = 2;         //Ouverture sur pin 2
int ouv_gnd = 3;     //Ouverture GND sur pin 3
int ferm = 9;        //Fermeture sur pin 9
int ferm_gnd = 11;   //Fermeture GND sur pin 11
int Pouv = 10;       //Porte ouverte sur pin 10
int Pferm = 12;      //Porte fermée sur pin 12
int Lum = 8;         //Luminosité sur pin 8
int TEST1 = 0;       //Porte ouverte sur pin RX
int TEST2 = 1;       //Porte ouverte sur pin TX
int RESET = 13;      //Porte ouverte sur pin 13
unsigned long Currenttime;
unsigned long Newtime;



void setup() {
  digitalWrite(RESET, HIGH);
  delay(200);
  pinMode (ouv, OUTPUT);
  pinMode (ouv_gnd, OUTPUT);
  pinMode (ferm, OUTPUT);
  pinMode (ferm_gnd, OUTPUT);
  pinMode (Pouv, INPUT);
  pinMode (Pferm, INPUT);
  pinMode (Lum, INPUT);
  pinMode (TEST1, OUTPUT);
  pinMode (TEST2, OUTPUT);
  pinMode (RESET, OUTPUT);
  digitalWrite(ouv, LOW);       //demarrage moteur non alimenté
  digitalWrite(ouv_gnd, HIGH);   //
  digitalWrite(ferm, HIGH);      //
  digitalWrite(ferm_gnd, HIGH);  //
  Serial.begin(9600);
  delay(10000);

}

void loop() {
  if (digitalRead (Pouv) == HIGH && digitalRead (Lum) == LOW ) {

    digitalWrite(ouv, LOW);       //Ouverture porte
    digitalWrite(ouv_gnd, LOW);   //Ouverture porte
  } else {
    digitalWrite(ouv, HIGH);       //Pas d'Ouverture porte
    digitalWrite(ouv_gnd, HIGH);   //Pas d'Ouverture porte
  }

  if (digitalRead (Pferm) == HIGH && digitalRead (Lum) == HIGH ) {
    digitalWrite(ferm, LOW);       //Fermeture porte
    digitalWrite(ferm_gnd, LOW);   //Fermeture porte
  } else {
    digitalWrite(ferm, HIGH);       //pas de Fermeture porte
    digitalWrite(ferm_gnd, HIGH);   //pas de Fermeture porte
  }
  
  Currenttime = millis();
  
  if (Currenttime >= 14000 ) {

    digitalWrite(RESET, LOW);
  }

  // while (digitalRead (Pouv) == HIGH) {
  // Serial.print(123456);
  //digitalWrite(ferm, LOW);  //Fermeture porte
  //digitalWrite(ferm_gnd, LOW);  //Fermeture porte

}

millis() ne fout pas le bazar si on l'utilise correctement voir l'exemple (blinkWithoutDelay).
En même temps, quand on regarde ton code, millis() n'est pas utilisé sauf pour faire le reset alors je ne vois pas trop l'intérêt.
Faire un reset parce qu'on a un code foireux n'est jamais une solution. Il vaut mieux chercher le problème et le résoudre. Enfin, c'est ma façon de voir les choses.....

Bonjour,

Je suis du même avis que fdufnews: si tu es obligé de faire un reset c'est que le programme est mal foutu.

Cependant si tu veux réellement faire un reset avec une pin du micro, il ne faut pas utiliser la pin 13 car celle ci est actionnée plusieurs fois par le bootloader provoquant un reset à répétition.

Bonjour,

Je suis du même avis que fdufnews et kamill : si tu es obligé de faire un reset c'est que le programme est mal foutu.

Cependant si tu veux réellement faire un reset il vaut mieux utiliser l'instruction qui va bien:asm("jmp 0"); // Reset

jpm 0 et reset matériel ne sont pas interchangeables.
jmp 0 ne réinitialise pas tous les registres à leur valeur par défaut, ce qui est fait par le reset matériel.

je souhaite utilisé une fonction millis et pour éviter que l'overflow me foute le bazar je voudrais reset l'Arduino régulièrement.

Son problème est là : le bazar pour lui c'est quand millis() déborde.

Et c'est un faux problème donc reset inutile.

Il ne faut pas utiliser millis() directement mais mettre sa valeur dans au moins deux variables entières.
Si milli() a débordé entre la prise des deux temps les règles de l'arithmétique sur les variables entières feront que la soustraction se passera correctement sans avoir besoin d'intervenir.

Juste pour enfoncer le clou, ou comment ne pas chercher MIDI à 14H00 :
https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/

jmp 0 ne réinitialise pas tous les registres à leur valeur par défaut, ce qui est fait par le reset matériel.

Bien vu! Mais si on passe par le watchdog, il doit s'agir d'un vrai reset, et on a ainsi la mise à défaut des registres? C'est moins encombrant que d'utiliser une broche physique.

Tout d'abord, merci pour toute ces réponse.

Merci particulièrement à kamill qui a résolu mon problème de RESET, c’était effectivement le fait d'utilisé la broche 13 qui posait problème.

Ensuite pour mon code "foireux", si j'ai bien compris, en utilisant millis de cette maniere je n'aurais pas de probleme d'overflow :

int ouv = 2;         //Ouverture sur pin 2
int ouv_gnd = 3;     //Ouverture GND sur pin 3
int ferm = 9;        //Fermeture sur pin 9
int ferm_gnd = 11;   //Fermeture GND sur pin 11
int Pouv = 10;       //Porte ouverte sur pin 10
int Pferm = 12;      //Porte fermée sur pin 12
int Lum = 8;         //Luminosité sur pin 8
int TEST1 = 0;       //Porte ouverte sur pin RX
int TEST2 = 1;       //Porte ouverte sur pin TX
int RESET = 5;      //Porte ouverte sur pin 5
unsigned long Interval = 4000;
unsigned long PreviousMillis = 0;



void setup() {
  digitalWrite(RESET, HIGH);
  delay(200);
  pinMode (ouv, OUTPUT);
  pinMode (ouv_gnd, OUTPUT);
  pinMode (ferm, OUTPUT);
  pinMode (ferm_gnd, OUTPUT);
  pinMode (Pouv, INPUT);
  pinMode (Pferm, INPUT);
  pinMode (Lum, INPUT);
  pinMode (TEST1, OUTPUT);
  pinMode (TEST2, OUTPUT);
  pinMode (RESET, OUTPUT);
  digitalWrite(ouv, HIGH);       //demarrage moteur non alimenté
  digitalWrite(ouv_gnd, HIGH);   //
  digitalWrite(ferm, HIGH);      //
  digitalWrite(ferm_gnd, HIGH);  //
  Serial.begin(9600);
  delay(10000);

}

void loop() {


  if (digitalRead (Pouv) == HIGH && digitalRead (Lum) == LOW ) {
    delay (4000);
    if (digitalRead (Pouv) == HIGH && digitalRead (Lum) == LOW ) {
      digitalWrite(ouv, LOW);       //Ouverture porte
      digitalWrite(ouv_gnd, LOW);   //Ouverture porte
      PreviousMillis = millis();
    }
  }


  if (digitalRead (Pferm) == HIGH && digitalRead (Lum) == HIGH ) {
    delay (4000);
    if (digitalRead (Pferm) == HIGH && digitalRead (Lum) == HIGH ) {
      digitalWrite(ferm, LOW);       //Fermeture porte
      digitalWrite(ferm_gnd, LOW);   //Fermeture porte
      PreviousMillis = millis();
    }
  }


  if (millis() - PreviousMillis >= Interval) {
    digitalWrite(ferm, HIGH);       
    digitalWrite(ferm_gnd, HIGH);   
    digitalWrite(ouv, HIGH);       
    digitalWrite(ouv_gnd, HIGH);
  }

Merci encore, c'est clair maintenant.

morph3u5:
en utilisant millis de cette maniere je n'aurais pas de probleme d'overflow

Exactement.
Mais alors, pourquoi avoir conservé des delay() dans ton code?

j'utilise les delay() pour retester la photorésistance, confirmé que c'est bien la nuit et non une baisse temporaire de luminosité.

j'utilise le millis() comme sécurité, si le capteur hall ne détecte pas la fin de course, je coupe le moteur après 4s.

Ce que je veux dire c'est que tu pourrais tout faire avec une petite machine à états rythmée avec cette temporisation de 4s avec millis() et tu aurais un soft bien propre et facile à maintenir ou à faire évoluer plus tard.