Fonction Loop

Bonjour

Évite la fonction delay() qui bloque le programme.

Cherche des infos sur la fonction millis() qui n'est pas bloquante. Elle renvoie une valeur que tu peux comparer à celle attendue.

Bonjour,
il faut écrire une machine à état.
Regardez ceci, je pense que l'idée de base y est:

Merci Micol Casimir et Pepe pour ces premiers indices; je ne pense pas me tourner vers la solution des millis(),

vue le commentaire sur le lien ci-dessous:

ou c'est dit que les millis() apres environs 50 jours le comptage se remet a zero...donc j'abandonne un peu cette piste.

Je me tourne plus-tot vers la solution de Pepe et si j'ai bien compris le principe, ce serait de programmer de

manière suivante:

test des températures puis action et attente 1 hre

Pendant l'heure d'attente RTC

Puis test et action et attente

Puis RTC etc.....

Suis-je juste?

Je vais faire un petit essai de programmation et le soumettre

Bonjour, me revoilà, je ne sais pas si quelqu'un est encore connecte vue le décalage horaire :wink: en tout cas

j'ai fait un petit programme d'essais ( en pièce jointe) et je remarque qu'en fait la combinaison de RTC et

servo fonctionne dans la même fonction Loop; juste qu'au niveau de l'affichage l'heure saute a toutes les

7 secondes : 1 seconde après affichage de l'heure sur LCD + 2 secondes après le premier mouvement du

servo+2 secondes après le deuxième mouvement du servo+ 2 secondes après le troisième mouvement du

servo, ce qui n'est pas genant pour des intervalles de secondes , mais si je mets un délai de 1 Hre voir 1

jour... :frowning: pas d'affichage! Alors j'ai essaye la méthode de Pepe, mais j'ai rien compris comment

faire...désolé Pepe et si tu pouvais me filer un petit coup de pouce sur ce coup j’apprécierais. :slight_smile:

horloge_affichage_servo_11.ino (1.59 KB)

Me revoilà; je me suis demande si mon post est au bon endroit....vraiment j’espère ne pas avoir gaffe

en le mettant dans ce forum :confused: si oui vraiment desole et pourriez-vous me dire comment

et ou le poster? Merci

J'ai un peu avance dans le sens de ce que dit Pepe, mais voila ou je bute:

Déjà j'ai remarque qu'il suffit de remplacer "delay()" par "loop()" pas besoin de mettre "loop_horloge()" :confused:

Par contre si je mets "loop()" en ligne 101,102,103 sur programme ci-joint, le servo continu de faire

l'action " temps+=400" et donc sature vers la droite :o :confused: aussi le mouvement du servo

est toutes les 1 seconde et non 3 secondes comme demande ( 3 x" loop()" ). Comme vous pouvez le voir

sur le programme, j'ai aussi essaye la fonction "for etc.." en ligne 99 mais cela ne change rien :confused:

Si je comprends bien, tout de suite après le premier"loop()" le programme repart au début

Ce que je voudrais arrive a faire serait d’arrêter le mouvement du servo a une position pendant un temps

X mais que l'affichage de l'heure continu.

L'autre quesdtion serait : comment recuperer le jour donne par RTC? EX: je veux faire tourner le servo

si le jour est "FRIDAY"?

Merci pour votre patience

Essai_horloge_affichage_servo_11.ino (1.87 KB)

pepe:
... millis() - Arduino Reference

ou c'est dit que les millis() apres environs 50 jours le comptage se remet a zero...donc j'abandonne un peu cette piste. ...

En utilisant une méthode avec millis() et une variable de mémorisation du moment pour chaque action qui doit se dérouler, le débordement de millis() n'influe pas sur le déroulement correct des actions et cela sans avoir à faire de test de débordement. Voir le sketch suivant :

/* Simulation du débordement de millis() ou micros() */

uint16_t tC, t0, t1, du0, du1;

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(100);
  du0 = 1000;
  t0 = 0;
  du1 = 2000;
  t1 = 0;
}

/* NOTA : en donnant des valeurs croissantes à tC, on voit les prises ou non en compte des actions.
    Si on fait tC = 65535, puis on déborde avec tC = 900, puis tC = 1100, puis tC = 2100, on voit successivement
    les actions prises ou non correctement en compte aux bons moments et cela indépendamment du débordeement de tC.
*/

