The MAX7219 LED display controller – real or fake?
Introduction
If you’re experimenting with various Arduino or other projects and working with LED matrices or lots of LEDs – you may have come across the Maxim MAX7219 “Serially Interfaced, 8-Digit, LED Display Driver” IC. It’s a great part that can drive an 8 x 8 LED matrix or eight digits of seven-segment LED displays very easily. However over the last few years the price has shot up considerably. Supply and demand doing their thing – and for a while there was also the Austria Microsystems AS1107 drop-in replacement, which could be had for a few dollars less. But no more.
So where does the budget-minded person go from here? Charlieplexing? Lots of shift registers? Or dig a little deeper to find some cheaper units. With a MAX7219 heading north of US$10 in single units, they may turn to ebay or other grey-market suppliers in the Far East. Everyone likes to save money – and who can blame them? However with the proliferation of counterfeiting, “third shift” operations and other shifty practices – is buying those cheaper examples worth it?
A few people have been asking me of late, and there’s only one way to find out … so over the last month I ordered eight random “MAX7219s” from different suppliers on ebay and will compare them to the real thing using somewhat unscientific methods, then see how they work. The funny thing was that after five weeks only six of the eight arrived – so there’s risk number one: if it doesn’t come from a reputable supplier, it might not come at all. Funny stuff. Anyhow, let’s get started by looking at the differences between the real MAX7219 and the others.
Pricing differences
The easiest hint is the price. The non-originals are always cheaper. And if you wonder how much the real ones are in bulk, the quickest indicator is to check the Maxim website and that of a few larger distributors For example the Maxim “sticker price” for 1000 units is US$4.18 each:
How much at Digikey? Lots of 500 for US$4.67 each:
And you wouldn’t buy just one from element14 at this price:
However in fairness to element14 they will price match if you’re buying in volume. So if you can get a “MAX7219″ delivered for US$1.50 – there’s something wrong. Moving on, let’s examine some of those cheap ones in more detail.
Visual differences
If you’ve never seen a real MAX7219 – here it is, top and bottom:
And here’s our rogue’s gallery of test subjects:
In a few seconds the differences should be blindingly obvious – look at the positioning of the printed bar across the part, the printing of the logo, and the general quality and positioning of the printing. Next, those circles embedded in the top of the body at both ends of the part, and the semi-circle at the top end. And if you turn them over, there’s nothing on the bottom. Furthermore, there isn’t a divot indicating pin 1 on the fakes, as shown on the real part:
Oh – did you notice the legs on the real one? Look closely again at the image above, then consider the legs on the others below:
Finally, the non-originals are shorter. The Maxim width can fall between 28.96 and 32.13 mm – with our original test MAX7219 being 32 mm:
and all the test subjects are narrower, around 29.7 mm:
Fascinating. Finally, I found the quality of the metal used for the legs to be worse than the original, they were easier to bend and had trouble going into an IC socket. You can find all the physical dimensions and other notes in the data sheet available from the Maxim website. Finally, this packaging made me laugh – knock-offs in knock-off tubes? (Maxim purchased Dallas Semiconductor a while ago)
Weight difference
Considering that they’re shorter, they must weigh less. In the following video I put the original on the scales, tare it to zero then place each test subject – you can see the difference in weigh. The scales are out a bit however the differences are still obvious:
However over time the manufacturers may go to the effort of making copies that match the weight, size and printing – so future copies may be much better. However you can still fall back to the price to determine a copy.
Do they actually work?
After all that researching and measuring – did they work? One of the subjects came with a small LED matrix breakout board kit:
… so I used that with a simple Arduino sketch that turned on each matrix LED one at a time, then went through the PWM levels – then left them all on at maximum brightness.
#include "LedControl.h" LedControl lc=LedControl(12,11,10,1); // data, clock, load, 1 MAX7219
void setup()
{
lc.shutdown(0,false);
lc.setIntensity(0,15);
lc.clearDisplay(0);
}
void single() {
for(int row=0;row<8;row++) {
for(int col=0;col<8;col++) {
delay(25);
lc.setLed(0,row,col,true);
delay(25);
for(int i=0;i
void loop()
{
single();
for (int n=0; n<5; n++)
{
for (int z=0; z<16; z++)
{
lc.setIntensity(0,z);
delay(100);
}
for (int z=15; z>-1; --z)
{
lc.setIntensity(0,z);
delay(100);
}
}
lc.setIntensity(0,15);
do { } while(1);
}
Here’s the real MAX7219 running through the test:
And test subjects one through to six running it as well:
And from a reader request, some current measurements. First the current used by the entire matrix module at full PWM brightness, then with LEDs off, then the MAX7219 in shutdown mode:
Well that was disheartening. I was hoping and preparing for some blue smoke, dodgy displays or other faults. However the little buggers all worked, didn’t overheat or play up at all.
Conclusion
Six random samples from ebay – and they all worked. However your experience may vary wildly. Does this tell us that copies are OK to use? From my own personal opinion – you do what you have to do with respect to your own work and that for others. In other words – if you’re making something for someone, whether it be a gift or a commercial product, or something you will rely on – use the real thing. You can’t risk a fault in those situations. If you’re just experimenting, not in a hurry, or just don’t have the money – try the cheap option. But be prepared for the worst – and know you’re supporting an industry that ethically shouldn’t exist. And at the end – to be sure you’re getting a real one – choose from a Maxim authorised source.
I’m sure everyone will have an opinion on this, so let us know about it in the moderated comments section below. 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.
Project: Clock Four – Scrolling text clock
Introduction
Time for another instalment in my highly-irregular series of irregular clock projects. In this we have “Clock Four” – a scrolling text clock. After examining some Freetronics Dot Matrix Displays in the stock, it occurred to me that it would be neat to display the time as it was spoken (or close to it) – and thus this the clock was born. It is a quick project – we give you enough to get going with the hardware and sketch, and then you can take it further to suit your needs.
Hardware
You’ll need three major items – An Arduino Uno-compatible board, a real-time clock circuit or module using either a DS1307 or DS3232 IC, and a Freetronics DMD. You might want an external power supply, but we’ll get to that later on.
The first stage is to fit your real-time clock. If you are unfamiliar with the operation of real-time clock circuits, check out the last section of this tutorial. You can build a RTC circuit onto a protoshield or if you have a Freetronics Eleven, it can all fit in the prototyping space as such:
If you have an RTC module, it will also fit in the same space, then you simply run some wires to the 5V, GND, A4 (for SDA) and A5 (for SCL):
By now I hope you’re thinking “how do you set the time?”. There’s two answers to that question. If you’re using the DS3232 just set it in the sketch (see below) as the accuracy is very good, you only need to upload the sketch with the new time twice a year to cover daylight savings (unless you live in Queensland). Otherwise add a simple user-interface – a couple of buttons could do it, just as we did with Clock Two. Finally you just need to put the hardware on the back of the DMD. There’s plenty of scope to meet your own needs, a simple solution might be to align the control board so you can access the USB socket with ease – and then stick it down with some Sugru:
With regards to powering the clock – you can run ONE DMD from the Arduino, and it runs at a good brightness for indoor use. If you want the DMD to run at full, retina-burning brightness you need to use a separate 5 V 4 A power supply. If you’re using two DMDs – that goes to 8 A, and so on. Simply connect the external power to one DMD’s terminals (connect the second or more DMDs to these terminals):

The Arduino Sketch
You can download the sketch from here. It was written only for Arduino v1.0.1. The sketch has the usual functions to set and retrieve the time from DS1307/3232 real-time clock ICs, and as usual with all our clocks you can enter the time information into the variables in void setup(), then uncomment setDateDs1307(), upload the sketch, re-comment setDateDs1307, then upload the sketch once more. Repeat that process to re-set the time if you didn’t add any hardware-based user interface.
Once the time is retrieved in void loop(), it is passed to the function createTextTime(). This function creates the text string to display by starting with “It’s “, and then determines which words to follow depending on the current time. Finally the function drawText() converts the string holding the text to display into a character variable which can be passed to the DMD.
And here it is in action:
Conclusion
This was a quick project, however I hope you found it either entertaining or useful – and another random type of clock that’s easy to reproduce or modify yourself. We’re already working on another one which is completely different, so stay tuned.
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.
Tutorial: Arduino and the MSGEQ7 Spectrum Analyzer
This is a tutorial on using the MSGEQ7 Spectrum Analyser with Arduino, and chapter forty-eight of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
Updated 30/01/2013
In this article we’re going to explain how to make simple spectrum analysers with an Arduino-style board. (Analyser? Analyzer? Take your pick).
First of all, what is a spectrum analyser? Good question. Do you remember what this is?
It’s a mixed graphic equaliser/spectrum analyser deck for a hi-fi system. The display in the middle is the spectrum analyser, and roughly-speaking it shows the strength of different frequencies in the music being listened to – and looked pretty awesome doing it. We can recreate displays similar to this for entertainment and also as a base for creative lighting effects. By working through this tutorial you’ll have the base knowledge to recreate these yourself.
We’ll be using the MSGEQ7 “seven band graphic equaliser IC” from Mixed Signal Integration. Here’s the MSGEQ7 data sheet (.pdf). This little IC can accept a single audio source, analyse seven frequency bands of the audio, and output a DC representation of each frequency band. This isn’t super-accurate or calibrated in any way, but it works. You can get the IC separately, for example:
and then build your own circuit around it… or like most things in the Arduino world – get a shield. In this case, a derivative of the original Bliptronics shield by Sparkfun. It’s designed to pass through stereo audio via 3.5mm audio sockets and contains two MSGEQ7s, so we can do a stereo analyser:
As usual Sparkfun have saved a few cents by not including the stackable header sockets, so you’ll need to buy and solder those in yourself. There is also space for three header pins for direct audio input (left, right and common), which are useful – so if you can add those as well.
So now you have a shield that’s ready for use. Before moving forward let’s examine how the MSGEQ7 works for us. As mentioned earlier, it analyses seven frequency bands. These are illustrated in the following graph from the data sheet:
It will return the strengths of the audio at seven points – 63 Hz, 160 Hz, 400 Hz, 1 kHz, 2.5 kHz, 6.25 kHz and 16 kHz – and as you can see there is some overlap between the bands. The strength is returned as a DC voltage – which we can then simply measure with the Arduino’s analogue input and create a display of some sort. At this point audio purists, Sheldonites and RF people might get a little cranky, so once again – this is more for visual indication than any sort of calibration device.
However as an 8-pin IC a different approach is required to get the different levels. The IC will sequentially give out the levels for each band on pin 3- e.g. 63 Hz then 160 Hz then 400 Hz then 1 kHz then 2.5 kHz then 6.25 kHz then 16 kHz then back to 63 Hz and so on. To start this sequence we first reset the IC by pulsing the RESET pin HIGH then low. This tells the IC to start at the first band. Next, we set the STROBE pin to LOW, take the DC reading from pin 3 with analogue input, store the value in a variable (an array), then set the STROBE pin HIGH. We repeat the strobe-measure sequence six more times to get the rest of the data, then RESET the IC and start all over again. For the visual learners consider the diagram below from the data sheet:
To demonstrate this process, consider the function
readMSGEQ7()
in the following example sketch (download):
// Example 48.1 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 // MSGEQ7 spectrum analyser shield - basic demonstration
int strobe = 4; // strobe pins on digital 4 int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays int right[7];
int band;
void setup()
{
Serial.begin(115200);
pinMode(res, OUTPUT); // reset
pinMode(strobe, OUTPUT); // strobe
digitalWrite(res,LOW); // reset low
digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
digitalWrite(res, HIGH);
digitalWrite(res, LOW);
for(band=0; band <7; band++)
{
digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band
delayMicroseconds(30); //
left[band] = analogRead(0); // store left band reading
right[band] = analogRead(1); // ... and the right
digitalWrite(strobe,HIGH);
}
}
void loop()
{
readMSGEQ7();
// display values of left channel on serial monitor
for (band = 0; band < 7; band++)
{
Serial.print(left[band]);
Serial.print(" ");
}
Serial.println();
// display values of right channel on serial monitor
for (band = 0; band < 7; band++)
{
Serial.print(right[band]);
Serial.print(" ");
}
Serial.println();
}
If you follow through the sketch, you can see that it reads both left- and right-channel values from the two MSGEQ7s on the shield, then stores each value in the arrays left[] and right[]. These values are then sent to the serial monitor for display – for example:
If you have a function generator, connect the output to one of the channels and GND – then adjust the frequency and amplitude to see how the values change. The following video clip is a short demonstration of this – we set the generator to 1 kHz and adjust the amplitude of the signal. To make things easier to read we only measure and display the left channel:
Keep an eye on the fourth column of data – this is the analogRead() value returned by the Arduino when reading the 1khz frequency band. You can also see the affect on the other bands around 1 kHz as we increase and decrease the frequency. However that wasn’t really visually appealing – so now we’ll create a small and large graphical version.
First we’ll use an inexpensive LCD, the I2C model from akafugu reviewed previously. To save repeating myself, also review how to create custom LCD characters from here.
With the LCD with have two rows of sixteen characters. The plan is to use the top row for the levels, the left-channel’s on … the left, and the right on the right. Each character will be a little bar graph for the level. The bottom row can be for a label. We don’t have too many pixels to work with, but it’s a compact example:
We have eight rows for each character, and the results from an analogueRead() fall between 0 and 1023. So that’s 1024 possible values spread over eight sections. Thus each row of pixels in each character will represent 128 “units of analogue read” or around 0.63 V if the Arduino is running from true 5 V (remember your AREF notes?). The sketch will again read the values from the MSGEQ7, feed them into two arrays – then display the required character in each band space on the LCD.
Here’s the resulting sketch (download):
// Example 48.2 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 // MSGEQ7 spectrum analyser shield and I2C LCD from akafugu
// for akafugu I2C LCD #include #include "TWILiquidCrystal.h" LiquidCrystal lcd(50);
// create custom characters for LCD
byte level0[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
byte level1[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte level2[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
byte level3[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
byte level4[8] = { 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level5[8] = { 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level6[8] = { 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level7[8] = { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
int strobe = 4; // strobe pins on digital 4 int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays int right[7];
int band;
void setup()
{
Serial.begin(9600);
// setup LCD and custom characters
lcd.begin(16, 2);
lcd.setContrast(24);
lcd.clear();
lcd.createChar(0,level0); lcd.createChar(1,level1); lcd.createChar(2,level2); lcd.createChar(3,level3); lcd.createChar(4,level4); lcd.createChar(5,level5); lcd.createChar(6,level6); lcd.createChar(7,level7);
lcd.setCursor(0,1);
lcd.print("Left");
lcd.setCursor(11,1);
lcd.print("Right");
pinMode(res, OUTPUT); // reset pinMode(strobe, OUTPUT); // strobe digitalWrite(res,LOW); // reset low digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield }
void readMSGEQ7()
// Function to read 7 band equalizers
{
digitalWrite(res, HIGH);
digitalWrite(res, LOW);
for( band = 0; band < 7; band++ )
{
digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band
delayMicroseconds(30); //
left[band] = analogRead(0); // store left band reading
right[band] = analogRead(1); // ... and the right
digitalWrite(strobe,HIGH);
}
}
void loop()
{
readMSGEQ7();
// display values of left channel on LCD
for( band = 0; band < 7; band++ )
{
lcd.setCursor(band,0);
if (left[band]>=895) { lcd.write(7); } else
if (left[band]>=767) { lcd.write(6); } else
if (left[band]>=639) { lcd.write(5); } else
if (left[band]>=511) { lcd.write(4); } else
if (left[band]>=383) { lcd.write(3); } else
if (left[band]>=255) { lcd.write(2); } else
if (left[band]>=127) { lcd.write(1); } else
if (left[band]>=0) { lcd.write(0); }
}
// display values of right channel on LCD
for( band = 0; band < 7; band++ )
{
lcd.setCursor(band+9,0);
if (right[band]>=895) { lcd.write(7); } else
if (right[band]>=767) { lcd.write(6); } else
if (right[band]>=639) { lcd.write(5); } else
if (right[band]>=511) { lcd.write(4); } else
if (right[band]>=383) { lcd.write(3); } else
if (right[band]>=255) { lcd.write(2); } else
if (right[band]>=127) { lcd.write(1); } else
if (right[band]>=0) { lcd.write(0); }
}
}
If you’ve been reading through my tutorials there isn’t anything new to worry about. And now for the demo, with sound -
That would look great on the side of a Walkman, however it’s a bit small. Let’s scale it up by using a Freetronics Dot Matrix Display - you may recall these from Clock One. For some background knowledge check the review here. Don’t forget to use a suitable power supply for the DMD – 5 V at 4 A will do nicely. The DMD contains 16 rows of 32 LEDs. This gives us twice the “resolution” to display each band level if desired. The display style is subjective, so for this example we’ll use a single column of LEDs for each frequency band, with a blank column between each one.
We use a lot of line-drawing statements to display the levels, and clear the DMD after each display. With this and the previous sketches, there could be room for efficiency – however I write these with the beginner in mind. Here’s the sketch (download):
// Example 48.3 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 // MSGEQ7 spectrum analyser shield with a Freetronics DMD
// for DMD #include // for DMD #include // SPI.h must be included as DMD is written by SPI (the IDE complains otherwise) #include #include "SystemFont5x7.h" // keep next two lines if you want to add some text #include "Arial_black_16.h" DMD dmd(1, 1); // creates instance of DMD to refer to in sketch
void ScanDMD() // necessary interrupt handler for refresh scanning of DMD
{
dmd.scanDisplayBySPI();
}
int strobe = 4; // strobe pins on digital 4 int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays int right[7];
int band;
void setup()
{
// for DMD
//initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
Timer1.initialize( 5000 ); //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
Timer1.attachInterrupt( ScanDMD ); //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
dmd.clearScreen( true ); //true is normal (all pixels off), false is negative (all pixels on)
// for MSGEQ7
pinMode(res, OUTPUT); // reset
pinMode(strobe, OUTPUT); // strobe
digitalWrite(res,LOW); // reset low
digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
digitalWrite(res, HIGH);
digitalWrite(res, LOW);
for( band = 0; band < 7; band++ )
{
digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band
delayMicroseconds(30); //
left[band] = analogRead(0); // store left band reading
right[band] = analogRead(1); // ... and the right
digitalWrite(strobe,HIGH);
}
}
void loop()
{
int xpos;
readMSGEQ7();
dmd.clearScreen( true );
// display values of left channel on DMD
for( band = 0; band < 7; band++ )
{
xpos = (band*2)+1;
if (left[band]>=895) { dmd.drawLine( xpos, 15, xpos, 1, GRAPHICS_NORMAL ); } else
if (left[band]>=767) { dmd.drawLine( xpos, 15, xpos, 3, GRAPHICS_NORMAL ); } else
if (left[band]>=639) { dmd.drawLine( xpos, 15, xpos, 5, GRAPHICS_NORMAL ); } else
if (left[band]>=511) { dmd.drawLine( xpos, 15, xpos, 7, GRAPHICS_NORMAL ); } else
if (left[band]>=383) { dmd.drawLine( xpos, 15, xpos, 9, GRAPHICS_NORMAL ); } else
if (left[band]>=255) { dmd.drawLine( xpos, 15, xpos, 11, GRAPHICS_NORMAL ); } else
if (left[band]>=127) { dmd.drawLine( xpos, 15, xpos, 13, GRAPHICS_NORMAL ); } else
if (left[band]>=0) { dmd.drawLine( xpos, 15, xpos, 15, GRAPHICS_NORMAL ); }
}
// display values of right channel on DMD
for( band = 0; band < 7; band++ )
{
xpos = (band*2)+18;
if (right[band]>=895) { dmd.drawLine( xpos, 15, xpos, 1, GRAPHICS_NORMAL ); } else
if (right[band]>=767) { dmd.drawLine( xpos, 15, xpos, 3, GRAPHICS_NORMAL ); } else
if (right[band]>=639) { dmd.drawLine( xpos, 15, xpos, 5, GRAPHICS_NORMAL ); } else
if (right[band]>=511) { dmd.drawLine( xpos, 15, xpos, 7, GRAPHICS_NORMAL ); } else
if (right[band]>=383) { dmd.drawLine( xpos, 15, xpos, 9, GRAPHICS_NORMAL ); } else
if (right[band]>=255) { dmd.drawLine( xpos, 15, xpos, 11, GRAPHICS_NORMAL ); } else
if (right[band]>=127) { dmd.drawLine( xpos, 15, xpos, 13, GRAPHICS_NORMAL ); } else
if (right[band]>=0) { dmd.drawLine( xpos, 15, xpos, 15, GRAPHICS_NORMAL ); }
}
}
… and here it is in action:
Conclusion
At this point you have the knowledge to use the MSGEQ7 ICs to create some interesting spectrum analysers for entertainment and visual appeal – now you just choose the type of display enjoy the results.
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, or join our 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.
April 2012 Competition Results
April is well and truly over so time to announce the results of our April 2012 Competition!
The winner of the First Prize is Michael F from Germany who will receive a new Freetronics DMD – Dot Matrix Display as reviewed recently and used in Clock One:
The DMD consists of 16 rows of 32 LEDs that can run directly from an Arduino-compatible board, or at a much higher brightness using an external power supply. It is simple to program for yet a load of fun to use. Specifications include:
- 32 x 16 high brightness Red LEDs (512 LEDs total) on a 10mm pitch
- 5V operation
- Viewable over 12 metres away
- Tough plastic frame
- Controller ICs on board, simple clocked data interface
- Arduino compatible library, graphics functions and example support
- Dimensions: 320(W) x 160(H) x 14(D)mm (30mm(D) including rear connectors)
DMDs are also available in blue, as shown below:
The winner of the Second Prize is Hendrik from Germany (!) who will receive one each of the eleven modules from the Freetronics Module/Sensor range, as reviewed recently:
With this range of modules you will be able to sense temperature, humidity, magnetic fields, light and sound pressure levels, sound and shock. Plus light up with the RGB LED, get more I/O with the expansion module, interface with the level shifter board, control high currents with the N-MOSFET, and power the lot with the tiny switch mode power supply. Available from Freetronics or a reseller near you.
For the curious, the questions and answers were:
- Name three HP calculators that use LED displays – There are many. Just scroll through the list available here.
- What does CPLD stand for? Complex programmable logic device. (Why CPLD? We were going to review some CPLD gear but it didn’t work out)
- In which year was Tektronix founded? 1946.
- Which company introduced the term “numitron”? RCA.
- Which company invented Bluetooth? Ericsson.
Thanks to Freetronics for the prizes!
In the meanwhile, follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column, or join our 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.
April 2012 Competition
Welcome back!
Another month and time for another competition! First we’ll look at the prizes, and then examine the rules of entry.
First Prize is a new Freetronics DMD – Dot Matrix Display as reviewed recently and used in Clock One:
The DMD consists of 16 rows of 32 LEDs that can run directly from an Arduino-compatible board, or at a much higher brightness using an external power supply. It is simple to program for yet a load of fun to use. Specifications include:
- 32 x 16 high brightness Red LEDs (512 LEDs total) on a 10mm pitch
- 5V operation
- Viewable over 12 metres away
- Tough plastic frame
- Controller ICs on board, simple clocked data interface
- Arduino compatible library, graphics functions and example support
- Dimensions: 320(W) x 160(H) x 14(D)mm (30mm(D) including rear connectors)
The winner can select either a red DMD as shown in the video above or a blue one as such:
Second Prize consists of one each of the eleven modules from the Freetronics Module/Sensor range, as reviewed recently:
With this range of modules you will be able to sense temperature, humidity, magnetic fields, light and sound pressure levels, sound and shock. Plus light up with the RGB LED, get more I/O with the expansion module, interface with the level shifter board, control high currents with the N-MOSFET, and power the lot with the tiny switch mode power supply. Available from Freetronics or a reseller near you.
How to enter!
There will be five questions for you to answer spread across articles published between the 1st and 30th of April. At the end of April and once you have answers to all five questions, email the answers along with your full name, email address and postal address to competition at tronixstuff dot com with the subject heading April.
During the second week of May, all the correct entries will be collated and two randomly chosen. The first correct entry drawn will win first prize, and the second entry the second prize. Entries will be accepted until 05/05/2012 0005h GMT.
As with any other competition, there needs to be some rules:
- Incomplete entries will be rejected, so follow the instructions!
- The winners’ first name and country will be announced publicly;
- The winners’ name and mailing address will be passed to the prize supplier only for the purpose of prize delivery and not for any form of marketing.
- Entries that contain text not suitable for minors or insulting to the competition will be rejected (seriously – it happens);
- Prizes will be delivered via Australia Post domestic or regular international air mail. We take absolutely no responsibility for packages that go missing or do not arrive. If you live in an area with a “less than reliable” domestic postage system, you can pay for registered mail or other delivery service at your expense.
- Winners outside of Australia will be responsible for any taxes, fees or levies imposed by your local Governments (such as import levies, excise, VAT, etc.) upon importation of purchased goods;
- Prizes may take up to 45 days to be received;
- No disputes will be entered in to;
- Prizes carry no warranty nor guarantee – and are to be used or abused at entirely your own risk;
- Entries will be accepted until 05/05/2012 0005h GMT.
Thanks to Freetronics for the prizes!
In the meanwhile, have fun and keep an eye out for the four competition questions spread through the February posts… In the meanwhile, follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column, or join our 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.
Project: Clock One
Let‘s make a huge analogue and digital clock using a dot-matrix display.
Updated 18/03/2013
For some strange reason I have a fascination with various types of electronic clocks (which explains this article). Therefore this project will be the start of an irregular series of clock projects whose goal will be easy to follow and produce interesting results. Our “Clock One” will use a Freetronics Dot Matrix Display board as reviewed previously. Here is an example of an operating Clock One:
As you can see, on the left half of the board we have a representation of an analogue clock. Considering we only have sixteen rows of sixteen LEDs, it isn’t too bad at all. The seconds are illuminated by sixty pixels that circumnavigate the square clock throughout the minute. On the right we display the first two letters of the day of the week, and below this the date. In the example image above, the time is 6:08. We omitted the month – if you don’t know what month it is you have larger problems.
Hardware
To make this happen you will need:
- A Freetronics Dot Matrix Display board;
- If you want the run the display at full brightness (ouch!) you will need a 5V 2.8A power supply – however our example is running without the external supply and is pretty strong
- An Arduino board of some sort, an Uno or Eleven is a good start
- A Maxim DS1307 real-time clock IC circuit. How to build this is explained here. If you have a Freetronics board, you can add this circuit directly onto the board!
Software
Planning the clock was quite simple. As we can only draw lines, individual pixels, and strings of text or individual characters, some planning was required in order to control the display board. A simple method is to use some graph paper and note down where you want things and the coordinates for each pixel of interest, for example:
Using the plan you can determine where you want things to go, and then the coordinates for pixels, positions of lines and so on. The operation for this clock is as follows:
- display the day of week
- display the date
- draw the hour hand
- draw the minute hand
- then turn on each pixel representing the seconds
- after the 59th second, turn off the pixels on the left-hand side of the display (to wipe the clock face)
There isn’t a need to wipe the right hand side of the display, as the characters have a ‘clear’ background which takes care of this when updated. At this point you can download the Arduino sketch from here. Note that the sketch was written to get the job done and ease of reading and therefore not what some people would call efficient. Some assumed knowledge is required – to catch up on the use of the display, see here; and for DS1307 real-time clock ICs, see here.
The sketch uses the popular method of reading and writing time data to the DS1307 using functions setDateDs1307 and getDateDs1307. You can initally set the time within void setup() – after uploading the sketch, comment out the setDateDs1307 line and upload the sketch again, otherwise every time the board resets or has a power outage the time will revert to the originally-set point.
Each display function is individual and uses many switch…case statements to determine which line or pixel to draw. This was done again to draw the characters on the right due to function limitations with the display library. But again it works, so I’m satisfied with it. You are always free to download and modify the code yourself. Moving forward, here is a short video clip of the Clock One in action:
For more information about the display used, please visit the Freetronics product page. Disclaimer – The display module used in this article is a promotional consideration made available by Freetronics.
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.
Arduino meets Las Vegas with the Freetronics DMD
Updated 30/01/2013
Time once more to have some fun, and this time by examining the new Freetronics DMD “Dot Matrix Display”. We will look at the setup and operation of the display. In a nutshell the DMD comprises of a board measuring approximately 320mm across by 160mm which contains 16 rows of 32 high-intensity red LEDs. For example, in the off state:
Connection of the DMD to your Arduino-compatible board is quite simple. Included with each DMD is a 2×8 IDC cable of around 220mm in length, and a PCB to allow direct connection to the Arduino digital pins D6~13:
Finally the cable connects to the left-hand socket on the rear of the DMD:
You can also daisy-chain more than one display, so a matching output socket is also provided. Finally, an external power supply is recommended in order to drive the LEDs as maximum brightness – 5V at ~4 A per DMD. This is connected to a separate terminal on the rear of the board:
Do not connect these terminals to the 5V/GND of your Arduino board!
A power cable with lugs is also included so you can daisy chain the high-intensity power feeds as well. When using this method, ensure your power supply can deliver 5V at 4A for each DMD used – so for two DMDs, you will need 8A, etc. For testing (and our demonstration) purposes you can simply connect the DMD to your Arduino via the IDC cable, however the LEDs will not light at their full potential.
Using the display with your Arduino sketches is quite simple. There is an enthusiastic group of people working on the library which you will need, and you can download it from and follow the progress at the DMD Github page and forks. Furthermore, there is always the Freetronics forum for help, advice and conversation. Finally you will also need the TimerOne library – available from here.
However for now let’s run through the use of the DMD and get things moving. Starting with scrolling text – download the demonstration sketch from here. All the code in the sketch outside of void loop() is necessary. Replace the text within the quotes with what you would like to scroll across the display, and enter the number of characters (including spaces) in the next parameter. Finally, if you have more than one display change the 1 to your number of displays in #define DISPLAYS_ACROSS 1.
Here is a quick video of our example sketch:
Now for some more static display functions – starting with clearing the display. You can use
dmd.clearScreen( true );
to turn off all the pixels, or
dmd.clearScreen( false );
to turn on all the pixels.
Note: turning on more pixels at once increases the current draw. Always keep this in mind and measure with an ammeter if unsure.
dmd.selectFont(System5x7);
for a smaller font or
dmd.selectFont(Arial_Black_16);
for a larger font. To position a single character on the DMD, use:
dmd.drawChar( x, y, 'x', GRAPHICS_NORMAL );
which will display the character ‘x’ at location x,y (in pixels – starting from zero). For example, using
dmd.drawChar( 10, 5, 'A', GRAPHICS_NORMAL );
results with:
Note if you have the pixels on ‘behind’ the character, the unused pixels in the character are not ‘transparent’. For example:
However if you change the last parameter to GRAPHICS_NOR, the unused pixels will become ‘transparent’. For example:
You can also use the parameter GRAPHICS_OR to overlay a character on the display. This is done with the blinking colon in the example sketch provided with the library.
Next, to draw a string (group of characters). This is simple, just select your font type and then use (for example):
dmd.drawString( 0,0, "Hello,", 5, GRAPHICS_NORMAL ); dmd.drawString( 2,9, "world,", 5, GRAPHICS_NORMAL );
Again, the 5 is a parameter for the length of the string to display. This results in the following:
Next up we look at the graphic commands. To control an individual pixel, use
dmd.writePixel( x,y, GRAPHICS_NORMAL,1); // turn on a pixel at location x,y
And changing the 1 to a 0 turns off the pixel. To draw a circle with the centre at x,y and a radius r, use
dmd.drawCircle( x, y, r, GRAPHICS_NORMAL );
To draw a line from x1, y2 to x2, y2, use:
dmd.drawLine( x1, y1, x2, y2, GRAPHICS_NORMAL );
To draw a rectangle from x1, y2 to x2, y, use:
dmd.drawBox(x1, y1, x2, y2, GRAPHICS_NORMAL );
And to draw a filled rectangle use:
dmd.drawFilledBox(x1, y1, x2, y2, GRAPHICS_NORMAL );
Now let’s put those functions to work. You can download the demonstration sketch from here, and watch the following results:
Update – the DMD will also be available in other colours, such as white:
So there you have it, an inexpensive and easy to use display board with all sorts of applications. Although the demonstrations contained within this article were rather simple, you now have the knowledge to apply your imagination to the DMD and display what you like. For more information, support and conversation visit the Freetronics product page and support forum.
Disclaimer – The parts reviewed in this article are a promotional consideration made available by Freetronics.
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, or join our 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.
Kit Review – the LoL Shield
Hello readers
Another month, so time for another kit review. In this article we exame the LoL Shield by Jimmie P. Rodgers. So what’s all this about? Simple – the Lol Shield is a shield with nine rows of fourteen 3mm diameter LEDs, available in red or green. The shield has many uses, from being another form of hypnotising blinking LEDs, to displaying messages, artwork, data in visual form, or perhaps the basis for a simple computer game. More on that later – first, let’s see how it goes together.
As is becoming the norm lately, the kit arrives in a resealable anti-static bag:
The contents are few in type but huge in number, the PCB:
… at which point you start to think – “Oh, there goes the evening”. And the LEDs confirm it:
You will need 126 LEDs. There was a surplus of seven in my bag, a nice thought by the kit assemblers. There isn’t too much to worry about to start off with, just remember the anodes for the LEDs are on the left-hand side, and start soldering. The greatest of shields starts with a single LED:
However after a while you get into the swing of it:
At this point, one wonders if there is a better way to solder all these in. If you diagonally stagger the LEDs as such:
the legs stay well apart making soldering a little easier:
… however one still needs to take care to keep the LEDs flush with the PCB. I wouldn’t want to do this for a living… Still, many more to solder in:
And – we’re done!
Phew – that’s a lot of LEDs. An inspection of the other side of the PCB to check for shorts in the soldering is a prudent activity during the soldering process. The final step was to now solder in the shield header pins:
And – we’re done! This example took me just over one hour, includind a couple of stretch and breathe breaks. When soldering a large amount, always try to have good ventilation and hopefully a solder fume extractor as well. Furthermore, pause to check your work every now and then, you don’t want to install the lot and find one LED is in the wrong way. To control the 126 LEDs the LoL Shield uses a technique called Charlieplexing. Furthermore, the creator has documented his design process and how this works very well on his website located here.
From a software perspective – there is a library to download and install, it can be found in the downloads section of this site. Don’t forget to use the latest version if you’re using Arduino v1.0 or greater. This will also introduce some demonstration sketches in the File>examples section of the Arduino IDE. The first one to try is basic test, as it fires up every LED. Here is a short video of this example:
Now that we have seen some blinking action, how do we control the shield? As mentioned earlier, you will need the library installed. Now consider the following basic sketch – it shows how we can individually control each LED (download sketch):
/*
Basic demonstration of LoL shield
http://tronixstuff.wordpress.com/kitreviews > LoL Shield
Needs library from http://code.google.com/p/lolshield/
*/
#include
int ad=20; // used for arbitrary delay
void setup()
{
LedSign::Init(); // initializes the screen
}
void loop()
{
for (int x=0; x<14; x++)
{
for (int y=0; y<9; y++)
{
LedSign::Set(x,y,1); // turns on LED at x,y
delay(ad);
}
}
delay(500);
for (int x=0; x<14; x++)
{
for (int y=0; y<9; y++)
{
LedSign::Set(x,y,0); // turns on LED at x,y
delay(ad);
}
}
delay(500);
}
As you can see in the sketch above we need to include the “Charlieplexing” library, and create an instance of LedSign in void setup(). Then each LED can be easily controlled with the function LedSign::Set(x,y,z) - where x is 1~14, y is 1~9 and z is 1 for on, or 0 for off. Here is a short video of the example above in action:
If you want to display animations of some sort – there is a tool to help minimise the work required to create each frame. Consider the example sketch Basic_Test that is included with the LoL Shield library – take note of the large array described before void setup();. This array contains data to describe each frame of the animation in the demonstration sketch. One can create the variables required for each frame by using the spreadsheet found here. Open the spreadsheet (Using OpenOffice.org or Libre Office), then go to the “Test Animation” tab as such:
You can define the frame on the left hand side, and the numbers required for the Arduino sketch are provided on the right. Easy. So for a final example, here is my demonstration animation. You can download the sketch, and the spreadsheet file used to create the variables to insert into the sketch.
However, thanks to an interesting website – there is a much, much easier way to create the animations. Head over to the LoL Shield Theatre web site. There you can graphically create each slide of your animation, then download the Arduino sketch to make it work. You can even test your animations on the screen just for fun. For example, here is something I knocked out in a few minutes – and the matching sketch. And the animation in real life:
So there you have it – another fun and interesting Arduino shield that won’t break the bank. For further questions about the Digit Shield visit the website. My LoL Shield came from Little Bird Electronics and is also available from the usual resellers.
As always, thank you for reading and I look forward to your comments and so on. Furthermore, don’t be shy in pointing out errors or places that could use improvement. Please subscribe using one of the methods at the top-right of this web page to receive updates on new posts, follow me on twitter, facebook or Google+, or join our Google Group for further discussion. No pre-teen girls were used in this kit review.
High resolution images are available on flickr.
[Note - The kit was ordered by myself and reviewed without notifying the manufacturer]
Otherwise, have fun, be good to each other – and make something!
Moving Forward with Arduino – Chapter 18 – RGB LED Matrix
Use an RGB LED matrix with Arduino in chapter 18 of a series originally titled “Getting Started with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
[Updated 09/01/2013]
In this instalment we will take a turn away from the serious things for a while, (plus I wanted a bit of a break) and instead enjoy some introductory fun with common-cathode RGB LED matrices. (Matrices is the plural form of matrix). I am sure some of you have seen these do all sorts of things, so now it is time for me to learn about them and share this with you.
First of all, let’s have a look at one:
Quite large – 60 by 60 mm. Thankfully this unit has the diffused/opaque LED surfaces – some cheaper ones have clear surfaces which don’ t look that good – it is like looking directly at an incandescent light globe, you can see the element more than the colour it emits. When you turn the matrix over, there are less pins than a newcomer may expect:
Two rows of sixteen pins. Considering there is so much real-estate on the bottom, one would think the manufacturer could print some markings on there – but they don’t. So you need the (example) data sheet.pdf. The three most important things we need to know are:
- the forward voltages: red – 2 V, green and blue – 3.3;
- the current at the recommended forward voltage – 20 milliamps;
- and the pinouts (click to enlarge):
It looks like a mess but isn’t that hard to work out. Do you remember how we used the 8×8 red LED matrix back in chapter nine? We will work on the same style of design in this chapter as well. I do realise there are chips from TI, Maxim and so on that are quite tricky – but I am trying to keep the cost down, of which I am sure you would appreciate. So instead we will use four 74HC595 shift registers (one to control the anodes of each colour, and one to control the cathodes via a bank of switching transistors.
To get this started, first let’s get the hardware out of the way. To fire this baby up we will need:
- an Arduino Uno or 100% compatible board;
- a common-cathode RGB LED matrix;
- 24 x 560 ohm resistors (this value may seem like a bit much – but the display was still very bright)
- 8 x 1 kilo ohm resistors (for transistors)
- 8 x BC548 transistors
- 4 x 74HC595 shift registers (IC1~4)
- 1 x 1uF 16V (or higher) electrolytic capacitor
- 1 x 0.1 uF 16V (or higher) ceramic capacitor
- a nice large breadboard
- plenty of connecting wire
Initially I was concerned about the amount of current this circuit would draw, however it was not to be an issue. With all the LEDs on, using the 560 ohm current-limiting resistors, the drain was much less than expected. To check, I powered the lot from a 9V PP3 battery and measured the current flow. 135 milliamps, not bad at all.
It just occurred to me that if you had an Arduino Mega-compatible board – it could directly take care of everything instead of using three of the shift registers. So here is our schematic:
In the schematic above, there are eight transistor-resistor combinations between the cathodes of the matrix (pins 25, 24, 23, 10, 9, 8, 7 and IC4. And there are 560 ohm resistors on all output pins of ICs 1~3. Furthermore, note that your LED matrix’s pinouts may vary – so please check your data sheet before wiring it all up… having to retrace all those wires once they’re in is a real problem. As you can see from the resulting breadboard photo:
Now how does all this work?
Quite easily really, the hardest part is putting the hardware together. First of all, please review how we used shift registers in chapter four. And, you may recall how we used two 74HC595 shift registers to control an 8×8 red LED matrix back in chapter nine. This is just the same type of set up, but with two more shift registers – now we have one for the cathodes (as we did before), and one shift register each for the red, green and blue LEDs.
Instead of sending out two bytes of data using shiftOut();, we need to send out four bytes. For example, to turn on every LED at once (thereby mixing red, green and blue – producing white) we would create a function such as:
void allOn()
// turns on all LEDs.
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, 255); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, 255); // green
shiftOut(datapin, clockpin, MSBFIRST, 255); // blue
shiftOut(datapin, clockpin, MSBFIRST, 255); // red
digitalWrite(latchpin, HIGH);
}
So as you can see, the first byte out the door is the data for the cathodes, in this case 255 – which is 11111111 in binary, or in 74HC595-speak “hey, turn on all outputs”. And the same again in turn for each bank of colours, the other three registers are told to open all gates and let current flow through the LEDs to the common-cathode lines controlled by IC4. So naturally, using some binary to base-10 conversion you can set which LEDs to come on and where. And of course, by mixing the primary colours – you can create new ones. For example, the additive colour chart gives us:
So now you can create yellow with red and green; red and blue makes purple; green and blue makes aqua or teal, etc. However I am colour blind, so you tell me.
Example 18.1
This time we will view the demonstration video first:
Download the matching sketch.
Now to examine how each of the effects were created, so you can understand, use and modify them yourself.
The basic operations are contained in these four lines:
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, c); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, g); // green
shiftOut(datapin, clockpin, MSBFIRST, b); // blue
shiftOut(datapin, clockpin, MSBFIRST, r); // red
digitalWrite(latchpin, HIGH);
So all you need to do is replace r, b, g and c with the base-10 values you want. For example, to light up the red LED in position 1, 1 – use 1, 0, 0, 1. Or if you want the whole first line to be green, use: 255, 0, 0, 1. After a few moments you should become proficient at converting binary to base-10. This chart from chapter four should help you:

Remember that you can also create patterns and so on. For example, if you only wanted LEDs 1 and 8 for your x-axis, you would add 1 and 128 together, and use the sum (129) for your x-value. To save some time, I have created a few functions for you to use. For example:
void displayLEDs(int rr, int gg, int bb, int cc, int dd)
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, cc); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, gg); // green
shiftOut(datapin, clockpin, MSBFIRST, bb); // blue
shiftOut(datapin, clockpin, MSBFIRST, rr); // red
digitalWrite(latchpin, HIGH);
delay(dd);
}
So instead of having to manually repeat a lot of code, you can just insert the values into displayLEDs();. Another handy thing to know about is looping. When looking at the matrix it is easy to accidentally think “Oh, I can just loop from 1 to 8″… No. Remember your binary to base-10 conversions. So if you wanted to scroll a horizontal line of red LEDs your cathode or y-axis value must increment as such: 1, 2, 4, 8, 16, 32, 64, 128. Every time the loop cycles, it needs to double the value. To do this, consider:
for (int q=1; q<129; q*=2)
{
displayLEDs(255,0,0,55,100);
}
Notice the q*=2? This will multiply the value of q by 2 every loop. Very useful. Another method would be to create an array, as such:
int va[]={1,2,4,8,16,32,64,128,255};
and refer to the elements as required. This is done within the function lostinspace(); within example 18.1.
The next thing to take into account is the screen refresh. Every time you send four bytes of data through the shift registers, those new bytes will ‘shift’ the old bytes out of the way. So if you want to alter the display even by just one LED, you need to redraw the entire display over again with four new bytes of data. Also note that to ‘hold’ an image on the display, you only need to send the data once – the shift registers will stay put until the next four bytes of data come along.
And sometimes, you might just want to turn off the display. Just send four zeros down to the registers, as the function clearMatrix(); does in the example sketch.
For now, please review the various functions found in example 18.1 – alter them, mess about and have some fun. Thus concludes our introduction to RGB LED matrices. However, stay tuned for more about this and other interesting things! If you have any requests, don’t hesitate to ask.
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, or join our 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.
Getting Started with Arduino! – Chapter Nine
This is part of a series titled “Getting Started with Arduino!” by John Boxall – A tutorial on the Arduino microcontrollers. The first chapter is here, the index is here.
Welcome back fellow arduidans!
In this chapter we will start looking at LED matrix displays, designing user interfaces, implementing a user interface for a clock, and finish up making an alarm clock.
Firstly, let’s have plenty of fun with 64 LEDs! Using an 8×8 LED display module:
Previously we have used 74HC595 shift registers to drive strips of LEDs, single and four-digit LED displays. An LED matrix seems complex at first, but after further investigation quite simple. With sixteen pins you can control 64 LEDs. It works by having 8 row pins, each pin connected to all the anodes on one row; and 8 pins each connected to the cathodes on one column:
It does look like a mess, but we can work it out. As we did with the 4-digit 7-segment display module, we just need one shift register for the anodes, and one for the cathodes. Moving along from exercise 6.2, it will be easy to drive the an LED matrix display – one shift register (the left hand side) will apply current to the rows (anodes) and the other shift register will apply current to NPN transistors to allow current to flow from the cathodes (columns) to ground. So we can make an example quite easily. You will need:
- Your standard Arduino setup (computer, cable, Uno or compatible)
- One 8×8 LED matrix. Try to find one that has LEDs with a forward voltage of 2 volts and a current of less than 20mA. If it is bicolour, that’s ok – just use one colour for now
- Eight 560 ohm 1/4 watt resistors
- Eight 1 kilo ohm 1/4 resistors
- Eight BC548 NPN transistors
- Two 74HC595 shift registers
- Solderless breadboard and connecting wires
Here is a circuit diagram for our example (click on it to enlarge):
Please note that there are eight transistor/resistor combinations from the second shift register – I just have not drawn them in to save my sanity. They’re on the bottom right of my board:
Now how are we going to light up those LEDs? We need to send two bytes of data to the shift registers, one byte for the row, and one for the column. For this example we will work with individual pixels. For example, say you want to turn on the pixel at 8 across, 8 down – the bottom right. You need to send the following bytes of data to the shift registers: b00000001 and b00000001. In decimal those two numbers are 128 and 128. Or the top-left LED, at 1 across, 1 down – it would be b10000000, b10000000 or decimal 1,1. Once again we can use the functions:
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, 1); // byte of data for the right-hand shift register (cathode controller)
shiftOut(datapin, clockpin, MSBFIRST, 1); // for the left-hand shift register (anode controller)
digitalWrite(latchpin, HIGH);
… to send the data to the shift registers. This example sketch for the above circuit should be pretty well self-explanatory if you have been following my tutorials.
Here is is in action:
Once again, quite mesmerising. Did you notice that the horizontal solid rows were dimmer than the solid vertical columns? This is because when you light up one row, all eight LEDs are drawing current from one pin of the shift register – so there is less current for each LED; whereas in the column, each LED has its own source of current, so can therefore operate at full brightness. So a hint – when you are creating images or characters for your display, use scrolling columns to display the image.
Experiment with the example 9.1 sketch, if you display only vertical columns, and make the delay zero – you can give the illusion that the entire display is on, but it is not.
Which leads us into the first exercise for the week!
Exercise 9.1
We can display entire columns with our matrix display. We can position these columns on demand. And without a delay, fill up the entire matrix. Now you can create images, or characters and display them on the matrix, one column at a time. For example, the little yellow dude from that popular arcade game many years ago might look like this:
Using the circuit described for example 9.1, create a character, shape, or whatever tickles your fancy, and animate it to move across the screen.
Hint – To animate an image, you will need to map the matrix every time the image changes – just like a normal animation or cartoon. However, store all the values for the entire animation in one array, otherwise you will go bonkers. When you need to read the array, each matrix image can be read as they are multiples of eight (then add the reference to the value you want).
For inspiration, here is what I came up with:
and the corresponding sketch.
How did you go? If you have an interesting animation, and you can do so – please email a link to Youtube, Vimeo, etc showing your creation – you could win a prize.
Time to get a little more serious now.
Over time you have been making things, some useful, some more experimental than anything. Hopefully you will reach the stage of designing something that has a real-world use and could be used by people other than yourself or your immediate circle of friends. In the next few weeks we will look at methods of transitioning projects from prototypes to standalone products you can develop!
A major part of your design should be the user interface, or how your project responds to user input and displays data, results and so on. If something is difficult to use, or understand, it will not be a good product. So what can we do about this? This week we will examine the clock made in example 7.4 and change it to be independent of a computer, and easy for the user to operate. But now for some design inspiration…
The humble alarm clock (it has been staring at me every morning). Here is my late grandfather’s clock from the 1960s:
Simple, yet functional. It does what it is supposed to do with the minimum of fuss. (It’s German). And that is how our project user interfaces should be. As technical people it is very easy to get carried away and put buttons, lights, and all sorts of things together, but at the end of the day, less is more. How can we emulate this with Arduino – but in a simple method?
Looking at the face of the clock, it displays the time (hours, minutes, seconds) and the alarm time. We can use an LCD for that. On the top is the alarm off button. We can use a button for that. On the rear there are winders for the time and alarm spring – we have electricity for that. There are two knobs, one to adjust the time, and one to adjust the alarm – here we have several options. We could use up/down buttons… perhaps we could use a knob as well? And finally there is the gain control – we don’t need this as our DS1307 is infinitely more accurate.
A rough map of how you want things to work is always a good start, for example my mess below:
How can this be implemented? Let’s see. The clock will normally display the date, time, etc. If a button is pressed, it will switch to menu mode (on the right). A knob will be used to select one of the options listed on the right, when the required option is displayed, the user presses the button to select the option. Then the user can use the knob to adjust the variable for that option, and press the button to return to the menu. The last menu option is to return to the clock display. So we can control the whole lot with only one button and one knob.
The button is easy with Arduino, and to save money we can use a potentiometer as a knob. Remember we did this in in exercise 6.2. Normally it can return a value between 0 and 1023, but with our clock we need it to return a value that falls within a variety of ranges – from 0 to 6 for day of the week, to 0 to 59 for the minute adjustment.
Exercise 9.2
Create a function to use a potentiometer to return an integer between zero and a maximum range value. The function will accept the maximum range value, and return an integer which represents the position of the knob. For example:
int dialposition(int maxrange);
Here is a short video of my interpretation in action.
And the resulting sketch. The value rangemax that is fed into the function is the number of positions in the range you want to work with. For example, if I want the knob to return a value between zero and fifty-nine (sixty values in the range) I would set rangemax to 60. The value dialpin is the number of the analogue pin the potentiometer is connected to. You should use a linear potentiometer to ensure a nice smooth adjustment.
Great – now we have a way of reading our knob and customising the result for our range requirements. Our clock example’s menu will require eight options, each with their own function (e.g. set hours, set minutes, set year, return to clock, etc). We have one button, so you could use that to trigger an interrupt to start the menu display (interrupts were covered in chapter three). However if you have made an LCD shield use the interrupt pins, you will need to check the button status while displaying the time. We will make the display of the menu a separate function as well.
For now we will make our clock respond to the ‘menu’ button, and display the eight options when the knob is rotated. We will build on the sketch from example 7.4. Here is the result of doing this:
Now it is time (ha!) to make those menu options actually do something. First we need our displaymenu() function to call the selected option. This can be done with a switch…case function. For example, I will put this code after the while loop:
switch(readdial(8,1))
{
case 0: msethours;
break;
case 1:
msetminutes;
break;
case 2:
mset1224;
break;
case 3: msetday;
break;
case 4: msetmonth;
break;
case 5: msetyear;
break;
case 6: msetdow;
break;
}
There is no need for a seventh option (return to clock display) as this will default if the knob is in the ’7′ range. Notice I have already declared the name of the functions to call. All we have to do is create the individual functions. However there is one catch to work around, when it comes to setting time and date data, this is all done with the one function:
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
So inside the function that (for example) sets the hour, immediately before setting the hour, read the rest of the values from the clock, and reset them back in with the setDateDS1307() function.
Once again the basic work has been done for you, please see this video:
… and the sketch. Although the contents of the LCD during the menus may be brief, the framework of the user interface has been created and can now be easily modified. For example, if you had a 20 x 4 character LCD, you could offer more help to the user.
But returning to the original task – emulating Grandfather’s alarm clock. We need an alarm!
Exercise 9.3
You guessed it – modify the clock in example 9.3 to have an alarm as well. User can set the alarm, and turn it on or off with the menu system. When the alarm sounds, the user should be able to turn off the alarm, Have fun!
How did you go? Here is a video demonstration of my work:
… and the sketch. That was really fun – I have a lot more clock ideas now.
I hope you enjoyed the change of pace this article and have a greater understanding on why we should create simpler human-machine interfaces wherever possible. Now to move on to Chapter Ten.
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, or join our 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.


































































