Drukknop meteen uitlezen

Goedenavond iedereen,

Ik heb een vraag. Ik ben aan het leren om met arduino te werken. Nu heb ik een programma gemaakt die twee verkeerslichten voor het autoverkeer regelt. Dit werkt goed.

Ook heb ik er een voetgangerslichtje bij geplaatst. Alleen zit hier een probleem. Het voetgangerslicht wordt alleen maar in werking gesteld als ik de drukknop induw, precies als de eerste oranje led (YELLOW) brandt.

Ik zou graag willen dat ik de drukknop 1x indruk, de arduino het programma afmaakt, de verkeerslichten voor het verkeer naar rood gooit om dan alsnog het programma voor het voetgangerslicht af te spelen. Ik krijg dit alleen niet voor elkaar.

Mijn programma:

//Voorbeeld van een verkeerslicht met drukknop voor voetgangers

const int RED = 12; //Eerste linkse rode led
const int YELLOW = 11; //Eerste linkse gele led
const int GREEN = 10; //Eerste linkse groene led
const int RED2 = 9; //Tweede rechtse rode led
const int YELLOW2 = 8; //Tweede rechtse gele led
const int GREEN2 = 7; //Tweede rechtse groene led
const int REDBOY = 6; //Voetgangerslicht rood
const int GREENBOY = 4; //Voetgangerslicht groen
const int BUZZER = 3; //Voetgangers groen licht verklikker
const int BUTTON = 2; //Drukknop voor voetgangers
int val = 0;

void setup(){
pinMode(RED, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(RED2, OUTPUT);
pinMode(YELLOW2, OUTPUT);
pinMode(GREEN2, OUTPUT);
pinMode(REDBOY, OUTPUT);
pinMode(GREENBOY, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(BUTTON, INPUT);
}

void loop(){
val = digitalRead(BUTTON);
if (val == HIGH) {
delay(300);
digitalWrite(REDBOY, LOW);
digitalWrite(GREENBOY, HIGH);
analogWrite(BUZZER, 150);
delay(5000);
for(int x=0; x<7; x++){
digitalWrite(GREENBOY, HIGH);
analogWrite(BUZZER, 150);
delay(200);
digitalWrite(GREENBOY, LOW);
analogWrite(BUZZER, 0);
delay(200);
}

}else {
digitalWrite(RED2, HIGH);
digitalWrite(REDBOY, HIGH);
digitalWrite(RED, HIGH);
delay(500);
digitalWrite(RED2, LOW);
digitalWrite(GREEN2, HIGH);
delay(6000);
digitalWrite(GREEN2, LOW);
digitalWrite(YELLOW2, HIGH);
delay(1000);
digitalWrite(YELLOW2, LOW);
digitalWrite(RED2, HIGH);
delay(500);
digitalWrite(RED, LOW);
digitalWrite(GREEN, HIGH);
delay(6000);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, HIGH);
delay(1000);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
}
}

Weten jullie de oplossing voor dit probleem?

Met vriendelijke groet,
Thomas

er zijn meerdere oplossingen:
allereerst de interupt: die is wat moeilijker te begrijpen, maar is hier het beste toepasbaar, zoek uit hoe je met een ingang een interupt kunt maken en dan wordt er naar een stukje programma gesprongen om een vlag aan te zetten dat er een voetganger staat te wachten.
dat moet je dan tussen elke fase checken en er zonodig naar toe springen.

jij gebruikt heel veel delay, dat is de oorzaak dat het niet goed gaat want jouw loop duurt gewoon heel erg lang. probeer het programma te maken met blink without delay(millis().(bij elke delay stopt het programma)

Nog een andere manier is een state machine met switch case te maken.

probeer alle manieren uit door ze toe te passen en dan je programma op te slaan, dan een andere methode enz.

Ik vind shooter's eerste oplossing overkill voor het gegeven probleem en het is geen oplossing voor het echte probleem.
Dat echte probleem word in oplossing 2 benoemd (en in mijn handtekening hieronder).
Oplossing 3, de state machine, komt ook kijken bij oplossing 2, en heeft niet per se switch...case nodig (alhoewel ik er ook wel van gecharmeerd ben).

Dus, gauw delay() afleren, en op zoek naar het alternatief !

Beste Shooter en MAS3,

Bedankt voor jullie meedenken. Ik ga er vanmiddag en/of vanavond weer mee aan de slag.
Zoals ik merk moet ik delay dus zo min mogelijk gebruiken.

Ik ga straks kijken hoe blink without delay werkt en alle beschreven oplossingen proberen.

Alvast bedankt,
Ik ga ermee aan de slag!

Thomas

29Thomas10:
Zoals ik merk moet ik delay dus zo min mogelijk gebruiken.

De enige reden om een delay te gebruiken is bijvoorbeeld bij Debounce van de knop. Ergens tussen de 15-30mSec. Voor de rest hoef je eigenlijk nooit gebruik te maken van de delay.

nicoverduin:
De enige reden om een delay te gebruiken is bijvoorbeeld bij Debounce van de knop. Ergens tussen de 15-30mSec. Voor de rest hoef je eigenlijk nooit gebruik te maken van de delay.

Ik zie nog 2 andere redenen om delay te gebruiken.
Delay is ook heel goed in een voorbeeld programma. Het laat de onervaren lezer toe om heel snel te begrijpen wat in welke volgorde gebeurd. Dat is dan ook de reden waarom delay zoveel gebruikt wordt in de voorbeeld programma's van Arduino. Het is een keuze van Arduino om zich te richten op de artiest en beginneling en daarom kiezen ze voor snel gewin. De kostprijs wordt betaald als je 2 dingen samen wilt doen.

Ook kan delay weinig of geen kwaad in setup omdat je dat maar 1 keer doet en je dan meestal ook sequencieel (dat is 1 ding na een ander) wil doen.

Als we er vanuit gaan dat we dus in de loop van een echt programma zitten ben ik het bijna helemaal eens met nico. Bijna want ik vind 15-30ms al veel te veel in een delay.

Met vriendelijke groet
Jantje

PS als er iemand goed animatie filmpjes kan maken dan heb ik een heel goed idee hoe we het delay probleem kunnen duidelijk maken. Daarvoor mag je me pm'en :slight_smile:

Jantje:
Bijna want ik vind 15-30ms al veel te veel in een delay.

Krent :grin:

nicoverduin:
Krent :grin:

rofl

allereerst de interupt, is de manier die hoort, want het is een interuptie op een lopend programma, dat is dus onderdeel van een normale cursus.
en nico zelfs 1 millisec is nog teveel, dan is mijn loop al een paar keer rond geweest (zo een honderd keer.
want als je twee knoppen indrukt dan werkt het al niet meer met delay van nico. dus ik geef mas3 gelijk.