Forum Électro-Bidouilleur
Sections => Dépannage d'Électronique et d'Informatique => Discussion démarrée par: Manu le Juin 14, 2021, 04:58:53 pm
-
Bonjour,
Je mets en oeuvre une minuterie qui se reset tous les 2 minutes. Et tout fonctionne bien, mais mon doute est quant à "millis()". Cela peut devenir un très grand nombre apparemment.
Y a-t-il une certaine limite ?
Exemple:
Disons que si je reset la minuterie tous les 120 jours, "millis()" atteindra la valeur de 10368000000 par exemple. C’est cette valeur qui m’inquiète.
Merci :)
modif v1.1: const long MsMin -> unsigned long MsMin
// http://forum.bidouilleur.ca/
// TimerMillis v1.1 Manu
// ( without RTC )
float sec=0;
float min=0;
float hour=0;
float day=0;
unsigned long previousMillis = 0; // previous time measured to compare with the next
unsigned long MsMin = 60000; // to add 1 min every 60000ms (60sec)
const long MinHour = 60; // to add 1 hour every 60 min
const long HourDay = 24; // to add 1 day every 24 hours
void setup(){
Serial.begin(9600);
}
void loop(){
unsigned long currentMillis = millis();
//switch for reset switch-----------------------------------
if(min>=2){ // this is a switch for reset timer
previousMillis = currentMillis; // reset timer
sec=0;
min=0;
hour=0;
day=0;
}else{
//Timer-----------------------------------------------------
if(currentMillis - previousMillis >= MsMin){
min++; // add 1min
previousMillis = currentMillis;
}
sec=((currentMillis - previousMillis)/1000); // for sec
if(min==MinHour){
hour++; // add 1hour
min=0;
}
if(hour==HourDay){
day++; // add 1 day
hour=0;
}
}
//Monitor Show----------------------------------------------
if(day<10){
Serial.print("0");
}
Serial.print(day,0);
Serial.print(" D ");
if(hour<10){
Serial.print("0");
}
Serial.print(hour,0);
Serial.print(":");
if(min<10){
Serial.print("0");
}
Serial.print(min,0);
Serial.print(":");
if(sec<10){
Serial.print("0");
}
Serial.println(sec,0);
//pause & loop--------------------------------------------
delay(990);
}
(https://i.ibb.co/wgc8VTQ/Timer-Millis-Test.png)
-
Bonjour Manu,
Bien sûr, il y a une limite car un nombre entier est forcement codé sur un nombre de bits fixe. Dans le cas de la fonction millis() elle retourne un long non signé sur 32 bits. La documentation officielle arduino dit que cela fait 50 jours avant que le compteur passe à 0.
PB
-
Merci papyblue 8)
Pour cette réponse aussi rapide. On ne peut pas demander plus, top !
Sinon pour plus de 50jours, je suis toujours à temps de rajouter un petit rtc ;D
C'était clairement écrit mais je ne l'avais même pas vu.
https://www.arduino.cc/reference/en/language/functions/time/millis/ (https://www.arduino.cc/reference/en/language/functions/time/millis/)
-
Bonjour,
C'est vrai que millis() reboucle au bout de 49 jours et quelques.
Par contre le test
if(currentMillis - previousMillis >= MsMin){
ne posera pas de problème même en cas de rebouclage car on fait le calcul sur des unsigned. Même si previousMillis est supérieur à currentMillis le résultat sera quand même positif et le test sera correct.
Par mesure de sécurité il faudra déclarer MsMin en unsigned long et non en long, mais je ne suis pas sur que ce soit nécessaire.
-
Merci Kamill,
Oui cela dépend apparemment de l’utilisation ou non de valeurs négatives. Merci d’avoir commenté. Je vais modifier le code v1.1
unsigned long --> 49,71 jours
32 bits (4 octets) ne stockent pas de nombres négatifs, de 0 à 4 294 967 295 (2^ 32 - 1).
https://www.arduino.cc/reference/en/language/variables/data-types/unsignedlong/ (https://www.arduino.cc/reference/en/language/variables/data-types/unsignedlong/)
const long --> 24,85 jours
32 bits (4 octets), des entiers -2 147 483 648 à 2 147 483 647.
https://www.arduino.cc/reference/en/language/variables/data-types/long/ (https://www.arduino.cc/reference/en/language/variables/data-types/long/)
-
Merci à vous deux, j'ai enfin pu améliorer mon contrôle deréservoire grâce à cela.
Top! ;)
http://forum.bidouilleur.ca/index.php?topic=1008.0 (http://forum.bidouilleur.ca/index.php?topic=1008.0)