pc meter header

Analog PC Stats Meter


At some point while researching microcontroller projects, I came across several people who had used Arduinos and PICs to drive analog panel meters so they would display computer stats such as CPU load, memory usage, etc.  It immediately struck me as something I just had to do.  Here it is.  My PC meter uses an Arduino microcontroller and receives the stats from a .NET Framework application I wrote in C#.Net.  It’s housed in a plastic enclosure and looks quite professional IMHO.  It was a fun project, and something I think most any computer/electronics geek would enjoy.  I love mine, and I look forward to building more.

Here it is in action:

Read on for details on the parts and tools I used, some info on the process of building the device (and the problems I ran into) and links to download the source code and meter templates.

The parts

  • Microcontroller – Arduino Leonardo (w/o headers).  It’s easy to learn, has plenty of outputs (this project requires 6), and has a built-in virtual serial port for communication with the PC to be monitored.  I picked the version w/o headers since this is a permanent build.
  • EnclosureSerpac 17s case in black.  It’s just about the right size to house the meters I selected, and the price is right.
  • ammetersMeters – There’s lots of options here.  I personally chose to go with 1ma ammeters, as I saw other examples that used them.  The specific ones I ordered came from Uxcell, a Hong Kong based company that sells factory-direct items from China.  I don’t know how accurate the meters are, but they’re good enough for this project, and they were cheap.  I ordered them through Uxcell on Amazon.com.  The listing is gone now, but they were described as model #85C1-A, Class 2.5 accuracy 0-1ma ammeters.  If you search Amazon.com or Ebay they’re pretty easy to find.  One caveat: some reviewers indicate quality issues with these imported meters.  Of the three I purchased, I did have one that I could not adjust to zero w/o opening it up.  Besides that though, they all work fine, and I think the quality matches the price I paid for them.
    • Resistors for meters – With 1ma ammeters, the correct resistor is 5kΩ ohm (to get 1ma of current at 5 volts.)  4.7kΩ (which I used) is more common, and will work just find as long as the code is adjusted accordingly.  I get into more detail about this in the code section.
  • LEDs – These are used to indicate when either the CPU load or memory usage is peaking (above 80%).  I used two 5mm red/green bicolor LEDs from Radio Shack (#276-0012) which are held in place with two snap-in panel mount LED holders, also from Radio Shack (#276-0079).
    • Resistors for LEDs – The LEDs I used are good for 30ma, and they seem to need it for optimal brightness in my opinion.  The resistor to do this at 5v is 100Ω.  Note that 30ma is getting close to the Leonardo’s maximum 40ma current per pin, but I haven’t had any problems so it seems to be safe.  I don’t know if all ‘duinos can source/sink 30ma, so if using another board, you’ll want to verify this.
  • Panel mount USB cable – The Leonardo has a USB micro connector, and I was concerned about durability as my meter device is plugged and unplugged over time.  So I installed a panel mount cable that brings the micro connector out to a USB B female connector.  I got mine from Adafruit.

The software

Software I used

  • Software usedArduino IDE – For developing the Arduino program.  Also includes the necessary drivers for the Arduino’s virtual serial port.
  • Microsoft Visual C# 2010 Express – For developing the desktop application.  It’s a free (as in beer) version of Microsoft’s Visual Studio IDE that supports the C#.Net 2010 language.
  • Inkscape – Open source vector graphic editor that I used to design the new meter faces.

Download the files

All of the code I wrote and the meter faces I created can be downloaded in one big ZIP archive here. The meter faces are released under a CC license and the Arduino code is public domain.  The desktop application is copyrighted, however it is released under a BSD license so you may use, modify and redistribute the code freely as long as credit is given.  See the license.txt file for more details.

If you’re not interested in the desktop application’s source code and just want the executable, you can find it in the ZIP archive in the PcMeterSln\PcMeter\bin\Release folder.  You’ll need the PcMeter.exe file which is the actual executable and the PcMeter.exe.config file which stores the configuration settings.  The program requires the Microsoft .NET Framework 4.0 to be installed on your computer, which is freely available here.

Building the Device

Cutting and drilling the enclosure

Cutting holes for metersFor me, this was the hardest part, and the least forgiving.  I bought two enclosures to be safe, but fortunately I only needed one.  I used a Dremel with the Circle Cutter & Straight Edge Guide accessory to cut the large circles needed to mount the meters.  I measured carefully, double-checked my measurements, and cut two perfect holes.  Somehow though, they ended up being just a little too small.  I don’t know if I messed up the circle cutter adjustment somehow, but that’s my best guess as to what went wrong.  Next time I’ll triple check it.  I ended up having to cut the holes larger “freestyle”, so now they don’t look so perfect.  But with the meters installed, it doesn’t show.

meter templateI had trouble figuring out how to determine the mounting location of the two bolts that hold the meter in place, so I made a template from some scrap wood to use as a guide.  It’s not perfect, but it did the job.


Creating the custom meter faces

meter facesThe meters ship with metal faces that indicate a reading from 0 to 1ma.  Disassembling the meters is very easy using a small screwdriver, allowing for the faces to be replaced with custom ones.  I scanned one of the original meters faces, imported it into Inkscape, and then drew new faces for CPU% and MEM% based on the scanned image.  The designs I came up with are pretty basic as I don’t have much experience with Inkscape but I’m pretty happy with them.  I printed the faces on card stock and used a hobby knife to cut them out and trim them to fit inside the meters.

Putting it all together

complete pc meter top view

internal view overviewarduino and wiringThe Arduino Leonardo and USB cable are mounted to the bottom portion of the Serpac enclosure, and the meters and LEDs are mounted to the top portion.  The position of the USB cable was carefully chosen so the cable runs in between the two terminals attached to the meter that’s mounted above it.  Somewhat of a tight fit, but it worked out.


PC meter backpc meter angle

The circuit is simple, so I skipped breadboarding the four resistors and just soldering them in with the wiring.  The resistors for the meters are soldered directly to the ring terminals which made them easy to implement.  The wiring going the Arduino is soldered as well since this is a permanent build.

The assembled unit looks great and is definitely one of the more “professional” looking projects I’ve build from scratch.  The size is a good fit for having it sitting on top of a desk or PC case.

Writing the code

This is just a quick overview of what the programs are doing, and some points of interest.

The desktop application

Desktop application screenshotThe desktop application is written in C#.Net and was developed using Microsoft Visual C# 2010 Express.  The program is a little “heavy”, as it requires .NET Framework 4.0 to be installed on the computer and it’s not particularly lean given the small task it has.  I’m a VB/C# developer by trade though so it was the most comfortable environment for me the develop the desktop application in.

I designed the program so it can be used by anyone without having to modify the source code.  All of the options you might need to change can be modified via the user interface.  You can specify the COM port to use, and choose to have the program connect to the COM port when it opens.  The program can also be set to start minimized.  This way, you can have it start when Windows loads and it will be out of the way.  When connected to the COM port, the application reads the CPU and memory usage (utilizing the System.Diagnostics.PerformanceCounter class) every 500ms and display the readings on the form and send them to the selected COM port. CPU usage comes from the System.Diagnostics.PerformanceCounter class, and memory usage is calculated using GetPerformanceInfo by Antonio Bakula.

The Arduino program

Arduino Leonardo in PC MeterThe Arduino program continuously reads the virtual COM port and when it receives data in the correct format, it parses it and sets the meters and LEDs accordingly.  Th reading for CPU% is “smoothed” over the last four readings to prevent drastic jumps in the displayed value.  This is not done for Memory usage, since it’s typically a more stable value.  If no data in the correct format is found for more than three seconds, the device enters a “screen saver” mode where it moves the needles on the meters back and forth in opposite directions to show it’s running but not receiving data.

Several constants are used to indicate which pins are used for the various outputs and other settings, so it’s easy to change them if necessary.  And actually, there are two that will almost always need to be changed for each specific device, which are METER_A_MAX and METER_B_MAX.  Let’s look at why this is.

The Arduino’s analogWrite function uses a maximum value of 255 which results in the max voltage (typically 5v) being output on the specified pin.  However, the “true” max value may be less than this, depending on the accuracy of the meters used and the value/accuracy of the resistors.  In the device I built, 5kΩ resistors were required to achieve 1ma of current at 5v, which would put the meters at the 100% position.  I could purchase precision 5kΩ resistors and have the current be really accurate, but its more convenient (and cheaper) to use 4.7kΩ 5% tolerance resistors instead, which are very common.  To compensate, I adjusted the two MAX constants to the necessary values to display 100% on the meters correctly.  Even with the correct precision resistors, this may still have been necessary as the inexpensive meters I used are probably not high precision.

Problems/potential enhancements


Overall the meter works great, but there are a few issues.

  • The desktop applications hangs on Windows shutdown – This is because of how I developed the program, and a bug in .Net applications that causes programs to lose track of their forms when they’re hidden from the taskbar.  I need to change the way I have the application setup to fix this, but since it’s not a huge issue it hasn’t been a priority.
  • The desktop application reports CPU activity when there is none, at least on one computer – I’ve seen this on a PC running Windows 7 Professional.  Other machines running Windows 7 and XP don’t do this.  I’m not sure it’s my implementation of the PerformanceCounter class, or if the class it just giving bad values, but I can’t see anything wrong in the code that would cause this.  I need to test it further.
  • The 100% position of the meters is affected by the input voltage – The typical USB voltage is 5v, but it can (and does) vary.  After finishing the project, and ensuring everything was working great, I moved the PC Meter from my laptop to a desktop PC, and I noticed right away that on the desktop PC, the needles weren’t quite hitting 100% when they should.  I suspected the voltage, so got my meter out and checked both machines.  Sure enough, they varied.  The laptop is right around 5v, and the desktop PC is about 4.9v.  It’s a small difference, and the needle position is not affected that much, but I still found it bothersome.  One fix would be to use the voltage regulator built into the Arduino, but then I would lose the convenience of plugging in just one cable for power and data.  Another idea is adding a potentiometer to the circuit and using it as an adjustment to account for voltage differences.

Potential enhancements

  • Vintage meterMeters for additional statistics – Besides CPU and memory usage, it might be nice to also monitor network bandwidth utilization, individual CPU cores, etc.  The PerformanceCounter class supports several stats, and the programs could be modified to support additional values with some simple modifications.
  • More aesthetically pleasing meter – I’m happy with how the device looks, but it is fairly simple and a bit “industrial” looking.  It might be nice to do something in a wood enclosure with some vintage meters.

Links/Sources of inspiration

The idea for this project and the information needed to complete it came from several sources, some of which I share here.

  • Show pc stats on analog gauges – great article with lots of info on interfacing with analog gauges.  It’s based on a PIC microcontroller, but much of the info applies regardless of the microcontroller used.  It uses the LCD Smartie application to send data over the serial port to the microcontroller.  I considered doing this myself before writing my own application. However, development on LCD Smartie appears to have stalled which concerned me, and I wanted to try out the PerformanceCounter class anyways.
  • Arduino Analog Gauge – Project that drives meters based on PC stats using an Arduino microcontroller.  It is based on the previously mentioned article and also uses LCD Smartie.
  • Arduino: Showing CPU load with 9 LEDs! – This project uses LEDs to display CPU load rather than a meter, but it uses a C#.Net application to drive the meter, which I referred to as I learned to do it myself.
  • GetPerformanceInfo by Antonio Bakula – this is the code I use to get the memory stats. See this stack overflow post as well.
  • mnedix brought the memory% issue in my original application to my attention. Check out his CPU/memory indicator that runs off my C# application but uses nixie tubes instead of panel meters as indicators. Very cool!

22 thoughts on “Analog PC Stats Meter

  1. Fabulous write-up. Been considering adding some gauges to a custom build and came across your article. It’s organized very nicely too, including issues you had, links to sources, etc. Was a good read and really helped me to organize my thoughts about how I might add some analog gauges. Thank you!

      1. Yes, 1 MΩ should work it’ll be more sesitnive to noise, so don’t make the lines to the PIR sensor too long. Note that current is only drawn when pulled down, so if no-motion is 1 , then the internal pull-up isn’t so bad (you could even turn it off once triggered, and periodically re-enable it to check until the input is high again).My impression is that there are always more tricks waiting behind the horizon

    1. resistors to the leds and connect them to the tiarsnstors. I then integrated the code that I used here in my sketch and uploaded it to my hexapod. I first had to replace the delay function, I just used

  2. Thank you for a great project. A question though: is it possible to use an Arduino Nano instead of a Leonardo? I see the specs are pretty much similar so it should be possible. I’m thinking of building your project but use Nixie tubes instead of analog meters, also for vintage/steampunk look. I assume that the pc_meter.txt file in the Arduino folder is the source code, right?
    PS: did you have a chance to work on the bugs?

    1. Thanks Nedix. I think the Nano should work – it’s got a USB interface and enough inputs/outputs. You’ll want to verify it for sure though, I haven’t used the Nano myself. The Nixie tube idea sounds awesome! You are correct, the txt file is the Arduino program. As for the bugs, I haven’t done any more troubleshooting. My PC meter has been installed on my work PC for several months and works great overall. Good luck with your project and please share it, I’d love to see what you come up with!

  3. Hello

    I’m trying to run your application on win 7, using a Leonardo board. But everytime I press “connect”, the application freezes, and no meter activity. Any idea what’s causing this?

    1. Quizz_Kid – Unfortunately, no. I’ve used it on Windows 7 64bit with no problem. The only thing I can suggest is to make sure that the selected COM port is correct. Even then though, it seems in the past when the port was wrong, it didn’t freeze for me, it just failed to connect and I had to fix the settings.

  4. Hi, great great programs, thx a lot for sharing !

    I’ve made a crazy project for cooling my PC, with a watercase, TECs, Arduino, vumeter, and all that good stuff.
    I’m using your program to show CPU and RAM usage, but since few days, the program is crashing like hell, so i went to this website, and pick up the last version.. First of all, i’m on Windows 8, and i keep having “smart screen” blocking pcmeter.exe when i launch it, like if it was a virus or key-logger.
    On the setting, i have tell windows to trust your program, but Avast! put it in quarantine… I’ve sent to Avast a report, for a false-positive.

    Have you any idea of what’s going on ?

    1. I’ve actually find out why pcmeter.exe crashing : By mistake, i’ve left something writing the serial port, and i think it just overflow pcmeter.exe.
      Now i have remove this serial thing, pcmeter don’t crash.

    2. Glad to hear you got the crashing fixed! As for Smartscreen and Avast, I don’t know why they think my program is behaving badly – it just polls the systems stats and sends it to the Arduino. I haven’t tried it on Win8 myself yet and don’t use Avast so I can’t comment. Thanks for telling me about it though, I appreciate the feedback!

  5. I am really glad to find your project. I had found a similar project a couple years ago that used a PIC processor:


    …and since I’m not a coder by trade or ability I found the PIC environment very difficult to navigate. Microchip aims directly at the professional market and makes no accommodation for amateur hobbyists. So I’ve been waiting for someone to do something similar with an Arduino.

    I have a Leonardo on order, and I already have the meters I want to use, pictured in the link below. These are called switchboard meters, commonly used in industrial panels such as in power plants. The pointer swings thru a 270 degree arc. To me these are super-cool and I’ve been itching to get them working as windows process monitors. Got these on EBay:

    1. Hi Les, Glad to be of help! I agree, PIC takes some dedication. Arduino is lots of fun because of how accessible it is. That meter you linked to is beautiful! Good luck with your project.

      1. I finally got this working. I had trouble with connecting the Leonardo to the USB port, and after sorting through 4 pages of the Arduino help forum I found that other people trying to run Leonardo on the 64-bit version of Windows 7 had the same problem. This was solved for us by switching from a USB 3.0 port to a USB 2.0 port. Go figger.

        Below is a clip of my preliminary results with the CPU meter. This meter responds with slow graceful movements, so I was able to disable the averaging function in the Arduino code.

        I will be setting this up in an enclosure along with the Memory Usage meter and LEDs. I modified the circuit by using a 4500 ohm resistor with a 1000 ohm potentiometer so that I can use the pot to adjust the full range setting on the meter.

        I eagerly wait for you to update this project with additional stats!


        1. I really like that meter! It does respond beautifully. Even with the averaging mine are a bit jerky to large changes. I could average it over a longer range, but haven’t tried it yet.

          I’m on Windows 7 64-bit myself, but never tried it on a USB 3.0 port, that’s good to know!

          I like the pot adjustment! I hope to do that if/when I build another one of these. I still hope to do another one in a custom wood case, with vintage meters and maybe some additional stats.

          Thanks so much for sharing your work and please keep letting me know about it! I enjoy hearing from others who have built on my work here. It helps encourage me to get back to working on it some more!

  6. Hey, i did your project and it works, but i wanted another meter to show cpu temp and found how limited WMI is for this. so i looked at a few options and ended up chancing on a fork of open hardware monitor (which has extensive sensor range) that has serial output, i modified it to output serial in your format and it works, then i also heavily modified your arduino code to make it how i like it with needle movement as smooth as possible and easily adaptable number of meters. (and took out the led code, as i dont have them). you can see my project page here: https://hackaday.io/project/10629-pc-analog-panel-meters-w-arduino and the OHM fork here: https://github.com/cody82/open-hardware-monitor

    1. Awesome! Nice work on on the OHM fork. Having temperature would be cool. That looks like a great program, I didn’t know about it but I’ll have to try it out. I like the meters too, fits under your monitor. That’s exactly what I want to do with my next meter build, so I can see it more easily. Thanks for sharing, love it!

  7. This looks like it would be a fun project. I have a few vintage meters but they are in A.C. milliampres Will they work ok with this setup? or do I need to do some more searching?

    1. Hi Anthony! I’ve never worked with AC meters, but since the output of the Arduino is DC, I expect it won’t work. If you want to go vintage though I can say I’ve had pretty good luck finding vintage 1ma DC meters, so that’s something you might consider looking into. Other small values will work to, you just have to change the resistor accordingly. Good luck, and if you build it, please share!

Leave a Reply

Your email address will not be published. Required fields are marked *