stspringer

latest traffic light working but 1 problem

Jun 12th, 2020
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.21 KB | None | 0 0
  1.  
  2. //John Guarnieri 06/11/2020 Simplified USA Traffic light system just using 5 led's 3 for traffic 2 for Pedestrian crossing.
  3. // I am relativly new to arduino and electronics, just a hobby, I like to learn new things.
  4. //My simplified USA Traffic Light System using 5 led's works as follows:
  5. //Red traffic immediatly to green traffic - green traffic to Yellow traffic - yellow traffic back to red traffic - repeat
  6.  
  7. //this script uses button array - sizeof() - Debounce - millis - machine state. I feel this sketch will be a good learning experience
  8. //for anyone who is interested in Arduino coding and how it works.
  9. //I did not write this code from scratch, I did edit it and added blocks form other google code and Arduino forum
  10.  
  11. //credits
  12. //larryd Arduino forum original code/John Guarnieri edit 05/30/2020
  13. // TrafficLightStateMachinePedSwitch.ino
  14. //hsiboy/MultiButton.ino multi button with debounce https://gist.github.com/hsiboy/f55a0911c7e8553092ea
  15. //revision hsiboy created this gist on Jan 30, 2015.
  16. //I can't find what was changed in the revision
  17.  
  18.  
  19. #define DEBOUNCE 20 // button debouncer, how many ms to debounce, 5+ ms is usually plenty
  20.  
  21. // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
  22. //byte buttons[] = {4, 9, 12, A0}; // the analog 0-5 pins are also known as 14-19
  23.  
  24. //my add or edit
  25. //**************************************************************************************************************
  26. byte buttons[] = {2, 3}; // the analog 0-5 pins are also known as 14-19
  27. //**************************************************************************************************************
  28.  
  29. // This handy macro lets us determine how big the array up above is, by checking the size
  30.  
  31. //original ClΓ©ment Lansmarie says below line is wrong
  32. //it still works in your case because buttons is an array of bytes
  33. //but it wouldn't work as intended with another type.
  34.  
  35.  
  36.  
  37. //If button is an array of integers, then the sizeof () that would be 8
  38. //since each button is 2 bytes. Your original statement only works
  39. //because button is a byte. The second form below is considered safer.
  40.  
  41. //#define NUMBUTTONS sizeof(buttons)
  42.  
  43. //recomended by facebook should be below line ClΓ©ment Lansmarie
  44.  
  45. #define NUMBUTTONS (sizeof(buttons) / sizeof(buttons[0]))
  46.  
  47.  
  48.  
  49.  
  50.  
  51. // we will track if a button is just pressed, just released, or 'currently pressed'
  52. volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
  53.  
  54. //my add or edit
  55. //**************************************************************************************************************
  56. // Traffic Light code
  57. //my add or edit
  58. enum STATES {STARTUP, RED, GREEN, YELLOW, CROSSING, REDdontWalk};
  59. STATES mState = STARTUP;
  60.  
  61.  
  62. //my add or edit
  63. unsigned long redMillis;
  64. unsigned long greenMillis;
  65. unsigned long yellowMillis;
  66. unsigned long REDdontWalkMillis;
  67. unsigned long currentMillis;
  68. unsigned long heartbeatMillis;
  69. unsigned long switchMillis;
  70. unsigned long pedMillis;
  71. unsigned long flashingMillis;
  72.  
  73. const unsigned long switchDelay = 25; //25ms
  74.  
  75. //my add or edit
  76. #define ENABLED true
  77. #define DISABLED false
  78.  
  79.  
  80. //my add or edit
  81. bool walkFlag = DISABLED;
  82. bool pedFlag = DISABLED;
  83. bool REDdontWalkFlag = DISABLED;
  84. bool flashingFlag = DISABLED;
  85.  
  86. //my add or edit
  87. //realistic times 1 minute on red and green 12 seconds on yellow
  88. /*
  89. //Change as needed
  90. #define redInterval 60 * 1000ul //ON time in seconds
  91. #define greenInterval 60 * 1000ul //ON time in seconds
  92. #define yellowInterval 12 * 1000ul //ON time in seconds
  93.  
  94. #define flashingDelay 40 * 1000ul //Time at which the flashing starts
  95. #define pedInterval 50 * 1000ul //Time at which the walk light goes off
  96.  
  97. #define REDdontWalkInterval 3 * 1000ul //wait 3 seconds before the "Don't Walk" comes on
  98. #define flashingInterval 200ul
  99.  
  100. #define minHoldTime 500ul
  101. */
  102.  
  103. //my add or edit
  104. //testing speed times 3 seconds
  105. //my edit alter times for testing speed
  106. #define redInterval 3 * 1000ul //ON time in seconds
  107. #define greenInterval 3 * 1000ul //ON time in seconds
  108. #define yellowInterval 3 * 1000ul //ON time in seconds
  109.  
  110. #define flashingDelay 10 * 1000ul //Time at which the flashing starts this has to be smaller than pedInterval
  111.  
  112. #define pedInterval 20 * 1000ul //Time at which the walk light goes off
  113.  
  114. #define REDdontWalkInterval 3 * 1000ul //wait 3 seconds before the "Don't Walk" comes on
  115. #define flashingInterval 200ul
  116.  
  117. #define minHoldTime 500ul
  118.  
  119. const byte redLED = 5; //+5V----[>|]----[220R]----GND
  120. const byte greenLED = 7;
  121. const byte yellowLED = 6;
  122. const byte walk_green_LED = 9;
  123. //look here study this original code
  124. const byte walk_red_LED = 8;
  125.  
  126. const byte heartbeatLED = 13;
  127. #define LEDon HIGH
  128. #define LEDoff LOW
  129.  
  130.  
  131.  
  132. //original code
  133. //**************************************************************************************************************
  134. void setup() {
  135. byte i;
  136.  
  137. // set up serial port
  138. Serial.begin(9600);
  139. Serial.print("Button checker with ");
  140. Serial.print(NUMBUTTONS, DEC);
  141. Serial.println(" buttons");
  142.  
  143. //my add or edit
  144. //*************************************************************************************************************
  145. pinMode(redLED, OUTPUT);
  146. pinMode(greenLED, OUTPUT);
  147. pinMode(yellowLED, OUTPUT);
  148. pinMode(walk_red_LED, OUTPUT);
  149. pinMode(walk_green_LED, OUTPUT);
  150. pinMode(heartbeatLED, OUTPUT);
  151.  
  152. //pinMode (walkSwitch.pin, INPUT_PULLUP);
  153. //walkSwitch.lastState = digitalRead(walkSwitch.pin);
  154.  
  155. //pinMode (otherSwitch.pin, INPUT_PULLUP);
  156. //otherSwitch.lastState = digitalRead(otherSwitch.pin);
  157.  
  158. //*************************************************************************************************************
  159.  
  160. // pin13 LED
  161. pinMode(13, OUTPUT);
  162.  
  163. // Make input & enable pull-up resistors on switch pins
  164. for (i=0; i < NUMBUTTONS; i++)
  165. { pinMode(buttons[i], INPUT);
  166. digitalWrite(buttons[i], HIGH);
  167. }
  168.  
  169. // I am not clear on how this TCCR2A works not using it for now
  170. //*************************************************************************************************************
  171. // Run timer2 interrupt every 15 ms
  172. //TCCR2A = 0;
  173. //TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
  174.  
  175. //Timer2 Overflow Interrupt Enable
  176. //TIMSK2 |= 1<<TOIE2;
  177.  
  178. } //end void setup
  179.  
  180.  
  181.  
  182. //SIGNAL(TIMER2_OVF_vect) {
  183. // check_switches();
  184. //}
  185.  
  186. //*************************************************************************************************************
  187.  
  188.  
  189. void check_switches()
  190. {
  191.  
  192. //***************************
  193. //Time to check the switches?
  194. if (currentMillis - switchMillis < switchDelay)
  195. {
  196. //it is not time yet
  197. return;
  198. }
  199.  
  200. //restart the TIMER
  201. switchMillis = switchMillis + switchDelay;
  202.  
  203. static byte previousstate[NUMBUTTONS];
  204. static byte currentstate[NUMBUTTONS];
  205. static long lasttime;
  206. byte index;
  207.  
  208. if (millis() < lasttime){ // we wrapped around, lets just try again
  209. lasttime = millis();
  210. }
  211.  
  212. if ((lasttime + DEBOUNCE) > millis()) {
  213. // not enough time has passed to debounce
  214. return;
  215. }
  216. // ok we have waited DEBOUNCE milliseconds, lets reset the timer
  217. lasttime = millis();
  218.  
  219. for (index = 0; index < NUMBUTTONS; index++){
  220. currentstate[index] = digitalRead(buttons[index]); // read the button
  221.  
  222. /*
  223. Serial.print(index, DEC);
  224. Serial.print(": cstate=");
  225. Serial.print(currentstate[index], DEC);
  226. Serial.print(", pstate=");
  227. Serial.print(previousstate[index], DEC);
  228. Serial.print(", press=");
  229. */
  230.  
  231. if (currentstate[index] == previousstate[index]) {
  232. if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
  233. // just pressed
  234. justpressed[index] = 1;
  235. }
  236. else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
  237. // just released
  238. justreleased[index] = 1;
  239. }
  240. pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
  241. }
  242. //Serial.println(pressed[index], DEC);
  243. previousstate[index] = currentstate[index]; // keep a running tally of the buttons
  244. }
  245. } //end void check_switches
  246.  
  247.  
  248. void loop() {
  249. //save current time
  250. //my add
  251. currentMillis = millis();
  252. // to run traffic lights automatically call checkTrafficLight() here in void loop
  253. //********************************
  254. //to help show if there is any blocking code, this LED toggles every 500ms
  255.  
  256. //BEGIN: substitute // Run timer2 interrupt every 15 ms here use millis
  257. if (currentMillis - heartbeatMillis >= 1000)
  258. {
  259. Serial.print("Time = ");
  260. Serial.println(currentMillis / 1000ul);
  261.  
  262. //start this TIMER
  263. heartbeatMillis = currentMillis;
  264.  
  265. digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  266. }
  267. //END: substitute // Run timer2 interrupt every 15 ms here use millis
  268.  
  269. check_switches();
  270.  
  271. checkTrafficLight();
  272.  
  273. for (byte i = 0; i < NUMBUTTONS; i++){
  274.  
  275. if (justpressed[i]) {
  276. justpressed[i] = 0;
  277. Serial.print(i, DEC);
  278. Serial.println(" Just pressed");
  279. // remember, check_switches() will CLEAR the 'just pressed' flag
  280. }
  281. if (justreleased[i]) {
  282. //do work here
  283. //my add or edit
  284. if (buttons[i] == 2) {
  285. // Do the thing for pin 2
  286. // to run traffic lights manually call checkTrafficLight() here
  287. //each button press on button 2 will go thru the traffic lights
  288. //based on millis times
  289. //my add
  290. //call function here if you want manual traffic light sequence using button 2
  291. //checkTrafficLight();
  292. }
  293.  
  294.  
  295.  
  296.  
  297.  
  298. //PROBLEM AREA
  299. if (buttons[i] == 3) {
  300. // Do the thing for pin 3
  301. //my add or edit fix for Pedestrian button firing off if pressed and released "again" during Pedestrian Crossing
  302. if ((currentMillis - REDdontWalkMillis > REDdontWalkInterval) && (pedFlag == DISABLED)) {
  303. REDdontWalkFlag = DISABLED;
  304. walkFlag = ENABLED;
  305. }
  306.  
  307. }
  308. justreleased[i] = 0;
  309. Serial.print(i, DEC);
  310. Serial.println(" Just released");
  311. // remember, check_switches() will CLEAR the 'just pressed' flag
  312. }
  313. if (pressed[i]) {
  314. Serial.print(i, DEC);
  315. Serial.println(" pressed");
  316. // is the button pressed down at this moment
  317. }
  318. }
  319. } //end void loop
  320.  
  321. //my add or edit
  322. //*************************************************************************************************************
  323. void checkTrafficLight()
  324. {
  325. switch (mState)
  326. {
  327. //*****************
  328. case STARTUP:
  329. {
  330. digitalWrite(redLED, LEDon);
  331. digitalWrite(greenLED, LEDoff);
  332. digitalWrite(yellowLED, LEDoff);
  333. digitalWrite(walk_red_LED, LEDon);
  334. digitalWrite(walk_green_LED, LEDoff);
  335.  
  336. //start the TIMER
  337. redMillis = currentMillis;
  338.  
  339. //next State
  340. mState = RED;
  341.  
  342. Serial.print("Red Traffic ON = ");
  343. Serial.println(currentMillis / 1000ul);
  344. }
  345. break;
  346.  
  347. //*****************
  348. case RED:
  349. {
  350. if (currentMillis - redMillis >= redInterval)
  351. {
  352. Serial.print("Red Traffic OFF = ");
  353. Serial.println(currentMillis / 1000ul);
  354.  
  355. digitalWrite(redLED, LEDoff);
  356.  
  357.  
  358. //this is ok here
  359. //begin my edit 05_30_2020 works. Had to set a flag here. This condition "if NOT walkFlag" is here to stop green traffic led from doing a
  360. //short unnecessary milli second blink when the Pedestrian button is pushed
  361. if (!walkFlag == ENABLED)
  362. {
  363. digitalWrite(greenLED, LEDon);
  364. }
  365. //end my edit 05_30_2020
  366.  
  367. //testing end 05/30
  368.  
  369. //start the TIMER
  370. greenMillis = currentMillis;
  371.  
  372. Serial.print("Green Traffic ON = ");
  373. Serial.println(currentMillis / 1000ul);
  374.  
  375. if (walkFlag == ENABLED)
  376. {
  377. digitalWrite(walk_red_LED, LEDoff);
  378. digitalWrite(walk_green_LED, LEDon);
  379.  
  380. //start the TIMER
  381. pedMillis = currentMillis;
  382.  
  383. walkFlag = DISABLED;
  384. pedFlag = ENABLED;
  385.  
  386. Serial.print("Walk Green ON = ");
  387. Serial.println(currentMillis / 1000ul);
  388. }
  389.  
  390. //next State
  391. mState = GREEN;
  392. }
  393. }
  394. break;
  395.  
  396. //*****************
  397. case GREEN:
  398. {
  399.  
  400. if (pedFlag == ENABLED)
  401. {
  402. mState = CROSSING;
  403. }
  404.  
  405. if (REDdontWalkFlag == ENABLED)
  406. {
  407. mState = REDdontWalk;
  408. }
  409.  
  410.  
  411. if (REDdontWalkFlag == DISABLED && pedFlag == DISABLED && currentMillis - greenMillis >= greenInterval)
  412. {
  413. Serial.print("Green Traffic OFF = ");
  414. Serial.println(currentMillis / 1000ul);
  415.  
  416.  
  417. //testing 05/30 ok leave it
  418. digitalWrite(greenLED, LEDoff);
  419.  
  420. digitalWrite(yellowLED, LEDon);
  421.  
  422. //start the TIMER
  423. yellowMillis = currentMillis;
  424. //next State
  425. mState = YELLOW;
  426.  
  427. Serial.print("Yellow Traffic ON = ");
  428. Serial.println(currentMillis / 1000ul);
  429. }
  430.  
  431. }
  432. break;
  433.  
  434. //*****************
  435. case CROSSING:
  436. {
  437. //next State
  438. //look here study this original code
  439. //mState = GREEN;
  440. //my edit turn this mState = GREEN; off
  441. //mState = GREEN;
  442.  
  443.  
  444. //my edit
  445. digitalWrite(redLED, LEDon);
  446. //digitalWrite(walk_red_LED, LEDoff);
  447.  
  448. //testing here this is ok leave it
  449. digitalWrite(greenLED, LEDoff);
  450.  
  451.  
  452.  
  453. //time to toggle LED ?
  454. if (flashingFlag == ENABLED && currentMillis - flashingMillis >= flashingInterval)
  455. {
  456. //start the TIMER
  457. flashingMillis = currentMillis;
  458.  
  459. //toggle LED
  460. //look here study this original code
  461. digitalWrite(walk_green_LED, !digitalRead(walk_green_LED));
  462. }
  463.  
  464. //is it time to start flashing the walk light ?
  465. if (flashingFlag == DISABLED && currentMillis - pedMillis >= flashingDelay)
  466. {
  467. flashingFlag = ENABLED;
  468.  
  469. //start the TIMER
  470. flashingMillis = currentMillis;
  471.  
  472. Serial.print("Walk Green Flashing = ");
  473. Serial.println(currentMillis / 1000ul);
  474. }
  475.  
  476. //has walking time expired ?
  477. if (currentMillis - pedMillis >= pedInterval)
  478. {
  479. pedFlag = DISABLED;
  480. flashingFlag = DISABLED;
  481.  
  482. digitalWrite(walk_green_LED, LEDoff);
  483.  
  484. Serial.print("Walk Green OFF = ");
  485. Serial.println(currentMillis / 1000ul);
  486.  
  487. REDdontWalkFlag = ENABLED;
  488. //start TIMER
  489. REDdontWalkMillis = currentMillis;
  490. //next State
  491. mState = REDdontWalk;
  492. }
  493.  
  494. }
  495. break;
  496.  
  497. //*****************
  498. case YELLOW:
  499. {
  500. if (currentMillis - yellowMillis >= yellowInterval)
  501. {
  502. Serial.print("Yellow Traffic OFF = ");
  503. Serial.println(currentMillis / 1000ul);
  504.  
  505. Serial.print("Red Traffic ON = ");
  506. Serial.println(currentMillis / 1000ul);
  507.  
  508. digitalWrite(yellowLED, LEDoff);
  509.  
  510. digitalWrite(redLED, LEDon);
  511.  
  512. //start the TIMER
  513. redMillis = currentMillis;
  514. //next State
  515. mState = RED;
  516.  
  517. }
  518. }
  519. break;
  520.  
  521. //*****************
  522. //look here study this original code
  523. case REDdontWalk:
  524. {
  525.  
  526. //next State
  527. //look here study this original code
  528. //mState = GREEN;
  529. //my edit turn this mState = GREEN; off
  530. //mState = GREEN;
  531.  
  532.  
  533. digitalWrite(walk_red_LED, LEDon);
  534.  
  535. if (currentMillis - REDdontWalkMillis > REDdontWalkInterval)
  536. {
  537. REDdontWalkFlag = DISABLED;
  538. //look here study this original code
  539. //digitalWrite(walk_red_LED, LEDon);
  540.  
  541. //Just my fussy idea to keep the red traffic red led on for N seconds for cosmetic effect
  542. //instead of shooting directly to greenled after pedestrian green walk led goes out
  543. //and Pedestrian redled comes on
  544. digitalWrite(redLED, LEDon);
  545.  
  546. Serial.print("Walk Red ON = ");
  547. Serial.println(currentMillis / 1000ul);
  548. //my edit
  549. mState = RED;
  550. }
  551. }
  552. break;
  553. } //END of switch(mstate)
  554.  
  555. } //END of checkTrafficLight()
  556.  
  557. //*************************************************************************************************************
Advertisement
Add Comment
Please, Sign In to add comment