void loop() {
  if (Serial.available()) {
    tC = Serial.readString().toInt(); // valeur entrée dans le moniteur série simulant la valeur de millis()
    Serial.print("tC = ");
    Serial.println(tC, HEX);
    if (tC - t0 > du0) { // une action à prendre toute les du0 mS
      t0 = tC; // mémorisation du moment où cette action a été prise en compte
      Serial.print("Vu  ; t0 = ");
      Serial.println(t0, HEX);
    } else {
      Serial.print("Pas Vu  ; t0 = ");
      Serial.println(t0, HEX);
    }
    if (tC - t1 > du1) { // une autre action à prendre toute les du1 mS
      t1 = tC; // mémorisation du moment où cette action a été prise en compte
      Serial.print("Vu  ; t1 = ");
      Serial.println(t1, HEX);
    } else {
      Serial.print("Pas Vu  ; t1 = ");
      Serial.println(t1, HEX);
    }
    Serial.println();
  }
}

Cordialement.

Pierre

c'est exactement le genre de projet où ma librairie YASM serait utile :wink:

tu peux aussi regarder ça, même si ce n'est pas encore vraiment fonctionnel, ça réponds sans doute à pas mal de tes questions

Bonjour tout le monde,

Merci pour ces pistes et félicitations a toi Bricofoy, très beau projet :slight_smile: effectivement cela rejoint un peu le mien, mais je ne vais pas faire de copie-colle bête et méchant car je veux comprendre ou je vais; par ailleurs on a tous une logique différente et donc le temps que j'arrive a comprendre la tienne ( même si pour toi c'est simple car tu y étais plonge des heures donc tu connais le truc par-coeur) cela me prendra ,je pense, autant de temps que d'avancer avec ma logique et l'aide des gens du forum; cela dit encore une fois FÉLICITATIONS.. Merci aussi a toi Pepe pour ton aide

Donc de retour a mon problème et ce que je craignais se produit:

Dans une fonction boucle on répète et répète sans sortir de la boucle, donc comment combiner deux boucles?? :frowning: J'ai essaye dans le programme ci-joint de placer la fonction "loop_horloge " en premier et l'affichage de l'heure se fait sur mon LCD mais le servo ne bouge plus( tourne en boucle dans "loop_horloge"), ensuite j'ai mis la fonction"loop()" en premier, et mon servo marche mais pas l'heure sur le LCD; puis j'ai essaye en ligne 73 et 75 d'integrer "loop_horloge" et l'heure est affiche sur LCD mais le servo ne marche pas :confused: :confused: :confused: Ensuite j'ai déplacé la fonction "for (i=0;i<2000;i++) loop_horloge();" en ligne 87-89 et le servo s'est mis en route pour deux mouvements puis l'affichage s'est mis en route sur le LCD et plus de mouvement pour le servo...????Je fais appel a ton aide Pepe

Concernant le repérage des jours de la semaine, dans la bibliothèque que j'utilise les jours sont effectivement représentés par des lettres c pour samedi, j pour dimanche etc...

Essai_horloge_affichage_servo_2.ino (2.05 KB)

Dans une fonction boucle on répète et répète sans sortir de la boucle, donc comment combiner deux boucles??

Il ne faut pas généraliser.
La boucle infinie est spéciale au fonctionnement du microcontroleur.
Si elle n'existait pas le programme se déroulerait, irait jusqu'à la fin de la mémoire et s’arrêterait.
Il faudrait appuyer sur le bouton Reset pour le relancer.

Revenons au cas général.
Dans une boucle il y a obligatoirement une condition :
Exemple :
while( machin == 0)
{
}
On reste dans la boucle tant que machin reste égal à 0, dès que machin n'est plus égal à 0 on sort de la boucle.

Imaginons que tu ai un bouton poussoir et que tu lises son état.
etat_bouton = digitalRead(pin_bouton );

On va utiliser une condition if pour modifier la valeur de la variable machin en fonction de l'état du bouton.

