Finished: DIY serial analog duty cycle meter (for CPU and RAM load) - Page 1
Forum section: electronics / beginners

author: faekjarz
author_rank: Regular Contributor
timestamp: October 19, 2016, 11:58:38 am
content: Hey there, i need some noob lube!I want to build aserial analog duty cycle meter.Its application would be a CPU load meter …like this:Core 2 Duo:Core i7 (w/ HT):Here's my idea (Plan A):The meter appliance will be connected via USB, and contain a USB-to-serial module (CH340)My OS of choice is Linux, so the software should be relatively easy: a shell script loop collects data (load per CPU core, as int 0-100) and dumps it (in CSV format, or such) to /dev/ttyUSBxAn MCU, probably an Arduino nano (ATmega328P), does some *magic* with the numbers and drives avoltage regulating black boxThe output of thevoltage regulating black boxis fed intothose panel meters(1 per core) …scale x10, 0V = 0% load, 10V = 100% loadBam, done, now i have moving needles which indicate CPU load…do i?This project has constants:It is connected via USB (, and preferably, but optionally, entirely powered via USB / 5V @ 500mA envelope)Data is fed serially via a USB-to-serial moduleThere are some Questions:Thevoltage regulating black boxis a mystery: …what could be inside? …PWM? …booster+switches+resistors?How much power do those panel meters consume?Maybe someone already built a "serial analog duty cycle meter" but DuckDuckGo didn't find it?What alternatives do exist? …maybe re-purposing a VU meter (those are basically Amps meters, right?)?

author: faekjarz
author_rank: Regular Contributor
timestamp: October 19, 2016, 01:26:22 pm
content: I found this ->https://learn.adafruit.com/trinket-powered-analog-meter-clock?view=all<- an analog meter clock. They use µA meters. I think i can go from there.

author: faekjarz
author_rank: Regular Contributor
timestamp: October 19, 2016, 01:41:01 pm
content: Seems like someone else had my idea before:http://www.sharebrained.com/2012/05/30/the-monulator/http://www.lungstruck.com/projects/pc-meter/… here are some more exampleshttps://www.google.de/search?tbm=isch&q=Clock+Analog+Meterhttps://www.google.de/search?tbm=isch&q=analog+usb+meter

author: Ian.M
author_rank: Super Contributor
timestamp: October 19, 2016, 02:01:28 pm
content: Arduino with enough PWM pins for the number of meters. RC filter for each meter with a time constant of the order of 0.1 seconds to get smooth movement, then direct to the meter coil. Adjust the total series resistance for full scale defection with a steady 5V output level. Its trivial enough not to even need a PCB apart from the arduino board, which should be bought without headers fitted so you can solder direct to it.The Arduino Nano only has 6 PWM pins so if you have more than 6 cores you need another solution. I suggest Arduino Pro Mini, which doesn't have on-board USB to serial. Feed all the Arduino RX lines in parallel via the same USB <=> serial converter, and use a protocol that 'tags' each value with the core meter its for, e.g. a binary protocol consisting of a continuous byte stream of [0x80 | meter_address<<1 | (PWM_value & 1) ],[PWM_value>>1], Because the high bit is set for the first byte of each meter block, synchronisation is easy. Set the first meter address by grounding a pattern of spare digital inputs on each board so they can all run absolutely identical firmware.That's the cheap and easy way to do it one-off. If you wish to mass produce them there are better options e.g. multi-channel LED driver chips with individual PWM dimming - just fit RC filters feeding meters instead of LEDs.

author: JS
author_rank: Frequent Contributor
timestamp: October 19, 2016, 03:26:43 pm
content: I don't think you need RC filters, the meters usually are slow enough so you don't have to worry about a fast enough PWM and then your smoothing could be done in software. Which is usually what you want with µC projects, as lower part count as possible, lines of code comes easier to swap if the first try isn't what you wanted.Then, for theyou need to understand a basic of how they work, of course you need a DC one. They move the needle proportionally to the current in the winding, the winding has a resistance, you could add a resistor in series to increase the voltage at the same current or you could use a shunt resistor in parallel to increase the total current for the same current through the winding. First, you want a low current instrument so you don't need to feed more power than what you need, second you want a low voltage instrument so you don't need to have a boost circuit to get to the max range. The easiest choice would be a 5V meter, so you have the 100% with 100% duty cycle, but the needle won't be death on 100%, so probably better to start with a lower one and have a little room to play. As you are adding a resistor you could just go for the lower current meter you can find (without getting crasy low cause they are more expensive) Try to get something low enough it can be driven directly from the µC, 1mA for example. Then you could add a trim for each one and leave space in the board in case you need that cap, you could add one later to dampen the PWM freq if needed. Or just buy the cheapest one, open (while you change the backing paper) and take the unneeded resistor out.JS

author: Ian.M
author_rank: Super Contributor
timestamp: October 19, 2016, 03:36:00 pm
content: Arduino PWMs aren't always that fast (can be as low as 488 Hz) and the RC filter also protects the MCU from back-EMF from PWMing the meter coil inductance. You need a resistor anyway to set the FSD and slapping a cap across the coil doesn't significantly increase the cost.

