Posted on

Using an Analog Panel Meter with a Center Zero with Arduino

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.

A quality zero-center analog panel meter

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.

My set up for the Fluke Meter

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.