machin = 0; // initialisation
while (machin == 0)
{
  etat_bouton = digitalRead(pin_bouton);  // lecture du bouton
  if (etat_bouton == 0)    // quand le bouton est appuyé on lit un état bas égal à 0 volt.
   {
      machin = 1 ; // on change la valeur de machin
   }
}

Maintenant tant que tu n'appuis pas sur bouton tu reste dans la boucle et dès que tu aura appuyé sur le bouton tu sortira de la boucle.

Ça c'est TON programme, la boucle infinie dans laquelle tourne la fonction appelée loop() c'est le problème de l'IDE tu n'as pas a t'en occuper tant que tu programme avec l'IDE..

Bonjour, je reposte le programme pour être sur qu'on parle de la même chose; je ne trouve pas les 33 mn d'attente d’où ma raison de reposter; dans l'etat actuel, le servo va de A (Position Verticale fixe en ligne 57 ) vers B ( droite fixe en ligne 105, puis attente de 2s) puis revient vers la gauche C (fixe en ligne 124, puis attente de 2 s) puis revient en ligne 105 pour se remettre au milieu puis attente 2 s...c'est ce que je constate et c'est comme cela que je l’interprète, y a-t-il une erreur? Mais pour autant l'heure ne s'affiche pas sur le LCD car une fois dans la fonction " loop() " on n'en sort plus, alors que si je valide les lignes 110 et 112 et mets la ligne 107 en attente, le servo se met a la verticale puis l'affichage sur LCD se met en route et je ne sorts plus de l'affichage, alors comment combiner les deux? :confused:

Essai_horloge_affichage_servo_2.ino (1.84 KB)

Merci a toi 68tjrs pour l'info et je pense avoir compris cela; mon soucis est que dans le programme global du projet, je ne sortirais pas de la boucle, car les sondes seront constamment en-train de prendre les températures extérieures, intérieures etc... avec un décalage de 1hre ou 2hre ou X temps et réajuster le réglage de la vanne 4 voies ainsi que des circulateurs et résistances de chauffe-eau....et tout ceci en fonction du jour et de l'heure, d’où mon soucis de combiner les deux " loop() ".

Suis-je assez explicite, car parfois j'ai tellement la tête dans ce truc en ce moment :confused:

Arrête une bonne fois pour toutes de dire "combiner deux loop()"
loop() avec deux parenthèses C'EST UNE FONCTION, et comme toute fonction dans un programme elle est unique, point barre.

je ne sortirais pas de la boucle, car les sondes seront constamment en-train de prendre les températures extérieures, intérieures etc.

C'est parce que tu t'y prend mal, ce cas se gère.
Tu veux aller plus vite que la musique en sautant les étapes.
Suis le tuto d'Eskimon, apprend à programmer avec des exemples simples au lieu de chercher d'emblée la difficulté.

Tel que tu pars c'est plantage assuré.
Tu mets la charrue avant les bœufs.

Bonjours 68tjrs, j'ai un peu l'impression que cela te porte sur les nerfs; je ne trouve pas de lien sur le tuto d'Eskimon...mais aussi pour info ou j'en suis: pour commencer sur Arduino j'ai fait un petit programme qui gère les sondes DS18B20 ( au nombre de 4), ensuite j'ai fait un petit programme pour gérer une RTC DS 1302 et en parcourant des postes je me suis dit que je devrais opter pour une RTC DS 3231 ( en commande), ensuite j'ai fait un petit programme pour gérer une carte avec 4 relais, puis un petit programme pour gérer un servo puis un petit programme pour un LCD et maintenant j'ai réussi a fusionner tout ces petits en un seul programme sauf que je n'arrive pas a gérer la RTC dans tout cela; alors si tu penses que le tuto de Eskimon pourra aider je suis preneur...Merci de me donner un lien.

je ne trouve pas de lien sur le tuto d'Eskimon.

Elle est bien bonne celle là !

Tu n'as pas vu qu'il y a des messages en tête de forum avec une petite punaise !
Tu n'a pas vu qu'il en avait un dont le titre est "Coup de gueule" ?

Franchement tu n'a pas chercher à comprendre le fonctionnement de ce forum.

