Saturday, 23 January 2010

Playing with 7 segment LED displays

I was looking though the maplin catalog when I was in there a few days ago and I saw this little beauty, so I bought it.



So, having got the LED display I have to look at how to run it. It is a common anode display (common positive) so it works by the controller pulling the pins to ground.
There are three basic ways I can do this:
  1. I can connect the pins directly to the arduino, and use that to control the display.
  2. I could use two eight bit shift registers, one for each digit.
  3. I could use a dedicated micro controller.
Let's look more closely at the above options. With option one the main problem with this method is that it uses a lot of pins. To run two digits I would need all 12 digital output pins and four of the analog output pins. This is far from ideal, so let's scratch that and move on to option two. At first appearance this looks like a very good idea, and it is. However, because I bought a common anode device and not a common cathode device we need to connect the pins to ground for them to light and according to the datasheet for the shift registers I have got, when the output it set to low it is just that, low: not connected to ground. So for the circuit to work we need to use pull down resistors. This could well be a very good solution, so let's put that to one side and look at the final option.
A bit of browsing of the Farnell website revealed the SAA1064 7 Segment LED controller. It connects to the arduino via the I2C bus, so it only requires two pins. This solution doesn't require 16 resistors to function and only cost a couple of pound, so I decided: sod it.
 
I had a quick browse around the internet and other people had had success with this chip and the arduino so I set to connecting it up. I did discover that for reliable function of the I2C bus with the arduino you need to use two pull up resistors on the SDA and SCL (serial data and serial clock) lines (you can just see one of them on the left of the picture. There seems to be some confusion over this, I have read that the Wire library automatically turns on the interal pull-up on the arduino so that the resistors aren't required, but if I do this then the connection is tenuous at best, and can take many presses of the reset button before it works. I nearly threw the whole lot out of the window before I figured that out!


I look at the datasheet for the SAA1064 and in order to operate more that two digits you need to run the device in multiplex mode. In this mode the chip switches rapidly between two outputs, turning on two digits at a time. However for this to work you need a 2nf capacitor. Which I didn't have. So I started off by running the chip in two digit mode.

Or tired to. I did have a few issues getting the damned thing to work at all but this turned out to be because the I2C rate was set to 400hz and the chip will only work at 100hz. Having worked around these 'teething' issues I did eventually get it to work so I decided to get the required 2nf capacitor and another display. Bring on Farnell! The next day I received two LED displays and 10 2nf capacitors (which they shipped to be from Belgium. It must gave cost more to send that the parts cost and postage was free. Work that out.)


With the capacitor in place, and with the addition of a couple of transistors I finally manged to get the display to output four digits. The slight fuzzing on the picture is caused by the multiplexing. It is far too quick to be seen by the human eye, but it can be seen by the camera (The shutter was set to 1/60th of a second.)

Now, having got it working I decided that I need to write a library so that it will be easy to use it in the future.
The things I want to accomplish here are: denary (base 10) and hex (base 16) display of integer values, along with denary display of real values to a specified number of decimal places.
I did this and the resulting library can be downloaded here.

The next thing I want to do is to incorporate this onto a circuit board so that I can use it more easly in the future. Bring on EAGLE.

The first problem was that there isn't a part in the library for the SAA1064 (or at least, if there is then I can't find it) so I had to make one.
The schematic on the left is the result of about an hours work. it would have been much less if I didn't have to make part.

The next thing was to make a board layout. This should have been quite simple, but no! The problem wasn't so much with the layout itself, but with the manufacturing methods. I can't solder the LED displays to the top of the board because a) the LED displays sit flush with the board and b) it would be hard, even if they didn't sit close to the board.

So I used top exclusion areas to make the auto-router connect to all the components on the bottom layer. Then the second problem arose: The built in auto-router in EAGLE is rubbish and couldn't route the whole board, but never fear, for freerouting.net comes to the rescue.

The only problem now is that I don't have the equipment to make the board, so I will have to save my pocket money!

Next project: An I2C connected real-time-clock

Sunday, 17 January 2010

Building a Display Adapter for the HD44780 LCD

Having successfully written a library for controlling the LCD screen using a shift register I thought: "How great would it be to have a small circuit board that plugs onto the back of the LCD screen so I don't have to use valuable space on my bread board?" So I made one.

