USB CPU load meter
I got inspired by a post about using analog gauges to display PC stats. The author of the article uses a voltmeter and a PIC 18F2550 connected to the USB port to display the CPU usage and the download speed. I wanted to do something similar and started looking on Ebay for a fancy voltmeter. I couldn’t find anything I really liked but there was a tachometer which got my attention.
A tachometer is usually installed in a car to measure the rotation speed of the engine. but I was going to use it to display the level of CPU usage. I bought the tachometer on Ebay, from a Chinese seller. I paid it only £20 delivered but I can not say it is a top quality device. Though It does its work it is very plasticky and the needle movement isn’t very precise.
The tachometer connects to the engine PC through 3 wires: 2 wires for the 12V power supply (the red and the black wires), whilst the green wire carries the signal which drives the needle. If the tachometer was installed in a car the signal would be a square wave coming from the engine coil: the higher the frequency of the square wave the further the needle moves. I wasn’t sure about the required amplitude of the signal but I found out that 5V were just right.
Of course I wasn’t connecting the tachometer to an engine’s coil but to a PIC 18F2550 microcontroller which would create the 5V square wave to drive the needle. The beauty of the 18F2550 is that its size is quite small, it has 28 pins, has a reasonable amount of program memory and also hardware support for the USB 2.0.
This was my first project involving USB communications and the main reason of this work was experimenting with this family of USB devices, as well as having a nice homemade gadget sitting on my desk.
The hardware
The circuit for this project is the simplest possible: the microcontroller, the 4 Mhz crystal together with the load capacitors, a 470nF capacitor connected to the Vusb pin and a decoupling capacitor connected to the power rails. The PIC 18F2550 microcontroller requires a 5V power supply whilst the tachometer need 12V. I didn’t want to use any external power adapter but only the 5V (ish) coming from the USB port, which is able to supply up to 500 mA to an attached device. How to convert the 5V from the USB to 12V for the tacho?
What I needed was a Boost Converter but I had no experience in building one so I decided to buy something already assembled. I got a Anyvolt Micro Converter from Dimension Engineering, in Ohio. This component costs $19.99 + $1.25 for S&H. I ordered it from the producer because it is slightly cheaper than the suppliers here in the UK.

It convert an input voltage range of 2.6V to 14V to an output voltage of any value from 2.6V to 14V. It is very small in size and very easy to use: the only thing to be aware of is the amount of drained current: the datasheet contains the maximum values, which depend on the input and output voltages.
The firmware
When connected to the PC’s USB port, the microcontroller is seen as a HID device. This means there is no need to write a device driver for the PC because all the operating systems include the drivers for this family of devices. I used the CCS compiler to write the firmware, starting from one of the example files and making all the required changes. The firmware is very easy: it has to generate a square wave, whose frequency changes depending on the position we want the needle to turn to. I used the TIMER0 which is a 16-bit register incremented at each clock pulse. When the register overflows, an interrupt is generated which is served by the ISR (interrupt service routine). All what the ISR does is to change the state of the pin carrying the square wave to the tachometer: if during a ISR the pin is driven LOW in the following it will be driven HIGH, so we have generated a square wave.
To change the frequency of the square wave we have to change the time required by the TIMER0 to overflow: because it is a 16-bit register it requires 65536 clock pulses to overflow, generate the interrupt and start counting from 0 again. If, for example, we want to half this time we could, during the ISR, write the value 32768 into the TIMER0 register. In this way after the overflow TIMER0 is forced to start counting from 32768 instead of from 0 and the next interrupt will occur in half time. The firmware keeps writing new values into TIMER0 register, every time the ISR is executed, controlling in this way the frequency of the generated square wave. The values to write into TIMER0 are calculated and sent by the PC, through the USB port.
The host application

