Aide pour temporisation

Bonjour a tous,

alors voila, je vous explique mon probleme : je souhaite creer une sorte d'automate pour mon aquarium recifal qui le permetterais de :

  • creer un mode nourissage (qui couperait mon brassage pendant 10 minutes a l'appui sur un BP)
  • creer un mode pour couper l'ecumeur pendant un temps prédéfini (pour l'ajout de produits dans le bac)

j'ai realiser plusieurs essais, mais c'est avec la temporisation que j'ai un probleme. En effet, j'utilise "delay" (ayant commencer le programmation arduino il n'y a vraiment pas tres longtemps), mais si mon ecumeur est deja coupé, je ne peut pas couper mon brassage.

Dans un premier temps, juste 2 LED RGD et 2 BP suffiront pour la partie hardware, en plus, bien sur, des relais, pour l'ecran tactile, on vera dans quelques années (pas encore les connaissance necessaire pour lol).

voila, si quelqu'un pouvait m'aider pour mon probleme de tempo.

cordialement

La solution : la fonction millis() !!!
Elle permet de temporise sans bloquer le programme.
C'est une horloge interne qui représente les millisecondes écoulés depuis le lancement du micro contrôleur

la fonction millis n'est pas limitée a 50 jours ?

je vais essayer d'ecrire un programme en remplacant delay par millis, et te tiens au courant.

Merci beaucoup (et desole si ma question est un peu "bebete", mais comme je l'ai dit, je debute lol)

je comprend pas bien comment utilisé millis, j'ai regarder sur google, mais on trouve tout un tas de chose differente.

Aurait-tu un exemple concret pour resoudre mon probleme stp

en te remerciant d'avance

tiotjordan:
la fonction millis n'est pas limitée a 50 jours ?

La fonction milli() telle que conçue par l'équipe arduino oui mais la tienne non . :grin:

La fonction milli utilise le timer 0 qui est prépositionné avec un pré-diviseur de 64 par la fonction init() qui s'exécute en tâche de fond sans que tu t'en aperçoive au début du programme.
Mais rien n'empèche de modifier les préréglages dans la suite du programme. Tu peux choisir un pré-scaler de 256 ou 1024, cf datasheet ATMega328p pages 109 et 110.
Il suffit de modifier la valeur des bits CS02, CS01, CS00 dans le registre TCCR0B.
Attention cette modification aura des conséquences sur la fréquence de la PWM et la valeur de delay().
On peut aussi s'inspirer du code de la fonction millis() pour écrire sa propre fonction qui utiliserait les timer1 ou 2 et éviterait les inconvénients précédents.

...
  readKbd();
  timeTch4=millis(); //capture la valeur de millis

  while (tch4){  // tant qu'on appui sur la touche 4
    if (millis()<timeTch4+1000) {
      Serial.println("appui court touche 4");
    }
    if (millis()>timeTch4+1000) {
      Serial.println("appui long touche 4");  
    }
    readKbd();
  }
...

tiotjordan:
je comprend pas bien comment utilisé millis, j'ai regarder sur google, mais on trouve tout un tas de chose differente.

Aurait-tu un exemple concret pour resoudre mon probleme stp

en te remerciant d'avance

Dans les exemples chargés avec l'IDE il y a le programme BlinkWithoutDelay. C'est un bon exemple de gestion de délai utilisant millis() à la place de delay().

mouais........ sa complique pas mal les choses se truc la, je comprend rien lol

je vais reecrire mon code en utilisant delay d'abord, et je verais pour modifier avec milliis par la suite.

Sans vouloir te paraître vexant, si tu trouves que millis est compliqué c'est que tu n'as pas du comprendre son utilité .

Millis te permet de maîtriser le temps dans une boucle d'un programme tout en continuant a exécuter d'autre tâche. Contrairement au delay qui ne permet d'exécuter aucun code.

Donc tu enregistres ton temps dans une variable en unsigned long puis dans ta boucle principale tu tests cette variable + ta tempo dans un if.
Comme ça tu déclenches ce que tu veux dans ton if sans bloque le reste des actions.

Bon alors :

millis() est une fonction qui retourne le nombre de millisecondes écoulées depuis le démarrage de l'arduino.

La valeur retournée est de type unsigned long int : c'est un nombre entier positif codé sur 32 bits.
Sa plage de valeurs va de 0 à 2^32-1, soit de 0 à 4 294 967 295

La valeur maxi est donc atteinte au bout de 4 294 967 295 millisecondes après le démarrage de l'arduino, soit 49 jours, 17 heures, 2 minutes, 47 secondes et 295 millisecondes.

Là, il se produit un roll over, c'est-à-dire que la valeur repasse à zéro, puis continue à s'incrémenter.

Il y a un moyen très simple d'éviter tout problème lié à ce phénomène de roll over.
Il suffit de ne pas utiliser telle quelle la valeur retournée par millis(), mais de raisonner uniquement sur la différence entre deux valeurs retournées par millis(), c'est-à-dire sur le délai écoulé entre les deux appels.

par exemple :

unsigned long int delai, topchrono;
...
//debut de periode de mesure
   topchrono = millis();
...
//vérification d'expiration du délai à intervalles réguliers
  delai = millis() - topchrono;
  if (delai > mon_delai_souhaite)
  {
    youpi_je_traite();
    //puis l'une ou l'autre des réinitialisations ci-dessous
    top_chrono = millis(); //pour un redéclenchement dans mon_delai_souhaite
    top_chrono += mon_delai_souhaite; //pour un redéclenchement à intervalles plus précis
  }

L'astuce réside dans le fait que l'opération de soustraction est insensible au roll over.

Ainsi, delai = millis() - topchrono donnera toujours un résultat correct, même si un roll over intervient dans la période d'attente.
Au moment du calcul, millis() aura alors une valeur très petite, et topchrono aura une valeur très grande.
D'un point de vue mathématique, le résultat de la soustraction devrait avoir une valeur négative.
Mais nous sommes dans le monde informatique, avec des entiers ayant une plage de valeurs limitée, et des opérateurs qui tronquent les résultats, ce qui donne au final des valorisations en boucles.
Ainsi par exemples :
4 294 967 295 + 1 = 0
2 - 4 294 967 295 = 3
Et tant pis pour les maths

Si sin j'ai compris l'utilité de millis, mais je ne comprend pas bien comment le codé

Tenez, je vous met le code comme je l'aurais fais avec delay

const int APPUI=LOW;
const int bp_ecumeur=2;
const int bp_nourissage=3;
const int relais_ecumeur=4;
const int relais_brassage=5;
const int relais_pompe=6;

const int Vert_ecumeur=7;
const int Rouge_ecumeur=8;

const int Vert_nourissage=9;
const int Rouge_nourissage=10;

void setup() {
  
  pinMode (bp_ecumeur, INPUT);
  pinMode (bp_nourissage, INPUT);
  pinMode (relais_ecumeur, OUTPUT);
  pinMode (relais_brassage, OUTPUT);
  pinMode (relais_pompe, OUTPUT);
  
  pinMode (Vert_ecumeur, INPUT);
  pinMode (Rouge_ecumeur, INPUT);
  pinMode (Vert_nourissage, INPUT);
  pinMode (Rouge_nourissage, INPUT);
  
  digitalWrite (bp_ecumeur, HIGH);
  digitalWrite (bp_nourissage, HIGH);
  digitalWrite (relais_ecumeur, LOW);
  digitalWrite (relais_brassage, LOW);
  digitalWrite (relais_pompe, LOW);
  
}

void loop () {
  
  if (digitalRead(bp_ecumeur)==APPUI) {
    
    digitalWrite (relais_ecumeur, HIGH);
    digitalWrite (Vert_ecumeur, LOW);
    digitalWrite (Rouge_ecumeur, HIGH);
    delay(21600000);
    digitalWrite (relais_ecumeur, LOW);
    digitalWrite (Vert_ecumeur, HIGH);
    digitalWrite (Rouge_ecumeur, LOW);
    
  }
  
  if (digitalRead(bp_nourissage)==APPUI) {
    
    digitalWrite (relais_brassage, HIGH);
    digitalWrite (relais_pompe, HIGH);
    digitalWrite (Vert_nourissage, LOW);
    digitalWrite (Rouge_nourissage, HIGH);
    delay(600000);
    digitalWrite (relais_brassage, LOW);
    digitalWrite (relais_pompe, LOW);
    digitalWrite (Vert_nourissage, HIGH);
    digitalWrite (Rouge_nourissage, LOW);
    
  }
  
}

si quelqu'un peut m'expliquer comment le modifier (en etant aider, je comprendrais peut etre mieux pour la prochaine fois

En vous remerciant d'avance

Delay 21600000

21 600 secondes d'arrêt 0_o !!!

et oui, 6h d'arret de l'ecumeur apres l'ajout de suppléments (afin d'eviter que l'ecumeur n'elimine les complements avant que les coraux est pu en profiter)

ok, je comprend un peu mieux, et je n'aurais jamais penser faire sa comme sa, je vais etudier sa de pres, faire un test, et je te tiens au courant.

En tout cas, merci beaucoup pour votre aide

d'ou l'interet de ne pas bloquer ton programme pendant 6h ! :stuck_out_tongue: avec millis

c'est surtout que la plupart du temps, le nourissage aura lieu pendant que l'ecumeur sera couper, et avec delay, tous se bloque, et je ne peut pas activer lemode nourissage quand l'ecumeur est couper

Mais avec sa, sa devrait aller, je vous tiendrez au courant

D'accord je vois ce que tu veux dire
Mais il suffira simplement de décoller les relais pendant ce laps de temps et non de tout bloquer.

Je ne me vois pas rester 1h devant le four pendant que le poulet cuit et ne rien faire ...

Ce que tu veux faire est correcte avec delay mais c'est dommage pour les autres tâches surtout que tu ne sais pas si tu intègreras d'autres équipements. Il faut aussi penser évolutivité

Bon courage :slight_smile: