Showing posts with label clock. Show all posts
Showing posts with label clock. Show all posts

Monday, June 25, 2012

Flickering LED Matrix

Running s simple sample driving a LED matrix, goes without any problem. But when you get more ambitious the LED matrix flickers regularly. I know that a digitalWrite can replaced by editing the registers directly, but hey I just don't like to rewrite all the code...

After some slight optimizations ordering the code a bit, I found a discussion on the Arduino forum that handles this topic.

In this discussion the digitalWrite and shiftOut are optimized. The regular shiftOut takes 110us to output a byte, but with the optimizations it performs 6 times better. Now thats a nice gain. That definitely should solve the flicker...

But wait, there's more! The compile optimization can really make a difference, when the compiler knows all values.

Quote:
The compiler will produce code that will do port I/O in a single instruction (65 nanoseconds) if it knows the port, pin and state at compile time.

So, when you define a hardcoded pin in your sketch, there's a real difference in the way you define it. A regular integer variable containing the pin number.
int OUTPUT_PIN = 5;
or a define statement:
#define OUTPUT_PIN  5
The #define is the way to go. This way, every occurrence of "OUTPUT_PIN" is replaced by the number 5 directly and the compiler can optimize the code. When using the first option, using a integer variable, the compiles should always retrieve the value from the variable first and the compiler does not know which value to expect. You probably never want to change a pin at runtime... and if you do, you can go for the "int" option anyway.

From now on, I'll code my pins using a #define statement, instead of regular variables!!!


Well, actually you can also use the following:
const int OUTPUT_PIN = 5;
This also tells the compiler that OUTPUT_PIN is never going to be changed, so the compiler can choose the most efficient way to use the value of OUTPUT_PIN.

So let us look at the following code:
void f(int);

void g()
{
  f(OUTPUT_PIN);
}
When using "#define OUTPUT_PIN 5" or "const int OUTPUT_PIN = 5;", the resulting instructions are in both cases:
push 5
call f
add esp, 4
To the compiler it is better to have the number 5 everywhere in the resulting binary, than having to fetch the number 5 from the variable, if you know that the number has not changed.

Okay, to summarize... use the "const" keyword for defining your pins and every other value that you know will not change.

From my rusty C++ guidelines I vaguely remember: "Use const wherever possible."


Extra:

Friday, July 2, 2010

Playing with LED Matrices

After completing all the ARDX experiments, I already had in mind what I would use for my first real project... a dot matrix clock using 8x8 LED matrices!

A LED matrix is a fancy piece of hardware having 64 LEDs (in my case 128, 64 red and 64 green leds), which have not as many pins. The idea is that with multiplexing, you can light one row at a time, and keep looping through all rows, so it looks all LEDs are lit, but actually are lit 1/8th of the time. (For some reason it seems more logical to me to loop through the 8 rows, in stead of the columns. Especially when you want to build a LED matrix showing the time or a nice message using 8 rows and many many columns.)

With a bit of research, I found a webshop called Sure Electronics offering 10 pieces 8x8 bicolor LED matrices. (With a bit of shipping costs, still very cheap. Actually I found their ebay webshop and ordered there.)

Controlling one 8x8 LED matrix required a lot of wires, 8 row and 8 column wires. But the ARDX kit comes with a 74HC595 shift register. Using this shift register, the number of required wires reduce a bit. We'd have: ground, vcc, data, clock, latch and 8 column wires. That is still 13 wires...

But when using multiple shift registers to power the columns, the number of required wires stays the same... The the shift registers pass on the data (on/off values of LEDs) and the row wires power the complete row of all LED matrices.

The ShiftOut tutorial provides all the details needed to wire everything up and even some code samples to get you started. Probably in some future post, I'll unveil my code and explain the fine details of controlling multiple shift registers for multiple LED matrices.

My project is a simple clock, that would require 32 colums, four 8x8 LED matrices, to display "HH:MM" in a 5x8 font. That requires quite a lot wires to put on a breadbord, or even two. So I bought a prototype circuit board, and I'll solder everything together. For now I've put 2 LED matrices on my breadboards, and I'm displaying only the hours.

At first I used a small resistor for every rows, adding to the number of connections, but if you carefully calculate every aspect of your setup, it might just work without the resistors... Tinkerlog.com thoroughly explained LEDs and why the would require a resistor. My LED matrix specs have the following relevant numbers:
  • Max current: 20mA
  • Max puls current: 100mA (pulse <= 10ms and duty < 1/10)
So trying to follow the calculations, I must admit, I lost it a bit... In my case, not all LEDs are lit and they are lit 1/8th of the time. Having 1 LED lit in a row, is something different from having approximately 10 lit on average. But after going through the calculations, a small 36 Ohm resistor would be required. Not having such a resistor and having more than one LED lit at a time, made me omit the resistors. The LEDs now shine nice and bright... ;-) but not so bright that they might burn. (Few days later I've bought 30 Ohm resistors, and adding them does almost not change the brightness. Leaving them out should not be a problem, as long as more than a few LEDs per row are lit.)

Tomorrow I'll start soldering everything together on a prototype circuit board. I guess it will take some time to solder all those pieces...

After that I'll add an alarm and programming buttons, DCF-77, some nice case with touch snooze switch?