The application running on the PC is in charge of detecting whether the USB tachometer is connected, reading the current CPU usage value and sending to the microcontroller the correct values to write into the TIMER0 register during the ISR. For a good introduction on detecting and sending data to USB HID device, my suggestion is to start from this article which is quite easy.
My application has been written using C# and Visual Studio 2008. I found a very useful free component to interact with USB HID devices using C#: it hid all the complexity of invoking the Windows API and saved me lots of time.
If you really want to get into the development of USB devices and applications you absolutely have to buy a copy of the book USB Complete: this is bible and it contains everything you need to know. The author’s website is very good as well: you will find example code in VB.NET, C#, VB6. C/C++, the firmware for the Microchip and Cypress microcontrollers and tools for the debugging.
If you want more details on any aspect of the project leave a comment and I will be happy to replay.
UPDATE
Some readers requested the firmware for the microcontroller and the application for the PC. These are the links for the source codes and the compiled versions. To rebuild the firmware you need the CCS compiler. The compilation of the Windows application requires Visual Studio 2008. I think you can also use C# 2008 Express Edition, which is free. I haven’t tried but I am quite sure it works. In any case you have to install the Microsoft .NET Framework 3.5
Microcontroller firmware – binaries
Microcontroller firmware – source code







Hi. I am Cristiano Cesaretto and this is my space to share with you how I spend my time: definitely programming, C# for 99% of the time. Other passions are electronics as a hobbyist, in particular experimenting with PIC microcontrollers. I also love flight simulation though I don't practice very much.



