Go Down

Topic: Fonction Loop (Read 1 time) previous topic - next topic

moumoune

Bonjour et merci  a tout ce monde qui aide; c'est très apprécie en ce qui me concerne. :) .

Je suis nouveau sur Arduino et après avoir démarré et cherche je bute sur la question suivante:

Lieu du projet: Canada, Ontario Nord-ouest

Le projet final: gérer un système de plancher chauffant d'une maison avec  trois sondes de température

DS18B20 ( température aller plancher, temp retour, temp chauffe-eau,temp extérieure), une RTC DS 3231

(en commande pour avoir la date et heure, heure pleine et creuse et week-end)), une carte 4 relais ( pour

2 circulateurs et le chauffe-eau,1 en attente), un servo couple sur une vanne 4 voies, afficher les

données sur un écran LCD 2x16.

Pour l'instant j'ai réussi a gérer les sondes avec le servo et l'affichage dans un seul programme; j'arrive

a gérer une RTC 1302 dans un programme séparé ( en attente de la RTC 3231) et c'est la que vient ma question:

Dans le programme de base qui gere les sondes et servo, dans la fonction Loop, j'ai pose des Delay en

fonction des températures ( Delay de 1hre ou plus) et dans le programme de la RTC il y a un Delay de

1000 ( 1 seconde) alors comment combiner les deux Loop vu les temps d'attente différent? :smiley-confuse:

En piece jointe  un exemple de programmation de la RTC et du servo.

J'espère avoir été assez clair, c'est un peu long mais.. :)

Merci d'avance pour le temps passe

micol

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.

*** Micol *** Les talibans du politiquement correct ont encore frappé. En 2017, la dernière victime est TEX.

casimir_isere

Bonjour,
il faut écrire une machine à état.
Regardez ceci, je pense que l'idée de base y est:
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

_pepe_

#3
Feb 06, 2018, 08:00 pm Last Edit: Aug 19, 2018, 03:24 am by _pepe_
Supprimé

moumoune

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:

https://www.arduino.cc/reference/en/language/functions/time/millis/

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

moumoune

Bonjour, me revoilà, je ne sais pas si quelqu'un est encore connecte vue le décalage horaire ;) 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... :( 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. :)

moumoune

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 :smiley-confuse: 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()" :smiley-confuse:

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  :smiley-confuse: 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 :smiley-confuse:
 
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

_pepe_

#7
Feb 08, 2018, 11:08 am Last Edit: Aug 19, 2018, 03:24 am by _pepe_
Supprimé

_pepe_

#8
Feb 08, 2018, 11:35 am Last Edit: Aug 19, 2018, 03:24 am by _pepe_
Supprimé

ChPr

#9
Feb 08, 2018, 04:04 pm Last Edit: Feb 08, 2018, 04:39 pm by ChPr
... https://www.arduino.cc/reference/en/language/functions/time/millis/

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 :

Code: [Select]
/* 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
Pourquoi faire simple alors qu'il est si facile de faire compliqué !

bricofoy

c'est exactement le genre de projet où ma librairie YASM serait utile ;)

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
-tu savais que si tu passe le CD de windows à l'envers, tu entends une chanson satanique ?
-non, mais il y a pire : à l'endroit, ça l'installe !

moumoune

Bonjour tout le monde,

Merci pour ces pistes et félicitations a toi Bricofoy, très beau projet  :) 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?? :(  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 :smiley-confuse:  :smiley-confuse:  :smiley-confuse: 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...

68tjs

Quote
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.
Code: [Select]
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..



_pepe_

#13
Feb 09, 2018, 06:16 pm Last Edit: Aug 19, 2018, 03:25 am by _pepe_
Supprimé

moumoune

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? :smiley-confuse:

Go Up