Advertisement
stspringer

Arduino sketch button array and sizeof()

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