CPU tachometer - Hack a Day | August 7th, 2009 at 1:20 pm #
[...] popular right now. [Cristiano] has done an analog display, but instead of brass and polished wood, he’s gone automotive themed with it. He purchased a cheap tachometer from ebay. A circuit had to be designed to give the tach [...]
yon | August 7th, 2009 at 1:50 pm #
Hi,
This is a great project!
Will you publish the hex code for the pic and the host application? I have some experience with electronics and have pretty much all the parts laying around but I can’t code, so it would be great if you would publish it and I’m sure many other people would appreciate it.
Congrats on the hackaday feature!
-Yon
CPU tachometer | Diy all the Way | August 7th, 2009 at 2:22 pm #
[...] popular right now. [Cristiano] has done an analog display, but instead of brass and polished wood, he’s gone automotive themed with it. He purchased a cheap tachometer from ebay. A circuit had to be designed to give the tach [...]
jehan | August 7th, 2009 at 3:02 pm #
amazing. simply amazing
Bruno Antunes | August 7th, 2009 at 4:28 pm #
I WANT ONE!
Very nice.
Phil C. | August 7th, 2009 at 7:30 pm #
Very nice. I remember seeing an LED version on the BeBox PC back in the ’90s and always wanted something like that for my PC. An analog one is pretty cool too. I don’t know if you’re running a dual- or quad-core rig, but it would be very nice to have a set of these (one for each CPU).
I also second the request for the downloadable PIC code. Without it, the schematic is useless.
NOTE: resubmittal due to mis-type of email address.
Cristiano | August 7th, 2009 at 8:48 pm #
Thanks everybody for the positive comments. I added the links to the firmware and Windows application at the end of the post, as requested. If you are not sure about anything, drop me a message and I will be happy to help.
yon | August 7th, 2009 at 9:11 pm #
Thank you!
otterpopjunkie | August 7th, 2009 at 9:47 pm #
Sweet!
I’ve got some real old ammeters lying around, might try and rig one up with this, great job!
Cristiano | August 7th, 2009 at 10:03 pm #
otterpopjunkie: have alook at the linked article at the beginning of the post. They used an ammeters and a voltmeter, like you want to do.
Fabriquez une Jauge USB pour la charge CPU. | www.semageek.com | August 7th, 2009 at 11:36 pm #
[...] Retrouvez l’intégralité du projet sur : http://www.cesaretto.it/usb-cpu-meter/ [...]
Marius van Witzenburg » USB CPU Meter with tachometer. | August 8th, 2009 at 8:12 am #
[...] For more information check the creators website at: http://www.cesaretto.it/usb-cpu-meter/ [...]
David Brenner | August 8th, 2009 at 4:52 pm #
Good job! I like the idea a lot and you did a great job documenting what you did.
Onur Toker | August 8th, 2009 at 6:54 pm #
Good job!
yon | August 8th, 2009 at 9:58 pm #
Hi,
For how many cylinder tachometer is this?
-Yon
Cristiano | August 8th, 2009 at 10:05 pm #
Yon, this is a tachometer for 4-cylinders engines
wanderingmoose | August 8th, 2009 at 11:45 pm #
Hi
Great idea, I have a serial port version, and I love it.
But more and more computers don’t have a serial port.
I was always wanting usb version….thanks!!!
(I now see others with the same thoughts….:) )
Now how about a three or four tach version that shows CPU, memory usage, Net speeds…..etc.
The other idea I had was to make the pc software configurable to choose the values to be indicated.
Thanks for love of programing and electronics.
yon | August 9th, 2009 at 2:21 am #
Ok, thank you, because that matters, right?
David Sutherland | August 10th, 2009 at 9:26 am #
How about an option switch on the CPU Meter that would allow the app to create an engine revving sound as the cpu throttles up?
Novel for a short time but it’d be worth it.
A la découverte de la Blogosphère » Un Tachometre USB pour son CPU. | August 11th, 2009 at 12:42 pm #
[...] Source : http://www.cesaretto.it/usb-cpu-meter/ [...]
Brett | August 13th, 2009 at 12:43 am #
I’m trying to use a similar tach with an Arduino and getting very weird results. The signal is a 5V square wave signal of equal time on/off, correct? So a 100Hz signal would be 5ms on followed by 5ms off.
Can you give an approximate frequency range that is being supplied to the tach? For instance, what is 1000rpm and what is 6000rpm? Thanks!
RuBBa_cHiKiN | August 13th, 2009 at 7:38 am #
I just ordered one of these http://www.directron.com/tachometer.html from Directron, as well as a Serial/USB adapter cable, and a Molex/AC adapter power set. (I’m hooking this up to a laptop.)
I’m going to change the tachometer at some point to a better pedestal one, similar to the one you’re using. Hopefully one with a 10k rpm limit, for more accurate percentage graphing. However, a lot of the ones I see on eBay are universal for 2,4,6,8 cyl engines. Would these still work with if they have a 3-wire setup? Or do I have to find one that’s a 4-cyl tach, and nothing else? Because that might be a bit harder to do.
Cristiano | August 13th, 2009 at 8:21 am #
@Brett:if I did the calculation correct, to set the tachometer at around 2000 RPM the 5V square wave has a frequency of 1184 Hz (422 us ON and 422 us OFF). These values suppose you are using a tachometer for 4 cylinders engines, otherwise the values will be different. Double check the tacho is power with 12V (5V should be OK for the pulse signal).
@#
RuBBa_cHiKiN: the universal tachometers you find on Ebay are all ok. They have a switch on the back to select the number of cylinders you want to use. Actually you can choose any number of cylinders, they are all right. What changes is the frequency of the pulse signal.
Brett | August 13th, 2009 at 9:19 pm #
Thanks for the quick reply Cristiano. I am using a universal tach set to 4 cylinder. I’m supplying 12V to the Arduino and using it’s Vin pin to power the tach (so it gets 12V as well), and of course the Arduino outputs 5V for the pulse. If I get it working I’ll post a little how-to for those with Arduinos (of course, it won’t work with your program, but there’s a lot of documentation for using serial with the Arduino).
RuBBa_cHiKiN | August 17th, 2009 at 12:23 pm #
Thanks for the info! =]
Maciej | September 29th, 2009 at 12:56 am #
Love it!! I was looking for something like that for a loooong time, i hope its not too hard for me to build it by myself though…
Pulsartomi | November 6th, 2009 at 8:59 pm #
Dear Cristiano!
Thank You for sharing this project, I’m new in programming usb port with pic, and I think it is a very good start for learning that.
Best Regards, Tomi
Pawel | December 6th, 2009 at 10:12 pm #
Where can we buy complete USB CPU load meter?
Fred | February 4th, 2010 at 8:51 am #
Hello Cristiano,
Any plan to update Call Manager to include Rynga.com ?
Regards
Fred