Hallo allemaal,
Zelf wilde ik een project beginnen met datum en tijd opslaan zonder het gebruik van RTC. Het zou mogelijk moeten zijn, maar heb zelf hierbij nog geen goede library gevonden. Heeft iemand tips welke library ik kan gebruiken?
Hallo allemaal,
Zelf wilde ik een project beginnen met datum en tijd opslaan zonder het gebruik van RTC. Het zou mogelijk moeten zijn, maar heb zelf hierbij nog geen goede library gevonden. Heeft iemand tips welke library ik kan gebruiken?
Het probleem is dat de oscillator van de meeste Arduino's niet echt nauwkeurig is, dus lange tijd de juiste tijd bijhouden is niet zo evident. Als het niet aankomt op een paar minuten is het natuurlijk doenbaar (afhankelijk van hoe lang je het programma wil laten lopen).
Een library is niet echt nodig. Je kan gewoon gebruik maken van de millis() functie om het aantal milliseconden sinds opstarten op te vragen. Zorg dat je unsigned long als datatype gebruikt.
Omzetten van milliseconden naar hh:mm:ss is erg eenvoudig:
ss = (millis()/1000 + startseconds)%60;
mm = (millis()/60000UL + startminutes)%60;
hh = (millis()/3600000UL + starthours)%24;
Analoog voor dagen en maanden. (startseconds, startminutes en starthours is de ingestelde tijd bij het opstarten.)
Dit werkt tot millis() overflowt. (Dat gebeurt na zo'n 49,7 dagen.)
Als ik echt de juiste tijd nodig heb gebruik ik soms een ESP8266 om de tijd op te vragen van het internet. Dit is relatief eenvoudig, even goedkoop als een RTC module (zo'n $3 uit China), en je hoeft het nooit in te stellen. (Je hebt natuurlijk wel een netwerkconnectie nodig.)
Pieter
Het komt niet op een paar minuten aan, dus ik ga dit zeker uitproberen! Dankje!
Beste Pieter,
Ik heb het programma in arduino gezet en het loopt opzich prima. Ik zag alleen dat het bij 14:59:59 het programma verder gaat bij 60 minuten en niet naar 15:00:00
Heb je hier misschien nog tips voor? Heb zelf al een beetje uitgetest met de formule maar kom er niet helemaal uit.
Alvast bedankt!
Sorry, had mijn haakjes verkeerd gezet. Ik heb de code hierboven aangepast, en nu zou het beter moeten werken.
Pieter
Hoi Pieter,
Ik denk dat het gelukt is, bedankt voor het helpen!
Mijn excuses, ik zat helemaal fout, met die offset werkt het niet, besef ik nu. Het probleem is dat je een floordeling doet zonder het aantal minuten en seconden in rekening te brengen. Daardoor telt het uur pas één op wanneer hij 60 minuten lang loopt, en niet wanneer de minuten 60 bereiken.
tijd = millis()/1000; // tijd in seconden
ss = (tijd + startseconds)%60; // blijft hetzelfde
mm = (tijd + startseconds)/60)%60;
hh = (tijd + startseconds+60*startminutes)/3600)%24;
Pieter
In de seconden en minuten klopt het wel. Maar de uren kloppen niet helemaal. Als ik 17 uur in milliseconde invul krijg ik -2 uur uit.
Hoe heb je je variabelen gedefinieerd?
PieterP:
Zorg dat je unsigned long als datatype gebruikt.
Pieter
Kijk dit is het programma :
unsigned long time;
int startseconds = 0;
int startminutes = 2220;
int starthours = 61200000;
int ss = 0;
int mm = 2220;
int hh = 61200000;
int tijd;
void setup() {
Serial.begin(9600);
}
void loop() {
tijd = millis()/1000; // tijd in seconden
ss = (tijd + startseconds)%60; // blijft hetzelfde
mm = ((tijd + startseconds)/60)%60;
hh = ((tijd + startseconds+60*startminutes)/3600)%24;
Serial.println("Tijd :");
Serial.println(ss);
Serial.println(mm);
Serial.println(hh);
Serial.println();
delay (5000);
}
84538:
int starthours = 61200000;
Hint: 216-1-1 = 32767
Pieter
PieterP:
Hint: 216-1-1 = 32767Pieter
Die hint snap ik niet, heb je iets meer toelichting voor mij?
Een int is 16 bits breed, dus je kan in totaal 216 getallen voorstellen, negatief en positief. Het grootste positieve getal dat je kan voorstellen is 216-1-1. Als je bij dat getal 1 optelt, wordt het een negatief getal. De variabele overflowt als je een groter getal probeert op te slaan in een int van 16 bits.
Een unsigned long is 32 bits breed, en enkel positief (unsigned). Het grootste getal dat je kan voorstellen is dus 232-1.
Pieter
PieterP:
Een int is 16 bits breed, dus je kan in totaal 216 getallen voorstellen, negatief en positief. Het grootste positieve getal dat je kan voorstellen is 216-1-1. Als je bij dat getal 1 optelt, wordt het een negatief getal. De variabele overflowt als je een groter getal probeert op te slaan in een int van 16 bits.Een unsigned long is 32 bits breed, en enkel positief (unsigned). Het grootste getal dat je kan voorstellen is dus 232-1.
Pieter
Oké, dus als ik het goed begrijp ( ben redelijk leek in arduino) mag ik niet meer dan zoveel getallen schrijven?
Jawel, maar als je ze in een int probeert te stoppen, houdt de Arduino enkel rekening met de laagste 16 bits, waardoor het niet meer je oorspronkelijke getal is.
Gebruik unsigned long i.p.v. int voor getallen groter dan 32767.
Pieter
Oke, ik ga het even uitproberen
PieterP:
Jawel, maar als je ze in een int probeert te stoppen, houdt de Arduino enkel rekening met de laagste 16 bits, waardoor het niet meer je oorspronkelijke getal is.Gebruik unsigned long i.p.v. int voor getallen groter dan 32767.
Pieter
Ik heb er nu dus dit van gemaakt :
unsigned long time;
int startseconds = 0;
int startminutes = 600000;
unsigned long starthours = 72000000;
int ss = 0;
int mm = 600000;
unsigned long hh = 72000000;
int tijd;
void setup() {
Serial.begin(9600);
}
void loop() {
tijd = millis()/1000; // tijd in seconden
ss = (tijd + startseconds)%60; // blijft hetzelfde
mm = ((tijd + startseconds)/60)%60;
hh = ((tijd + startseconds+60*startminutes)/3600)%24;
Serial.println("Tijd :");
Serial.println(ss);
Serial.println(mm);
Serial.println(hh);
Serial.println();
delay (5000);
}
En dan krijg ik dit de zien :
Tijd :
0
0
5
Tijd :
5
0
5
Tijd :
10
0
5
Tijd :
15
0
5
Tijd :
20
0
5
Tijd :
25
0
5
Onderste is de uren dus 5. Maar 72000000 moeten 20 uur zijn. En minuten geeft hij ook niet goed aan
int startminutes = 600000; heb ik ondertussen ook veranderd in unsigned long startminutes = 600000
En met int mm heb ik hetzelfde gedaan.
Maar nog steeds werkt het niet helemaal.
Ben echt niet goed wakker, om de een of andere reden zijn de startminutes en starthours eruit gevallen...
unsigned long tijd = millis()/1000; // tijd in seconden
unsigned long ss = (tijd + startseconds)%60; // blijft hetzelfde
unsigned long mm = ((tijd + startseconds)/60+startminutes)%60;
unsigned long hh = ((tijd + startseconds+60*startminutes)/3600+starthours)%24;
Snap je ongeveer wat ik probeer te doen?
Eigenlijk tel ik gewoon de starttijd op bij 'tijd', en zet dan 'tijd' om in hh:mm:ss.
Pieter