Aller lis donc celui dont je mets le lien. Entre autre tu y trouvera le lien vers le tuto d'Eskimon.
Il n'est pas de moi, j'ai juste fais le secrétaire, il est l'œuvre d'une vingtaine de "forumeur actifs" qui en avait marre que les questions soit mal posées et de réexpliquer continuellement les mêmes choses.
https://forum.arduino.cc/index.php?topic=324322.0

Bonne lecture.

Merci Pepe pour tout cela; en fait j'ai réussi a faire ce que je voulais a savoir: faire bouger le servo et afficher l'heure en même temps; je reprendrais la discution au sujet du servo plus tard, car pour l'instant je vais me consacrer a bien lire le tuto d'Eskimon comme le suggère tjrs68; juste une petite mise au point: dans la fonction " delay(2000)" il s’agit bien de 2 secondes en attente, alors que si je te comprends bien dans la fonction
for (i=0; i<2000; i++)
loop_horloge(); on met environs 33mn en attente???? Est-ce bien cela? En piece jointe la version qui marche. Je prends tout commentaire a ce stade; merci

Essai_horloge_affichage_servo_2.ino (1.86 KB)

Merci Pepe,

Ceci explique pour moi pourquoi je ne trouvais pas les fameuses 33mn, car le chiffre 2000 était le même pour moi dans les 2 fonctions :confused:

Ok pour le Ctrl+T cela clarifie la situation et je pense que ceci doit être explique dans le tuto!! :blush: Je rigole

moumoune:
Donc de retour a mon problème et ce que je craignais se produit:

Dans une fonction boucle on répète et répète sans sortir de la boucle, donc comment combiner deux boucles??

en fait ce qu'il faut comprendre c'est que le programme est relancé à l'infini (par le biais de la fonction loop() d'arduino, qui comme son nom l'indique, tourne en boucle infinie). Cette fonction est mise en place par l'IDE arduino, et tu n'as pas à t'en préoccuper ni à essayer de la relancer toi-même. Tu as juste à mettre ton code à l'intérieur pour qu'elle réalise ce que tu veux.

Ensuite, à l'intérieur de cette boucle infinie, à toi de faire un code qui ne soit jamais bloquant (et c'est ce qui est très simplifié si tu utilises ma librairie ), donc il faut à tout prix éviter d'utiliser par exemple delay(duree), qui va rester bloqué à cet endroit dans le programme le temps "duree" et donc empêcher de faire autrechose pendant ce temps. Pour résoudre ce problème, il faut réaliser tes temporisations de manière non bloquante, c'est à dire que tu va dans le déroulement de ton programme par exemple :
-tester si ta temporisation 1 est finie ->non,
-afficher des valeurs sur le lcd
-tester si ta tempo 2 est finie->non
-faire autrechose
et... c'est tout. Comme tout ce code est placé dans loop(), justement, il sera ensuite relancé à l'infini. Tant et si bien qu'au bout d'un moment, tu va avoir le déroulement suivant :
-tester si ta temporisation 1 est finie ->oui,
-faire ce qu'il y a à faire si tempo1 finie
-afficher des valeurs sur le lcd
-tester si ta tempo 2 est finie->non
-faire autrechose
et ainsi de suite.

Pour réaliser les temporisations de manière non bloquante, il faut employer la technique de l'exemple fourni avec l'IDE "blink without delay", au moins pour comprendre le principe, qui est le suivant :

-lire l'horloge du microcontrôleur avec millis() et stocker cette valeur

puis dans les appels suivant de la boucle
-lire la valeur de l'horloge avec millis() et comparer avec la valeur stockée+la durée voulue.
si < --->la tempo n'est pas finie, on ne fait rien de spécial
si > --->la tempo est finie, alors :
-on stocke la nouvelle valeur pour la fois suivante
-on fait ce qu'on doit faire quand la tempo est finie

on restocke la nouvelle valeur pour la prochaine fois

et ainsi de suite

tout ça, c'est pas compliqué, mais c'est fastidieux. Il faut le faire pour comprendre, mais ensuite... pourquoi réinventer la roue ?
avec ma librairie, tu peux executer plusieurs taches en //, et faire une tempo est aussi simple que

if(tache1.elapsed(duree))
    faire_un_truc();

