**Introduction**

In this review we have a look at the mini 8×8 LED matrix with I2C backpack from adafruit industries. It looked like a small yet versatile display unit for a couple of project ideas, so as part of the evaluation we’ll run through it with you here. As you can see below, it’s quite small with a 20mm square matrix:

The matrix and the controller are seperate which gives you the option of ordering different colours of matrix. Using LED matrices can be a pain, however these units use the Holtek 16K33 controller IC (data sheet) which has an I2C interface – much easier than the usual mess of shift registers and I/O pins:

Furthermore you can change the I2C address using the solder pads on the PCB, giving you four possible options. And as it’s I2C, you can use it with other microcontrollers with a little detective work. Moving forward, we’ll assemble the display then explain how to use it with an Arduino, and show a few demonstrations.

**Assembly**

There really isn’t anything major to do, just solder the matrix to the backpack and some header pins if you need them. adafruit include some however I’m using the 90-degree ones for my own use:

The soldering should take about one minute tops, and then you’re done:

**Using the matrix**

From a hardware perspective you only have four wires – 5V, GND, SDA and SCL. Yes – it’s a 5V part, so all you Raspberry Pi fans will need a level shifter, which you can get from adafruit as well. Anyhow once you’ve got it connected to your Arduino, a couple of libraries are required – the matrix and GFX libraries. Be sure to install them in your *sketchbook/libraries* folder and not the usual location. When saving the library files, call the first folder Adafruit_LEDBackpack and the second Adafruit_GFX as they don’t arrive in that format.

Now for a quick demonstration, it’s simply one from the included library. The display is very bright, so I had to reduce the exposure on the camera which makes the background a little dark – but you get the idea:

A pair of those fitted to a dummy or doll would be quite interesting, or make good eyes for a 21st century “Metal Mickey”. Well that’s quite interesting, so how do you in fact display things on the matrix? I’ve deconstructed a few examples to show you how it’s done.

No matter what, you need to include the libraries, define the matrix object in the sketch and then start it with the matching I2C address – for example:

1 2 3 4 5 6 7 8 9 10 11 12 13 |
// required libraries #include <Wire.h> #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // define matrix object Adafruit_8x8matrix matrix = Adafruit_8x8matrix(); void setup() { // start the matrix at I2C address - default is 0x70 matrix.begin(0x70); // pass in the address } |

To scroll text across the display, modify the following chunk of code:

1 2 3 4 5 6 7 8 9 10 11 12 |
matrix.setRotation(0); matrix.setTextSize(1); matrix.setTextWrap(false); // false means nice scroll, true means each character appears, scrolls off, then repeat matrix.setTextColor(LED_ON); for (int8_t x=0; x>=-96; x--) // 96 is number of characters to display x 8 { matrix.clear(); matrix.setCursor(x,0); matrix.print("Hello, world"); matrix.writeDisplay(); delay(100); } |

First, the *setRotation() *value is 0~3 and determines which way the text scrolls across the screen. This is useful if you mount the matrix in different positions, as you can still keep the text scrolling in a readable manner. Next, *matrix.setTextWrap()* – leave this as *false, * as true displays each character and then just scrolls it in turn – looking rather odd. Now multiply the number of characters you want to display by 8, and replace the number -96 with negative your value and of course “Hello, world”. Finally follow with rest of the code. There’s a quick demonstration of this code in the sketch and video below:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
// required libraries #include <Wire.h> #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // define matrix object Adafruit_8x8matrix matrix = Adafruit_8x8matrix(); void setup() { // start the matrix at I2C address - default is 0x70 matrix.begin(0x70); // pass in the address } void loop() { matrix.setRotation(0); matrix.setTextSize(1); matrix.setTextWrap(false); // false means nice scroll, true means each character appears, scrolls off, then repeat matrix.setTextColor(LED_ON); for (int8_t x=0; x>=-96; x--) // 96 is number of characters to display x 8 { matrix.clear(); matrix.setCursor(x,0); matrix.print("Hello, world"); matrix.writeDisplay(); delay(100); } delay(500); matrix.setRotation(1); matrix.setTextSize(1); matrix.setTextWrap(false); // false means nice scroll, true means each character appears, scrolls off, then repeat matrix.setTextColor(LED_ON); for (int8_t x=0; x>=-96; x--) // 96 is number of characters to display x 8 { matrix.clear(); matrix.setCursor(x,0); matrix.print("Hello, world"); matrix.writeDisplay(); delay(100); } delay(500); matrix.setRotation(2); matrix.setTextSize(1); matrix.setTextColor(LED_ON); for (int8_t x=0; x>=-96; x--) // 96 is number of characters to display x 8 { matrix.clear(); matrix.setCursor(x,0); matrix.print("Hello, world"); matrix.writeDisplay(); delay(100); } delay(500); matrix.setRotation(3); matrix.setTextSize(1); matrix.setTextColor(LED_ON); for (int8_t x=0; x>=-96; x--) // 96 is number of characters to display x 8 { matrix.clear(); matrix.setCursor(x,0); matrix.print("Hello, world"); matrix.writeDisplay(); delay(100); } } |

Now for some graphics. You can define your own images (!) and store them in an array. Each arrays consists of eight bytes, each representing a row of the matrix. You can use binary to help visualise the results, for example:

1 2 3 4 5 6 7 8 9 10 |
static uint8_t PROGMEM crosshatch[] = { B10101010, B01010101, B10101010, B01010101, B10101010, B01010101, B10101010, B01010101 }; |

and then to display that on the matrix, use the following:

1 2 3 4 |
matrix.clear(); // clear the display matrix.drawBitmap(0, 0, crosshatch, 8, 8, LED_ON); // setup the image to display matrix.writeDisplay(); // display the image delay(1000); |

… which resulted with:

To control individual pixels, send one or more of the following:

1 |
matrix.drawPixel(x, y, LED_ON); |

where x and y are the pixel’s coordinates (that fall between zero and seven), followed by:

1 |
matrix.writeDisplay(); |

Here’s a neat example sketch and video of a single pixel “running around the border”:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
// required libraries #include <Wire.h> #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // define matrix object Adafruit_8x8matrix matrix = Adafruit_8x8matrix(); int z; void setup() { // start the matrix at I2C address - default is 0x70 matrix.begin(0x70); // pass in the address } void loop() { matrix.clear(); // clear display for (z=0; z<8; z++) { matrix.drawPixel(z, 0, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(50); matrix.drawPixel(z, 0, LED_OFF); matrix.writeDisplay(); // write the changes we just made to the display } for (z=0; z<8; z++) { matrix.drawPixel(7, z, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(50); matrix.drawPixel(7, z, LED_OFF); matrix.writeDisplay(); // write the changes we just made to the display } for (z=7; z>=0; --z) { matrix.drawPixel(z, 7, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(50); matrix.drawPixel(z, 7, LED_OFF); matrix.writeDisplay(); // write the changes we just made to the display } for (z=7; z>=0; --z) { matrix.drawPixel(0, z, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(50); matrix.drawPixel(0, z, LED_OFF); matrix.writeDisplay(); // write the changes we just made to the display } } |

By this point you should be getting the hang of things now, so we’ll finish up with the last three graphic functions at once. To draw a line between x1, y1 and x2, y2 – use:

1 |
matrix.drawLine(x1 ,y1 , x2, y2, LED_ON); |

To draw a rectangle with corners at x1, y2, x2, y2 – use:

1 |
matrix.drawRect(x1, y1, x2, y2, LED_ON); |

To draw a filled rectangle with corners at x1, y2, x2, y2 – use:

1 |
matrix.fillRect(x1, y1, x2, y2, LED_ON); |

And to draw a circle with axis at x,y and a radius of r pixels – use:

1 |
matrix.drawCircle(x, y, r, LED_ON); |

Now we’ll put those functions into the following sketch and video:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// required libraries #include <Wire.h> #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // define matrix object Adafruit_8x8matrix matrix = Adafruit_8x8matrix(); int y, z; void setup() { // start the matrix at I2C address - default is 0x70 matrix.begin(0x70); // pass in the address } void loop() { // circles for (y=0; y<5; y++) { for (z=0; z<8; z++) { matrix.clear(); matrix.drawCircle(3,3, z, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(100); } } for (y=0; y<=5; y++) { // rectangles matrix.clear(); matrix.drawRect(0, 0, 4, 4, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(250); matrix.clear(); matrix.drawRect(4, 0, 4, 4, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(250); matrix.clear(); matrix.fillRect(4, 4, 7, 7, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(250); matrix.clear(); matrix.fillRect(0, 4, 4, 7, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display delay(250); } } |

If you want to get someone’s attention, you can blink whatever’s on the matrix at various frequencies – and of course turn it off. In the following function, use 0 for off, and 1~3 for different rates:

1 |
matrix.blinkRate(x); |

Finally, you can also adjust the brightness to one of sixteen levels (0~15) using:

1 |
matrix.setBrightness(level); // level: 0~15 |

That’s enough blinkiness for now. Remember the library is just shielding you from the raw I2C commands, so if you want to create your own functions or use a non-Arduino board – examine the library and the data sheet.

**Conclusion**

The backpack makes using the matrix an absolute breeze, and the library saves a lot of time and effort – leaving you to get on with creating your ideas into projects. You can get the matrix from adafruit and their distributors.

Full-sized images available on flickr. And if you made it this far – check out my new book “Arduino Workshop” from No Starch Press.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.

[Note – item purchased without notifying the supplier]