
{"id":165,"date":"2017-04-09T17:46:28","date_gmt":"2017-04-09T07:46:28","guid":{"rendered":"http:\/\/bakke.online\/?p=165"},"modified":"2017-04-09T17:46:28","modified_gmt":"2017-04-09T07:46:28","slug":"arduino-traffic-lights-simulator-part-3","status":"publish","type":"post","link":"https:\/\/www.bakke.online\/index.php\/2017\/04\/09\/arduino-traffic-lights-simulator-part-3\/","title":{"rendered":"Arduino traffic lights simulator, part 3"},"content":{"rendered":"<p>In the previous two parts, I have shown how to build a 2-way traffic light and how to write a sketch to control it.<\/p>\n<p>This time we&#8217;ll rewrite the sketch to use state tables.<\/p>\n<p>In microcontroller programming, we are often dealing with a set of well defined states. \u00a0State tables describe what each state means, rules for transitioning between the different states, for what is allowed and what is expected. \u00a0Keeping this in a set of tables helps keep the code simple by avoiding a big, tangled mess of if-else statements. \u00a0This, in turn keeps the code smaller so we can do more with the rather limited memory on the microcontroller.<\/p>\n<p><!--more--><\/p>\n<h3>Program state<\/h3>\n<p>Looking at the traffic lights, each cycle has 6 distinct states:<\/p>\n<table>\n<tbody>\n<tr>\n<th>State<\/th>\n<th>Left side<\/th>\n<th>Right side<\/th>\n<\/tr>\n<tr>\n<td>0<\/td>\n<td>Green<\/td>\n<td>Red<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>Yellow<\/td>\n<td>Red<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>Red<\/td>\n<td>Red<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>Green<\/td>\n<td>Red<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>Yellow<\/td>\n<td>Red<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>Red<\/td>\n<td>Red<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We&#8217;ll start a new sketch but this time we&#8217;ll not define the pin numbers by using #define. \u00a0This time we&#8217;ll declare an array of 6 pin numbers:<\/p>\n<pre><span style=\"color: #33cccc;\">const uint8_t<\/span> pins[6] = { 9, 10, 11, 8, 6, 5 };<\/pre>\n<p>Doing it this way means we can use a loop to process the pins. \u00a0It doesn&#8217;t give the same level of flexibility as setting pins individually, but it is more compact. \u00a0We are also not going to modify any of these values in the code, so we tell the compiler they are constants. This allows the compiler to validate that we are not trying to write to somewhere we shouldn&#8217;t, and to make certain optimisations.<\/p>\n<p>And here comes the state table. \u00a0We declare a two-dimensional array of pin states, describing the table above:<\/p>\n<pre><span style=\"color: #808080;\">\/\/                               Left            Right<\/span>\n<span style=\"color: #808080;\">\/\/                               Red  Yel  Grn   Red   Yel  Grn<\/span>\n<span style=\"color: #33cccc;\">const uint8_t<\/span> lights[6][6] = { { <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span> },  <span style=\"color: #808080;\">\/\/ State 0<\/span>\n                               { <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span> },  <span style=\"color: #808080;\">\/\/ State 1<\/span>\n                               { <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span> },  <span style=\"color: #808080;\">\/\/ State 2<\/span>\n                               { <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span> },  <span style=\"color: #808080;\">\/\/ State 3<\/span>\n                               { <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span> },  <span style=\"color: #808080;\">\/\/ State 4<\/span>\n                               { <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">HIGH<\/span>, <span style=\"color: #33cccc;\">LOW<\/span>, <span style=\"color: #33cccc;\">LOW<\/span> } };<span style=\"color: #808080;\">\/\/ State 5<\/span><\/pre>\n<p>Each row contains the values that should be written to each of the LEDs for that particular state. \u00a0For example, state 1 says that in the left channel red is off, yellow is on, green is off. \u00a0Right channel has red on, yellow and green off. \u00a0The state table is done, but we&#8217;ll need somewhere to track the current state. \u00a0As we&#8217;ll need to track this between each call to loop(), this will be a global variable.<\/p>\n<pre><span style=\"color: #33cccc;\">int<\/span> state = 0;<\/pre>\n<p>Now, let&#8217;s look at the setup() function. \u00a0We have replaced the individual pinMode() and digitalWrite() with a for-loop. \u00a0It still achieves the same result as in the original version.<\/p>\n<pre><span style=\"color: #33cccc;\">void<\/span> <span style=\"color: #808000;\">setup<\/span>() {\n  <span style=\"color: #808080;\">\/\/ Set all 6 pins to output and make sure the LEDs are all off when the sketch starts<\/span>\n  <span style=\"color: #808000;\">for<\/span>( <span style=\"color: #33cccc;\">int<\/span> idx = 0; idx &lt; 6; idx++ )\n  {\n    <span style=\"color: #ff6600;\">pinMode<\/span>( pins[idx], <span style=\"color: #33cccc;\">OUTPUT<\/span> );\n    <span style=\"color: #ff6600;\">digitalWrite<\/span>( pins[idx], <span style=\"color: #33cccc;\">LOW<\/span> );\n  }\n}<\/pre>\n<p>The loop() function is a lot more interesting this time. \u00a0Again we have replaced the individual calls to digitalWrite() with a for-loop. \u00a0The for-loop processes each LED pin in turn, and is using the state number to choose which row in the lights array to read.<\/p>\n<pre><span style=\"color: #33cccc;\">void<\/span> <span style=\"color: #808000;\">loop<\/span>() {\n  <span style=\"color: #808000;\">for<\/span>( <span style=\"color: #33cccc;\">int<\/span> idx = 0; idx &lt; 6; idx++ )\n  {\n   <span style=\"color: #ff6600;\">digitalWrite<\/span>( pins[idx], lights[state][idx] );\n  }<\/pre>\n<p>For each pass through the loop() function, we&#8217;ll increase the state number by one. \u00a0If we reach 6, we&#8217;ll start over again from 0.<\/p>\n<pre>state++;\n<span style=\"color: #808000;\">if<\/span>( state == 6 )\n{\n  state = 0;\n}<\/pre>\n<p>Finally, as we&#8217;re going to fit a push button into the circuit later, we&#8217;ll just do a simple 5 second wait for now.<\/p>\n<pre><span style=\"color: #ff6600;\"> delay<\/span>( 5000 ); <span style=\"color: #808080;\">\/\/ Wait 5 seconds<\/span>\n}<\/pre>\n<p>Compile and upload to the microcontroller and verify that it is working. \u00a0The traffic lights should work as before, just with a fixed 5 second timing.<\/p>\n<p>When compiled for the ATmega328 on the Pro Trinket board, the resulting binary is 1128 bytes, compared to 1076\u00a0bytes for the original version.<\/p>\n<p>As usual, you can grab the whole sketch from here:\u00a0<a href=\"https:\/\/www.bakke.online\/wp-content\/uploads\/2017\/04\/trafficlights_state-1.zip\">trafficlights_state-1.zip<\/a><\/p>\n<p>Next time, how to add a push button&#8230;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous two parts, I have shown how to build a 2-way traffic light and how to write a sketch to control it. This time we&#8217;ll rewrite the sketch to use state tables. In microcontroller programming, we are often dealing with a set of well defined states. \u00a0State tables describe what each state means, &hellip; <a href=\"https:\/\/www.bakke.online\/index.php\/2017\/04\/09\/arduino-traffic-lights-simulator-part-3\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Arduino traffic lights simulator, part 3&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,14,1],"tags":[8,13,15],"class_list":["post-165","post","type-post","status-publish","format-standard","hentry","category-arduino","category-electronics","category-uncategorized","tag-arduino","tag-beginners","tag-electronics"],"_links":{"self":[{"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/posts\/165","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/comments?post=165"}],"version-history":[{"count":0,"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/posts\/165\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/media?parent=165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/categories?post=165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bakke.online\/index.php\/wp-json\/wp\/v2\/tags?post=165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}