In this article I describe the simple setup and explain the code to drive analog meters using PWM outputs from an Arduino and the LCD Smartie program. I also replace the meter face to show the proper scale. Replacing the meter scale is very easy to do with most meters and can really add some style to your project.

A few recent articles around the web have been about interfacing an analog gauge to the PC to show things like the CPU% load. I have been wanting to do something like this for a long while and had bought an analog gauge for the purpose. These articles used a Microchip PIC microcontroller and the LCD Smartie program. I built one using the Arduino. I also included an LED to signal high CPU usage and setup the serial command decoding so that the Arduino could support a meter on all six of it’s PWM outputs.

Everything you need to know about interfacing to analog gauges is included in the DIY Life article "Show PC stats on Analog Gauges", including a video. I followed these instructions for configuring LCD Smartie so I will not cover that in this article. I will show you how to use the Arduino instead of the PIC.

This program is commonly used to drive small LCD displays with information from your PC. It can show things like CPU load and temperature, memory usage, even how much email you have or the song playing from your WinAmp. If you have a parallel port and a small LCD you might want to get this program a try, it is very simple to interface the LCD to the parallel port.

Driving an analog meter. The "Show PC stats on Analog Gauges" article describes the details very well. I highly recommend it for the basic understanding of analog gauges and driving them form a microcontroller. The basic idea is to use a PWM output signal to generate the average current needed to swing the needle.

Meters typically need a small current to operate. The typical meter needs 1mA to swing full scale. Some meters are 10mA and the extra sensitive meters used in handheld volt meters may be 1uA meters. To set the full scale for a volt meter a series resistor is used. For example you would use a 5.0K resistor to make a 1mA meter swing full scale at 5V. This is just ohms law, with the 5K series resistor, 5V drop would be 1mA. Of course you may need to consider the meters resistance as it is in series but typically the meter has a very low resistance so ignoring it will result in a very small error.

To drive the meter from a microcontroller we need to generate a voltage which can drop across our scaling resistor to be measured by the meter. We typically have a 1mA meter and a 5V supply so a 4.7K resistor will do the job. The meter will swing a bit past full scale but you could compensate for this in software if you wish. If you need high precession you can get a 1% 5K resistor. For my experiments I used a normal 5% 4.7K.

The other article suggest that you use a transistor to drive the meter. This is a good idea especially if you have a meter that requires more then 1mA. Most microcontrollers can output about 5mA, some less. The transistor will make the circuit insensitive to the amount of current a meter needs. I did not use the transistor myself, I had plenty of 1mA meters to play with.

PWM can generate the analog voltage for our meter. In the Arduino this is very simple. Just select a PWM capable pin and use the AnalogWrite() function. If you have set the meter to swing full scale with 5V then the AnalogWrite function will swing the meter from 0 to full scale with 0 to 100% PWM or 0-255 as the input to the function.

PWM PWM is short for Pulse Width Modulation. PWM is a digital output that is either on or off, 0 or 5V in most systems. A digital I/O pin toggles at a given frequency with a square wave shape. The amount of on time verses off time is measured as a duty cycle.

The Arduino PWM outputs have a frequency of about 500Hz. This means that the pin cycles from 0 to 5V and back to 0 again 500 times a second. This frequency is fixed but the amount of time the signal is low vs. high is set by the second parameter in the AnalogWrite() function.

The way PWM generates an analog signal is that we average the voltage level as a function of the percentage duty cycle. Say for example that we have 5V supply so our PWM is switching form 0 to 5V at a 50% duty cycle. Half the time it’s at 0 and half it’s at 5V so the average is 2.5V. A simple resistor and capacitor will filter out the frequency component and give us a steady (DC) voltage. We don’t need the RC to drive a meter because it will filter the PWM for us.

If you did a software PWM by togging the pin using code as opposed to the hardware timers and the rate was slow, you might need a capacitor as described in the original article. If you keep the PWM frequency high enough, the meter should not respond by wiggling. For the Arduino code, the 500Hz PWM is plenty fast enough. A meter is not going to visibly wiggle at 500Hz.

AnalogWrite Function

The AnalogWrite() function takes two parameters, the pin to drive and a drive value in the range of 0-255. The pin must be one of the PWM ready Arduino digital pins (3, 5,6,9,10, or 11). The drive value of 0 would set the PWM pin to 0% or off, a drive value of 128 would be about 1/2 of the range and would give about 50% on the PWM pin. 255 would set the PWM to 100%, a steady 5V. The pin will begin to toggle at 500Hz after your first call to the function.

