Vertraging maar geen gewone delay.

Ik ben op zoek naar een sketch voorbeeld van een vertraging.
Als je een knop of sensor inschakeld mag er pas na een voor ingestelde tijd dat de knopingedrukt blijft, een aktie komen. Als je de knop eerder los laat mag er geen aktie komen. Vertragingstijd moet zich dan weer resetten, zodat bij opnieuw indrukken de gehele vertragingstijd word gebruikt. Het gaat hier om hooguit enkele sec.

zoiets?

#define VERTRAGING	2000	// vertraginstijd is hier 2 seconden
#define KNOP	 5					// als voorbeeld
unsigned long timer;			// vertragingstimer


void setup() {
	//
	// zet de pinnen in I/O mode
	//
	pinMode(KNOP, INPUT);
	timer = 0;						// de timer staat uit
}

void loop() {
	//
	// kijk eerst of de knop is ingedrukt
	//
	if (digitalRead(KNOP) == LOW) {			// we gaan uit van active LOW
		//
		// kijk of de timer al loopt
		//
		if (timer != 0) {
			//
			// hij loopt al dus kijk of we voorbij de vertraginstijd zijn
			//
			if (millis() > timer) {
				//
				// ja dus actie uitvoeren
				//

				//
				// en eventueel de timer weer resetten als de knop ingedrukt blijft
				//
			}
		} else {
			//
			// de timer loopt nog niet dus aanzetten
			//
			timer = millis() + VERTRAGING;
		}
	} else {
		//
		// de knop is los dus zondermeer de timer uitzetten
		//
		timer = 0;
	}
}

Hoi Arjen, en welkom.

Dit is een klassiek voorbeeld van blink without delay
Dat is een sketch die je in de voorbeelden kunt vinden, die zijn meegeleverd met de IDE.
Als je daarmee een beetje speelt door ermee te variëren, leer je dit ook in andere gevallen te gebruiken zoals jouw vraag.
Nico Verduin heeft je al zo'n uitwerking voorgeschoteld, en dit soort oplossingen verdient ook 1000x keer meer de voorkeur dan een delay.
Dan moet je m uiteraard wel binnen je loop hebben zitten (of aanroepen).

Die voorbeelden zijn overigens sowieso een dikke aanrader.
Op zichzelf zijn het namelijk niet zulke bijzondere sketches, maar ze zijn juist zo gemaakt dat je er mee kunt spelen.
Zo kun je dus proberen wat er gebeurt als je iets in die sketch verandert, en das bijzonder leerzaam.

Bedankt voor jullie antwoorden. Ik ga hier mee aan de slag

Note: de sketch van Nico gaat mis als

timer = millis() + VERTRAGING;

boven de MAX UNSIGNED LONG gaat en weer begint bij 0 (lage waarde)

dan is de volgende milliseconde

millis() > timer

altijd waar en reageert de code niet goed.

Code van NIco gepatched.
(changed INPUT to INPUT_PULLUP to trigger active low)

#define VERTRAGING	2000	// vertraginstijd is hier 2 seconden
#define KNOP	 5		// als voorbeeld
unsigned long timer;		// vertragingstimer


void setup() {
    //
    // zet de pinnen in I/O mode
    //
    pinMode(KNOP, INPUT_PULLUP);  // <<<<<<<
    timer = 0;						// de timer staat uit
}

void loop() {
    //
    // kijk eerst of de knop is ingedrukt
    //
    if (digitalRead(KNOP) == LOW) {			// we gaan uit van active LOW
        //
        // kijk of de timer al loopt
        //
        if (timer != 0) {
            //
            // hij loopt al dus kijk of we voorbij de vertraginstijd zijn
            //
            if (millis() - timer > VERTRAGING) {
                //
                // ja dus actie uitvoeren
                //

                //
                // en eventueel de timer weer resetten als de knop ingedrukt blijft
                //
            }
        } else {
            //
            // de timer loopt nog niet dus aanzetten
            //
            timer = millis();
        }
    } else {
        //
        // de knop is los dus zondermeer de timer uitzetten
        //
        timer = 0;
    }
}

Ik weet het :slight_smile: Ik ga er altijd maar vanuit dat ze de sketch niet meer dan 49 dagen continu draaien :slight_smile: Toch bedankt. Ik had de oplossing al eens gelezen bij onze australische vrind :). Moet er alleen nog een gewoonte van maken om het zo standaard te doen :slight_smile:

Rekenen met tijd op een computer is net als rekenen met pointers.

twee tijdsmomenten aftrekken geeft altijd een valide tijdsduur (zolang tijdsduur < 49 dagen, anders moet je een RTC)
een tijdsduur bij een tijdsmoment optellen kan een “time wrap” geven

twee pointers aftrekken geeft de grootte van een stuk geheugen (RAM, EEPROM, FLASH)
een size bij een pointer optellen kan een “memory wrap” geven
ook bekend bij bv EEPROM page boundaries

Ben een stuk opgeschoten, maar kan de schakeling nu maar 1x laten lopen.
Ik heb het volgende gedaan:

