{"id":514,"date":"2009-05-28T01:39:21","date_gmt":"2009-05-28T06:39:21","guid":{"rendered":"http:\/\/www.tigoe.net\/pcomp\/code\/?p=514"},"modified":"2009-05-31T02:56:23","modified_gmt":"2009-05-31T07:56:23","slug":"tilty-ball-controlling-64-leds-and-a-2-axis-accelerometer","status":"publish","type":"post","link":"https:\/\/www.tigoe.com\/pcomp\/code\/arduinowiring\/514\/","title":{"rendered":"Tilty ball:  Controlling 64 LEDs and a 2-axis accelerometer"},"content":{"rendered":"<p>This example shows how to control 64 LEDs and read the input from two axes of an accelerometer on an Arduino.\u00a0 The Arduino used here is a Duemilanove, but it will work on any of the models out there prior to the Duemilanove as well.\u00a0 This example uses <strong>row-column scanning <\/strong>as a way to control more LEDs than you have output pins.\u00a0 It also uses some of the analog pins as digital I\/O pins.<\/p>\n<h2>Parts you&#8217;ll need<\/h2>\n<ul>\n<li>Arduino Duemilanove or equivalent<\/li>\n<li>2-axis accelerometer. I used the <a href=\"http:\/\/www.adafruit.com\/index.php?main_page=product_info&amp;cPath=35&amp;products_id=163&amp;sessid=870a452f071654f124ae9bbe9f01101e\">ADXL335 breakout board<\/a> from <a href=\"http:\/\/www.adafruit.com\">adafruit.com<\/a>, and only used two axes.<\/li>\n<li>8&#215;8 LED matrix.\u00a0 I used one I bought surplus.\u00a0 See <a href=\"https:\/\/tigoe.com\/pcomp\/code\/category\/arduinowiring\/424\">this post<\/a> for details on figuring out your matrix&#8217;s pins if you don&#8217;t have the data sheet.<\/li>\n<li>Breadboard or prototyping shield.\u00a0 I used the <a href=\"http:\/\/www.adafruit.com\/index.php?main_page=product_info&amp;cPath=17_21&amp;products_id=51&amp;sessid=870a452f071654f124ae9bbe9f01101e\">proto shield and tiny breadboard<\/a> from adafruit.com.<\/li>\n<\/ul>\n<h2><!--more-->The circuit<\/h2>\n<h3>Connecting the matrix<\/h3>\n<p>Since all of the pins of the matrix are going to be connected to digital I\/O pins of the Arduino, it doesn&#8217;t matter what order you connect them in.\u00a0 You can arrange them as you need them in software.\u00a0 So connect them in a way that makes the wiring simple.\u00a0 I left digital pins 0 and 1 free since they&#8217;re the serial communication pins.\u00a0 You&#8217;ll need to use four of the analog inputs as digital I\/O pins to get 16 pins.\u00a0 When used as digital I\/O, the analog pins 0 through 5 are digital I\/O pins 14 through 19, respectively.\u00a0 I used pins 2 through 13, and 16 through 19.\u00a0 Here&#8217;s how it looks:<\/p>\n<table border=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td valign=\"bottom\">\n<p><figure id=\"attachment_515\" aria-describedby=\"caption-attachment-515\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194347.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-515\" style=\"border: 0pt none; margin: 3px;\" title=\"090527194347\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194347-300x199.jpg\" alt=\"090527194347\" width=\"300\" height=\"199\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194347-300x199.jpg 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194347-1024x680.jpg 1024w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194347.jpg 1156w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-515\" class=\"wp-caption-text\">Arduino with prototyping shield, wired to take an 8x8 LED matrix<\/figcaption><\/figure><\/td>\n<td valign=\"bottom\">\n<p><figure id=\"attachment_516\" aria-describedby=\"caption-attachment-516\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/8x8-led-to-arduino.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-516\" style=\"border: 0pt none; margin: 3px;\" title=\"8x8-led-to-arduino\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/8x8-led-to-arduino-300x171.png\" alt=\"The connection of the matrix pins to the Arduino I\/O pins\" width=\"300\" height=\"171\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/8x8-led-to-arduino-300x171.png 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/8x8-led-to-arduino-1024x586.png 1024w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/8x8-led-to-arduino.png 1223w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-516\" class=\"wp-caption-text\">The connection of the matrix pins to the Arduino I\/O pins<\/figcaption><\/figure><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Connecting the Accelerometer<\/h3>\n<p>The accelerometer runs on 3.3V.\u00a0 If you&#8217;re using an Arduino that doesn&#8217;t have a 3.3V output (i.e. any prior to the Diecimila), you&#8217;ll need to add a 3.3V voltage regulator. Otherwise, you can connect directly to the 3.3V output of the Arduino. Connect the accelerometer&#8217;s 3V pin to the Arduino&#8217;s 3.3V output, and the ground to the Arduino&#8217;s ground.\u00a0 Connect the accelerometer&#8217;s X and Y axes to analog inputs 0 and 1, respectively.\u00a0 Make a connection from the 3.3V pin to the Arduino&#8217;s AREF too, so that the analog inputs know that the maximum voltage that the accelerometer will output is 3.3V.\u00a0 Here&#8217;s what the wiring looks like:<\/p>\n<table border=\"0\">\n<tbody>\n<tr>\n<td valign=\"bottom\">\n<p><figure id=\"attachment_520\" aria-describedby=\"caption-attachment-520\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194458.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-520\" style=\"border: 0pt none; margin: 3px;\" title=\"090527194458\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194458-300x199.jpg\" alt=\"090527194458\" width=\"300\" height=\"199\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194458-300x199.jpg 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194458-1024x680.jpg 1024w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194458.jpg 1156w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-520\" class=\"wp-caption-text\">The wiring for the accelerometer added<\/figcaption><\/figure><\/td>\n<td valign=\"bottom\">\n<p><figure id=\"attachment_522\" aria-describedby=\"caption-attachment-522\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/adxl355-accelerometer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-522\" style=\"border: 0pt none; margin-top: 0px; margin-bottom: 0px;\" title=\"adxl355-accelerometer\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/adxl355-accelerometer-300x276.png\" alt=\"adxl355-accelerometer\" width=\"300\" height=\"276\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/adxl355-accelerometer-300x276.png 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/adxl355-accelerometer.png 704w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-522\" class=\"wp-caption-text\">Schematic of the acceleromter connections<\/figcaption><\/figure><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The final assembly looks like this:<\/p>\n<figure id=\"attachment_523\" aria-describedby=\"caption-attachment-523\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194602.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-523\" style=\"border: 0pt none; margin: 3px;\" title=\"090527194602\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194602-300x199.jpg\" alt=\"090527194602\" width=\"300\" height=\"199\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194602-300x199.jpg 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194602-1024x680.jpg 1024w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194602.jpg 1156w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-523\" class=\"wp-caption-text\">The assembled board, with matrix and accelerometer<\/figcaption><\/figure>\n<p style=\"text-align: left;\">Now that the board is assembled, you&#8217;re ready to write some code.<\/p>\n<h2 style=\"text-align: left;\">The Code<\/h2>\n<p style=\"text-align: left;\">You&#8217;ll code this in three parts:\u00a0 First, a quick sketch to test and scale the accelerometer.\u00a0 Then, a second sketch to test the matrix.\u00a0 Finally, a sketch to combine them.<\/p>\n<h3 style=\"text-align: left;\">Test the Accelerometer<\/h3>\n<p style=\"text-align: left;\">You need to know the range that the accelerometer outputs.\u00a0 To do this, enter the following code:<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>setup<\/strong><\/span>() {\r\n  <span style=\"color: #777755;\">\/\/ initialize the serial port:<\/span>\r\n  <span style=\"color: #996600;\">Serial<\/span>.<span style=\"color: #996600;\">begin<\/span>(9600);\r\n}\r\n\r\n<span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>loop<\/strong><\/span>() {\r\n  <span style=\"color: #777755;\">\/\/ print the analog readings, separated by a tab:<\/span>\r\n  <span style=\"color: #996600;\">Serial<\/span>.<span style=\"color: #996600;\">print<\/span>(<span style=\"color: #996600;\">analogRead<\/span>(0));\r\n  <span style=\"color: #996600;\">Serial<\/span>.<span style=\"color: #996600;\">print<\/span>(<span style=\"color: #CC0000;\">\"t\"<\/span>);\r\n  <span style=\"color: #996600;\">Serial<\/span>.<span style=\"color: #996600;\">println<\/span>(<span style=\"color: #996600;\">analogRead<\/span>(1));\r\n}<\/pre>\n<p style=\"text-align: left;\">Next, with the serial monitor open, tilt the board 180 degrees in the X or Y axis.\u00a0 Write\u00a0 down the maximum and minimum values you get.\u00a0 Then repeat for the other axis.\u00a0 Your range will vary, but you should get values ranging from about 380 to 620.\u00a0 Note these values.\u00a0 They will be the maxima and minima for mapping the accelerometer values to pixel movement later.<\/p>\n<h3 style=\"text-align: left;\">Test the Matrix<\/h3>\n<p style=\"text-align: left;\">To control the matrix, first you need to have your I\/O pins arranged sensibly.\u00a0 Since they&#8217;re in a non-numerical order, the easiest way to manage them is to put them into two arrays that you can iterate over. Arrange the pins in the array so that the pin number for row 1 corresponds with array element row[0], row 1 with row[2], and so forth, like so:<\/p>\n<pre>const <span style=\"color: #996600;\">int<\/span> row[8] = {\r\n  9,8,4,17,3,10,11,6  };\r\n\r\nconst <span style=\"color: #996600;\">int<\/span> col[8] = {\r\n  16,12,18,13,5,19,7,2  };<\/pre>\n<p style=\"text-align: left;\">Once you&#8217;ve got them in arrays, you can set up for loops to work with the pins easily. Here&#8217;s a setup method to initialize all the pins, and to take the cathodes high so all the LEDs are off:<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>setup<\/strong><\/span>() {\r\n  <span style=\"color: #777755;\">\/\/ initialize the I\/O pins as outputs:<\/span>\r\n\r\n  <span style=\"color: #777755;\">\/\/ iterate over the pins:<\/span>\r\n  <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisPin = 0; thisPin &lt; 8; thisPin++) {\r\n    <span style=\"color: #777755;\">\/\/ initialize the output pins:<\/span>\r\n    <span style=\"color: #996600;\">pinMode<\/span>(col[thisPin], <span style=\"color: #CC0000;\">OUTPUT<\/span>);\r\n    <span style=\"color: #996600;\">pinMode<\/span>(row[thisPin], <span style=\"color: #CC0000;\">OUTPUT<\/span>);\r\n    <span style=\"color: #777755;\">\/\/ take the col pins (i.e. the cathodes) high to ensure that<\/span>\r\n    <span style=\"color: #777755;\">\/\/ the LEDS are off: <\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisPin], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n  }\r\n}<\/pre>\n<p>In the matrix I used, the rows were the anodes and the columns were the cathodes.\u00a0 It may be the reverse for your matrix.\u00a0 If so, reverse them in the code. Take the cathodes high to ensure that the LEDs are off, whether they are the rows or columns.<\/p>\n<p>In the main loop, you use two nested for loops.\u00a0 The outer loop takes the anodes high one at a time, then the inner loop iterates over the cathodes. To turn a given LED on, take its cathode low; to turn it off, take its cathode high.<\/p>\n<p>Again, if your rows and columns are reversed from this, you need to correct the code.\u00a0 The anodes are always taken high in the outer for loop, and the cathodes in the inner loop.<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>loop<\/strong><\/span>() {\r\n  <span style=\"color: #777755;\">\/\/ iterate over the rows (anodes):<\/span>\r\n  <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisRow = 0; thisRow &lt; 8; thisRow++) {\r\n    <span style=\"color: #777755;\">\/\/ take the row pin (anode) high:<\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(row[thisRow], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n    <span style=\"color: #777755;\">\/\/ iterate over the cols (cathodes):<\/span>\r\n    <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisCol = 0; thisCol &lt; 8; thisCol++) {\r\n\r\n      <span style=\"color: #777755;\">\/\/ when the row is HIGH and the col is LOW,<\/span>\r\n      <span style=\"color: #777755;\">\/\/ the LED where they meet turns on:<\/span>\r\n      <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisCol], <span style=\"color: #CC0000;\">LOW<\/span>);\r\n      <span style=\"color: #777755;\">\/\/ wait a few milliseconds to see it:<\/span>\r\n      <span style=\"color: #996600;\">delay<\/span>(30);\r\n      <span style=\"color: #777755;\">\/\/ turn the pixel off:<\/span>\r\n      <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisCol], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n    }\r\n    <span style=\"color: #777755;\">\/\/ take the row pin low to turn off the whole row:<\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(row[thisRow], <span style=\"color: #CC0000;\">LOW<\/span>);\r\n  }\r\n}<\/pre>\n<p style=\"text-align: left;\">Here&#8217;s a simpler loop method that just turns on all the LEDs:<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>loop<\/strong><\/span>() {\r\n  <span style=\"color: #777755;\">\/\/ iterate over the rows (anodes):<\/span>\r\n  <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisRow = 0; thisRow &lt; 8; thisRow++) {\r\n    <span style=\"color: #777755;\">\/\/ take the row pin (anode) high:<\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(row[thisRow], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n    <span style=\"color: #777755;\">\/\/ iterate over the cols (cathodes):<\/span>\r\n    <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisCol = 0; thisCol &lt; 8; thisCol++) {\r\n      <span style=\"color: #777755;\">\/\/ when the row is HIGH and the col is LOW,<\/span>\r\n      <span style=\"color: #777755;\">\/\/ the LED where they meet turns on:<\/span>\r\n      <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisCol], <span style=\"color: #CC0000;\">LOW<\/span>);\r\n    }\r\n  }\r\n}<\/pre>\n<p style=\"text-align: left;\">Once you know all the LEDs work you can put the whole thing together.<\/p>\n<h3 style=\"text-align: left;\">Combine the Input and Output<\/h3>\n<p style=\"text-align: left;\">The following sketch reads the accelerometer values from the X and Y axes, and maps them to a 0 to 7 range.\u00a0 Then it sets the position of a pixel in a two-dimensional array to the scaled X and Y values.\u00a0 Finally, it reads the matrix to light the LEDs of the matrix.<\/p>\n<p style=\"text-align: left;\">The global variables are a bit more extensive. In addition to the arrays, you now need a two-dimensional array for the pixel array, and two ints for the X and Y position. You also need to constants for the sensor minima and maxima:<\/p>\n<pre><span style=\"color: #777755;\">\/\/ max and min values from the accelerometer, <\/span>\r\n<span style=\"color: #777755;\">\/\/ found by experiment:<\/span>\r\nconst <span style=\"color: #996600;\">int<\/span> sensorMin = 380;\r\nconst <span style=\"color: #996600;\">int<\/span> sensorMax = 620;\r\n\r\n<span style=\"color: #777755;\">\/\/ 2-dimensional array of row pin numbers (for two matrices):<\/span>\r\nconst <span style=\"color: #996600;\">int<\/span> row[8] = {\r\n  9,8,4,17,3,10,11,6  };\r\n\r\n<span style=\"color: #777755;\">\/\/ 2-dimensional array of column pin numbers (for two matrices):<\/span>\r\nconst <span style=\"color: #996600;\">int<\/span> col[8] = {\r\n  16,12,18,13,5,19,7,2  };\r\n\r\n<span style=\"color: #777755;\">\/\/ 2-dimensional array of pixels:<\/span>\r\n<span style=\"color: #996600;\">int<\/span> pixels[8][8];           \r\n\r\n<span style=\"color: #777755;\">\/\/ cursor position:<\/span>\r\n<span style=\"color: #996600;\">int<\/span> x = 5;\r\n<span style=\"color: #996600;\">int<\/span> y = 5;<\/pre>\n<p style=\"text-align: left;\">The setup is basically the same as above, but adds a for loop to initialize the 2D pixel array.\u00a0 The pixel array is holding the values of the cathode for each LED, so you set each element HIGH so they&#8217;re all turned off:<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>setup<\/strong><\/span>() {\r\n  <span style=\"color: #996600;\">Serial<\/span>.<span style=\"color: #996600;\">begin<\/span>(9600);\r\n  <span style=\"color: #777755;\">\/\/ initialize the I\/O pins as outputs:<\/span>\r\n\r\n  <span style=\"color: #777755;\">\/\/ iterate over the pins:<\/span>\r\n  <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisPin = 0; thisPin &lt; 8; thisPin++) {\r\n    <span style=\"color: #777755;\">\/\/ initialize the output pins:<\/span>\r\n    <span style=\"color: #996600;\">pinMode<\/span>(col[thisPin], <span style=\"color: #CC0000;\">OUTPUT<\/span>);\r\n    <span style=\"color: #996600;\">pinMode<\/span>(row[thisPin], <span style=\"color: #CC0000;\">OUTPUT<\/span>);\r\n    <span style=\"color: #777755;\">\/\/ take the col pins (i.e. the cathodes) high to ensure that<\/span>\r\n    <span style=\"color: #777755;\">\/\/ the LEDS are off: <\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisPin], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n  }\r\n\r\n  <span style=\"color: #777755;\">\/\/ initialize the pixel matrix:<\/span>\r\n  <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> x = 0; x &lt; 8; x++) {\r\n    <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> y = 0; y &lt; 8; y++) {\r\n      pixels[x][y] = <span style=\"color: #CC0000;\">HIGH<\/span>;\r\n    }\r\n  }\r\n}<\/pre>\n<p style=\"text-align: left;\">The loop is very simple, to let you know what&#8217;s happening. All the work is done in external methods:<\/p>\n<pre style=\"text-align: left;\"><span style=\"color: #CC6600;\">void<\/span> <span style=\"color: #993300;\"><strong>loop<\/strong><\/span>() {\r\n  <span style=\"color: #777755;\">\/\/ read input:<\/span>\r\n  readSensors();\r\n\r\n  <span style=\"color: #777755;\">\/\/ draw the screen:<\/span>\r\n  refreshScreen();\r\n}<\/pre>\n<p style=\"text-align: left;\">The readSensors() method reads the accelerometer and scales the values to the width and height of the pixel array.\u00a0 First, though, it sets the last pixel position HIGH to turn it off. Once it&#8217;s read the new value, it sets the corresponding array element LOW so that pixel will turn on:<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> readSensors() {\r\n  <span style=\"color: #777755;\">\/\/ turn off the last position:<\/span>\r\n  pixels[x][y] = <span style=\"color: #CC0000;\">HIGH<\/span>;\r\n  <span style=\"color: #777755;\">\/\/ read the sensors for X and Y values:<\/span>\r\n  x = 7 - <span style=\"color: #996600;\">map<\/span>(<span style=\"color: #996600;\">analogRead<\/span>(0), sensorMin, sensorMax, 0, 7);\r\n  y = <span style=\"color: #996600;\">map<\/span>(<span style=\"color: #996600;\">analogRead<\/span>(1), sensorMin, sensorMax, 0, 7);\r\n  pixels[x][y] = <span style=\"color: #CC0000;\">LOW<\/span>;\r\n}<\/pre>\n<p style=\"text-align: left;\">The refreshScreen method does all the work of controlling the pixels.\u00a0 It looks a lot like the nested for loops above.\u00a0 The biggest change is that it gets its value for each cathode from the 2D pixel array:<\/p>\n<pre><span style=\"color: #CC6600;\">void<\/span> refreshScreen() {\r\n  <span style=\"color: #777755;\">\/\/ iterate over the rows (anodes):<\/span>\r\n  <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisRow = 0; thisRow &lt; 8; thisRow++) {\r\n    <span style=\"color: #777755;\">\/\/ take the row pin (anode) high:<\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(row[thisRow], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n    <span style=\"color: #777755;\">\/\/ iterate over the cols (cathodes):<\/span>\r\n    <span style=\"color: #CC6600;\">for<\/span> (<span style=\"color: #996600;\">int<\/span> thisCol = 0; thisCol &lt; 8; thisCol++) {\r\n      <span style=\"color: #777755;\">\/\/ get the state of the current pixel;<\/span>\r\n      <span style=\"color: #996600;\">int<\/span> thisPixel = pixels[thisRow][thisCol];\r\n      <span style=\"color: #777755;\">\/\/ when the row is HIGH and the col is LOW,<\/span>\r\n      <span style=\"color: #777755;\">\/\/ the LED where they meet turns on:<\/span>\r\n      <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisCol], thisPixel);\r\n      <span style=\"color: #777755;\">\/\/ turn the pixel off:<\/span>\r\n      <span style=\"color: #CC6600;\">if<\/span> (thisPixel == <span style=\"color: #CC0000;\">LOW<\/span>) {\r\n        <span style=\"color: #996600;\">digitalWrite<\/span>(col[thisCol], <span style=\"color: #CC0000;\">HIGH<\/span>);\r\n      }\r\n\r\n    }\r\n    <span style=\"color: #777755;\">\/\/ take the row pin low to turn off the whole row:<\/span>\r\n    <span style=\"color: #996600;\">digitalWrite<\/span>(row[thisRow], <span style=\"color: #CC0000;\">LOW<\/span>);\r\n  }\r\n}<\/pre>\n<p style=\"text-align: left;\">This same method can be used for more complex animations; in fact, it&#8217;s the most common way of managing computer animation.\u00a0 You store the image in an offscreen array, then rely on a driver method to read the array and set the appropriate elements.<\/p>\n<p style=\"text-align: left;\">That&#8217;s the whole sketch.\u00a0 When you run it, you should see an initial state like this, when your board is sitting on a level surface:<\/p>\n<p style=\"text-align: center;\">\n<figure id=\"attachment_525\" aria-describedby=\"caption-attachment-525\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/matrix_video-desktop.m4v\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-525\" title=\"090527194620\" src=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194620-300x199.jpg\" alt=\"The finished tilty matrix. Click the image to see a video of it in action.\" width=\"300\" height=\"199\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194620-300x199.jpg 300w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194620-1024x680.jpg 1024w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/090527194620.jpg 1156w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-525\" class=\"wp-caption-text\">The finished tilty matrix. Click the image to see a video of it in action.<\/figcaption><\/figure>\n<p style=\"text-align: left;\">\n<p style=\"text-align: left;\">You can use this same method for controlling other outputs as well. You&#8217;ll need to replace the LEDs with NPN transistors. Put the base of the transistor in place of the LED and connect the load to the transistor the same way you normally would for a high current load. Now you can control a whole lot more physical output.\u00a0 Enjoy!<\/p>\n<p style=\"text-align: left;\">Here&#8217;s the <a href=\"https:\/\/tigoe.com\/pcomp\/code\/wp-content\/uploads\/2009\/05\/matrix_0001.zip\">final sketch for download<\/a>.<\/p>\n<p style=\"text-align: left;\">\n","protected":false},"excerpt":{"rendered":"<p>This example shows how to control 64 LEDs and read the input from two axes of an accelerometer on an Arduino.\u00a0 The Arduino used here is a Duemilanove, but it will work on any of the models out there prior to the Duemilanove as well.\u00a0 This example uses row-column scanning as a way to control &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.tigoe.com\/pcomp\/code\/arduinowiring\/514\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Tilty ball:  Controlling 64 LEDs and a 2-axis accelerometer&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,22,24],"tags":[36,56,64],"class_list":["post-514","post","type-post","status-publish","format-standard","hentry","category-arduinowiring","category-AVR","category-circuits","tag-accelerometer","tag-led-matrix","tag-row-column-scanning"],"_links":{"self":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/comments?post=514"}],"version-history":[{"count":13,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/514\/revisions"}],"predecessor-version":[{"id":567,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/514\/revisions\/567"}],"wp:attachment":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/media?parent=514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/categories?post=514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/tags?post=514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}