// on road work mode flash orange light only at all junction void FlashForRoadWork() { static Counter roadWorkCounter; // flash the orange light by checking the counter time if(roadWorkCounter.GetCounter() <= 500) { trafficLight0.RoadWorkLightOnly(); trafficLight90.RoadWorkLightOnly(); trafficLight270.RoadWorkLightOnly(); } else if(roadWorkCounter.GetCounter() <= 1000) { trafficLight0.ledOrange.SwitchOff(); trafficLight90.ledOrange.SwitchOff(); trafficLight270.ledOrange.SwitchOff(); } else roadWorkCounter.Reset(); }
// on ped crossing mode when time is finished flash ped light at all junction void FlashForPedCrossFinish() { static Counter pedCrossCounter; // flash the ped light by checking the counter time if(pedCrossCounter.GetCounter() <= 500) { trafficLight270.ledPed.SwitchOn(); trafficLight0.ledPed.SwitchOn(); trafficLight90.ledPed.SwitchOn(); } else if(pedCrossCounter.GetCounter() <= 1000) { trafficLight0.ledPed.SwitchOff(); trafficLight90.ledPed.SwitchOff(); trafficLight270.ledPed.SwitchOff(); } else pedCrossCounter.Reset(); }
// Method is called when the obeservable object has a change in its state void CounterObserver::Update(Observable* obj) { Counter* pCounter = dynamic_cast<Counter*>(obj); if(pCounter != NULL) std::cout << "Observer address : " << this << " Counter has changed : " << pCounter->GetCounter() << std::endl; else std::cout << "Unknown observable" << std ::endl; }
// this function simulates normal light condition when called at every loop // it automatically transitions from green to red signal by using the OrangeTransitionCounter void UpdateWithLightTransition(bool goSignal, bool turnLight, bool pedLight, int orangeLightTime) { // if green or go signal turn off transitioning process // and only light up the green light if (goSignal) { transitionState = 0; GreenLight(); } // if red signal and green light was previously on // start transitioning to red by firt turning on the // orange light else if(!goSignal && ledGreen.IsOn() && transitionState == 0) { OrangeLight(); transitionState = 1; OrangeTransitionCounter.Reset(); } // if red signal and greenlight was not on, directly // switch on the red light else if(!goSignal && !ledGreen.IsOn() && transitionState == 0) RedLight(); // check if we are still transitioning to red light // if orangeTransitionCounter has passed orangeLightTime interval // turn on the Red light only if (transitionState == 1) { if (OrangeTransitionCounter.GetCounter() < orangeLightTime) OrangeLight(); else transitionState = 2; } if (transitionState == 2) RedLight(); if (turnLight) ledFilterTurn.SwitchOn(); else ledFilterTurn.SwitchOff(); // ped lights turn on only when the normal lights are in red signal if (pedLight && ledRed.IsOn()) ledPed.SwitchOn(); else ledPed.SwitchOff(); }
// Update normal light sequence by checking the main counter int UpdateNormalSequence(int goLightTime) { int i = 1; while (mainCounter.GetCounter() > i * goLightTime) i++; // On Select Sequence Button, cycle through the sequences immediately if (btnSelectSequence.IsPressed()) { // reset the main counter to start of new sequence mainCounter.Reset(i * goLightTime); i++; } // if maximum sequences has reached reset the main counter if (i == MAX_SEQUENCES + 1) { mainCounter.Reset(); i = 1; } return i; }
void loop() { delay(50); boolean hotDay = ther.GetKelvinTempUsingHart() >= THER_CRITICAL_DEG; boolean nightMode = ldr.ReadADC() <= LDR_DARK_ADC; static int goLightTimeCalibed = DEFAULT_GO_LIGHT_TIME; static int orangeLightTimeCalibed = DEFAULT_ORANGE_LIGHT_TIME; // if both emergency button and road work are pressed activate the calibration if (btnEmergency.IsPressed() && btnRoadWork.IsPressed()) { goLightTimeCalibed = map(pot.ReadADC(), 0, 1023, DEFAULT_GO_LIGHT_TIME/2, DEFAULT_GO_LIGHT_TIME * 2); orangeLightTimeCalibed = map(pot.ReadADC(), 0, 1023, DEFAULT_ORANGE_LIGHT_TIME/2, DEFAULT_ORANGE_LIGHT_TIME * 2); } else { boolean emergencyMode = btnEmergency.ReadSwitch(); boolean roadWorkMode = btnRoadWork.ReadSwitch(); if (emergencyMode) { OnEmergencyMode(); } if (roadWorkMode) { FlashForRoadWork(); } // pause the main counter when one of the modes are activated if(roadWorkMode || emergencyMode) { mainCounter.Pause(); return; } } int goLightTime = goLightTimeCalibed; int orangeLightTime = orangeLightTimeCalibed; double multiplier = 1.0; if (nightMode) { multiplier += 0.4; } if(hotDay) { multiplier += 0.3; } // extended the go or green signal time and the orange light time int goLightTime = goLightTimeCalibed * multiplier; int orangeLightTime = orangeLightTimeCalibed * multiplier; // get the current state of the sequence int state = UpdateNormalSequence(goLightTime); // print out the state of the system for debugging Serial.print("Temperature: "); Serial.print(ther.GetKelvinTempUsingHart()); Serial.print(" LDR: "); Serial.print(ldr.ReadADC()); Serial.print(" PotADC: "); Serial.print(pot.ReadADC()); Serial.print(" Cross: "); Serial.print(btnPedCross0.IsPressed() || btnPedCross90.IsPressed() || btnPedCross270.IsPressed()); Serial.print(" main Counter: "); Serial.print(mainCounter.GetCounter()); Serial.print(" goTime: "); Serial.print(goLightTime); Serial.print(" Orange: "); Serial.print(orangeLightTime); Serial.print(" state: "); Serial.println(state); // if alarm is in progress, exit from normal sequence if (AddPedCrossStageOnRequest(state, goLightTime, orangeLightTime)) return; // unpause the main counter if it was paused mainCounter.UnPause(); // update the leds on the traffic light depending on the values in the sequence array trafficLight270.UpdateWithLightTransition(sequence[state - 1][0], sequence[state - 1][1], sequence[state - 1][2], orangeLightTime); trafficLight0.UpdateWithLightTransition(sequence[state - 1][3], sequence[state - 1][4], sequence[state - 1][5], orangeLightTime); trafficLight90.UpdateWithLightTransition(sequence[state - 1][6], sequence[state - 1][7], sequence[state - 1][8], orangeLightTime); }
// function to allow for ped crossing on the press of a button // ped crossing works by pausing the main counter at the end of a sequence // and resuming after the ped has crossed. // returns whether alarm is currently on progression or not bool AddPedCrossStageOnRequest(int state, int pedCrossTime, int orangeLightTime){ #define NO_PED_CROSS 0 #define PED_CROSS_BTN_PRESSED 1 #define PED_CROSS_IN_PROGRESS 2 static int alarmState = 0; // check for button presses at all the junctions if(btnPedCross0.IsPressed() || btnPedCross90.IsPressed() || btnPedCross270.IsPressed()) if (alarmState == NO_PED_CROSS) alarmState = PED_CROSS_BTN_PRESSED; // update the buzzer asyncronously trafficLight0.crossingBuzzer.UpdateAsync(); trafficLight90.crossingBuzzer.UpdateAsync(); trafficLight270.crossingBuzzer.UpdateAsync(); static int prevState = 0; static Counter pedCrossCounter; // check if the current sequence has ended if (prevState != state && alarmState == PED_CROSS_BTN_PRESSED) { // pause the timer mainCounter.Pause(); // reset the crossing counter to 0 pedCrossCounter.Reset(); // activate the flag to transition all the green signal to red first alarmState = PED_CROSS_IN_PROGRESS; return true; } if (alarmState == PED_CROSS_IN_PROGRESS) { if (pedCrossCounter.GetCounter() <= pedCrossTime) { // if there were no green lights from the previous sequence, directly turn on the red light if (trafficLight0.ledRed.IsOn() && trafficLight90.ledRed.IsOn() && trafficLight270.ledRed.IsOn()) { trafficLight270.UpdateWithLightTransition(0, 0, 1, orangeLightTime); trafficLight0.UpdateWithLightTransition(0, 0, 1, orangeLightTime); trafficLight90.UpdateWithLightTransition(0, 0, 1, orangeLightTime); trafficLight0.crossingBuzzer.TriggerAlarm(); trafficLight90.crossingBuzzer.TriggerAlarm(); trafficLight270.crossingBuzzer.TriggerAlarm(); } // if there were green lights on the previous sequence, transition to red first else { trafficLight270.UpdateWithLightTransition(0, 0, 0, orangeLightTime); trafficLight0.UpdateWithLightTransition(0, 0, 0, orangeLightTime); trafficLight90.UpdateWithLightTransition(0, 0, 0, orangeLightTime); trafficLight0.crossingBuzzer.TurnOffAlarm(); trafficLight90.crossingBuzzer.TurnOffAlarm(); trafficLight270.crossingBuzzer.TurnOffAlarm(); } return true; } // if ped cross time has finish blink the ped light as in australian ped crossing else if (pedCrossCounter.GetCounter() <= pedCrossTime + orangeLightTime) { FlashForPedCrossFinish(); trafficLight0.crossingBuzzer.TurnOffAlarm(); trafficLight90.crossingBuzzer.TurnOffAlarm(); trafficLight270.crossingBuzzer.TurnOffAlarm(); return true; } else { alarmState = NO_PED_CROSS; } } prevState = state; return false; }