Step 1:

Start with the schematic from my last post:




Step 2:

Design the circuit layout. If I was going to make a PCB this would be quite straight forward as I created the schematic in EAGLE; I would just select 'File > Switch to board', position the components and hit autoroute. However, I am going to be using vero / strip board so I have to do the layout myself. I did it on paper, but I have re-done it using DIY Layout Creator
 


Step 3:

Cut out the board and start soldering in the components:



Once all the components are soldered in we can start placing the jumper wires:



The last thing to do is to attach the cable we will use to attach it to the arduino. I had a good length of 5 core cable from a Nintendo Gamecube controller which is perfect for this task, I just need to attach pins to the end of it so it can plug into the arduino.




Step 4:

Testing. This at least is simple. Just plug and play. Like windows, only this might actually work!



Step 5:

All I need now is a stand for it. Thankfully I have an old library card that will suffice just nicley. So two minutes work with a craft knife, a ruler and a screw driver and we have the finished product!



I know the stand looks a bit crude, but it does the job nicely.

Saturday, 16 January 2010

Controlling an LCD Display with a Shift Register

When I first ordered my Arduino Experimentation Kit from those nice people at oomlout I also ordered a 16 character by 2 line LCD display.

It was really easy to set up and use thanks to the instructions that came with it and the LiquidCrystal library bundled with the Arduino software.
The only problem is that it takes up a lot of valuable output pins, 6 in 4bit mode and 10 in 8bit mode, this makes it difficult to use in large projects, as you can quickly run out of pins.

The solution to this was quite obvious; use a shift register. So I fired up Google and had a look to see what other people had done. I found a great article on the Arduino playground (here) except I could figure out how to get their circuit to work with my shift register, as they use 74*LS*164 but I had a few 74HC595 registers knocking about. I also tried the other article on Arduino playground, but that one doesn't work very well, as it has large delays in it and you have to make sure that data you are sending to it is in the correct format (for example, it doesn't like numbers, you have to convert them into strings first)

So, here are my goals
  • Operate the LCD screen using a shift register
  • Use no more than three data pins
  • Maintain full compatibility with the LiquidCrystal library

The first two these are quite simple. Use the circuit below for a 4bit interface:


This circuit will allow us to control the output of the display, as well as the LED backlight. The backlight is controlled by an N-Channel MOSFT connected to pin QF on the shift register. We are using a MOSFET because the input impedance of the MOSFET is very very high which makes it ideal for using in logic circuits.

To meet the third goal I decided to modify the LiquidCrystal library. The reason being that the wonderful people who wrote it in the first place already did all the hard work of programming the methods for initialising the display and outputting data so it would be a bit daft to re-write all of that when all that is really needed is to change the way that the LiquidCrystal library sends data to the display.

After a couple of hours I had successfully rewritten the 'send', 'write8bits' and 'write4bits' methods and began testing.
The image above looks very complicated, but that is because those two bread boards contain both the 8bit and 4 bit versions (the screen is plugged into the 8bit interface).

In conclusion: the shift register interface is very simple to build and not too hard to program and makes the LCD screen easier to use in your projects.


You can download my completed ShiftLCD Library here

Sunday, 10 January 2010

5v Regulated Power Supply

While playing around with a few things I have on the go at the moment, I found that quit often I was only using the Arduino to provide power for the project while I mucked around with the components. Then a though struck me; I have a couple of really nice little 7.4v lithium polymer batteries that I use with my model helicopter and wouldn't it be great if I could use these to power my projects!

One trip to Maplin later I had acquired a TS2940CZ50 1A Ultra Low Dropout Fixed Positive Voltage Regulator. Yeah.
Basically this little gizmo looks like a transistor with a nice big metal tab on the top, and when used in conjunction with a couple of capacitors provides a regulated 5v DC output from an input voltage of up to 30v DC.

Next step is to read the datasheet (available from alldatasheet.com) and then using the sample circuit on page 3 I built this little thing on a scrap of vero board I had lying around:


