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:

Tuesday, July 13, 2010

Measuring current and voltage

How nice would it be if you could measure current and voltage of some power source. In my case for my RC plane, I'd like to know how much current the motor is drawing and what the battery voltage is.
To measure current, the theory used is that when current flows through a resistor, a voltage difference can be measured over that resistor (also known as shunt). So we'd like to measure up to a 100 amps. The analog input pins can measure from 0 to 5 volt. So 0 amps would measure 0 volts and a 100 amps would measure 5 volts.

Some calculations with Ohms law gives us:
I=V/R => 100=11/R => R=11/100=0.11 Ohm

That is one tiny resistor that needs to cope with high currents... And how accurate would that be? Looking through some RC forums, there was suggested to use copper wire. Copper wire has some resistance, so if you know the resistance per length, you can measure out the length of wire required. The RC guys really like to use a wire that gives you a voltage of 1 mVolt for 1 amp.

Anyway, for our purpose it does not really matter. Just keep your required range of amps, mapped to a measurable range of volts. And above all, we're not tied to 1 mVolt per amp, but we can calibrate the Arduino with our multimeter and use some magic factor in the code.

After I made a nice wire measuring the amps I wanted, it turned out the copper wire was more than 2 meter long. The Arduino has an option to change the measuring range of an analog pin from 0-5 volt to 0-1.1 volt, that is the internal voltage. (analogReference(INTERNAL);) This way, the length can be reduced by approximately a factor 5 and 30 to 40 cm of wire in a small model airplane is way better than 2 meter.
To measure voltage, a simple voltage divider is used. The theory is that is current flows through a resistor, a voltage difference can be measured over that resistor. So, flowing from + to -, the voltage drops with each resistor. First the voltage should be brought down to acceptable levels for the Arduino, and then a smaller resistor is used to measure the voltage difference. The voltage of a battery is 11 volt (3S lipo).

The formula to use is:
Vout = Vin * R2/R1+R2 where Vin is 11 volt and Vout should be 1.1 volt so the Arduino can use the internal voltage as reference. For example R2=10KOhm and R1=90KOhm are nice values. With 100KOhm the current that will flow through those resistors is: I = V/R = 11/100.000 = 0.11 mAmps.

Again, accuracy is not very important because we can use a multimeter to calibrate and use some magic factor.
The values of R1 and R2 I took are easy to calculate with, but in reality more than 11 volts need to be measured. The values I took are R2=1KOhm and R1=100KOhm. So the maximum voltage we can measure with this shunt:
Vout = 1.1v = Vin * R2/R1+R2 = Vin * 1K/100K =>
Vin = 110v, which is more than enough.

I've combined these two schematics into one, which goes between the battery and electronic speed controller (ESC). The shunt is placed in the wire that runs to the ground of the battery. This because now the volt an amp meters have a common ground. This was only 3 wires are required instead of 4.

So with my LCD screen working, I got these numbers to display on my LCD screen very easily. And I've also ordered a SD card holder, so I could turn my Ardiuno into a logger like this, but I'll save that for another blog post.

Currently I'm figuring out how to measure the RPM of a brushless motor, so the most important motor parameters for a logger are covered. Actually, the "figuring out" part is done. Now I'm composing a list of components I want to order for all my great idea's! Somehow the list keeps growing, but I still want to finish my LED matrix clock first.

Thursday, July 8, 2010

Buying cheap

Now I've started experimenting, new components are a must!

While looking for new experiments I found these new experiments, thanks to Oomlout:

Buying a LCD 16x2 screen from a regular webshop costs 9 to 11eu (incl. potmeter and headers), and from another webshop it costs 3.95eu, still requires soldering though...

Buying a 8x8 bi-color LED matrix from a regular webshop cost 3.60eu, but from eBay you can get 10 pieces for only 12.30eu including shipping costs!

Hold on a second, why on earth would order 10 of those?!? And don't forget to order 10 shift registers, to control the LED matrices...

So buy your stuff at the best place:

I guess I'll be shopping again real soon:

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?

Monday, June 28, 2010

LCD display and soldering it

In one of my buying rages, I included a LCD display for 3.95eu. Now I got Hello world working on my LCD screen!!!

The LCD screen is really simple to get working:
http://www.arduino.cc/en/Tutorial/LiquidCrystal

The only thing that would give me problems is soldering the headers on. I really could not solder one month ago, no really... I could not. I had ordered a bunch of deans plugs to solder to my lipo battery, but I melted them all.

I blamed the 30 watt soldering iron and I bought a 60 watt. 60 watts ought to be enough for anybody. But still, I could not solder...

Many burn marks on my fingers and a bunch of molten plugs later, I still could not solder. So I asked a friend to solder the plugs on and that looked really really easy... After a complete step by step walkthru, I figured I should be able to solder. Two weeks later after walking through the soldering steps many times in my head, I finally pickup my soldering iron and some scraps and started soldering everything together. And guess what?! After a few tries, I finally managed to solder things together. Actually, it was as easy as it seemed when watching my friend solder.

So, what was I doing wrong? It is simple, I did not tin the tip of the solder iron... I knew I had to tin the tip, I tried to tin the tip, but the tin just fell right off. Even after sanding and filing the tip, the tin did not really stick But I was thinking it was okay like that... I did not have a wet sponge to clean the tip and you really need a wet sponge or cloth to clean the tip properly.

So tinning your tip correctly is crucial! The molten tin transfers the heat from the tinned tip to the object to solder. Clean the tip with sandpaper and the sponge, and tin the tip directly after, let the tin stay on the tip. Clean the tip and you're ready to go. The tip should be nice and shiny now...

So, what did I learn?
  • Tin the tip
  • You really need a wet sponge
  • Clean the tip often
  • Do not let your object get too hot
    • Soldering should not take more than 2 seconds
    • Especially PCBs, they should be soldered even faster.
    • 30 watt is enough to solder, only really fat wires do require a bigger tip or bigger iron.
  • Practice for an evening
    • Get some scraps and solder everything together
    • Don't forget to practice desoldering
Finally I soldered the headers onto the display in 15 seconds with my 30 wat iron, a real piece of cake! And got Hello World displayed following the LCD tutorial.

Please click on the image and notice the solder joints, they seem perfect to me...

Never thought that controlling a LCD display could be that simple... In one of my next posts I will display something more useful on the LCD display.

Thursday, June 24, 2010

Welcome to this blog

I know this is yet another Arduino blog, but my Arduino experiences should be shared with the rest of the world!

Since a few months I am thinking about an [undisclosed] project which requires a computer to calculate and control an physical mechanism. Soon I realized Arduino would be the solution.

The Arduino is a very simple way to get started with electronics. I’ve been working as software engineer for more than a decade so programming on the Arduino should not be any problem, although my C/C++ knowledge is a little rusty. But electronics are totally new to me. For me the Arduino is an real good way to connect the virtual world to the real world... Anybody got some red pills left?
To get started I bought the Arduino Experimentation Kit (ARDX) from a small dutch webshop called Floris.cc. The kit was originally created by Oomlout and they did a really nice job! All kinds of simple experiments are available to get acquainted with Arduino and electronic components (led, transistor, motor, servo, buttons, sensors, etc). Arduino is all about open source, so you can reproduce the boards and even the experimentation kits from Oomlout. 

After working on some ARDX experiments, combining them and thinking of new projects, I really needed to share my Arduino knowledge, thoughts and projects with the rest of the world.

As I'm not really a social media kind of guy, blogging was a real no-go... untill I bought my first Arduino.

So, welcome to my first blog!