Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *
- *
- * the more time that is added to the yellow led "warning light" is on, the shorter "less time", the green traffic go time will be, or the red stop led time will be.
- *
- * north_south red 78000ms, 78 seconds
- * north_south green 74000ms, 74 seconds
- * north_south yellow 40000ms, 4 seconds
- *
- * east_west red 78000ms, 78 seconds
- * east_west green 74000ms, 74 seconds
- * east_west yellow 40000ms, 4 seconds
- *
- *
- *
- *
- *
- * 03_21_2022 I made a simple USA traffic light out of this script and added a momentary-on button
- * State machine example https://forum.arduino.cc/t/how-to-use-multiple-buttons-and-functions/529178/19
- * Requirement :
- * Blink one LED at a steady rate whilst turning on a series of LEDs for periods that are
- * different for each LED
- *
- * The single blinking LED is implemented using the BlinkWithoutDelay principle so that its
- * operation does not slow down or stop the operation of the remainder of the program
- *
- * Control of the other 3 LEDs is controlled using a "State Machine".
- * The program is in one of 3 states during which one of the LEDs is illuminated for
- * a period of time. Again timing is implemented using millis(). Once the period for the
- * current state is over the program moves onto the next state in the series.
- *
- * NOTE : this is not necessarily the best way to write a program to meet the requirements
- * but it is written this way to illustrate the use of a "State Machine". The Serial monitor
- * is used for feedback as to what is happening in the program so it can be tested without LEDs
- * Instead of turning an LED on for a period in each state any appropriate non blocking code for the current
- * state could be run such as testing for user input and changing state if it is detected.
- * UKHeliBob
- * UKHeliBob Jun '18
- * It is important that states are exited and entered with the system correctly configured. Look at the REDLED case
- * in this example code and note the sequence of commands that are executed when the time comes to change state.
- * Some are needed to exit the current state cleanly, such as turning off the LED and other are needed for clean
- * entry to the next state, such as saving the current time.
- *
- *
- * This proves millis doesn't delay the program because the led blinking light works during signal changes
- * the for loop in setup that loads the led's adds time initally to the redled
- *
- * Pushing the button doesn’t cause a “WALK” signal to appear immediately.
- * The system still needs to complete its cycle and allow cars enough time to get through the
- * intersection. That could take anywhere from five seconds to two minutes, depending on the signal settings and the traffic.
- *
- * Peter Koonce, traffic signal manager for the city of Portland, Oregon, adds that the vast majority of buttons do work.
- * They may just take a while to do so—especially in areas where traffic lights are coordinated across intersections to increase
- * throughput. Durations will vary block to block and by time of day. But if you suspect that a button is truly broken, you should notify
- * your city’s department of transportation.
- *
- *
- * The north_south_sequencePeriods array has 3 values, one period for each LED and the state values come from the north_south_ledStates enum so the values will
- * be 0, 1 or 2 depending on which LED we are dealing with. So, when the current state is
- * REDLED the index will be zero, when GREENLED it will be 1 and when BLUELED it will be 2
- */
- const byte North_South_Pedistrian_Button_1 = 4;
- int north_south_buttonState = HIGH; //this variable tracks the state of the button, low if not pressed, high if pressed
- int north_south_ledState = -1; //this variable tracks the state of the LED, negative if off, positive if on
- long north_south_lastDebounceTime = 0; // the last time the output pin was toggled
- long debounceDelay = 50; // the debounce time; increase if the output flickers
- ///*
- enum north_south_ledStates //red comes on first give the states names (actually numbers 0 to 3) to make reading the code easier
- {
- NORTH_SOUTH_REDLED, //pin 6 state 0
- NORTH_SOUTH_GREENLED, //pin 7 state 1
- NORTH_SOUTH_YELLOWLED //pin 8 state 2
- };
- byte north_south_currentState;
- //adding east_west signal
- enum east_west_ledStates //red comes on first give the states names (actually numbers 0 to 3) to make reading the code easier
- {
- EAST_WEST_REDLED, //pin 10 state 0
- EAST_WEST_GREENLED, //pin 11 state 1
- EAST_WEST_YELLOWLED //pin 12 state 2
- };
- byte east_west_currentState;
- //============================================================================================================================================================================
- //BEGIN: Original Code
- //============================================================================================================================================================================
- //physical pins location this works pin 12 red, pin, pin 10 green, pin 11 yellow
- const byte north_south_blinkLedPin = 9;
- const byte north_south_redLedPin = 6; //pin 6, state 0, 8500ms
- const byte north_south_greenLedPin = 7; //pin 7, state 1, 8500ms
- const byte north_south_yellowLedPin = 8; //pin 8, state 2, 4500ms
- const byte east_west_redLedPin = 10; //pin 10, state 0, 8500ms
- const byte east_west_greenLedPin = 11; //pin 11, state 1, 8500ms
- const byte east_west_yellowLedPin = 12; //pin 12, state 2, 4500ms
- //============================================================================================================================================================================
- //END: Original Code
- //============================================================================================================================================================================
- //============================================================================================================================================================================
- //Below goes by pin numbers of the led's
- //============================================================================================================================================================================
- const byte north_south_sequenceLedPins[] = {north_south_redLedPin, north_south_greenLedPin, north_south_yellowLedPin};//Goes by states, same as enum order north_south_redLedPin, Pin# 6, state zero,, is first, north_south_greenLedPin, Pin# 7, state 1, is second, north_south_yellowLedPin, Pin# 8, State 2, is last
- //east_west red 30 seconds
- //east_west green 57 seconds
- //east_west yellow 4 seconds
- const byte east_west_sequenceLedPins[] = {east_west_redLedPin, east_west_greenLedPin, east_west_yellowLedPin};
- //============================================================================================================================================================================
- //north_south_sequencePeriods
- //============================================================================================================================================================================
- //the green leds on both north_south and east_west have to terminate early by 4000ms
- // the more time that is added to the yellow led "warning light" is on, the shorter "less time", the green traffic go time will be, or the red stop led time will be. your choice
- //4 seconds yellow warning led
- //unsigned long north_south_sequencePeriods[] = {78000, 74000, 4000}; //sequence of times State 0, north_south_redLedPin, pin 6, 8500ms, State 1, north_south_greenLedPin, pin 7, 8500ms, State 2, north_south_yellowLedPin, pin 8, 4500ms
- //unsigned long east_west_sequencePeriods[] = {78000, 74000, 4000}; //sequence of times State 0, east_west_redLedPin, pin 10, 3000ms,State 1, east_west_greenLedPin,pin 11, 57000ms,State 2, east_west_yellowLedPin,pin 12,4000ms
- //6 seconds yellow warning led
- unsigned long north_south_sequencePeriods[] = {78000, 72000, 6000}; //sequence of times State 0, north_south_redLedPin, pin 6, 8500ms, State 1, north_south_greenLedPin, pin 7, 8500ms, State 2, north_south_yellowLedPin, pin 8, 4500ms
- unsigned long east_west_sequencePeriods[] = {78000, 72000, 6000}; //sequence of times State 0, east_west_redLedPin, pin 10, 3000ms,State 1, east_west_greenLedPin,pin 11, 57000ms,State 2, east_west_yellowLedPin,pin 12,4000ms
- const byte north_south_NUMBER_OF_LEDS = sizeof(north_south_sequenceLedPins) / sizeof(north_south_sequenceLedPins[0]);
- unsigned long north_south_currentTime;
- unsigned long north_south_blinkLedStartTime;
- unsigned long north_south_sequenceLedStartTime;
- unsigned long north_south_blinkLedPeriod = 300;
- const byte east_west_NUMBER_OF_LEDS = sizeof(north_south_sequenceLedPins) / sizeof(north_south_sequenceLedPins[0]);
- unsigned long east_west_currentTime;
- unsigned long east_west_blinkLedStartTime;
- unsigned long east_west_sequenceLedStartTime;
- unsigned long east_west_blinkLedPeriod = 300;
- void setup()
- {
- Serial.begin(115200);
- pinMode(North_South_Pedistrian_Button_1, INPUT_PULLUP);
- pinMode(north_south_blinkLedPin, OUTPUT);
- digitalWrite(north_south_blinkLedPin, LOW); //turn off the blinkLed initially
- for (int north_south_led = 0; north_south_led < north_south_NUMBER_OF_LEDS; north_south_led++) //set pinMode()s for LEDs
- {
- pinMode(north_south_sequenceLedPins[north_south_led], OUTPUT);
- digitalWrite(north_south_sequenceLedPins[north_south_led], LOW); //turn all sequence LEDs off initially
- }
- for (int east_west_led = 0; east_west_led < east_west_NUMBER_OF_LEDS; east_west_led++) //set pinMode()s for LEDs
- {
- pinMode(east_west_sequenceLedPins[east_west_led], OUTPUT);
- digitalWrite(east_west_sequenceLedPins[east_west_led], LOW); //turn all sequence LEDs off initially
- }
- north_south_currentState = NORTH_SOUTH_REDLED; //start in this state
- digitalWrite(north_south_currentState, HIGH); //UKBob said to add this to end of setup()
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //added this line turn on first LED
- north_south_reportState();
- east_west_currentState = EAST_WEST_GREENLED; //start in this state
- digitalWrite(east_west_currentState, HIGH); //UKBob said to add this to end of setup()
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //added this line turn on first LED
- east_west_reportState();
- }//setup
- void loop()
- {
- north_south_currentTime = millis(); //used throughout loop() for consistent timing
- east_west_currentTime = millis(); //used throughout loop() for consistent timing
- //sample the state of the button - is it pressed or not?
- north_south_buttonState = digitalRead(North_South_Pedistrian_Button_1);
- //filter out any noise by setting a time buffer
- if ( (millis() - north_south_lastDebounceTime) > debounceDelay)
- {
- //if the button has been pressed, lets toggle the LED from "off to on" or "on to off"
- if ( (north_south_buttonState == LOW) && (north_south_ledState < 0) )
- {
- north_south_Blink(); //call the north_south_Blink() function
- //to make a latched switch uncomment north_south_ledState = -north_south_ledState;
- //north_south_ledState = - north_south_ledState; //now the LED is on, we need to change the state
- north_south_lastDebounceTime = millis(); //set the current time
- }
- else if ( (north_south_buttonState == HIGH) && (north_south_ledState > 0) )
- {
- //to make a latched switch uncomment north_south_ledState = -north_south_ledState;
- //north_south_ledState = - north_south_ledState; //now the LED is off, we need to change the state
- north_south_lastDebounceTime = millis(); //set the current time
- }
- }//close if(time buffer)
- //now we need to check which state we are in and run the appropriate code for it
- //note that by using millis() for timing we keep loop() running freely
- //so that we can blink the single LED
- //when the priod for the current state ends we set the entry conditions for the next state,
- //change the current state so that next time through the code for the next state is executed
- switch (north_south_currentState)
- {
- case NORTH_SOUTH_REDLED:
- //when the priod for the current state ends we set the entry conditions for the next state,
- //change the current state so that next time through the code for the next state is executed
- if (north_south_currentTime - north_south_sequenceLedStartTime >= north_south_sequencePeriods[north_south_currentState]) //time to change states
- {
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], LOW); //turn off the north_south_yellowLedPin
- north_south_currentState = NORTH_SOUTH_GREENLED; //next state to move to
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //turn on current LED north_south_redLedPin
- north_south_sequenceLedStartTime = north_south_currentTime; //start time for next state
- north_south_reportState();
- }
- break; //end of code for this state
- case NORTH_SOUTH_GREENLED:
- if (north_south_currentTime - north_south_sequenceLedStartTime >= north_south_sequencePeriods[north_south_currentState]) //time to change states
- {
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], LOW); //turn off the north_south_redLedPin
- north_south_currentState = NORTH_SOUTH_YELLOWLED; //next state to move to
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //turn on current LED north_south_greenLedPin
- north_south_sequenceLedStartTime = north_south_currentTime; //start time for next state
- north_south_reportState();
- }
- break; //end of code for this state
- case NORTH_SOUTH_YELLOWLED:
- if (north_south_currentTime - north_south_sequenceLedStartTime >= north_south_sequencePeriods[north_south_currentState]) //time to change states
- {
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], LOW); //turn off the north_south_greenLedPin
- north_south_currentState = NORTH_SOUTH_REDLED; //next state to move to
- digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //turn on current LED north_south_yellowLedPin
- north_south_sequenceLedStartTime = north_south_currentTime; //start time for next state
- north_south_reportState();
- }
- break; //end of code for this state
- } //switch
- //==========================================================================================
- switch (east_west_currentState)
- {
- case EAST_WEST_REDLED:
- //when the priod for the current state ends we set the entry conditions for the next state,
- //change the current state so that next time through the code for the next state is executed
- if (east_west_currentTime - east_west_sequenceLedStartTime >= east_west_sequencePeriods[east_west_currentState]) //time to change states
- {
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], LOW); //turn off the east_west_yellowLedPin
- east_west_currentState = EAST_WEST_GREENLED; //next state to move to
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //turn on current LED east_west_redLedPin
- east_west_sequenceLedStartTime = east_west_currentTime; //start time for next state
- east_west_reportState();
- }
- break; //end of code for this state
- case EAST_WEST_GREENLED:
- if (east_west_currentTime - east_west_sequenceLedStartTime >= east_west_sequencePeriods[east_west_currentState]) //time to change states
- {
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], LOW); //turn off the east_west_redLedPin
- east_west_currentState = EAST_WEST_YELLOWLED; //next state to move to
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //turn on current LED east_west_greenLedPin
- east_west_sequenceLedStartTime = east_west_currentTime; //start time for next state
- east_west_reportState();
- }
- break; //end of code for this state
- case EAST_WEST_YELLOWLED:
- if (east_west_currentTime - east_west_sequenceLedStartTime >= east_west_sequencePeriods[east_west_currentState]) //time to change states
- {
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], LOW); //turn off the east_west_greenLedPin
- east_west_currentState = EAST_WEST_REDLED; //next state to move to
- digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //turn on current LED east_west_yellowLedPin
- east_west_sequenceLedStartTime = east_west_currentTime; //start time for next state
- east_west_reportState();
- }
- break; //end of code for this state
- } //switch
- } //loop
- void north_south_reportState()
- {
- /*
- *What the F() macro Does
- That long string of code tells the compiler to keep a string inside of PROGMEM and not allow it to consume RAM.
- Using the F() Macro
- Here’s an example of how you would use the F() macro with Serial.print() or Lcd.print().
- Serial.println(F(“Hello World”));
- Lcd.print(F(“W”));
- That’s all there is to it. Simply wrap your string (const character array) with F().
- Why is the F() Macro Needed?
- Remember that the Arduino Uno (and it’s cousins) are based on the ATmega328.
- This microcontroller only offers 2,048 bytes of RAM. 2k,
- that’s it. Even the Uno’s big brother, the Mega2560, only has 8K of RAM.
- */
- Serial.print(F(" Now in state "));
- Serial.print(north_south_currentState);//States
- Serial.print(" Pin # ");
- Serial.print(north_south_sequenceLedPins[north_south_currentState]);//pin numbers
- if (north_south_currentState == 0)
- {
- Serial.print(" north_south_red led");
- }
- else if (north_south_currentState == 1)
- {
- Serial.print(" north_south_green led");
- }
- else
- {
- Serial.print(" north_south_yellow led");
- }
- Serial.print(F(" for "));
- Serial.print(north_south_sequencePeriods[north_south_currentState]);//time period
- Serial.println(F(" milliseconds"));
- }
- //==============================================================
- void east_west_reportState()
- {
- /*
- *What the F() macro Does
- That long string of code tells the compiler to keep a string inside of PROGMEM and not allow it to consume RAM.
- Using the F() Macro
- Here’s an example of how you would use the F() macro with Serial.print() or Lcd.print().
- Serial.println(F(“Hello World”));
- Lcd.print(F(“W”));
- That’s all there is to it. Simply wrap your string (const character array) with F().
- Why is the F() Macro Needed?
- Remember that the Arduino Uno (and it’s cousins) are based on the ATmega328.
- This microcontroller only offers 2,048 bytes of RAM. 2k,
- that’s it. Even the Uno’s big brother, the Mega2560, only has 8K of RAM.
- */
- Serial.print(F(" Now in state "));
- Serial.print(east_west_currentState);//States
- Serial.print(" Pin # ");
- Serial.print(east_west_sequenceLedPins[east_west_currentState]);//pin numbers
- if (east_west_currentState == 0)
- {
- Serial.print(" east_west_red led");
- }
- else if (east_west_currentState == 1)
- {
- Serial.print(" east_west_green led");
- }
- else
- {
- Serial.print(" east_west_yellow led");
- }
- Serial.print(F(" for "));
- Serial.print(east_west_sequencePeriods[east_west_currentState]);//time period
- Serial.println(F(" milliseconds"));
- }
- void north_south_Blink()
- {
- //let's start with the single blinking LED
- if (north_south_currentTime - north_south_blinkLedStartTime >= north_south_blinkLedPeriod) //time to change the single LED state
- {
- digitalWrite(north_south_blinkLedPin, !digitalRead(north_south_blinkLedPin));
- north_south_blinkLedStartTime = north_south_currentTime;
- Serial.println(F("\tBLINK"));
- } //if
- } //Bliknk
- This page was last modified on 2 April 2022, at 15:43.
Advertisement
Add Comment
Please, Sign In to add comment