/*
Door aan de potmeters te draaien kan benodigte schakeltijd (switchDelay)
worden in gesteld (signalTime).
*/

# define KNOP 5// switchPin = 8;
int ledPin = 13;
int sensePinA =0;                                    // delay tijd
unsigned long timer;
boolean firstTime;
int startTime;

void setup()
{
  pinMode(KNOP, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  timer = 0;
  firstTime = true;
}

void loop()
{
  int valA = analogRead(sensePinA);                  // leest potmeter en steld delay tijd in.
  int switchDelay = map(valA,0, 1023, 500, 8000);    // zet potmeter signaal om in max. en min. tijd in mil.sec.
  
  if (digitalRead(KNOP) == HIGH)
  {
    timer = millis();
    if (timer != 0) {
      firstTime = false;
    }
    if (timer > startTime + switchDelay) {
      digitalWrite(ledPin, HIGH);
      delay(500);
      digitalWrite(ledPin, LOW);
      firstTime = true;
    }
  }
  
  if (digitalRead(KNOP) == LOW) {
    firstTime = true;
    return;
  } 
}

Waar ga ik fout?

Ik heb maar heel even gekeken naar je huidige sketch dus ik kan iets gemist hebben, maar vroeg me af:
Wat doet die return daar aan het eind (sowieso; wat doet een return eigenlijk) ?
Waarom zit die daar ?

MAS3:
(sowieso; wat doet een return eigenlijk) ?

Beetje een versnelde manier om uit een functie te springen. In dit geval niet echt handige plaats.

Verder is dit ook niet echt handig:

    timer = millis();
    if (timer != 0) {
      firstTime = false;
    }

Timer is in dit geval nooit 0
Dus is firstTime altijd false,

    if (timer > startTime + switchDelay) {

startTime wordt volgens mij nergens geïnitialiseerd.

daarnaast zou ik haakje gebruiken bij de conditie, dus:

    if (timer > (startTime + switchDelay)) {

Dus eerst beide optellen en dan de vergelijking maken

Duidelijk een andere routine dan was aangegeven..... ach ja.....

Hoi Nico,.

Dat wist ik wel, maar ik vraag me af of Arjen het ook weet.
Want uit welke functie wil je terugkeren daar ?
Het is de bedoeling dat hij er zelf over nadenkt in plaats van een vraag beantwoord te krijgen en er verder niet meer over hoeven nadenken.
Dat leert iets beter lijkt mij.

MAS3:
Hoi Nico,.

Dat wist ik wel

ik was al verbaasd :grin:Ik schatte jou veel hoger in :grin:

MAS3:
Het is de bedoeling dat hij er zelf over nadenkt in plaats van een vraag beantwoord te krijgen en er verder niet meer over hoeven nadenken.
Dat leert iets beter lijkt mij.

Is achteraf ook heel dom van mij. Je hebt volkomen gelijk. Op het NL forum geef ik ze (redelijk direct :grin:) op hun fl.kker als ze alleen maar komen halen en hier tuinde ik er gelijk in ^&^%$#$%^%$#. Niet dat het veel heeft geholpen.... Geef je ze een mooie oplossing gaan ze hem gelijk verkrachten....

Ik had die millis() voorbeelden ook gevonden maar heb preventief iets verzonnen om die 49 te overbruggen (oprekken eigenlijk)

if((timer + 1000) < millis()){
clocktime = millis()-timer;
if(clocktime > 1000){
runtime++;
}
timer = millis();
}

runtime telt de totaal aantal seconden dat het apparaat draait.
Hier heb ik een factoor 1000 meer ruimte in de variable runtime voor het overturned. (in contrast afhankelijk te zijn van een waarde gebasseerd op millis() )

Als timer overturned dan zal ie misschien een tiental milliseconded mislopen van twee keer de loop doorlopen met nieuwe waardes voor timer.

Of dit goed is, volgens mij wel, alleen misschien iets minder nauwkeurig (elke 49 dagen overturned timer)

Ik kreeg het in me kop toen ik las over dat 49 dagen probleem door ruimte gebrek in de variable.
Als het goed is draait bovenstaande 49000 dagen voor er issues optreden met overturn in de variable runtime.

Het neemt natuurlijk wel twee extra long variablen in beslag.

Aha.
Dat verklaart een en ander in de andere thread.
Ik zat daar al te turen naar hoe je de timer daar afhandelt, deze uitleg maakt het wat duidelijker.

MAS3:
Aha.
Dat verklaart een en ander in de andere thread.
Ik zat daar al te turen naar hoe je de timer daar afhandelt, deze uitleg maakt het wat duidelijker.

XD

Was toeval dat je het er over had, we zaten volgens mij tegelijk te typen haha.

volgens mij wil jij een knopje die v.b de secondes telt en na waarde van inhouden een functie uitvoerd ?
dus ik druk op knopje houdt hem 2 seconden in dan gaat deur open ,, als ik 5 seconden doe gaat die weer dicht of zo ?
led blink die aangeevt hoeveel sec of blinks ,, dus led knippert per sec of zo ,, en dan weet je welke functie die ingaat
zoiets ?