author: faekjarz
author_rank: Regular Contributor
timestamp: November 25, 2016, 12:00:29 am
content: Hey there!Here's an update on the project progress.Firstly, my Arduino firmware.The host script, that collects CPU and RAM load data and pushes it to /dev/ttyUSBn does not exist, yet. I'll publish it in this thread, once it's done.Code:/*Serial Analogue Duty Cycle MeterArduino firmwareAuthor: faekjarzVersion: 20161124.2License: WTF-DNSM (Public Domain -ish)> Do Whatever The Funk you want with it, but> Do Not Sue Me if it burns your house and/or kills your cat!Developed and tested on an Arduino Nano 3 clone w/ CH340G USB ttyThe communication protocol is simple. One line per dataset,terminated by a line feed char (\n). A dataset comprises of an integerchannel identifier, a colon, and a duty cycle integer of max 3 digits.e.g. 0:42\n1:69\n0:100\1:0Datasets will be somewhat validated, and the duty cycle values will beconstrain()ed to the range of 0 to 100 (%). The duty cycle values willthen be map()ed (translated) to the calibrated full scale PWM values.For full scale PWM calibration, i used the Fade example,from the Arduino IDE: File > Examples > 01.Basics > Fade.I adjusted fadeAmount to 1 and played with the 255 in the if statement.I used an initial maximum of 100, and a 22k resistor between pin and meter,then incremented my way up to full scale, until the needle didn't move further.Channel data is identified by the array index.i.e. chPin, calPWMfs, ... relate to channel 0 (1st),chPin, calPWMfs, ... relate to channel 1 (2nd), ...If your setup has more than two meters, well then, just add more channels. ;DOnly the first 3 variables, chCount, chPin, and calPWMfs, have to be altered.*/// the amount of channels: 2 meters = 2 channels = 2// afaik, there is no method to count array elements, must set manuallyconst int chCount = 2;// to wich pins the meters are connectedconst int chPin[] = {3, 5};// calibrate max PWM for full scale deflection// These are MY values, for MY meters, and MY 22k resistors// Your cal may vary.// 0, right, yellow, 152// 1, left, red, 177const int calPWMfs[] = {152, 177};// miscellanious initialisationconst boolean d = true; // serial debuggingconst int loopDelay = 50; // milliseconds (1/1000)boolean inputReady = false;String inputString;int seppos;int ch;int duty;int valDuty; // an array with chCount elementsint valPWM; // an array with chCount elementsvoid setup (){// initialise UARTSerial.begin(9600);Serial.println("begin");if(d)Serial.println("debug output is enabled");if(d){Serial.print("channels: ");Serial.println(chCount);}// set meter pin modefor (int i = 0; i < chCount; i++){pinMode(chPin, OUTPUT);if(d){Serial.print("channel ");Serial.print(i);Serial.print(" pin ");Serial.print(chPin);Serial.println(" mode: OUTPUT");}}}void loop (){// handle input when readyif (inputReady){if(d){Serial.println("inputReady");Serial.print("inputString: '");Serial.print(inputString);Serial.println("'");}// find separatorseppos = inputString.indexOf(':');if(d){Serial.print("seppos: ");Serial.println(seppos);}// validate separator positionif (seppos < 1){if(d){Serial.println("nope: invalid input");}}else{// extract channel id fieldch = inputString.substring(0, seppos).toInt();if(d){Serial.print("ch: ");Serial.println(ch);}// extract duty cycle fieldduty = inputString.substring(seppos + 1).toInt();if(d){Serial.print("duty: ");Serial.println(duty);}// constrain duty cyle value (0 - 100%)duty = constrain(duty, 0, 100);if(d){Serial.print("constrained duty: ");Serial.println(duty);}// update memory and meters only if changedif (duty == valDuty) {if(d){Serial.println("nope: no changes");}}else{if(d){Serial.print("old valDuty: ");Serial.println(valDuty);}valDuty = duty;if(d){Serial.print("new valDuty: ");Serial.println(valDuty);}// map value to calibrated PWM valuevalPWM = map(valDuty, 0, 100, 0, calPWMfs);if(d){Serial.print("mapped valPWM: ");Serial.println(valPWM);}// update meter pin, set new PWM valueanalogWrite(chPin, valPWM);}}// handling done reset input varsinputString = "";inputReady = false;}// everyone loves a little nap, right?delay(loopDelay);}void serialEvent (){while (Serial.available()){// collect new bytechar newb = (char)Serial.read();// check for newline (\n), end of datasetif (newb == '\n'){inputReady = true;}else{// append to string variableinputString += newb;}}}Secondly, a picture of the disassembled dual meter, that arrived from China the other day.…and a screen shot of the Serial Monitor with some debug output

author: faekjarz
author_rank: Regular Contributor
timestamp: November 28, 2016, 03:00:15 pm
content: May I introduce the Pussy Meter.It doesn't purr, but its whiskers twitch.Here's a video of it:with twitter account:https://twitter.com/faekjarz/status/803241651074371584without twitter account:https://video.twimg.com/ext_tw_video/803241308890533888/pu/vid/1280x720/UJz6VopR6-nzyP_A.mp4Here're the essential project files, see attachment:SerialAnalogueMeter.ino: Arduino firmwareSerialAnalogueMeter.sh: Linux host shell scriptscale.svg: the face plate created with Inkscapeoutput.pdf: same face plate, different file format…this is the meter I used:https://www.aliexpress.com/item/new-SZ-70-Panel-Dual-SWR-Forwad-Reflected-VU-Meter-100uA/1585330306.html

author: faekjarz
author_rank: Regular Contributor
timestamp: April 21, 2017, 12:18:15 pm
content: Pussymeter mk 2:Firmware / script upgradei hope you don't mind my thread cross-linking:https://www.eevblog.com/forum/beginners/iterating-serial-ports-to-identify-the-target-device/The systemd upgrade, i.e. updated project ZIP archive, will be posted here in this thread.