Jouw constatering is niet geheel juist.
Je moet net op het juiste moment op de knop drukken, of deze lang genoeg indrukken om geregistreerd te krijgen dat deze knop is ingedrukt.
Dat betekent dat jouw code toch een blokkerend deel er in moet hebben zitten.
Blokkerende code is niet alleen delay(), en die heb je ook niet als ik even snel door jouw code scan.
Maar er zitten wel for... loops in, en die zijn ook blokkerend.
Ik zie ook iets over timers voorbij komen, dus die moet je ook controleren of daar wat blokkeert.
Er staat toch iets over delay in je debounce deel, controleer dat ook.
En wat betekent keep debounced ?
Zoals ik de code begrijp , blijft die groen totdat er een knop is ingedrukt
En hebben we een soort van delay ingebouwd zodat een voetganger niet steeds het voetgangerslicht op groen en de auto's op rood laten staan.
Dit betekent voor zover ik het begrijp dat de knop pas verander als de tijd tussen dat die ingedrukt is en de vorige keer groter is dan een bepaalde tijd.
Zo niet, wacht dan een aantal seconden en ga naar het oranje licht.
case st_Green_Cars_Red_Pedestrians heeft geen timer nodig; je wilt onmiddellijk op de knop (kunnen) reageren.
Er moet wel ergens een soort vertraging in zitten die voorkomt dat als voetgangers constant die knop indrukken het verkeer geen kans heeft. Als ik me niet vergis hadden we dat opgelost in je andere verkeerslicht onderwerp (maar ik weet niet meer precies welke dat is of in welke bericht in dat onderwerp).
Volgens mij is dat waar lastTimePressed (misschien heette die in het verleden anders) voor bedoeld was.
case stX:
/*
Geen verandering in lichten.
Als een voetgangerscyclus niet recentelijk was gedaan (bv laatste 120 seconden) gaan we naar stOR.
Anders wachten we 120 seconden en gaan naar stOR; dit voorkoomt dat motorvoertuigen geen kans krijgen.
In deze stap moet je bijhouden wanneer deze de laatste keer was aangeroepen.
*/
interval_loop = 4000;
if (millis() - lastTimePressed > 4000) {
currentState = stOR;
clearCurrentState();
} else {
if (timer_loop(interval_loop)) {
currentState = stOR;
clearCurrentState();
}
}
break;
De interval is nu in de list geregeld en heet nu resetState die wordt aangeroepen door enterState die door nextByTable wordt aangeroepen.
En die wordt hier aangeroepen :
case stX:
if (millis() - lastTimePressed > getStateInfo(currentState)->duration) {
currentState = nextByTable(currentState);
} else {
if (timers.loop.expired(getStateInfo(currentState)->duration)) {
currentState = nextByTable(currentState);
}
}
break;
Toon de timers in je debug venster, dan kun je zien hoe ze er voor staan.
Dus de status van je drukknop, alle timers en eventuele vlaggen die je zet toon je dan in je debug venster.
Voor zover ik het kan testen wel.
ik heb meerdere keren vlak na elkaar gedrukt en de eerste keer gaat die naar de voetgangers cyclus en daarna gaat die gewoon door.
Vlak na elkaar is niet helemaal de juiste benadering, denk ik. Dat werkt inderdaad omdat je de knop alleen in st_Green_Cars_Red_Pedestrians gebruikt.
Stel je bent een voetganger en je wilt autootje pesten. Je neemt een tandenstoker mee, druk de knop in en gebruik de tandenstoker zodat de knop ingedrukt blijft.