So to drive an analog meter we simply select the correct resistance to drive swing the needle to full scale at our supply voltage, 5V for the Arduino. The original article provides some example methods to determine the correct drive for a meter you might scrounge.

If you have a volt meter to play with, chances are it will have a scale much higher then 5V. If it was a 5V meter then you are all set, it has the built in resistor. One of the meters I played with had an 80V scale. I looked into the back of the meter and found a 1% precision 80K resistor so I knew it was a 1mA meter. I just removed the resistor from inside and changed the scale out.

Adding a warning LED I drilled a small hole in the plastic back of my meter and inserted a high intensity red LED. This LED is driven from the Arduino and flashes each time the rate is updated. It can be set to be full on or flashing when the CPU load is over some level, Maybe 80%. The LED I used needs a bit more current to get fully bright but I went ahead with a simple series resistor to set the current to something the AVR could handle. It could be brighter but that will require a drive transistor.

I plan to either mount this board and a few meters into the side of my PC case or maybe use a separate box to set on my desk. I want to see several items displayed on the meters. I keep thinking about the line of meters in "Forbidden Planet". I could have a dozen meters mounted along the curve in my desk monitor riser.

For the initial setup I found a four conductor cable and routed a separate wire for each connection, two for the meter and two for the LED. Three wires would be enough as ground is common to the meter and LED but I had four wires so I did not bother to figure out which side of the LED would have been ground. For now, I set the meter on my monitor riser between my monitors so I could watch the CPU load and the little LED flash as I use my computer.

New Meter Face

So far I have not done anything really new compared to the original "Show PC stats on Analog Gauges" article. But I did take an extra step that really makes things nice. You can replace the scale behind the needle on most meters. The scale is usually a small painted piece of aluminum held in place by small screws.

To make a replacement meter face, I needed to get the scaling and placement of everything to match the existing scale. The first step was to use a flat bed scanner to scan the existing meter face. In the picture here you can see a scan from one of the meters I messed around with.

Once you have the scanned image, load it up into a graphics editing program and trim it to the exact size. If your program supports accurate scaling, set the height and width of the image precisely. I used a caliper to measure the meter face and set these numbers into Inkscape where I imported the scanned image. Draw your new meter face over the scanned image then delete the scanned image and print at a one to one scale. You can print in color to make it more snazzy. If you use plain paper, cut out the new scale and tape it to the original metal one. Place it back on the meter and your all set.

I had trouble with my color printer printing to scale correctly so I did a B/W meter scale on my laser printer. My fancy scale is shown here. I will get this on the meter when I find time to work out the printer issue.

I used cardstock for the scale so I was able to completely replace the metal scale. Cardstock paper is strong enough that it does not need a backing. I marked the screw holes and punched the paper with a jewelers screwdriver so that the original screws could be used to mount it. Unfortunately I lost one of the screws so I went ahead and stuck the scale down with some white tape. You can see the tape in the picture. I will improve all these cosmetic issues when I do the color scale.

This project was simple and fun. I plan on some neat analog gauges which show things like the number of visitors to the site. I hate to tie up one of my Arduino boards so I might do a separate board where I just plug in the microcontroller chip.

Other ideas If you have a parallel port you might drive a few meters using a DAC on the digital output pins. I talk about the R2R DAC in a previous article. If you used 4 Bits for the DAC that would give 16 levels of control for the meter. I think you could drive about 3 meters directly with 4 Bit DACs on the parallel port.

You don’t have to show percentage on the meter. You can display anything you like so long as the display does not need to change fast. You could display the weather on a meter, of course you could display temperature but you could also show the cloud conditions. Sunny, partly cloudy, overcast, raining, snowing etc… Just print a scale with icons for each of the weather conditions and have the meter swing to the right value to represent the conditions.

How about a day clock that shows you how much time you have left at work. You could mark the scale with lunch time, breaks, etc… I look forward to comments on this article with interesting things to display on an analog meter face.

Arduino program The simple protocol setup in the PIC based version of the PWM meter driver works great so I just implemented the same on the Arduino. Basically it’s just a number for the percent level and a letter identifying the channel. I assigned channel A to I/O 3 and B to I/O 5. The way I decode the protocol makes it very easy to add more channels. You just need another few lines of code in the switch statement.

Finding Meters I bought mine at All Electronics. The 1mA panel meter cost about $12. I would like to find a good meter that cost a less. I cant afford my "Forbidden Planet" meter set at $12/each. I also got a smaller meter to try out. It is similar to this one but has a fuel gauge scale that would be fine for a memory status indicator. One idea is to buy some of those really cheap volt meters and pull out the meter. This would likely be a 1uA meter and has a large face. It’s a shame to throw away the rest of the meter but for the price you get a good meter and maybe some other useful parts. Let us know if you have a good source.

No not 5 amps. Meters work on very low currents. A series resistor is used to convert voltage to current for the movement. A meter might swing to full scale with 1mA so if you want full scale at 5V you would use a 5K resistor. 5V dropping on 5K would be 1mA.

To make a current meter a shut is used. The shunt is basiacly a small value resistor in parallel with the meter. Most of the current flows though the shunt with a small amount passing though the meter movement.

The scale on the face of a meter may not tell you anything about the movement. In most cases the meter is setup to act as the face indicates but not always. A 5Amp meter might really be a 1mA movement meant for use with a shunt.

You need a meter that has a 5V movement if you don’t want to add an external resistor. Meters usually work on current and 1mA movements are common. You can make a 1mA meter movement work with about 5K of series resistance.

I have also found that you can open many meters and remove or replace an internal resistor to get the desired voltage range. This resistor is usually connected directly to the internal connection terminals. Be careful as it is very easy to damage a meter either physical or via too much current burning out the winding.

So I’ve got my Arduino, I’ve got my code, it all makes my portable meter twitch (hooray!). Now, I need to get actual meters to install. Ideally, since I’m buying these new, I’d prefer not to use resistors in the end. Should I simply buy a meter that goes to 5 amps, or my math wrong here?

use a 4.7K or 5.1K resistor in series to your meter from any Arduino PWM compatable output pin. There are 6 to choise from. Ground the other side of your meter. Use the AnalogWrite funciton and your meter will go from 0 to full scale with values from 0 to 255.

Great article, thank you! I’ve ordered my Arduino and the 1mA gauge to experiment on. One question, though – I’m not exactly sure where to solder on the Arduino. I couldn’t find a diagram or detailed photo on this article – could you help me out with this?

You need to close LCDSmartie when you upload. Only one applicaiton can use the serial port at a time, this is true for the USB interface as well as a hardware serial one.

The problem may be in your decoder code. I beleive LCDSmartie sends all the messages back to back so one decode function my be affecting another. Also check how you handle CR/LF in case that could be getting you.

I recomend starting with only one parameter from LCD Smartie. Test all you can with a single data value and your decoder. Since you have mulitple indicators you may have used multiple messages from LCD Smartie, if so, activate them one at a time. If you used a single long message, try one feild at a time. Also do these steps with the terminal instead of LCDSmartie. Look for a case where when you add one more of the steps to the configuration, things stop working. That will be the clue you need to isolate the problem.

This project gave me the inspiration to work on one of my own. I’m going to build a display with gauges an LCD and some RGB LEDs to show various hardware parameters. I’ve got it working intermittently but I’m having trouble with getting LCD smartie and the Arduino to play together. I’m able to connect and the arduino is receiving data, but it apparently isn’t receiving it in the right format to parse. I think I have LCD smartie configured correctly according to your guide but no luck. I’ve tested the arduino and gauges by sending my own serial characters to it in terminal and everything works fine. I’m wondering if the problem might have to do with LCD smartie transmitting data before the arduino is done running the bootloader? Any ideas?

If you can get at the analog signal feeding the meter then use an A/D converter. There are some products that interface via USB that can read analog voltages. Or you could use an Ardunio and a small applicaiton on your PC. The Ardunio has several 10-Bit A/D inputs.

They most gorgeous meters. Most if it is first hand – but essentially old stock in the style of http://www.navyradio.se/att/AA4.jpg. And the prices are extremely resonable – just a few euro’s to ten or so.

Eventually I will replace the faces, but I need to work on the mounting, and make it a little cleaner. These guys have an analog clock kit, quite different from mine, but they have nice templates I’ll use. Had I found these guys earlier, I might not have tried the Arduino thing: