Décalage du temps millis()

Bonsoir à tous :slight_smile:
Je suis en train de programmer un arduino pour faire un petit terrarium autonome et je suis confronté à un petit soucis avec la fonction millis()

J'utilise plusieurs fois cette fonction pour faire des delay sans bloquer le programme. Mais dans la fonction fournis en pièce jointe, j'ai un décalage de plusieurs secondes : 30 secondes avec millis() correspondent a 18 secondes. Alors peut-être que c'est mon code le problème ?
J'ai une seconde question ? Quelle solution avez vous à me proposer pour régler le problème de millis lorsque les 50 jours ce sont écoulés ? Un reset ?

Merci de votre aide :slight_smile:

code.ino (1.14 KB)

J'ai une interrogation à laquelle je ne sais pas répondre : est-ce bien raisonnable d'utiliser conjointement millis() et delay() qui se partagent le même timer (le 0) ?

Il existe une autre fonction pour les delais
http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html
Elle est fournie par Atmel et n'utilise pas de timer mais se base uniquement sur la parfaite connaissance qu''Atmel a de son produit. Elle utilise des opérations dont le nbre de cycles horloge est parfaitement connu.

J'ai remplacé tout les delay par la fonction proposé par atmel mais ça n'a rien changé au problème :confused:

bonjour,
je vois pas ce qui pourrait provoquer cette différence dans le bout de code.
à mon avis, ca se trouve ailleurs ou alors tu as quelque chose qui utilise le même timer.
pour le soucis de 50 jours, soit la lib timer, soit une RTC.

tynnor:
j'ai un décalage de plusieurs secondes : 30 secondes avec millis() correspondent a 18 secondes.

bonsoir
Il y a là eventuellement un quasi un facteur 2 (clocking)
fait une verif sur une periode plus longue , millis() theoriques/reçus donnent quoi sur une heure apres reset ?

Qu'est ce que cette histoire de timer ? J'en ai jamais entendu parlé
Vous me conseillez d'utiliser cette librairie :
http://playground.arduino.cc/Code/Timer
?
Et je n'aurais pas de soucis de 50 jours ?
Merci de votre aide :slight_smile:

Un timer c'est une partie du micro-controleur qui ne se programme pas comme le reste. C'est plus de l'électronique pure.
Les programmes peuvent inter agir avec par l'intermédiaire de registres.

Un Timer c'est principalement un compteur qui compte les périodes de la frequence système (16 MHz pour les cartes Arduino), il est donc facile de passer d'un nombre de périodes horloge à un temps, c'est comme cela que millis et delay procèdent avec le timer 0.
Il est évident que si une fonction utilise ce timer 0 et le modifie, millis et delay ne fonctionne plus correctement d'où la question qui t'as été posée.

L'usage des timer est très puissant, ce sont eux qui génèrent la PWM et bien d'autre choses aussi comme des interruptions. Les possibilités sont décrites dans la datasheet du micro.

Merci pour vos réponses claires et précises ! :slight_smile:
Je vais voir ça

Telle que tu utilises millis() tu n'auras pas de problème au bout de 50 jours.
Le problème peut être ailleurs dans le code si une fonction vient modifier la configuration du timer. Ou alors tu as un problème avec ta carte arduino qui ne tourne pas à la fréquence attendue.

Il y a quand même une erreur d'écriture dans ta méthode

if(time - previousMillis >= 1000 * 30 || previousMillis == 0) // impulsion toute les 30 secondes

tu manipules des long donc il faut l'écrire comme ça:

if(time - previousMillis >= 1000L * 30L || previousMillis == 0) // impulsion toute les 30 secondes

Que va t-il se passer quand les 50 jours se seront écoulé ? Millis reviens à 0 et c'est repartie ? Dans quel cas j'aurais un problème ?

Effectivement. Je pense pas que le fait de mettre des int a la place de long est un impact mais je vais corriger ça ce soir.
Merci pour vos réponses :slight_smile:

Ben si comparer un int (donc signé) avec un unsigned long peut poser problème.

68tjs:
J'ai une interrogation à laquelle je ne sais pas répondre : est-ce bien raisonnable d'utiliser conjointement millis() et delay() qui se partagent le même timer (le 0) ?

Toute les fonctions de base liées au temps s'appuie sur micros() donc il n'y a aucun problème, en tout cas pour le bas niveau. C'est sur que si tu colles un delay() de 20 sec dans une boucle qui utilise millis() pour un timing à la seconde près, t'es dans les choux ...

infobarquee:
pour le soucis de 50 jours, soit la lib timer, soit une RTC.

Non pas besoin, l'overflow est géré :wink: même si le dépassement se produit pendant une "pause" le calcul sera juste.

Sinon previousMillis est bien un unsigned long ?

Effectivement...va falloir changer ça !

Je vais regarder plus attentivement mon code ce soir et avoir d'ou peut venir le problème

Merci :slight_smile:

Oui j'ai compris :slight_smile:

Bonsoir,
J'ai essayé d'isoler petit à petit mon code, jusque finalement garder seulement la fonction que je vous ai envoyé...et j'ai toujours le même problème.
J'ai essayé de faire le même code dans un nouveau projet et je n'ai pas de soucis.
Que faire ?

que faire?
montrer ton code entier pour trouver ce qui ne va pas :wink:

Vous êtes bien courageux ! :-[
J'ai l'habitude de me débrouiller seul mais là j'avoue que je sèche bien
Voici en pièce jointe la totalité de mon projet

Merci à vous ! :slight_smile:

programme_principal.ino (1.94 KB)

DHT.h (820 Bytes)

pins.h (165 Bytes)

RTCDate.h (471 Bytes)

Terrarium.h (670 Bytes)

DHT.cpp (3.92 KB)

RTCDate.cpp (1.77 KB)

Terrarium.cpp (2.64 KB)

déjà, tu as un delay(2000); dans le loop
donc 30mn pourrait correspondre à ton erreur :wink:
après, j'ai pas décortiqué les libs avec les timers pour vérifier.

attends, tu utilise en plus un rtc?

Non mais le delay dans le loop c'était juste pour mettre au point le capteur DHT, je venais de le mettre :stuck_out_tongue: Ce n'est pas ça le problème (quand même^^')
Il faut un certain temps pour que le capteur puisse lire les données. Il faut que je modifie les fonctions qui récupèrent les mesures afin de gérer ça
Heu oui j'utilise un rtc, le ds1307

Bonsoir
ton programme principal fait un init de serial , mais ne l'utilise pas
ajoute simplement une sortie serial "durée theorique" sur un test basé sur millis() : temps present - temps "ancien" toutes les 20 secondes (ou autre durée assez conséquente)
tu va vite voir si la derive est significative , et si elle l'est :sunglasses: , tu pourra pister le perturbateur