ik wil een schakelklokje (voor tuin besproeiing)met arduino uno maken maar stoot op het timer probleem. Standaard zit er in de proggramatie " delay" (bij delay blijft de arduino gewoon wachten en doet niks verder) kan het op en andere manier? De lengte van de schakelperioden is _/+ 15 min.
Heeft er iemand een tip hoe ik dat kan aanpakken. Al bedankt
boven in het programma:
#define DUUR 900000 // 15 x 60 x 1000 milliseconden
uint32_t timer; // 32 bits timer
in de setup:
delay(5); // mijn ervaring is dat als millis() op 0 staat dan loopt het niet lekker
timer = millis();
in de loop:
//
// check of de timer gezet is
//
if (timer != 0) {
//
// kijk of de timer verlopen is
//
if ((millis() - timer) > DUUR ) {
//
// timer is verlopen dus doe je ding
//
.........
//
// start de timer voor de volgende keer
//
timer = millis();
//
// of zet hem uit
//
timer = 0;
}
}
Je kunt een niet-blokkerende vertraging maken. Zoek op het internet naar 'blink without delay' om een idee te krijgen.
bool theDelay(unisgned long duration)
{
// start tijd van vertraging
static unsigned long starttime = 0;
// niet gestart
if(starttime == 0)
{
// zet start tijd
starttime = millis();
}
if(millis() - starttime > duration)
{
// reset start tijd voor de volgende keer
starttime = 0;
// geef aan dat vertraging voorbij is
return true;
}
// vertraging nog aan de gang
return false;
}
Je kunt de bovenstaande functie in een loop aanroepen. Iedere keer test je de geretourneerde waarde. Als die 'true' is, is de vertraging voorbij.
Betere methode is waarschijnlijk een 'zogenaamde' statemachine. Je programma wacht to het tijd is (state 1). Als het tijd is wordt de 'state' veranderd naar 2. In 'state' 2 schakel je de sproeier aan en wacht 15 minuten en vervolgens schakel je de sproeier uit.
Onderstaande kode kan als startpunt worden gebruikt.
void setup()
{
...
...
delay(1);
}
// huidige stap in de statemachine
int currentstate = 1;
void loop()
{
switch (currentstate)
{
case 1:
checkTime();
break;
case 2:
sprinklerOn(90000);
break;
}
}
void checkTime()
{
// lees de tijd
...
...
// als het tijd is
if (hetistijd)
// ga naar de volgende stap
currentstate = 2;
}
void sprinklerOn(unsigned long duration)
{
// start tijd van besproeing
static unsigned long starttime = 0;
// als de sproeier nog niet is ingeschakeld
if (starttime == 0)
{
// zet de start tijd
starttime = millis();
// schakel sproeier in
...
...
}
if (millis() - starttime > duration)
{
// reset start tijd voor de volgende keer
starttime = 0;
// schakel sproeier uit
...
...
// ga naar volgende stap
currentstate = 1;
}
}
Je kunt checkTime vervangen door aan functie die een knop leest; als de knop is ingedrukt ga je naar de volgende stap.
I hoop dat dit helpt.
Kom ik nog met een andere mogelijkheid.
Je kan ook gebruik maken van een interrupt. Wat er dan gebeurt is dat je programma om de zoveel tijd zelf schakelt naar een bepaalde functie. Hierin kan je dan iets doen.
Het voordeel hiervan is dat je geen delay of andere blokkerende calls in je loop() hebt zitten. Hier kan je dus in de tussentijd andere dingen blijven doen.
Meer uitleg over een interrupt staat hier: Interrupt
bedankt voor de hints kan nu proberen het verder uit te werken
les 2 blink without delay