stspringer

My_Working_USA_Traffic_Light_Script_No_Pedestrian_Button

Jul 4th, 2023
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.93 KB | None | 0 0
  1. /*
  2. *
  3. *
  4. * 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.
  5. *
  6. * north_south red 78000ms, 78 seconds
  7. * north_south green 74000ms, 74 seconds
  8. * north_south yellow 40000ms, 4 seconds
  9. *
  10. * east_west red 78000ms, 78 seconds
  11. * east_west green 74000ms, 74 seconds
  12. * east_west yellow 40000ms, 4 seconds
  13. *
  14. *
  15. *
  16. *
  17. *
  18. * 03_21_2022 I made a simple USA traffic light out of this script and added a momentary-on button
  19. * State machine example https://forum.arduino.cc/t/how-to-use-multiple-buttons-and-functions/529178/19
  20. * Requirement :
  21. * Blink one LED at a steady rate whilst turning on a series of LEDs for periods that are
  22. * different for each LED
  23. *
  24. * The single blinking LED is implemented using the BlinkWithoutDelay principle so that its
  25. * operation does not slow down or stop the operation of the remainder of the program
  26. *
  27. * Control of the other 3 LEDs is controlled using a "State Machine".
  28. * The program is in one of 3 states during which one of the LEDs is illuminated for
  29. * a period of time. Again timing is implemented using millis(). Once the period for the
  30. * current state is over the program moves onto the next state in the series.
  31. *
  32. * NOTE : this is not necessarily the best way to write a program to meet the requirements
  33. * but it is written this way to illustrate the use of a "State Machine". The Serial monitor
  34. * is used for feedback as to what is happening in the program so it can be tested without LEDs
  35. * Instead of turning an LED on for a period in each state any appropriate non blocking code for the current
  36. * state could be run such as testing for user input and changing state if it is detected.
  37. * UKHeliBob
  38.  
  39. * UKHeliBob Jun '18
  40. * It is important that states are exited and entered with the system correctly configured. Look at the REDLED case
  41. * in this example code and note the sequence of commands that are executed when the time comes to change state.
  42. * Some are needed to exit the current state cleanly, such as turning off the LED and other are needed for clean
  43. * entry to the next state, such as saving the current time.
  44. *
  45. *
  46. * This proves millis doesn't delay the program because the led blinking light works during signal changes
  47. * the for loop in setup that loads the led's adds time initally to the redled
  48. *
  49. * Pushing the button doesn’t cause a “WALK” signal to appear immediately.
  50. * The system still needs to complete its cycle and allow cars enough time to get through the
  51. * intersection. That could take anywhere from five seconds to two minutes, depending on the signal settings and the traffic.
  52. *
  53. * Peter Koonce, traffic signal manager for the city of Portland, Oregon, adds that the vast majority of buttons do work.
  54. * They may just take a while to do so—especially in areas where traffic lights are coordinated across intersections to increase
  55. * 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
  56. * your city’s department of transportation.
  57. *
  58. *
  59. * 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
  60. * be 0, 1 or 2 depending on which LED we are dealing with. So, when the current state is
  61. * REDLED the index will be zero, when GREENLED it will be 1 and when BLUELED it will be 2
  62. */
  63. const byte North_South_Pedistrian_Button_1 = 4;
  64. int north_south_buttonState = HIGH; //this variable tracks the state of the button, low if not pressed, high if pressed
  65. int north_south_ledState = -1; //this variable tracks the state of the LED, negative if off, positive if on
  66.  
  67. long north_south_lastDebounceTime = 0; // the last time the output pin was toggled
  68. long debounceDelay = 50; // the debounce time; increase if the output flickers
  69.  
  70. ///*
  71. enum north_south_ledStates //red comes on first give the states names (actually numbers 0 to 3) to make reading the code easier
  72. {
  73. NORTH_SOUTH_REDLED, //pin 6 state 0
  74. NORTH_SOUTH_GREENLED, //pin 7 state 1
  75. NORTH_SOUTH_YELLOWLED //pin 8 state 2
  76. };
  77.  
  78.  
  79. byte north_south_currentState;
  80.  
  81. //adding east_west signal
  82. enum east_west_ledStates //red comes on first give the states names (actually numbers 0 to 3) to make reading the code easier
  83. {
  84. EAST_WEST_REDLED, //pin 10 state 0
  85. EAST_WEST_GREENLED, //pin 11 state 1
  86. EAST_WEST_YELLOWLED //pin 12 state 2
  87. };
  88.  
  89.  
  90. byte east_west_currentState;
  91. //============================================================================================================================================================================
  92. //BEGIN: Original Code
  93. //============================================================================================================================================================================
  94.  
  95.  
  96. //physical pins location this works pin 12 red, pin, pin 10 green, pin 11 yellow
  97. const byte north_south_blinkLedPin = 9;
  98. const byte north_south_redLedPin = 6; //pin 6, state 0, 8500ms
  99. const byte north_south_greenLedPin = 7; //pin 7, state 1, 8500ms
  100. const byte north_south_yellowLedPin = 8; //pin 8, state 2, 4500ms
  101.  
  102.  
  103. const byte east_west_redLedPin = 10; //pin 10, state 0, 8500ms
  104. const byte east_west_greenLedPin = 11; //pin 11, state 1, 8500ms
  105. const byte east_west_yellowLedPin = 12; //pin 12, state 2, 4500ms
  106. //============================================================================================================================================================================
  107. //END: Original Code
  108. //============================================================================================================================================================================
  109.  
  110.  
  111.  
  112. //============================================================================================================================================================================
  113. //Below goes by pin numbers of the led's
  114. //============================================================================================================================================================================
  115.  
  116. 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
  117.  
  118. //east_west red 30 seconds
  119. //east_west green 57 seconds
  120. //east_west yellow 4 seconds
  121.  
  122. const byte east_west_sequenceLedPins[] = {east_west_redLedPin, east_west_greenLedPin, east_west_yellowLedPin};
  123. //============================================================================================================================================================================
  124. //north_south_sequencePeriods
  125. //============================================================================================================================================================================
  126. //the green leds on both north_south and east_west have to terminate early by 4000ms
  127. // 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
  128.  
  129.  
  130. //4 seconds yellow warning led
  131. //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
  132. //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
  133.  
  134.  
  135. //6 seconds yellow warning led
  136. 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
  137. 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
  138.  
  139.  
  140. const byte north_south_NUMBER_OF_LEDS = sizeof(north_south_sequenceLedPins) / sizeof(north_south_sequenceLedPins[0]);
  141. unsigned long north_south_currentTime;
  142. unsigned long north_south_blinkLedStartTime;
  143. unsigned long north_south_sequenceLedStartTime;
  144. unsigned long north_south_blinkLedPeriod = 300;
  145.  
  146. const byte east_west_NUMBER_OF_LEDS = sizeof(north_south_sequenceLedPins) / sizeof(north_south_sequenceLedPins[0]);
  147. unsigned long east_west_currentTime;
  148. unsigned long east_west_blinkLedStartTime;
  149. unsigned long east_west_sequenceLedStartTime;
  150. unsigned long east_west_blinkLedPeriod = 300;
  151.  
  152. void setup()
  153. {
  154. Serial.begin(115200);
  155.  
  156. pinMode(North_South_Pedistrian_Button_1, INPUT_PULLUP);
  157. pinMode(north_south_blinkLedPin, OUTPUT);
  158. digitalWrite(north_south_blinkLedPin, LOW); //turn off the blinkLed initially
  159.  
  160. for (int north_south_led = 0; north_south_led < north_south_NUMBER_OF_LEDS; north_south_led++) //set pinMode()s for LEDs
  161. {
  162. pinMode(north_south_sequenceLedPins[north_south_led], OUTPUT);
  163. digitalWrite(north_south_sequenceLedPins[north_south_led], LOW); //turn all sequence LEDs off initially
  164. }
  165.  
  166. for (int east_west_led = 0; east_west_led < east_west_NUMBER_OF_LEDS; east_west_led++) //set pinMode()s for LEDs
  167. {
  168. pinMode(east_west_sequenceLedPins[east_west_led], OUTPUT);
  169. digitalWrite(east_west_sequenceLedPins[east_west_led], LOW); //turn all sequence LEDs off initially
  170. }
  171.  
  172. north_south_currentState = NORTH_SOUTH_REDLED; //start in this state
  173. digitalWrite(north_south_currentState, HIGH); //UKBob said to add this to end of setup()
  174. digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //added this line turn on first LED
  175. north_south_reportState();
  176.  
  177. east_west_currentState = EAST_WEST_GREENLED; //start in this state
  178. digitalWrite(east_west_currentState, HIGH); //UKBob said to add this to end of setup()
  179. digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //added this line turn on first LED
  180. east_west_reportState();
  181.  
  182. }//setup
  183.  
  184. void loop()
  185. {
  186.  
  187. north_south_currentTime = millis(); //used throughout loop() for consistent timing
  188. east_west_currentTime = millis(); //used throughout loop() for consistent timing
  189.  
  190.  
  191. //sample the state of the button - is it pressed or not?
  192. north_south_buttonState = digitalRead(North_South_Pedistrian_Button_1);
  193.  
  194. //filter out any noise by setting a time buffer
  195. if ( (millis() - north_south_lastDebounceTime) > debounceDelay)
  196. {
  197.  
  198. //if the button has been pressed, lets toggle the LED from "off to on" or "on to off"
  199. if ( (north_south_buttonState == LOW) && (north_south_ledState < 0) )
  200. {
  201. north_south_Blink(); //call the north_south_Blink() function
  202. //to make a latched switch uncomment north_south_ledState = -north_south_ledState;
  203. //north_south_ledState = - north_south_ledState; //now the LED is on, we need to change the state
  204. north_south_lastDebounceTime = millis(); //set the current time
  205.  
  206. }
  207. else if ( (north_south_buttonState == HIGH) && (north_south_ledState > 0) )
  208. {
  209. //to make a latched switch uncomment north_south_ledState = -north_south_ledState;
  210. //north_south_ledState = - north_south_ledState; //now the LED is off, we need to change the state
  211. north_south_lastDebounceTime = millis(); //set the current time
  212. }
  213.  
  214. }//close if(time buffer)
  215.  
  216. //now we need to check which state we are in and run the appropriate code for it
  217. //note that by using millis() for timing we keep loop() running freely
  218. //so that we can blink the single LED
  219. //when the priod for the current state ends we set the entry conditions for the next state,
  220. //change the current state so that next time through the code for the next state is executed
  221.  
  222.  
  223. switch (north_south_currentState)
  224. {
  225. case NORTH_SOUTH_REDLED:
  226. //when the priod for the current state ends we set the entry conditions for the next state,
  227. //change the current state so that next time through the code for the next state is executed
  228. if (north_south_currentTime - north_south_sequenceLedStartTime >= north_south_sequencePeriods[north_south_currentState]) //time to change states
  229. {
  230. digitalWrite(north_south_sequenceLedPins[north_south_currentState], LOW); //turn off the north_south_yellowLedPin
  231. north_south_currentState = NORTH_SOUTH_GREENLED; //next state to move to
  232. digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //turn on current LED north_south_redLedPin
  233. north_south_sequenceLedStartTime = north_south_currentTime; //start time for next state
  234. north_south_reportState();
  235. }
  236. break; //end of code for this state
  237.  
  238. case NORTH_SOUTH_GREENLED:
  239. if (north_south_currentTime - north_south_sequenceLedStartTime >= north_south_sequencePeriods[north_south_currentState]) //time to change states
  240. {
  241. digitalWrite(north_south_sequenceLedPins[north_south_currentState], LOW); //turn off the north_south_redLedPin
  242. north_south_currentState = NORTH_SOUTH_YELLOWLED; //next state to move to
  243. digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //turn on current LED north_south_greenLedPin
  244. north_south_sequenceLedStartTime = north_south_currentTime; //start time for next state
  245. north_south_reportState();
  246. }
  247. break; //end of code for this state
  248.  
  249. case NORTH_SOUTH_YELLOWLED:
  250. if (north_south_currentTime - north_south_sequenceLedStartTime >= north_south_sequencePeriods[north_south_currentState]) //time to change states
  251. {
  252. digitalWrite(north_south_sequenceLedPins[north_south_currentState], LOW); //turn off the north_south_greenLedPin
  253. north_south_currentState = NORTH_SOUTH_REDLED; //next state to move to
  254. digitalWrite(north_south_sequenceLedPins[north_south_currentState], HIGH); //turn on current LED north_south_yellowLedPin
  255. north_south_sequenceLedStartTime = north_south_currentTime; //start time for next state
  256. north_south_reportState();
  257. }
  258. break; //end of code for this state
  259.  
  260. } //switch
  261.  
  262. //==========================================================================================
  263.  
  264.  
  265. switch (east_west_currentState)
  266. {
  267. case EAST_WEST_REDLED:
  268. //when the priod for the current state ends we set the entry conditions for the next state,
  269. //change the current state so that next time through the code for the next state is executed
  270. if (east_west_currentTime - east_west_sequenceLedStartTime >= east_west_sequencePeriods[east_west_currentState]) //time to change states
  271. {
  272. digitalWrite(east_west_sequenceLedPins[east_west_currentState], LOW); //turn off the east_west_yellowLedPin
  273. east_west_currentState = EAST_WEST_GREENLED; //next state to move to
  274. digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //turn on current LED east_west_redLedPin
  275. east_west_sequenceLedStartTime = east_west_currentTime; //start time for next state
  276. east_west_reportState();
  277. }
  278. break; //end of code for this state
  279.  
  280. case EAST_WEST_GREENLED:
  281. if (east_west_currentTime - east_west_sequenceLedStartTime >= east_west_sequencePeriods[east_west_currentState]) //time to change states
  282. {
  283. digitalWrite(east_west_sequenceLedPins[east_west_currentState], LOW); //turn off the east_west_redLedPin
  284. east_west_currentState = EAST_WEST_YELLOWLED; //next state to move to
  285. digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //turn on current LED east_west_greenLedPin
  286. east_west_sequenceLedStartTime = east_west_currentTime; //start time for next state
  287. east_west_reportState();
  288. }
  289. break; //end of code for this state
  290.  
  291. case EAST_WEST_YELLOWLED:
  292. if (east_west_currentTime - east_west_sequenceLedStartTime >= east_west_sequencePeriods[east_west_currentState]) //time to change states
  293. {
  294. digitalWrite(east_west_sequenceLedPins[east_west_currentState], LOW); //turn off the east_west_greenLedPin
  295. east_west_currentState = EAST_WEST_REDLED; //next state to move to
  296. digitalWrite(east_west_sequenceLedPins[east_west_currentState], HIGH); //turn on current LED east_west_yellowLedPin
  297. east_west_sequenceLedStartTime = east_west_currentTime; //start time for next state
  298. east_west_reportState();
  299. }
  300. break; //end of code for this state
  301.  
  302. } //switch
  303. } //loop
  304.  
  305.  
  306.  
  307. void north_south_reportState()
  308. {
  309. /*
  310. *What the F() macro Does
  311. That long string of code tells the compiler to keep a string inside of PROGMEM and not allow it to consume RAM.
  312. Using the F() Macro
  313. Here’s an example of how you would use the F() macro with Serial.print() or Lcd.print().
  314. Serial.println(F(“Hello World”));
  315. Lcd.print(F(“W”));
  316. That’s all there is to it. Simply wrap your string (const character array) with F().
  317.  
  318. Why is the F() Macro Needed?
  319. Remember that the Arduino Uno (and it’s cousins) are based on the ATmega328.
  320. This microcontroller only offers 2,048 bytes of RAM. 2k,
  321. that’s it. Even the Uno’s big brother, the Mega2560, only has 8K of RAM.
  322. */
  323.  
  324.  
  325. Serial.print(F(" Now in state "));
  326. Serial.print(north_south_currentState);//States
  327. Serial.print(" Pin # ");
  328. Serial.print(north_south_sequenceLedPins[north_south_currentState]);//pin numbers
  329. if (north_south_currentState == 0)
  330. {
  331. Serial.print(" north_south_red led");
  332. }
  333. else if (north_south_currentState == 1)
  334. {
  335. Serial.print(" north_south_green led");
  336. }
  337. else
  338. {
  339. Serial.print(" north_south_yellow led");
  340. }
  341. Serial.print(F(" for "));
  342. Serial.print(north_south_sequencePeriods[north_south_currentState]);//time period
  343. Serial.println(F(" milliseconds"));
  344.  
  345. }
  346.  
  347. //==============================================================
  348. void east_west_reportState()
  349. {
  350. /*
  351. *What the F() macro Does
  352. That long string of code tells the compiler to keep a string inside of PROGMEM and not allow it to consume RAM.
  353. Using the F() Macro
  354. Here’s an example of how you would use the F() macro with Serial.print() or Lcd.print().
  355. Serial.println(F(“Hello World”));
  356. Lcd.print(F(“W”));
  357. That’s all there is to it. Simply wrap your string (const character array) with F().
  358.  
  359. Why is the F() Macro Needed?
  360. Remember that the Arduino Uno (and it’s cousins) are based on the ATmega328.
  361. This microcontroller only offers 2,048 bytes of RAM. 2k,
  362. that’s it. Even the Uno’s big brother, the Mega2560, only has 8K of RAM.
  363. */
  364.  
  365.  
  366. Serial.print(F(" Now in state "));
  367. Serial.print(east_west_currentState);//States
  368. Serial.print(" Pin # ");
  369. Serial.print(east_west_sequenceLedPins[east_west_currentState]);//pin numbers
  370. if (east_west_currentState == 0)
  371. {
  372. Serial.print(" east_west_red led");
  373. }
  374. else if (east_west_currentState == 1)
  375. {
  376. Serial.print(" east_west_green led");
  377. }
  378. else
  379. {
  380. Serial.print(" east_west_yellow led");
  381. }
  382. Serial.print(F(" for "));
  383. Serial.print(east_west_sequencePeriods[east_west_currentState]);//time period
  384. Serial.println(F(" milliseconds"));
  385.  
  386. }
  387.  
  388. void north_south_Blink()
  389. {
  390. //let's start with the single blinking LED
  391. if (north_south_currentTime - north_south_blinkLedStartTime >= north_south_blinkLedPeriod) //time to change the single LED state
  392. {
  393. digitalWrite(north_south_blinkLedPin, !digitalRead(north_south_blinkLedPin));
  394. north_south_blinkLedStartTime = north_south_currentTime;
  395. Serial.println(F("\tBLINK"));
  396. } //if
  397. } //Bliknk
  398.  
  399.  
  400. This page was last modified on 2 April 2022, at 15:43.
Advertisement
Add Comment
Please, Sign In to add comment