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 :

Arduino Nano et millis()


Sujet :

Arduino

  1. #1
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut Arduino Nano et millis()
    Bonjour à tous

    je dois entrainer à l'aide d'un petit moteur pas à pas un mécanisme d'horloge
    pour ce faire, la programmation se base sur la fonction millis() dans ce programme

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    #define MILLIS_PER_MIN 60000 // millisecondes par minute
    int port[4] = {7, 6, 5, 4};
     
    // Paramètres du moteur et de l'horloge
    #define STEPS_PER_ROTATION 1536 
     
    // attendre un seul pas du stepper
    int delaytime = 3;
     
    // séquence de la commande du moteur pas à pas
    int seq[4][4] = {
      {  LOW,  LOW, HIGH,  LOW},
      {  LOW,  LOW,  LOW, HIGH},
      { HIGH,  LOW,  LOW,  LOW},
      {  LOW, HIGH,  LOW,  LOW}
    };
     
    void rotate(int step) {
      static int phase = 0;
      int i, j;
      int delta = (step > 0) ? 1 : 3;
      int dt = 20;
     
      step = (step > 0) ? step : -step;
      for(j = 0; j < step; j++) {
        phase = (phase + delta) % 4;
        for(i = 0; i < 4; i++) {
          digitalWrite(port[i], seq[phase][i]);
        }
        delay(dt);
        if(dt > delaytime) dt--;
      }
      // power cut
      for(i = 0; i < 4; i++) {
        digitalWrite(port[i], LOW);
      }
    }
     
    void setup() {
      Serial.begin(9600);
      pinMode(port[0], OUTPUT);
      pinMode(port[1], OUTPUT);
      pinMode(port[2], OUTPUT);
      pinMode(port[3], OUTPUT);
      rotate(-10); // pour la course d'approche
      rotate(10); // l'approche fonctionne sans charge lourde
      rotate(STEPS_PER_ROTATION);
    }
     
    void loop() {
      static long prev_min = 0, prev_pos = 0;
      long min;
      static long pos;
     
      min = millis() / MILLIS_PER_MIN;
      if(prev_min == min)
      {
        return;
      }
      prev_min = min;
      pos = (STEPS_PER_ROTATION * min);
      rotate(-10); // pour la course d'approche
      rotate(10); // l'approche fonctionne sans charge lourde
      if(pos - prev_pos > 0) {
        rotate(pos - prev_pos);
      }
      prev_pos = pos;
    }
    Je constate une dérive légère sur 24h à savoir 120s
    le premier réflexe serait de diminuer
    #define MILLIS_PER_MIN 60000 =>> 59916 ( calcul estimé) pour compenser

    mais n'existe-t-il pas une autre approche plus fiable ?

    pascal
    Images attachées Images attachées  

  2. #2
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 264
    Points : 4 810
    Points
    4 810
    Par défaut
    Bonjour Pascal

    La photo c'est le montage en question?

    Si oui, il faut dans l'ordre:
    - remplacer le résonateur céramique par un quartz, ce qui devrait supprimer ou au moins fortement réduire la dérive de temps en lien avec la température ambiante.
    - calibrer le quartz, comme le font les vrais horloges, et qualibrer le quartz revient à ajuster le décompte de mills (ce que tu proposes).

    Delias

  3. #3
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut
    Merci Delias


    La photo c'est le montage en question?
    oui , c'est le moteur en question

    remplacer le résonateur céramique par un quartz, ce qui devrait supprimer ou au moins fortement réduire la dérive de temps en lien avec la température ambiante
    .
    Concrètement quel quartz utiliser stp ?

    En fouillant je suis tombé sur çà :
    https://passionelectronique.fr/intro...timer-arduino/
    en réglant la base de temps à l'aide des registres çà serait une bonne approche ?

    pascal

  4. #4
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 264
    Points : 4 810
    Points
    4 810
    Par défaut
    J'ai peut-être répondu un peu vite.
    Je parlais de la platine électronique de la photo, j'ai cru que la puce c'était un ATTiny et le composant jaune un résonateur céramique. Alors que c'est probablement juste le driver moteur, et son condensateur céramique de découplage.
    Un Arduino Nano officiel utilise déjà un quartz, une copie chinoise par contre ce n'est pas certain.

    millis() utilise les registres, si c'est correctement utilisé, cela aura la même précision.

    Après ton code me paraît très compliqué pour ce que tu cherches à faire. Surtout s'il ne fait que cela.

    J'avais déjà répondu à un problème similaire il y a longtemps sur le forum. Le problème c'est que tu perds beaucoup de précision dans ton calcul.
    Une des bonnes méthodes est expliquée là: https://www.developpez.net/forums/d2.../#post11374505
    J'en avais une plus détaillé, mais pas possible de la retrouver rapidement.

  5. #5
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut
    En regardant le site précédent, j'ai incorporé l'utilisation des registres
    et je me suis dis que j'allais peut-être gagné en précision

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
     
    #define MILLIS_PER_MIN 60000 // milliseconds per a minute
     
    // ports utilisés pour contrôler le moteur pas à pas
    // si votre moteur tourne dans le sens inverse, 
    // changez l'ordre en {4, 5, 6, 7} ;
    // pour Arduino nano
    int port[4] = {7, 6, 5, 4};
    // for ESP32 (example)
    // int port[4] = {12, 32, 25, 27};
     
    // Paramètres du moteur et de l'horloge
    #define STEPS_PER_ROTATION 1536 // steps for a minute
     
    // attendre un seul pas du stepper
    int delaytime = 3;
     
    // séquence de la commande du moteur pas à pas
    int seq[4][4] = {
      {  LOW,  LOW, HIGH,  LOW},
      {  LOW,  LOW,  LOW, HIGH},
      { HIGH,  LOW,  LOW,  LOW},
      {  LOW, HIGH,  LOW,  LOW}
    };
     
    //***********************************
    void rotate(int step) {
      static int phase = 0;
      int i, j;
      int delta = (step > 0) ? 1 : 3;
      int dt = 20;
     
      step = (step > 0) ? step : -step;
      for(j = 0; j < step; j++) {
        phase = (phase + delta) % 4;
        for(i = 0; i < 4; i++) {
          digitalWrite(port[i], seq[phase][i]);
        }
        delay(dt);
        if(dt > delaytime) dt--;
      }
      // power cut
      for(i = 0; i < 4; i++) {
        digitalWrite(port[i], LOW);
      }
    }
     
    // ======================
    // Setup
    // ======================
    void setup() {
      Serial.begin(9600);
      pinMode(port[0], OUTPUT);
      pinMode(port[1], OUTPUT);
      pinMode(port[2], OUTPUT);
      pinMode(port[3], OUTPUT);
      rotate(-10); // pour la course d'approche
      rotate(10); // l'approche fonctionne sans charge lourde
      rotate(STEPS_PER_ROTATION);
      pinMode (LED_BUILTIN, OUTPUT);
     
      // ======================================================================================================================================================
      // Paramétrage du timer1, pour qu'il déclenche une interruption, à chaque fois que sa valeur sera égale à celle qu'on aura indiqué dans le registre OCR1A  
      // ======================================================================================================================================================
      noInterrupts();                 // On désactive les interruptions, pour commencer
     
      // On règle les bits WGM10, WGM11, WGM12, WGM13 pour fonctionner en mode "CTC" (c'est à dire, en mode "comparaison timer <-> valeur de référence")
      bitClear(TCCR1A, WGM10);        // On met le bit WGM10 à 0 (contenu dans le registre TCCR1A)
      bitClear(TCCR1A, WGM11);        // On met le bit WGM11 à 0 (contenu dans le registre TCCR1A)
      bitSet(TCCR1B, WGM12);          // On met le bit WGM12 à 1 (contenu dans le registre TCCR1B)
      bitClear(TCCR1B, WGM13);        // On met le bit WGM13 à 0 (contenu dans le registre TCCR1B)
     
      // Ensuite, on règle les bits CS10, CS11, et CS12 pour que le prédiviseur du timer1 fasse une division par 256
      bitClear(TCCR1B, CS10);         // On met le bit CS10 à 0 (contenu dans le registre TCCR1B)
      bitClear(TCCR1B, CS11);         // On met le bit CS11 à 0 (contenu dans le registre TCCR1B)
      bitSet(TCCR1B, CS12);           // On met le bit CS12 à 1 (contenu dans le registre TCCR1B)
     
      // Puis on active l'interruption du timer1, qui test en permanence s'il y a égalité entre la valeur courant du timer, et la valeur
      // stockée dans un registre de comparaison. En pratique, pour ce faire, on va mettre à 1 le bit OCIE1A dans le registre TIMSK1,
      // afin qu'une interruption soit générée, à chaque fois que la valeur du timer1 sera égale à la valeur qu'on aura renseigné dans le registre OCR1A
      bitSet(TIMSK1, OCIE1A);         // On met le bit OCIE1A à 1 (contenu dans le registre TIMSK1)
     
            /* Pour info, on aura pu simplifier l'écriture des lignes ci-dessus, en entrant directement la valeur de tous les bits à la fois, 
             * dans leurs registres correspondants. Pour cela, il aurait fallut écrire les lignes suivantes (au lieu de bitClear/bitSet) : 
             * 
             *      TCCR1A = 0b00000000;      // pour WGM11=0 et WGM10=0
             *      TCCR1B = 0b00001100;      // pour WGM12=1 et WGM13=0, puis CS12=1/CS11=0/CS10=0 pour prédiviseur réglé sur division par 256
             *      TIMSK1 = 0b00000010;      // pour OCIE1A=1, afin d'activer l'interruption par comparaison "A" (test d'égalité entre timer et valeur de registre OCIE1A)
             */
     
     
      // Enfin, on met le compteur à zéro, on entre la valeur déclenchant l'interruption (nos "31250" coups d'horloge), et on réactive les interruptions
      TCNT1 = 0;            // Mise du timer1 à zéro
      OCR1A = 31250;        // Valeur correspondant à 500ms (car 31250 fois 16 µS donne bien 500ms ; pour rappel, ces 16 µS proviennent du calcul 1/(16MHz/256),
                            // avec les 16 MHz correspondant à la fréquence du quartz de l'ATmega328P, et le 256 au réglage du prédiviseur du timer1 fait précédemment)
      interrupts();         // Et, on ré-active les interruptions
     
    }
     
    // ======================
    // Loop
    // ======================
    void loop() {
      static long prev_min = 0, prev_pos = 0;
      long min;
      static long pos;
     
      min = millis() / MILLIS_PER_MIN;
      if(prev_min == min)
      {
        return;
      }
      prev_min = min;
      pos = (STEPS_PER_ROTATION * min);
      Serial.println();
      rotate(-10); // pour la course d'approche
      rotate(10); // l'approche fonctionne sans charge lourde
      if(pos - prev_pos > 0) {
        rotate(pos - prev_pos);
      }
      prev_pos = pos;
    }
     
    // ======================
    // Routine d'interruption
    // ======================
    ISR(TIMER1_COMPA_vect) {
      // À chaque appel d'interruption, on inverse l'état de la LED
      // En bref : si elle était allumée, alors on l'éteint, et si elle était éteinte, alors on l'allume !
      digitalWrite (LED_BUILTIN, !digitalRead(LED_BUILTIN));
    }

    les résultats sont les suivants :

    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
     
    11:29:30.716 -> 
    11:30:30.571 -> 
    11:31:30.491 -> 
    11:32:30.364 -> 
    11:33:30.257 -> 
    11:34:30.147 -> 
    11:35:30.081 -> 
    11:36:29.972 -> 
    11:37:29.859 -> 
    11:38:29.737 -> 
    11:39:29.637 -> 
    11:40:29.502 -> 
    11:41:29.422 -> 
    11:42:29.294 -> 
    11:43:29.231 -> 
    11:44:29.113 -> 
    11:45:28.983 -> 
    11:46:28.900 -> 
    11:47:28.777 -> 
    11:48:28.668 -> 
    11:49:28.575 -> 
    11:50:28.434 -> 
    11:51:28.334 -> 
    11:52:28.268 ->
    les écarts varient quelques peu entre chaque minute , peut-être qu'en finalisant avec millis() on peut arriver à une précision acceptable ?

    pascal

  6. #6
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 652
    Points : 5 139
    Points
    5 139
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    ...
    OCR1A = 31250; // Valeur correspondant à 500ms (car 31250 fois 16 µS donne bien 500ms ; pour rappel, ces 16 µS proviennent du calcul 1/(16MHz/256),
    // avec les 16 MHz correspondant à la fréquence du quartz de l'ATmega328P, et le 256 au réglage du prédiviseur du timer1 fait précédemment)
    ...
    ==> tout le code dépend au final de la précision de l'horloge et du respect des 16MHz exactement.

  7. #7
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut
    Salut Jay M

    effectivement mais peut-on améliorer les choses de façon hardware ?
    un oscillateur indépendant par ex ?

    pascal

  8. #8
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 010
    Points : 2 311
    Points
    2 311
    Par défaut
    Bonjour cobra38

    Peut être avec un récepteur DCF77?

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  9. #9
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut
    Bonjour jpbbricole

    Peut être avec un récepteur DCF77?
    Oui, cool une excellente idée
    avec 1 pulse par minute

    pascal

  10. #10
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 544
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 544
    Points : 56 433
    Points
    56 433
    Billets dans le blog
    39
    Par défaut
    Bonsoir,

    Citation Envoyé par cobra38 Voir le message
    Je constate une dérive légère sur 24h à savoir 120s
    le premier réflexe serait de diminuer
    #define MILLIS_PER_MIN 60000 =>> 59916 ( calcul estimé) pour compenser
    À noter que la fonction millis() fait déjà un calcul pour compenser :
    millis() is incremented (for 16 MHz AVR chips and some others) every 1.024 milliseconds, then incrementing by 2 (rather than 1) every 41 or 42 ticks, to pull it back into synch; thus some millis() values are skipped.
    La fonction millis() s'incrémente en fait toutes les 1,024 millisecondes, il y a donc un incrément de 2 (au lieu de 1) toutes les 41-42 pulsations de l'horloge 16MHz pour rattraper le retard et se resynchroniser.

  11. #11
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 652
    Points : 5 139
    Points
    5 139
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    effectivement mais peut-on améliorer les choses de façon hardware ?
    si vous prenez une RTC comme la DS3231 vous aurez l'heure avec une dérive faible mais aussi la possibilité d'avoir une interruption toutes les secondes (ou à 1 4 ou 8KHz) en utilisant le quartz plus précis de la RTC

  12. #12
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut
    Bonsoir Jay M

    Le but étant de réveiller le DS3231 toutes les minutes ( le nano envoi un top toutes les minutes via le moteur de l'horloge )
    à l'aide d'une interruption sur par ex l’entrée 2 du nano ?

    c'est cela ?

  13. #13
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    717
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 717
    Points : 217
    Points
    217
    Par défaut
    Bonjour à tous

    Pour suite aux précédents posts
    J'ai tenté de faire fonctionner l'exemple suivant avec DS3231 et UNO

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    #include <RTClib.h>
    // #include <Wire.h>
     
    RTC_DS3231 rtc;
     
    // the pin that is connected to SQW
    #define CLOCK_INTERRUPT_PIN 2
     
    void setup() {
        Serial.begin(9600);
     
        // initializing the rtc
        if(!rtc.begin()) {
            Serial.println("Couldn't find RTC!");
            Serial.flush();
            while (1) delay(10);
        }
     
        if(rtc.lostPower()) {
            // this will adjust to the date and time at compilation
            rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        }
     
        //we don't need the 32K Pin, so disable it
        rtc.disable32K();
     
        // Making it so, that the alarm will trigger an interrupt
        pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);
     
        // mettre le drapeau de l'alarme 1, 2 à faux (donc l'alarme 1, 2 ne s'est pas produite jusqu'à présent)
        // si ce n'est pas fait, cela conduit facilement à des problèmes, car les deux registres ne sont pas réinitialisés au redémarrage/recompilation
        rtc.clearAlarm(1);
        rtc.clearAlarm(2);
     
        // arrêter les signaux oscillants à SQW Pin
        // sinon setAlarm1 échouera
        rtc.writeSqwPinMode(DS3231_OFF);
     
        // Désactiver l'alarme 2 (au cas où elle ne le serait pas déjà)
        // encore une fois, ceci n'est pas fait au redémarrage, de sorte qu'une alarme précédemment réglée pourrait facilement ne pas être prise en compte
        rtc.disableAlarm(2);
     
        // schedule an alarm 10 seconds in the future
        if(!rtc.setAlarm1(
                rtc.now() + TimeSpan(10),
                DS3231_A1_Second // ce mode déclenche l'alarme lorsque les secondes correspondent. Voir Doxygen pour d'autres options
        )) {
            Serial.println("Erreur, l'alarme n'a pas été réglée !");
        }else {
            Serial.println("L'alarme se déclenchera dans 10 secondes !");
        }
    }
     
    void loop() {
        // print current time
        char date[10] = "hh:mm:ss";
        rtc.now().toString(date);
        Serial.print(date);
     
        // la valeur d'alarme enregistrée + le mode
        DateTime alarm1 = rtc.getAlarm1();
        Ds3231Alarm1Mode alarm1mode = rtc.getAlarm1Mode();
        char alarm1Date[12] = "DD hh:mm:ss";
        alarm1.toString(alarm1Date);
        Serial.print(" [Alarm1: ");
        Serial.print(alarm1Date);
        Serial.print(", Mode: ");
        switch (alarm1mode) {
          case DS3231_A1_PerSecond: Serial.print("PerSecond"); break;
          case DS3231_A1_Second: Serial.print("Second"); break;
          case DS3231_A1_Minute: Serial.print("Minute"); break;
          case DS3231_A1_Hour: Serial.print("Hour"); break;
          case DS3231_A1_Date: Serial.print("Date"); break;
          case DS3231_A1_Day: Serial.print("Day"); break;
        }
     
        // the value at SQW-Pin (because of pullup 1 means no alarm)
        Serial.print("] SQW: ");
        Serial.print(digitalRead(CLOCK_INTERRUPT_PIN));
     
        // whether a alarm fired
        Serial.print(" Fired: ");
        Serial.print(rtc.alarmFired(1));
     
        // Serial.print(" Alarm2: ");
        // Serial.println(rtc.alarmFired(2));
        // control register values (see https://datasheets.maximintegrated.com/en/ds/DS3231.pdf page 13)
        // Serial.print(" Control: 0b");
        // Serial.println(read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL), BIN);
     
        // réinitialisation du SQW et du drapeau de l'alarme 1
        // à l'aide de setAlarm1, l'alarme suivante peut maintenant être configurée
        if (rtc.alarmFired(1)) {
            rtc.clearAlarm(1);
            Serial.print(" - Alarme effacée");
        }
        Serial.println();
     
        delay(2000);
    }
     
    void onAlarm() {
        Serial.println("Une alarme s'est déclenchée !");
    }

    mais j'ai un souci je demande un déclenchement toutes les 10 secondes
    ce qu'il fait mais une fois (?) mais ensuite il déclenche l'alarme toutes les minutes
    sans que j'arrive à trouver de cohérence

    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
    40
     
    23:54:10 [Alarm1: 27 23:49:31, Mode: Second] SQW: 1 Fired: 0
    Alarm will happen in 10 seconds!
    23:54:14 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:16 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:18 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:20 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:22 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    Une alarme s'est déclenchée !
    23:54:24 [Alarm1: 27 23:54:24, Mode: Second] SQW: 0 Fired: 1 - Alarme effacée
    23:54:26 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:28 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:30 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:32 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:34 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:36 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:38 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:40 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:42 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:44 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:46 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:48 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:50 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:52 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:54 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:56 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:54:58 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:00 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:02 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:04 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:06 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:08 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:10 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:12 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:14 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:16 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:18 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:20 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    23:55:22 [Alarm1: 27 23:54:24, Mode: Second] SQW: 1 Fired: 0
    Une alarme s'est déclenchée !
    Une idée svp ?

    pascal

  14. #14
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 590
    Points : 1 462
    Points
    1 462
    Par défaut
    Ça me parait normal.

    Dans le setup(), tu demandes de déclencher une alarme à la seconde x (edit: et pas toutes les 10 secondes comme tu le penses). C'est d'ailleurs ce que tu indiques dans ton commentaire ligne 48.

    Le listing que tu donnes montre bien le déroulement: déclenchement à 23:54:24, le prochain déclenchement aura lieu lorsque les secondes seront égales à 24, soit une minute plus tard. Ce qui arrive à 23:55:24. Et le déclenchement suivant aura lieu à 23:56:24.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

Discussions similaires

  1. Conflit Arduino nano "clone" Yosemite 10.10.5
    Par Kogoro dans le forum Arduino
    Réponses: 0
    Dernier message: 20/06/2017, 13h57
  2. Réponses: 5
    Dernier message: 27/04/2017, 10h44
  3. A propos de LED_BUILTIN sur Arduino Nano
    Par Chamac dans le forum Arduino
    Réponses: 10
    Dernier message: 10/01/2017, 12h59
  4. Réponses: 8
    Dernier message: 23/12/2016, 20h06
  5. Thermocouple avec Arduino Nano v3.0
    Par redui dans le forum Arduino
    Réponses: 13
    Dernier message: 13/12/2016, 13h23

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