IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Mettre une boucle en dehors du loop


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    1 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 372
    Par défaut Mettre une boucle en dehors du loop
    Bonjour,

    Je précise que je suis ultra débutant en Arduino et novice en électronique.
    Je travail sur un petit projet qui doit tourner en boucle infinie et commencer par un paramétrage de l'heure et de la date
    Pour ça, j'ai l'intention d'utiliser un module DS3231 pour mémoriser et d'un DCF77 pour initialiser et actualiser.

    Au démarrage de mon projet j'ai donc besoin de lancer la mise à jour de l'heure et date et ensuite, mon intention est de le faire une fois pas jour.

    Pour ça, je me disais qu'en début de loop, je pourrais utiliser un booléen quime permet de savoir si l'heure doit ou non être initialisée
    Si elle doit l'être, je lance la fonction dédiée mais dans cette fonction, je dois intégrer une boucle qui va décoder la trame du DCF77
    Et comme la réception n'est pas toujours optimale, j'avais l'intention de mettre une autre boucle pour gérer un nombre d'essai limité.

    Voilà donc ma question est :
    Quand je rentre dans une fonction, est il possible de reste dans cette fonction en y intégrant une boucle et de n'en ressortir que quand je l'ai décidé ?

    Merci de votre aide

  2. #2
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Citation Envoyé par lololebricoleur Voir le message
    Quand je rentre dans une fonction, est il possible de reste dans cette fonction en y intégrant une boucle et de n'en ressortir que quand je l'ai décidé ?
    Oui bien sûr: une fonction ne se termine (normalement) qu'avec l'exécution de l'instruction return ou de la dernière instruction (celle qui précède l'accolade fermante du code de la fonction).
    Donc, c'est toi qui décides.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    1 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 372
    Par défaut
    Merci de ta réponse Jackk,

    Compte tenu la courte description de mon petit projet, est-ce que tu penses que c'est comme ça que je dois m'y prendre ?

    Merci de ton aide

  4. #4
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Mes connaissances sont limitées en Arduino.

    Mais si je peux me permettre, j'intégrerais le décodage de la trame DCF77 dans une fonction qui renverrait un booléen renseignant si le décodage s'est bien effectué ou pas. Si oui, on met à l'heure et si non, on attend le prochain appel de la fonction.
    Je ne sais pas si l'arduino utilise un watchdog qui vérifie si la boucle principale (la fonction loop) s'effectue en un temps donné, mais d'une manière générale, il n'est pas bon de bloquer cette boucle principale, ne serait-ce que pour exécuter le reste du code.

  5. #5
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    salut

    une idée de structure de code (tapée ici, non testée)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    const unsigned long deltaMAJ = 86400000UL;    // 24h en ms
    unsigned long derniereMAJ = -deltaMAJ;        // pour forcer une MAJ au démarrage
     
    bool lireDCF77(const unsigned long delaiMax = 1000) { // valeur du timeout par défaut 1s
      bool lectureCorrecte = false;
      unsigned long debut = millis();
      while (!lectureCorrecte && (millis() - debut <= delaiMax)) {
        // faire une lecture DCF77
        // si elle est réussie, mettre lectureCorrecte à true
        // *** à faire ***
      }
      return lectureCorrecte;
    }
     
    void actualiserDS3231() {
      // *** à faire ***
    }
     
     
    void miseAJourHeure() {
      if (millis() - derniereMAJ >= deltaMAJ) {   // on vérifie si c'est le moment de la MàJ
        if (lireDCF77()) {                        // on va lire l'heure DCF77, si ça s'est bien passé
          actualiserDS3231();                     // on met à jour la RTC (appel bloquant avec un délai qu'on peut passer en paramètre)
        }
        derniereMAJ = millis();                   // on se souvient avoir effectué la demande (même si elle n'a pas aboutie)
      }
    }
     
    void setup() {
      // *** à faire ***
    }
     
    void loop() {
      miseAJourHeure();
     
      // ici le reste du programme
      // *** à faire ***
     
    }
    dans la loop() on appelle constamment la fonction miseAJourHeure() qui ne fait rien sauf 1 fois par jour où elle va essayer de lire la DCF77 pendant un temps max que l'on peut préciser dans l'appel de la fonction lireDCF77() (si on ne met pas de paramètre, le paramètre par défaut de la déclaration de la fonction est pris, soit 1000ms)

    Une alternative, comme vous avez une RTC DS3231, serait de déclencher une alarme toutes les 24h et c'est sur traitement de cette alarme que vous allez appeler la fonction lireDCF77()

    Enfin, à noter qu'il existe une bibliothèque Time de Michael Margolis et Paul Stoffregen pour la gestion du temps avec une source externe de synchro (la doc mentionne même la DCF77)

    je n'ai jamais joué DCF77, si le temps d'acquisition est long il faut sans doute dans ce cas rendre asynchrone sa lecture

  6. #6
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Citation Envoyé par Jay M Voir le message

    je n'ai jamais joué DCF77, si le temps d'acquisition est long il faut sans doute dans ce cas rendre asynchrone sa lecture
    Une trame dure une minute, à raison d'un bit par seconde.
    En suivant ton lien, on arrive à une bibliothèque spécifique pour DCF77.

  7. #7
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    Citation Envoyé par jackk Voir le message
    Une trame dure une minute, à raison d'un bit par seconde.
    Ok donc Il faut une petite machine à etat asynchrone pour écouter la trame de temps en temps

  8. #8
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Pourquoi pas, mais il y a peut-être plus simple.
    Il faut travailler en interruption: une sur chaque front pour mesurer la durée du bit et en déduire sa valeur.
    Une fois la trame terminée, reste le choix de la stratégie:
    - polling: un booléen est positionné dès que la trame est décodée et le programme scrute régulièrement si le flag est levé.
    - événement, donc asynchrone comme tu le prévoyais: il faut trouver un moyen de lancer un événement et je ne pense pas qu'on puisse générer facilement une interruption logicielle. Une autre solution, s'il reste des I/O est de relier une sortie à une entrée programmée pour générer une interruption et du coup ça devient moins compliqué.

  9. #9
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    Citation Envoyé par jackk Voir le message
    Pourquoi pas, mais il y a peut-être plus simple, Il faut travailler en interruption: une sur chaque front.
    oui c’est la bonne approche
    ( ça reste une machine à état dont les événements sont les interruptions )

    il faut trouver un moyen de lancer un événement et je ne pense pas qu'on puisse générer facilement une interruption logicielle.
    On peut avoir des interruptions logicielles avec les timers. Mais dans le cas présent le timing de mise à jour de l’horloge n’est pas à la ms près. Un drapeau mis lorsque l'heure est prête et on le lit au prochain tour de loop ou alors on met à jour la RTC dans l’interruption mais c’est un peu plus touchy car il faudra réactiver les interruptions.

    A noter que si on a un moyen de se synchroniser de temps en temps alors on peut se passer de la RTC et donc ça enlève les soucis d’interruption bloquée

Discussions similaires

  1. Peut on mettre une boucle FOR dans un echo ?
    Par floproc dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 09/05/2017, 11h02
  2. l'interet de mettre une boucle Boolean
    Par Adilleroy dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 27/05/2010, 17h28
  3. Mettre une boucle pour texte défilant
    Par Greatz dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 09/07/2008, 15h40
  4. mettre une boucle dans une recherchev
    Par robbillard dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 05/06/2007, 16h15
  5. Mettre une boucle en arrière plan!
    Par dongnold dans le forum Linux
    Réponses: 2
    Dernier message: 19/06/2006, 09h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo