Beginning of January I saw a video demonstrating a clock which also plays Game of Life during displaying the clock. This so called Clock of Life uses the Adafruit 16×32 LED matrix and a Arduino Uno microcontroller board. I never came across this LED matrix before but it seems like a nice and popular display to tinkle around with, so off course it was only days later that I owned my own copy of it. As far as the clock goes, I’d very much like to achieve using it as a clock too, but the Game of Life option I’d like to skip, instead I want it to be wireless connected to the internet so that NTP servers can help me keeping the time more or less correct and thrust worthy over longer periods of time, maybe even years. With this wireless connection of course come a lot more possibilities, like setting a alarm clock to wake you up by using your smart phone, set background images and let the user configure the clock remotely. Well off course there is lots of more features I could add, but let’s not start to think to wide before we can even get it working.
For the wireless connection I opted for using the Adafruit C3300 Wifi adapter. After receiving both this unit and the 16×32 LED matrix I noticed that combining both on a Arduino Uno was going to be pretty hard on pin usage. Furthermore I was also not very sure how processor intensive everything combined was going to be, and keeping in mind I might want to add even more features I opted for a more speedier and advanced solution: the Arduino Due. It’s a 84MHz processor with a lot more in- and outputs. First thing I did back in January was making sure NTP server requests indeed do work using the C3300 on Arduino Due as a standalone solution. Next: make another standalone version where I test the LED matrix, but it was then that I noticed the Adafruit 16×32 LED matrix is currently not supported for Arduino Due. Nooo!
After some googling I found out the display does take quite some processing power to display full colors. Some of the code has been really optimized for using the Arduino Uno/MEGA internal functionality. So it was more or less at this time that I started to notice this project was going to take a lot more time since I’d be writing the display driver myself. The Adafruit tutorial tells you some of the details of how the boards works, and if you read it very carefully you’ll notice it’s not so very difficult to do some basic stuff like lighting some LED in either a red, green, blue or white color, or not light it at all. However, for mixing colors and dimming the display more advanced programming is needed. But first something about the display.
Without getting to much into the details on how the display works electrically here are the available pins we should take care of:
A, B, C => row address select pins
R1, B1, G1 => red, green, blue led on/off pin of a pixel of an upper row
R2, B2, G2 => red, green, blue led on/off pin of a pixel of an lower row
CLK => clock pin
OE => output enable pin
LAT => data latch pin
For the display to work you’ll have to send data at a constant rate as the display itself does not have any memory. This implies a lot of other stuff which I’ll get into more detail later. The A, B, C row address pins (3 pins = 3 bits) allow us to select 8 different addresses. For each address not one but two rows are being selected. So setting the bits for address 000 does not only select row 1, it also select another row being it the 9th. The 9th and not the second, because it allows to have less scan rate. For each row we have 32 pixels, so with 2 rows selected each time we set an address we now have 64 pixels available to manipulate (where each pixel has 3 LEDs, for red, green and blue color). Setting the pixel color however happens in a serial way, first one has to set a appropriate signal on the R, G, B pins, but because we have 2 rows selected at the same time we also have these R, G, B pins twofold. R1, B1, G1 for pixels in the upper region, and R2, G2, B2 for pixels in the lower region. Next the CLK (clock pin), LAT (data latch pin) and OE (enable pin) should be used to send the RGB LED’s On/Off state for each of the 32 pixels per line in a serial way.
While this might not seem to complicated to understand, there is more than meets the eye. For drawing in either red, green, blue or white colors it’s as sample as setting only the correct bits at the RGB pins, though when one wants to set a yellow or purple or any other color more complex methods will be needed because we have only 3 bits per drawing cycle to our disposal. We will have to fool our user by setting a pixel first red, than blue, than red again, than back to blue, … nnd this very quickly so that for the user the different colors mix up into something that might look like purple. So let’s say with 3 bits we can have 8 colors, 2 drawing cycles would make 2 times 2 bits resulting in 6 bit color (= 64 colors), and 3 cycles would result in 9 bit color which represents 512 colors.
But it gets more complicated. What if we want to dim our display? We not only need to mix for the correct color, we also need more drawing cycles for PWM dimming the display (if the goal is to implement it). So Let’s say we mix to get to the correct color in 3 drawing cycles, we’ll probable need another 2-3 drawing cycles where all LEDs per pixel or not illuminating to get to the a 50% duty cycle. This however is a layman implementation because not all colors are evenly bright. Red for example requires only one LED, while white requires all LEDs to be illuminating and thus the white color will always be a lot brighter the full red. For this and other technical difficulties I did not yet think of I still need more time to work it out, for now I can only show you some basic code where the Arduino Due is used to show 3 bit color on the Adafruit 16×32 LED matrix: