I always wanted to build a synth inside of a mannequin head and the Noise Toaster Custom Build Contest seemed like a good reason to do it. The head came from a beauty supply shop. All the knobs and switches were in my stock of spare parts. The pots and components for the circuit board are new. This is a fresh build of a noise toaster, just with an unusual enclosure.
My cameraman started to fade along with the frequency, but we got a short demo video.
In the previous post I promised an interesting analog panel meter to integrate with the Arduino, and here it is. I picked up this Fluke branded panel meter at an amateur radio swap meet for maybe five dollars. What caught my eye was first that it was a Fluke, and second that it has zero at the center. This style of meter is much less common than the ones with zero at one end. This panel meter likely came out of a differential volt meter like the Fluke 803. In a differential volt meter you need to be able to measure how far off you are in the positive or negative direction from a reference voltage, hence a zero at the center.
The conundrum here is that while we can fake an analog output of zero to five volts using a PWM output pin to swing the meter in the positive direction, we don’t have a way to produce a negative voltage from an output pin to swing the meter in the negative direction. Luckily, we don’t have to. Remember that the meter is really an ammeter. It doesn’t respond to negative voltages, it responds to the current flowing in one direction to the other. Normally we could run an analog panel meter by connecting one end to a PWM output pin through a resistor and connecting the other end to ground. This time, though, we will connect both ends of the meter to PWM output pins. That way we can turn one output on and the other off to make the current go one way, and then switch the one off and the other on to make the current go the other way.
First I needed to find the series resistance necessary to get a full-scale reading at 5V on the meter. To do this I connected the meter up to two PWM output pins through a 100k potentiometer and a 10k resistor. I then wrote a very small Arduino program to turn the one pin on full while keeping the other one off. Once I had adjusted the potentiometer to get full-scale, I revisited the code.
I decided to encapsulate the control of the meter in one function. Because we want to take advantage of the full PWM resolution in the positive and negative direction, the function takes an integer between -255 and +255. After some range limiting, the function simply turns on one of the PWM outputs or the other to make the needle move left or right. Code in the loop() function just moves the needle left and right through the meter’s range.
#define NEG_METER 9
#define POS_METER 10
void setPanelMeter(int value) {
if (value > 255) {
value = 255;
}
if (value < -255) {
value = -255;
}
if (value > 0) {
analogWrite(NEG_METER, 0);
analogWrite(POS_METER, value);
}
else {
analogWrite(NEG_METER, -1*value);
analogWrite(POS_METER, 0);
}
}
void setup() {
pinMode(NEG_METER, OUTPUT);
pinMode(POS_METER, OUTPUT);
}
void loop() {
// This code "exercises" the meter through its range
int i = 0;
int direct = 1;
while (true) {
if (direct * i >= 255) {
direct *= -1;
}
i += direct;
setPanelMeter(i);
delay(10);
}
}
So what will I use this meter for? I’m not sure at this point. My first thought is to keep it analog and maybe build a differential volt meter out of it. Whatever I do, I won’t try to change the scale.
One fun way to give your project a retro feel is to salvage analog panel meters and use them as output devices. Integrating an analog panel meter into your project will take a little experimentation, however. It’s rare that salvaged meters come with a datasheet, so we will have to measure the meter’s electrical characteristics ourselves.
The first thing to know about analog panel meters is that the scale printed on the face of the meter often has nothing to do with what the meter actually measures. This is because all analog meters are ammeters. A current through a coil in the meter pushes the needle against a spring until the two reach an equilibrium at the desired reading. Making an analog panel meter measure voltage or wattage requires additional circuitry to convert those quantities into a current to move the meter. If you don’t see any additional circuitry, it’s best to assume your panel meter is a normal ammeter and that the current needed for a full-scale reading is small, very small, possibly a few microamperes. So we need to be careful here. What you will need for this measurement are:
An Arduino, preferably the one you intend to use in your project
Potentiometers of several values, 100k and 10k for example.
Resistors of several values, 100k, 10k, 1k for example. Don’t go smaller than 125R.
Optionally, a multimeter
To start, make sure your potentiometer is turned all the way to maximum resistance and that you know which terminals to connect to for maximum resistance. The muiltimeter can help you do this. Turn the largest-value potentiometer fully counter-clockwise and test the leads to find out which two give maximum resistance. With the multimeter still attached, turn the knob a little to make sure the resistance changes. If it doesn’t, try a different pair of leads. When you have the right two leads, hook one of them to the 5V pin on the Arduino and hook the other lead to the largest fixed-value resistor you have. In my case, I am hooking a 100k potentiometer to the 5V pin on the Arduino and to a 75k fixed resistor. (A 200k fixed resistor would be an even better starting point.) Note that if you are using an Arduino variant that runs at 3.3V then you should connect the potentiometer to the 3.3V supply. We want to use the same voltage that you will be using for I/O. (If you want very accurate results, write up a program for your Arduino that sets high the exact output pin you intend to connect the meter to in your final project and connect the potentiometer to that pin instead of 5V.)
Next you can hook the positive terminal of the analog panel meter to the other end of the fixed resistor and the negative terminal to the ground (GND) pin on the Arduino. If you are lucky, the back of your meter will have a plus sign next to the positive terminal, or it will be marked red. If there are no markings, don’t fret! The convention for panel meter hookups is that when you are looking at the meter from the front, as you would read it, the positive terminal will be to the right and the negative to the left. Once we have everything hooked up you can double check by turning the power on briefly. If the needle seems to push in the wrong direction, you can disconnect the power and reverse the connections.
Our goal in measuring the meter is to determine exactly what additional resistance we need in-line with the analog panel meter to produce a full-scale reading when driven by our Arduino. To do this, turn on the power and check that the needle has moved, even if just a little bit. Then slowly turn the resistance down on the potentiometer until the needle sweeps all the way to full scale. With the first resistor value you try, there is a very good chance the meter will not reach full-scale. In that case, turn the potentiometer back up and replace the resistor with a smaller one. In my case, I had to replace the 75k resistor with a 3.6k resistor in order to make the analog meter read full-scale. If you find that control of the potentiometer is too sensitive and you can’t get the needle right on the maximum reading then put in a smaller-value potentiomter and slightly higher-value fixed resistor. For example, instead of using a 100k potentiometer and a 3.6k fixed resistor, it would have worked for me to use a 10k potentiometer and a 10k resistor. If you have lowered the total resistance down to 125 ohms and still haven’t reached full-scale, don’t try to go any lower. You simply have a meter that the Arduino can’t drive. Your meter might have a low-value internal shunt resistor, or it may simply be broken. The only exception might be if the scale on the meter reads 5V at full scale and it turns out to really be a 5V volt meter. In that case you can just hook it up directly.
Once you have dialed in full-scale on your analog panel meter, you could go ahead and use it with the potentiometer and fixed resistor just as they are. Simply move the connection from the 5V pin over to a PWM output pin (one with a ‘~’ by it) and you can use analogWrite() statements to set the meter to any intermediate value. If you don’t want to tie up that particular potentiometer, or if you want to have data for future reference, it’s probably a good idea to measure how much resistance you needed to add to the meter for a full-scale reading. Simply disconnect the potentiometer from the Arduino and use a multimeter to measure the resistance across the potentiometer and fixed resistor. In my case, I needed a total of 11.35k in addition to the analog meter to read full-scale.
If you want to know what current values the meter is really reading at full scale, you can connect up the analog panel meter to the Arduino as you did before, but insert the multimeter between the analog panel meter’s negative terminal and ground. Put the multimeter in mA or uA mode, which may require moving the test leads to a different socket. In my case, I was stretching the capabilities of this inexpensive meter, but it read in the ballpark of 260uA, which is what this meter reads at full-scale.
In our next post we will look at some code and a trickier panel meter that needs two Arduino pins to reach full scale.
So long as you’re dealing with switches and potentiometers as input sources, there is little reason to consider overvoltage conditions on microcontroller pins. If you power the switch or potentiometer from the same supply as the microcontroller, you can’t go overvoltage. Once you’re taking input from less well-controlled sources, however, you’ll want to consider how to protect the microcontroller so it isn’t destroyed. This became a concern for us when designing our Metal Detector kit since the pulse we induce in the coil produces oscillations with peaks above 10V and below 0V. This oscillation is fed to analog inputs on an ATtiny microcontroller.
To start, it’s good to understand the overvoltage protection that already exists in the microcontroller. In our ATtiny, and all other AVR microntrollers that we know of, there are overvoltage protection diodes right at each input pin. Any voltage on the input pin higher than VCC plus the forward voltage drop of the diode will cause it to conduct, dumping current onto VCC until the voltage on the pin drops. Similarly, if the voltage on the pin dips down more than the lower diode’s forward voltage drop below ground, then current will flow up from ground to the pin.
The effectiveness of these diodes depends on the impedance of the overvoltage source and the current carrying capability of the diodes. The datasheet tells us to expect a forward voltage drop of 0.5 V for the diodes, but it doesn’t specify a maximum current. Atmel gives a hint, though, in a rather remarkable application note on using an AVR digital pin as a zero-crossing detector. In it, they propose hooking an AVR digital pin to AC mains through a 1 MOhm resistor. (I wouldn’t do it.) In the text, they say that it is best to limit current through the protection diodes to 1 mA.
So it would seem that throwing a 1 MOhm resistor in front of our pins would give us about +/- 1000V overvoltage protection. As appealing as a one-component solution is, there are some limitations. The most significant limitation is that this won’t work for ADC input pins. Returning to the ATtiny datasheet, we find the recommendation that the input impedance to any ADC pin not exceed 10 kOhms. This is because the ADC uses a sample and hold capacitor to keep the sampled voltage steady for ADC conversion. This capacitor can’t charge quickly enough with 1 MOhm of resistance between it and the voltage we want to measure. (Leakage current and pin capacitance are also considerations.)
Without checking their math, let’s assume 10 kOhms is a reasonable limitation. If we put a 10 kOhm resistor at the input and assume 1 mA current limit for the diode then we could accept input voltages on an ADC input pin from VCC + 10.5 V to GND – 10.5 V. This isn’t a very wide range, but it is enough for our metal detector.
So what if we really want that +/- 1000V protection? There is all kind of advice in forum posts about how to handle this, usually involving resistors and diodes. Much of this advice doesn’t account for the amount of impedance in front of the ADC or the voltages at which the internal protection diodes begin to clamp. Consider instead putting an op amp in front of the ADC. If we do this, we provide a low-impedance source to the microcontroller’s ADC while accepting a high-impedance signal on the op amp’s input. A low-cost op amp like the MCP602 doesn’t mind having a 1 MOhm resistor in front of its input. (They even discuss overvoltage protection in the datasheet.) With an op amp we will also get the opportunity to amplify, attenuate or bias the input signal into our ADC’s range, which is commonly needed. Many ADC application notes assume there will be an op amp in front of the ADC.
In a technical article about protecting ADC inputs, Analog Devices shows an approach I’ve used. (figure above) Single-supply op amps like the MCP602 often can’t reach VCC output when used as unity-gain buffers. However, for precision ADC measurements you would typically want to use a voltage reference anyway. Using a 4.096 V reference while powering the op amp from VCC gives you almost a volt of headroom at the upper end of the op amp’s output range, and makes the binary to decimal conversion of the ADC value easy. (Alternately, you could use the 2.56 V reference internal to AVR microcontrollers.)