{"id":201,"date":"2014-11-17T22:39:10","date_gmt":"2014-11-17T22:39:10","guid":{"rendered":"http:\/\/www.benningtons.net\/?p=201"},"modified":"2015-01-04T02:14:25","modified_gmt":"2015-01-04T02:14:25","slug":"more-8x8-led-matrix","status":"publish","type":"post","link":"https:\/\/www.benningtons.net\/index.php\/more-8x8-led-matrix\/","title":{"rendered":"More 8&#215;8 LED matrix"},"content":{"rendered":"<p>As I mentioned in my previous <a href=\"http:\/\/www.benningtons.net\/index.php\/8x8-led-matrix\/\" title=\"LED matrix post\" target=\"_blank\">LED matrix post<\/a>, there is no need to use 16 Arduino outputs to drive an 8&#215;8 LED matrix when a serial interface and 5 pins could be used. But whilst I&#8217;ve got this basic version wired-up then I thought I&#8217;d just try using bitmaps and scrolling.<br \/>\n<a href=\"http:\/\/www.benningtons.net\/wp-content\/images\/led_array.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.benningtons.net\/wp-content\/images\/led_array.jpg\" alt=\"led_array\" width=\"200\" height=\"200\" class=\"alignnone size-full wp-image-169\" \/><\/a><\/p>\n<p>So this is what I did&#8230;<\/p>\n<p><b>Data definitions:<\/b><br \/>\n<nl><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/*\r\n * 8x8 led array bitmaps\r\n * A simple eye that looks left, right and blinks\r\n *\/\r\n\r\n\/\/ Arduino pin definitions - (ordered to keep wiring tidy)\r\nint col[] = {14,10,4,12,9,5,8,6};    \/\/columns - driven LOW for on\r\nint row[] = {11,7,3,15,2,13,16,17};  \/\/rows - driven HIGH for on\r\n<\/pre>\n<p><nl><\/p>\n<p style=\"padding-left: 30px;\">Although I&#8217;m using the same wiring you may notice that I&#8217;ve switched the row and column fields and reversed the order of the rows. This is simply to ensure the bitmaps in my following code have the same orientation when displayed on the matrix (in the direction that it is facing me, which is from the left of the above circuit).<br \/>\nThis shows that once wired-up the display can be manipulated with code to display in any direction.<br \/>\n<nl><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/\/ bitmaps of images to display\r\nbyte ledBitmap[5][8] = {\r\n  B00101000,              \/\/eye open\r\n  B10111010,\r\n  B01000100,\r\n  B10010010,\r\n  B01000100,\r\n  B00111000,\r\n  B00000000,\r\n  B00000000,\r\n\r\n  B00101000,              \/\/look left\r\n  B10111010,\r\n  B01000100,\r\n  B10100010,\r\n  B01000100,\r\n  B00111000,\r\n  B00000000,\r\n  B00000000,\r\n\r\n  B00101000,              \/\/look right\r\n  B10111010,\r\n  B01000100,\r\n  B10001010,\r\n  B01000100,\r\n  B00111000,\r\n  B00000000,\r\n  B00000000,\r\n\r\n  B00101000,              \/\/eye half open\r\n  B10010010,\r\n  B01101100,\r\n  B11010110,\r\n  B01101100,\r\n  B00010000,\r\n  B00000000,\r\n  B00000000,\r\n\r\n  B00101000,              \/\/eye closed\r\n  B10101010,\r\n  B01111100,\r\n  B11111110,\r\n  B01111100,\r\n  B00000000,\r\n  B00000000,\r\n  B00000000,\r\n};\r\n<\/pre>\n<p><nl><\/p>\n<p style=\"padding-left: 30px;\">This <b>ledBitmap<\/b> array holds five crude images of an eye looking in different directions and in two stages of blinking (half-open and closed). They look better on the matrix than as 1&#8217;s and 0&#8217;s!<br \/>\nWhere my previous example inefficiently used a whole int to hold the on\/off status of each LED in the matrix, this time I&#8217;m being more efficient and using a single bit (1 or 0) per LED.\n<\/p>\n<p><b>Setup function:<\/b><br \/>\n<nl><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid setup()\r\n{\r\n  for (int i=0; i&lt;8; i++)        \/\/set arduino pins to be outputs\r\n  {\r\n    pinMode(row[i], OUTPUT);\r\n    pinMode(col[i], OUTPUT);\r\n  }\r\n}\r\n<\/pre>\n<p style=\"padding-left: 30px;\">Since my earlier post I&#8217;ve discovered that there&#8217;s no need to initialise the LEDs by turning them all off. So the <b>setup<\/b> function is shorter and just needs to set the Arduino pins as outputs.\n<\/p>\n<p><b>My bitmap displaying function &#8211; ledout :<\/b><br \/>\n<nl><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid ledout(int iBitMapNo, int hOffset, int vOffset, int iDuration)\t\t\/\/Display bitmap number - iBitMapNo\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/With a horizontal offset of - hOffset\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/With a vertical offset of - vOffset\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/Keep the bimap displayed for - iDuration\r\n{\r\n  for (int i=0; i&lt;iDuration; i++)        \/\/repeat image a few times to ensure the eye can see it\r\n  {\r\n    for (int j=0; j&lt;8; j++)              \/\/for each row\r\n    {\r\n      if (j+vOffset&gt;=0 &amp;&amp; j+vOffset&lt;8)   \/\/are we within the boundaries of the chosen bitmap\r\n      {\r\n        for (int k=0; k&lt;8; k++)          \/\/set leds in current row according to the bitmap\r\n        {\r\n          digitalWrite(col[k], !bitRead(ledBitmap[iBitMapNo][j+vOffset],k+hOffset));\r\n        }\r\n        digitalWrite(row[j], HIGH);      \/\/display the row, lighting required leds\r\n      }\r\n      delay(2);                          \/\/pause for it to be seen\r\n      digitalWrite(row[j], LOW);         \/\/turn row off again\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p style=\"padding-left: 30px;\">Here I&#8217;ve placed all the tricky image display commands into one function. This helps to keep the calling <b>loop<\/b> function simple and therefore easier to build animations.<br \/>\nThe inner loop (subscript k) checks each bit in a line of the selected bitmap to see if the corresponding LED should be turned on or off. This is repeated for each row of the bitmap in the next loop out (subscript j).<br \/>\nThe outer loop (subscript i) repeats the display to retain the image on the matrix. Remember, only one line is being displayed at a time so using a sleep command won&#8217;t pause the display but, like a raster scan on a TV, repeating the display of all rows will steady the display.<br \/>\n<nl><br \/>\nAlthough not used in this eye example the vertical and horizontal offsets are used to change where the bitmap is displayed on the matrix. Setting both to 1 will display the bitmap one column to the right and one row higher. I&#8217;ll add an example using these in a mo.<\/p>\n<\/p>\n<p><b>Loop function:<\/b><br \/>\n<nl><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid loop()\r\n{\r\n  ledout(0,0,0,30);            \/\/ Open eye centre\r\n  ledout(1,0,0,30);            \/\/ Open eye look left\r\n  ledout(0,0,0,30);            \/\/ Open eye centre\r\n  ledout(2,0,0,30);            \/\/ Open eye look right\r\n  ledout(0,0,0,30);            \/\/ Open eye centre\r\n  ledout(3,0,0,3);             \/\/ half-open\r\n  ledout(4,0,0,6);             \/\/ closed\r\n  ledout(3,0,0,3);             \/\/ half-open\r\n}\r\n<\/pre>\n<p><nl><\/p>\n<p style=\"padding-left: 30px;\">With all the tricky code in <b>ledout<\/b> this loop function is now a fairly straightforward list of which bitmap to display, where to display it (0,0 keeps it central) and how long to keep each bitmap displayed.<br \/>\nAs with all Arduino <b>loop<\/b> functions the sequence is then repeated indefinately.<br \/>\n<nl>\n<\/p>\n<p><b>Pacman example:<\/b><br \/>\n<nl><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/\/ bitmaps of images to display\r\nbyte ledBitmap[3][8] = {\r\n  B00000000,              \/\/pacman with mouth nearly closed\r\n  B00111100,\r\n  B01111110,\r\n  B01111110,\r\n  B01111100,\r\n  B01111110,\r\n  B00111100,\r\n  B00000000,\r\n\r\n  B00000000,              \/\/pacman with mouth half open\r\n  B00111100,\r\n  B01111110,\r\n  B01111000,\r\n  B01110000,\r\n  B01111110,\r\n  B00111100,\r\n  B00000000,\r\n\r\n  B00000000,              \/\/pacman with mouth full open\r\n  B00111100,\r\n  B01111000,\r\n  B01110000,\r\n  B01100000,\r\n  B01111110,\r\n  B00111100,\r\n  B00000000,\r\n\r\n};\r\n\r\nvoid loop()\r\n{\r\n  for (int j=-6; j&lt;9; j++)\r\n  {\r\n    if (j%2)\r\n    {\r\n      for (int i=0; i&lt;3; i++) ledout(i,j,0,3);\r\n    }\r\n    else\r\n    {\r\n      for (int i=2; i&gt;=0; i--) ledout(i,j,0,3);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p><nl><\/p>\n<p style=\"padding-left: 30px;\">Here the the bitmap declarations and <b>loop<\/b> function of the earlier blinking eye example are replaced. Showing how the same <b>ledout<\/b> function can be used to display a pacman character that opens and closes it&#8217;s moouth as it moves left to right across the matrix.<br \/>\nThe outer loop (subscript j) sets the horizontal offset from -6 (off the left side of the matrix) to 9 (off the right side of the matrix). The inner loops (subscript i) alternate between animating an opening mouth or closing mouth as the bitmap is moved right.<br \/>\n<nl>\n<\/p>\n<p><nl><br \/>\nHaving used <b>ledout<\/b> to scroll bitmaps of the alphabet in all directions, including diagonally if vertical and horizontal offsets are changed together, I believe I&#8217;ve done all that I can with this particular circuit.<br \/>\nNext time I use an LED matrix I&#8217;ll use a serial interface and far fewer wires. Possibly with several matrices in sequence?<br \/>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As I mentioned in my previous LED matrix post, there is no need to use 16 Arduino outputs to drive an 8&#215;8 LED matrix when a serial interface and 5 pins could be used. But whilst I&#8217;ve got this basic version wired-up then I thought I&#8217;d just try using bitmaps and scrolling. So this is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[20],"tags":[19,23],"_links":{"self":[{"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/posts\/201"}],"collection":[{"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":4,"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/posts\/201\/revisions"}],"predecessor-version":[{"id":205,"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/posts\/201\/revisions\/205"}],"wp:attachment":[{"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/media?parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/categories?post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.benningtons.net\/index.php\/wp-json\/wp\/v2\/tags?post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}