/* CVO De Verdieping: Arduino
Sketch: Voetgangerslicht (interrupts alternatief)
Oefening Voetgangerslicht interrupts alternatief
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
// 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 (digitalRead(PIN_LED_AANVRAAG) == HIGH) // Als de LED brandt, heeft iemand ook op de knop gedrukt
{
// knop is ingedrukt geweest, anders was er geen aanvraag ...
detachInterrupt(digitalPinToInterrupt(PIN_KNOP)); // ... zet de interrupts even af
// 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); // Nu wordt ook de LED terug afgezet, zodat we later terug kunnen zien of hij weer aan staat.
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()
{
digitalWrite(PIN_LED_AANVRAAG, HIGH);
}
void ISR_dummy() {} // lege interrupt om hangende IRQ's te wissen