/* CVO De Verdieping: Arduino Voetgangerslicht_interrups
Sketch: Voetgangerslicht (interrupts)
Oefening Voetgangerslicht interrupts
Op een drukke oversteekplaats wordt besloten om een verkeerslicht
voor voetgangers te plaatsen. Hierdoor wordt de veiligheid voor de
zwakke weggebruiker aanzienlijk verhoogd.
Default: voertuigen GROEN, voetgangers ROOD
Indien knop ingedrukt, wordt volgende sequentie doorlopen:
3s voertuigen ORANJE, voetgangers ROOD
5s voertuigen ROOD, voetgangers ROOD (sper periode)
23s voertuigen ROOD, voetgangers GROEN
7s voertuigen ROOD, voetgangers GROEN knipperend 2 Hz
5s voertuigen ROOD, voetgangers ROOD (sper periode)
30s voertuigen GROEN, voetgangers ROOD
Houtmeyers Patrick
2023 - 2024
*/
// CONSTANTEN
const int PIN_LED_AUTO_ROOD = 8;
const int PIN_LED_AUTO_GEEL = 9;
const int PIN_LED_AUTO_GROEN = 10;
const int PIN_LED_VOET_ROOD = 11;
const int PIN_LED_VOET_GROEN = 12;
const int PIN_LED_AANVRAAG = 13;
const int PIN_KNOP = 2;
const int VERSNELLING = 3; // Hoeveel keer sneller loopt de sequentie
// tijden in ms
const unsigned int AUTO_ORANJE_TIJD = 3000 / VERSNELLING;
const unsigned int SPER_TIJD = 5000 / VERSNELLING;
const unsigned int VOET_GROEN_TIJD = 23000 / VERSNELLING;
const unsigned int VOET_KNIPPER_TIJD = 7000 / VERSNELLING;
const unsigned int AUTO_GROEN_TIJD = 30000 / VERSNELLING;
const unsigned int KNIPPER_TIJD = 250 / VERSNELLING; // Halve periode 2Hz
// (GLOBALE) VARIABELEN
volatile bool aanvraag = false; // gedeelde variabele tussen loop() en ISR()
// VOORBEREIDING
void setup()
{
// Definiëer input en output pinnen
pinMode(PIN_LED_AUTO_ROOD, OUTPUT);
pinMode(PIN_LED_AUTO_GEEL, OUTPUT);
pinMode(PIN_LED_AUTO_GROEN, OUTPUT);
pinMode(PIN_LED_VOET_ROOD, OUTPUT);
pinMode(PIN_LED_VOET_GROEN, OUTPUT);
pinMode(PIN_LED_AANVRAAG, OUTPUT);
pinMode(PIN_KNOP, INPUT);
// Zet de startconditie
digitalWrite(PIN_LED_AUTO_GROEN, HIGH);
digitalWrite(PIN_LED_VOET_ROOD, HIGH);
// koppel de interrupt
attachInterrupt(digitalPinToInterrupt(PIN_KNOP), ISR_knop, RISING);
}
// UITVOERING
void loop()
{
// INVOER
// VERWERKING + UITVOER
if (aanvraag) // korte notatie voor (aanvraag == true), aangezien aanvraag al een bool is
{
// knop is ingedrukt geweest, anders was er geen aanvraag ...
detachInterrupt(digitalPinToInterrupt(PIN_KNOP)); // ... zet de interrupts even af
aanvraag = false; // ... en wis nu de aanvraag, opgelet, eerst interupt af, dan de variabele
// 3s voertuigen ORANJE, voetgangers ROOD
digitalWrite(PIN_LED_AUTO_GROEN, LOW);
digitalWrite(PIN_LED_AUTO_GEEL, HIGH);
delay(AUTO_ORANJE_TIJD);
// 5s voertuigen ROOD, voetgangers ROOD (sper periode)
digitalWrite(PIN_LED_AUTO_GEEL, LOW);
digitalWrite(PIN_LED_AUTO_ROOD, HIGH);
delay(SPER_TIJD);
// 23s voertuigen ROOD, voetgangers GROEN
digitalWrite(PIN_LED_VOET_ROOD, LOW);
digitalWrite(PIN_LED_VOET_GROEN, HIGH);
digitalWrite(PIN_LED_AANVRAAG, LOW);
delay(VOET_GROEN_TIJD);
// 7s voertuigen ROOD, voetgangers GROEN knipperend 2 Hz
// De knipper periode is 500 ms. Op 7 seconden gaat de led dus
// 14 keer aan en uit (7s x 2/s of 7s:0.5s)
int aantalKeren = VOET_KNIPPER_TIJD / (2 * KNIPPER_TIJD); // KNIPPER_TIJD is de HALVE periode
for (int i = 0; i < aantalKeren ; i++)
{
digitalWrite(PIN_LED_VOET_GROEN, LOW);
delay(KNIPPER_TIJD);
digitalWrite(PIN_LED_VOET_GROEN, HIGH);
delay(KNIPPER_TIJD);
}
// 5s voertuigen ROOD, voetgangers ROOD (sper periode)
attachInterrupt(digitalPinToInterrupt(PIN_KNOP), ISR_dummy, RISING); // wis een eventueel hangende interrupt met de dummy ISR ...
attachInterrupt(digitalPinToInterrupt(PIN_KNOP), ISR_knop, RISING); // ... en hang de 'echte' ISR er aan
digitalWrite(PIN_LED_VOET_GROEN, LOW);
digitalWrite(PIN_LED_VOET_ROOD, HIGH);
delay(SPER_TIJD);
// 30s voertuigen GROEN, voetgangers ROOD
digitalWrite(PIN_LED_AUTO_ROOD, LOW);
digitalWrite(PIN_LED_AUTO_GROEN, HIGH);
delay(AUTO_GROEN_TIJD);
}
}
// Interrupt Service Routine (ISR)
void ISR_knop()
{
aanvraag = true;
digitalWrite(PIN_LED_AANVRAAG, HIGH);
}
void ISR_dummy() {} // lege interrupt om hangende IRQ's te wissen