Oppgave 9: Finished?

This commit is contained in:
Alex Thomassen 2019-01-30 13:13:31 +01:00
parent 81800e580b
commit 15e27078ff
Signed by: Alex
GPG Key ID: 10BD786B5F6FF5DE

View File

@ -1,13 +1,15 @@
// "ped" = Pedestrian
// Fotgjengerlys og bryter.
int pedGreen = 6;
int pedRed = 7;
int pedSwitch = 11;
/**
* Fotgjengerlys + bryter
* `ped` = pedestrian = fotgjenger
*/
const int pedGreen = 6;
const int pedRed = 7;
const int pedSwitch = 11;
// Trafikklys
int trafficRed = 8;
int trafficYellow = 9;
int trafficGreen = 10;
const int trafficRed = 8;
const int trafficYellow = 9;
const int trafficGreen = 10;
void setup() {
// Pins som skal være output, brukes bare i setup.
@ -34,28 +36,29 @@ void setup() {
/**
* Lengde hvor lenge hvert trafikklys, i millisekunder.
*/
int redLength = 5000;
int redYellowLength = 2000;
int greenLength = 10000;
int yellowLength = 2000;
const int redLength = 5000;
const int redYellowLength = 2000;
const int greenLength = 10000;
const int yellowLength = 2000;
/**
* Trafficstates er:
* - -1: Oppstart av programmet.
* - 0: Rødt lys (5 sek)
* - 1: Rødt + gult (2 sek)
* - 2: Grønt (10 sek)
* - 3: Gult (2 sek)
* - -1: Oppstart av programmet/Arduino.
*
* - 0: Rødt lys (5 sek eller `redLength`)
* - 1: Rødt + gult (2 sek eller `redYellowLength`)
* - 2: Grønt (10 sek eller `greenLength`)
* - 3: Gult (2 sek eller `yellowLength`)
*/
int trafficState = -1;
int redState = 0;
int redYellowState = 1;
int greenState = 2;
int yellowState = 3;
const int redState = 0;
const int redYellowState = 1;
const int greenState = 2;
const int yellowState = 3;
/**
* Lengder som kan refereres basert array index
* Array index vil være det samme som "trafficState"
* Array index vil være det samme som `trafficState`
*/
int trafficLightLengths[] = {
// redState
@ -69,7 +72,7 @@ int trafficLightLengths[] = {
};
/**
* Antall millisekunder siden "trafficState" var sist endret.
* Antall millisekunder siden `trafficState` var sist endret.
*/
unsigned long lastStateChange = millis();
@ -87,18 +90,28 @@ unsigned long pedLastEnd = 0;
/**
* Antall millisekunder fotgjengere har å "krysse".
*/
int pedLength = 8000;
const int pedLength = 8000;
/**
* Antall millisekunder mellom hvert "blink" for fotgjengerlyset.
*/
int pedBlinkLength = 250;
const int pedBlinkLength = 250;
/**
* Antall ganger fotgjengerlyset har blinket.
*/
int pedBlinkCount = 0;
/**
* Maksimum antall ganger fotgjengerlyset skal blinke.
*/
const int pedMaxBlinkCount = 10;
/**
* Lagre sist gang fotgjengerlys "blinket" (var av).
*/
unsigned long pedLastBlinkChange = 0;
/**
* Om fotgjengerne er "aktive", altså at trafikklys skal stoppe (og holde seg rødt).
*/
@ -110,19 +123,100 @@ bool pedActive = false;
*/
bool pedShouldActivate = false;
/**
* Lagre verdien for når `pedShouldActivate` ble oppdatert.
*/
unsigned long pedShouldActivateTime = 0;
/**
* Hvor mange millisekunder etter at fotgjengerknappen har blitt trykket inn
* som fotgjengerlys skal aktivere.
*
* I følge oppgaven skal dette være 5 sekunder.
*/
const int pedActivateAfter = 5000;
void loop() {
/**
* Definer en felles verdi som er et resultat av millis().
*
* Kan hende at denne verdien er noen millisekunder feil når den brukes i diverse kode nedenfor,
* men det bør ikke være noen merkbar forskjell.
*/
unsigned long currentTime = millis();
/**
* Sjekk om fotgjengerknappen er trykt og
* oppdater verdier basert dette.
*
* Knappen setter et flagg (`pedShouldActivate`) som sjekkes etter at trafikklys har gått tilbake til rødt.
*/
if (analogRead(pedSwitch) == LOW) {
if (analogRead(pedSwitch) == LOW && !pedActive) {
pedShouldActivate = true;
pedShouldActivateTime = currentTime;
}
/**
* Aktiverer fotgjengerlys. `ped` = pedestrian.
* `pedActive` er som default false, men blir satt til true
* når `pedShouldActivate` er true og trafikklysene har gått tilbake til rødt.
*/
if (pedActive) {
// TODO: Oppgave 9
bool pedLightOn = false;
if (pedBlinkCount == 0) {
pedLightOn = true;
}
if (currentTime - pedLastStart >= pedLength) {
/**
* Om fotgjengerlyset er starten av "avsluttingsblink",
* vil det grønne fotgjengerlyset slå seg av.
*
* `pedLastBlinkChange` vil oppdateres og dette sjekkes videre i neste if-setning.
*/
if (pedBlinkCount == 0) {
pedLightOn = false;
pedLastBlinkChange = currentTime;
}
/**
* Sjekker om `pedLastBlinkChange` er mer eller lik `pedBlinkLength`,
* altså om siste "blink endring" var over 250 ms siden.
*
* `pedLightOn` bool vil "flippes" fra true => false, eller false => true
* som videre påvirker om det grønne fotgjengerlyset lyser.
*
* `pedLastBlinkChange` vil da oppdateres til nåværende millis().
*
* Hvis `pedLightOn` er true etter dette, vil `pedBlinkCount` inkrementeres.
* Dette vil da bare skje når det grønne fotgjengerlyset lyser igjen
* og ikke mens det har sloknet.
*/
if (currentTime - pedLastBlinkChange >= pedBlinkLength) {
pedLightOn = !pedLightOn;
pedLastBlinkChange = currentTime;
if (pedLightOn) {
pedBlinkCount++;
}
}
}
/**
* Sjekker om fotgjengerlyset har blinket 10 ganger (basert : `pedMaxBlinkCount`)
* og setter da `pedActive` tilbake til false slik at trafikklysene kan begynne vanlig syklus.
*/
if (pedBlinkCount >= pedMaxBlinkCount) {
pedActive = false;
pedLightOn = false;
}
/**
* Om `pedLightOn` er true, vil pedGreen lyse, hvis ikke er den av.
* Noe lignende gjelder for `pedRed` bare at den sjekker om fotgjengermodus er aktiv (`pedActive`).
*/
digitalWrite(pedRed, !pedActive ? HIGH : LOW);
digitalWrite(pedGreen, pedLightOn ? HIGH : LOW);
}
/**
@ -137,14 +231,49 @@ void loop() {
return;
}
/**
* `lightLength` er antall millisekunder som nåværende lys skal lyse.
* Dette hentes fra array'et trafficLightLengths, som igjen bare refererer til satte variabler.
*/
int lightLength = trafficLightLengths[trafficState];
if (!pedActive && currentTime - lastStateChange >= lightLength)
/**
* Denne if-setningen sjekker to forskjellige ting:
*
* 1: `pedActivateNow`
* Aller først sjekker den om fotgjengerknappen har blitt trykket.
* 5 sekunder etter (basert variabelet `pedActivateAfter`) skal trafikklys avslutte syklusen.
* Dette vil da skje tidligere enn vanlig i visse tilfeller.
* Om trafikklys allerede er vei til å avslutte syklusen, kan det hende at dette skjer før 5 sekunder.
*
* 2: `incrementTrafficState`
* Den vanlige sjekken er om `trafficState` skal inkrementes. Det vil da si at trafikken går som vanlig.
*/
bool pedActivateNow = (pedShouldActivate && currentTime - pedShouldActivateTime >= pedActivateAfter);
bool incrementTrafficState = (!pedActive && currentTime - lastStateChange >= lightLength);
if (pedActivateNow || incrementTrafficState)
{
/**
* Definer standard lysverdier for trafikklys, overskrives i switch nedenfor.
*/
int redLight = LOW;
int yellowLight = LOW;
int greenLight = LOW;
/**
* Inkrement `trafficState` som da sammenlignes med red-, yellow- eller greenState
*/
trafficState++;
/**
* Siden `trafficState` ble inkrementert, oppdater lastStateChange-verdien til mest nylig millis()-verdi.
*/
lastStateChange = currentTime;
/**
* Trafikklys er ferdig med syklus, tilbake til rødt.
* Hvis `trafficState` er mer enn 3, betyr det at siste del av syklus (gult lys) er ferdig.
* Dermed blir denne verdien resettet tilbake til 0 for å starte syklusen nytt.
*/
if (trafficState > 3)
{
@ -157,38 +286,47 @@ void loop() {
{
pedLastStart = currentTime;
pedActive = true;
pedBlinkCount = 0;
}
}
/**
* `trafficState` er en verdi som sammenlignes med variablene som har en `State` suffix.
* Dette brukes for å sjekke hvilke trafikklys som skal lyse.
*
* Som default er red-, yellow- og greenLight satt til LOW.
* Disse oppdateres basert hvilke trafikklys som skal lyse, som igjen er basert trafficState.
* Etter switch-case skrives disse til LED og de aktiveres ettersom.
*/
switch (trafficState)
{
// Rødt lys
case 0:
digitalWrite(trafficRed, HIGH);
digitalWrite(trafficYellow, LOW);
digitalWrite(trafficGreen, LOW);
case redState:
redLight = HIGH;
break;
// Rødt + gult lys
case 1:
digitalWrite(trafficRed, HIGH);
digitalWrite(trafficYellow, HIGH);
digitalWrite(trafficGreen, LOW);
case redYellowState:
redLight = HIGH;
yellowLight = HIGH;
break;
// Grønt lys
case 2:
digitalWrite(trafficRed, LOW);
digitalWrite(trafficYellow, LOW);
digitalWrite(trafficGreen, HIGH);
case greenState:
greenLight = HIGH;
break;
// Gult lys
case 3:
digitalWrite(trafficRed, LOW);
digitalWrite(trafficYellow, HIGH);
digitalWrite(trafficGreen, LOW);
case yellowState:
yellowLight = HIGH;
break;
}
/**
* Oppdater trafikklys etter de verdiene som er satt i switch-case.
*/
digitalWrite(trafficRed, redLight);
digitalWrite(trafficYellow, yellowLight);
digitalWrite(trafficGreen, greenLight);
}
}