Arduino Drives 7-segment LED Display

7-segment LED display

A standard 4-digit display. I fiddled with the image to make it look lit up.

7-segment Displays

This type of LED (Light Emitting Diode) display has been around for a long time, and you can still find them in many devices. For most applications they have been replaced with LCDs which use less power and are more versatile. But if all you need to do is display numbers, and you have some old parts around that you want to use, then you might be interested in putting one of these things into a “modern” project, such as one using an Arduino (programmable microcontroller).

Pin Count

The simplest Arduino has only 20 pins that can be used for digital I/O (inputs/outputs). A 7-segment display requires 8 pins to drive the segments (if you want to use the decimal point) and a pin for every digit. For 4 digits, that’s 12 pins. For 8 digits, that’s 16 pins. That doesn’t leave many pins for other functions in your project. But, you might not need many other pins.

There are ways to reduce pin count. One way is to use ICs (integrated circuits) that will take a binary number at the input, say from 0 (B0000) to 9 (B1001) and output the appropriate pattern to the segments to display those numerals. You can also use a simpler encoder to run the digits; 3 (binary) lines in, 8 lines (or digits) out. That means you could operate an 8-digit display using only 7 Arduino pins.

Drive Current

An older LED, like you find in these displays, requires at least 5ma (milli-amps) of current to look reasonably bright. Most are rated for 20ma. These arrays are actually scanned (only one digit on at a time), so it helps to make them look brighter if you drive them with more current than the LEDs would need if they stayed on all the time. However, unless you can find a special IC to do your decoding, one specifically designed to drive LED arrays at those current levels, most ICs won’t be able to do the job. The average CMOS (complementary metal oxide semiconductor) IC that hobbyists use is only rated for about 2ma output current.

However, the Arduino itself is rated for about 20mA output. So the Arduino pins can run the LED segments unassisted. I use transistor arrays to run the digits. They take about 1ma in and can output up to 500ma or so. However, these drive transistors invert the input signal (in high, out low), so to drive the digits requires a signal of opposite polarity to what you would use if you weren’t using the transistors.

Existing Solutions

Most – but not all – of these factors are taken into account by an Arduino code add-on (called a library) named “SevSeg” (for “seven segments”). What it does not take into account is using encoder ICs to lower the pin count. My design uses an encoder to select the digits, but runs the segments directly from the Arduino. So, I could not use the library that had already been written for this purpose.

My Own Solution

I am writing this because I thought I could come up with something relatively simple that would do the job, but I wasn’t sure.

The basic cycle of action is fairly straightforward:

  1. Set up the 8 segment drivers to be high or low depending which segments you need on or off to display the desired numeral (or other pattern) for the first digit.
  2. Select that digit by outputting the binary number corresponding to that digit’s hardware position. (Say, B000, three low lines for binary zero, “digit zero.”)
  3. Keep that pattern on for a little while (a milli-second maybe), then switch to the pattern for the next digit.
  4. Repeat this process for each digit, until all have been lit, then repeat the entire cycle as long as you want the display to show something.

I used what is sometimes referred to as a “brute force” method to select the digits. For each digit, I just tell the Arduino which lines to make high and which lines to make low. It’s only 3 lines, so not that hard to do it that way. Those lines will stay that way until I tell the Arduino to change them, so it’s just three commands for each digit. Pretty easy.

I could have done the same for the segments, but I was hoping for a simpler solution. I found one by using a built-in Arduino function (built into the code writing system, not the microcontroller!). This function is one of several that treat a number as a string of binary bits. They are called the “bit functions.” The one I used is called “bitRead().” You give this function almost any number and it can tell you whether there is a “1” or a “0” in any of the places in its binary form. For example, the number 255 is binary “11111111.” All its places are ones. The number 254, one less, is B11111110. There’s a zero at the end instead of a one. So bitRead(254,0) would return zero, while bitRead(254,1) would return 1. As is customary in most of these programming languages, lists of things usually start with “item 0” instead of “item 1” as most of us would assume. So, if you want the first item in the list you have to ask for “0” and if you want the 8th item you ask for “7”. Seems weird but you get used to it after a while.

For the eight segments on an LED display (including the decimal point) there are 256 possible different patterns, each represented by a number from 0 to 255. So I just had to figure out which numbers would produce the correct patterns to display numerals 0 to 9 on the display, then put those numbers in a list, with their position in the list corresponding to the numeral they represented. Then to display that numeral, I would just have to use bitRead() on the number selected from the list, going through each of the 8 binary places, and matching up each place with the pin I used for that segment (another list) and I would have the entire pattern properly outputted.

For my hardware, I wasn’t using the decimal point, and the list I came up with was: {63,6,91,79,102,109,125,7,127,111} for numerals 0 to 9. The numeral 8 has all seven segments on, so would be 127 (B1111111) in almost any system using this idea. The other numbers could change if the wiring of pins to segments was different than the one I used.

Note on touch screen styluses

I’ve been playing around with my touch screen devices, an iPod Touch and an HP Stream tablet. They both have “capacitive” screens and therefore require a conductive rubber stylus if you don’t want to use your fingers. I found a nice ballpoint pen downtown that uses the “eraser” as a stylus tip, and two children’s styluses at Walmart. I like to use the styluses instead of fingers, and hope to locate a drawing program for my tablet before too long.

styluses for touch screens

Advertisements

Tags: , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.