Remplacer Delay() par millis()


bonjour et bonne année à tous,

j'ai utilisé un pro mini pour modifier une télécommande 433 mhz sans fil qui à l'origine commute un relais à l'appui sur un unique bouton. le relais décolle au relâché du bouton.
a partir de 30 m du récepteur, la commande est aléatoire et le relais se ferme et s'ouvre plusieurs fois sur une commande d'une durée de 2 secondes environ. cela fonctionne ainsi jusqu'à une centaine de mètres, endroit ou je désire commander une pompe avec un appui pour marche et un autre appui pour arrêt.

sur la carte récepteur, j'ai séparé la sortie du circuit intégré décodeur > pin2 du pro mini, du transistor commandant le relais > pin4. l'impulsion fait 5 v, donc compatible arduino.

c'est tout bête me direz-vous ;)

en temps normal, le µp est endormie (consommation 3.5 ma).
j'ai prévu une mise en marche de la pompe au front montant de la première impulsion, suivi d'un verrouillage de l'entrée pendant 4 secondes. le µp est sorti du mode veille en même temps.

la pompe reste en fonctionnement jusqu'au prochain appui sur le bouton de la télécommande. ce qui arrête la pompe et retour en veille au bout de 5 secondes.

pour simplifier le mode veille, j'utilise la librairie low-power

en cas de déclenchement involontaire, j'ai programmé un arrêt forcé avec millis() au bout de 10 mn

par contre les temporisations de 4 et 5 secondes sont faites avec delay() que je n'arrive pas à modifier avec la commande millis().

tout fonctionne mais je ne comprends pas comment, ni pourquoi j'ai du ajouter cette tempo de 5 secondes, sinon la mise en veille ne se fait pas après arrêt de la pompe.
code: [select]
#include "lowpower.h"

const byte interruptpin = 2;
const byte led = 13;
const byte pomp = 4;
int etatpin2;
int actif = 0;
unsigned long temps1;// première impulsion de commande
unsigned long temps2;//

void pompoff() {
    digitalwrite (led, 0);
    digitalwrite (pomp, 0);
    delay(5000);// doit être plus long que le délai de départ pompe.
    actif = 0;
    veille();
}
void wake () {
  // ne fait rien
}  // end of wake


void veille() {
  attachinterrupt(0, wake, high);
  lowpower.powerdown(sleep_forever, adc_off, bod_off);
  detachinterrupt(0);
}

void setup ()
{
  pinmode(led, output);
  pinmode(pomp, output);
  pinmode(interruptpin, input_pullup);
  digitalwrite (interruptpin, high);  // sinon se mets en veille sur front descendant
  veille();
}  // end of setup

void loop ()
{
  etatpin2 = digitalread(interruptpin);
  if (etatpin2 == 1) {// frond montant
    //if (temps2 > 4000)pompoff(); // prochaine impulsion = arrêt pompe
    if (!actif) {// joué une fois pour mémoriser la première impulsion
      digitalwrite (led, 1);
      digitalwrite (pomp, 1);
      temps1 = millis();
      actif = 1;
      delay(4000);
    }
   else pompoff();// nouvelle impulsion sur entrée après 4 secondes.
  }
  temps2 = millis() - temps1;
  if (temps2 > 600000) pompoff(); // arret forcé à 10 mn
} // end of loop

combien de temps la pin de la télécommande reste à high sur l'entrée 2 ?

à la fin de setup() vous rentrez en veille et ne commencez la loop() que quand une interruption arrive. ça appelle wake() qui ne fait rien puis détache l'interruption et la loop() commence.

--> du temps s'est écoulé entre l'interruption et l'arrivée dans la loop(), êtes vous toujours 100% sûr à ce moment là que la pin 2 est toujours high?

en supposant que ce soit le cas vous rentrez dans le if et mettez actif à 1 et initialisez correctement temps1 puis attendez 4 secondes. --> est-ce suffisant pour que la pin 2 retombe à zéro? (que se passe-t-il si vous avez tenu la télécommande appuyée)

en supposant qu'elle était retombée à low, vous tournez dans la loop() soit tant que la télécommande n'est pas appuyée de nouveau, soit 600000ms (10 min). à ce moment là vous appelez pompoff()

si vous aviez déclenché pompoff() en appuyant sur la télécommande et pas avec les 10 minutes, vous allez arrêter la pompe mais là encore vous n'êtes pas sûr de l'état de la pin 2 avant d'aller vous endormir. le
code: [select]
    delay(5000);// doit être plus long que le délai de départ pompe.
sert en fait d'attente active pour que le bouton de la télécommande soit relâché, sinon au moment même ou vous vous endormez la pin 2 et high et l'interruption se déclenche et vous vous réveillez.

à mon avis au lieu de faire un delay de x secondes vous feriez mieux d'attendre que la pin2 retombe à low avant de poursuivre et donc je mettrais un
code: [select]
while (digitalread(interruptpin) == low);à la place des 2 delay()




ps
• utilisez un boolean plutôt qu'un int pour actif et utilisez true et false.
• de même préférez pour la lisibilité high ou low pour les opération de digitalwrite / test sur digitalread
• utilisez plutôt la notation 600000ul pour bien montrer que c'est un unsigned long


Arduino Forum > International > Français (Moderators: jfs, Snootlab) > Remplacer Delay() par millis()


arduino

Comments

Popular posts from this blog

DHT11 Time out error using v0.4.1library

Sketch upload fails with Java error (___REMOVE___/bin/avrdude)!

Arduino Uno + KTY81/210 temperature sensor