Whilst reading the datasheet I noticed that the voltage regulator requires a minimum current draw of 10ma to ensure proper regulation (something to do with leakage currents dominating the output and driving it high) so I added an LED and a 560ohm resistor, providing a current draw of about 8ma, the idea being that adding anything else at all to the circuit will give a current draw of more than 10ma.

The other thing I have done is to use a standard two pin header and push the pins right through the board so that they stick out the other side (you can see the top of the header protruding form under the LED). This means that I can plug it into the breadboard like this.


So there we have it, a functioning 5v regulated PSU.

The only modification I want to make for the future is to include low voltage protection for the battery, as li-po's do not like going completely flat. In fact they like it so little that they die.

Thursday, 31 December 2009

RGB LED

As I said in my previous post, those good people at oomlout sent me a free RGB LED sample so I felt it would be daft to to have a good play with it.
Following the circuit diagram on the piece of paper and using the three resistors taped to the back I built this lovely little bit of gizmometry:










Using the following code I set the the LED to flash red, then green, then blue.


/**
* RGB LED test
*/

int redLed = 11;
int greenLed = 12;
int blueLed = 13;

const boolean ON = LOW;
const boolean OFF = HIGH;

const boolean RED[] = {ON, OFF, OFF};
const boolean GREEN[] = {OFF, ON, OFF};
const boolean BLUE[] = {OFF, OFF, ON};


void setup()
{
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
}

void loop()
{
setColour(RED);
delay (100);
setColour(GREEN);
delay (100);
setColour(BLUE);
delay (100);
}

void setColour(const boolean* colour)
{
digitalWrite (redLed, colour[0]);
digitalWrite (greenLed, colour[1]);
digitalWrite (blueLed, colour[2]);
}


Now this is all well and good, but it isn't very interactive is it? So I decided to add a potentiometer to the circuit and feel the output of the pot to the analogue in of the Arduino, the idea being to control the colour of the LED using the pot.
I also decided that red, green and blue were just too boring, so I also added the secondary colours yellow, cyan and magenta as these can be created by simply mixing red, green and blue.

Then with the following code we read the value of the potentiometer and set the colour accordingly.

/**
* RGB LED test version 2
*/

int redLed = 11;
int greenLed = 12;
int blueLed = 13;
int potPin = 0;
int potValue = 0;

const boolean ON = LOW;
const boolean OFF = HIGH;

const boolean RED[] = {ON, OFF, OFF};
const boolean GREEN[] = {OFF, ON, OFF};
const boolean BLUE[] = {OFF, OFF, ON};
const boolean YELLOW[] = {ON, ON, OFF};
const boolean CYAN[] = {OFF, ON, ON};
const boolean MAGENTA[] = {ON, OFF, ON};
const boolean WHITE[] = {ON, ON, ON};



void setup()
{
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
}

void loop()
{
potValue = analogRead (potPin);
if (potValue > -1 && potValue < 170) {
setColour(RED);
} else if (potValue > 170 && potValue < 341) {
setColour(YELLOW);
} else if (potValue > 341 && potValue < 512) {
setColour(GREEN);
} else if (potValue > 512 && potValue < 682) {
setColour(CYAN);
} else if (potValue > 682 && potValue < 853) {
setColour(BLUE);
} else {
setColour(MAGENTA);
}
}

void setColour(const boolean* colour)
{
digitalWrite (redLed, colour[0]);
digitalWrite (greenLed, colour[1]);
digitalWrite (blueLed, colour[2]);
}

The end result can be seen in this little video:

Getting Started..

Following a recommendation by a friend of mine I decided to order an Arduino Experimentation Kit from oomlout.com

It arrived well packaged in a very nice multi compartment plastic box with everything I need to get going.
Those good people at oomlout also sent me a free sample RGB LED that I shall play with later in this blog

I run an iMac and the software installed very easily (just make sure you have the
latest version) and worked straight off. Just follow the lovely instructions in the Arduino Experimenter's Guide supplied with the kit.

The first thing I did was to unpack the Arduino board and the breadboard and attach them to the acrylic base plate provided. I then tried the simple 'Blinking LED' example provided with the kit.

The software is good if a little basic, but it is very easy to use. My advice tho is to keep the experimenter's guide to hand and use it to check your syntax by looking at their examples.

All in all this little thing looks awesome. Iona, I owe you a drink.