moumoune:
Merci pour ces pistes et félicitations a toi Bricofoy, très beau projet :slight_smile: effectivement cela rejoint un peu le mien, mais je ne vais pas faire de copie-colle bête et méchant car je veux comprendre ou je vais; par ailleurs on a tous une logique différente et donc le temps que j'arrive a comprendre la tienne ( même si pour toi c'est simple car tu y étais plonge des heures donc tu connais le truc par-coeur) cela me prendra ,je pense, autant de temps que d'avancer avec ma logique et l'aide des gens du forum;

c'est là où je pense que tu te trompes. c'est là aussi ce que je disais plus haut en parlant de ne pas réinventer la roue... sinon pourquoi utiliser une libraire existante pour lire la RTC ou les DS18B20 ? il faut créer la tienne pour en maîtriser la logique... D'un autre coté, tu peux aussi dire que c'est ce j'ai fait, c'est vrai, mais avant j'ai utilisé celles des autres, et j'ai toujours trouvé ça ou trop limité ou bien trop compliqué. D'ou la création d'un truc simple d'emploi mais qui évite toutes les limitations que j'ai trouvé ailleurs. Et si le projet est sur github, c'est justement pour que d'autres puissent l'utiliser soit tel quel soit le copier et le modifier pour l'adapter à leurs besoins.

Il en va de même pour le projet thermalduino, l donne déja un cadre de base qui permet d'enregistrer des sondes DS18B20 via un menu sur le LCD, de lire ces DS18B20, afficher les valeurs, exécuter des taches en fonction de ces valeurs, stocker les valeurs mesurées sur carte SD, régler les paramètres via un menu sur l'afficheur, etc
Tu peux parfaitement utiliser uniquement le squelette du projet, et mettre ensuite dedans ta propre logique pour gérer le servo, les démarrages de pompes etc etc. De toutes manières ma gestion du servo n'est pas encore au point :stuck_out_tongue:
Mais la lecture des DS18B20, l’enregistrement des valeurs etc etc, ça fonctionne très bien

Bonjour a tous,

Me revoilà, j'ai enfin eu ma RTC DS3231 et je l'ai installée sur mon circuit et fait une programmation qui me convient assez pour l'instant :slight_smile:
Je mets le programme en lien; pour info la carte est une Arduino MEGA, l'afficheur est un 2 x 16 rangées et les sondes sont des DS18B20, comme Librairie pour la RTC j'ai pris le lien ci-dessous:

Je n'ai pas encore inclus la position d'exploitation du servo pour la vanne 4 voies....cela viendra par la suite ainsi qu'un petit schéma du montage.

S'il y a des commentaires pour améliorer l'existant ( je suis sur qu'il y en a ) je suis preneur :slight_smile:

Bonne journée a vous tous. :slight_smile:

temp_et_servo_21.ino (6.69 KB)

Bonjour tout le monde,

Me revoilà sur le site et je poste mon programme qui me convient pour l'instant :slight_smile: j'ai encore deux petites questions:

concernant la ligne suivante:

if ((t.hour) == 19 || (t.hour) == 20 || (t.hour) == 21 || (t.hour) == 22 || (t.hour) == 23 || (t.hour) == 24 || (t.hour) == 0 etc... jusqu'a 6

Sachant que je dois gérer la plage horaire de 19 a 6 du matin; peut-on faire plus court?

L'autre étant: j'ai connecte 5 capteurs DS18B20 mais je ne peux en lire que 4 ( ce qui me suffit pour l'instant), pour le cinquième il m'affiche une valeur de -127C, sachant que j'ai branche les 5 capteurs en parallèle sur la carte :confused: et j'ai deja change le cinquieme capteur par un nouveau (en cas de défaut de fabrication :confused: ) et revu les connexions, rien n'y fait!!!alors que les 4 autres fonctionnent très bien :confused:

Concernant la partie Servo, je le démarre en position milieu pour ensuite ouvrir ou fermer en fonction des températures captées par les sondes avec des points maxi et mini.

Je joindrais un plan de montage des différents composants et du branchement un peu plus-tard.

En espérant que ceci pourra aider quelqu'un. :slight_smile:

temp_et_servo_21.ino (10.5 KB)