I have the exact same scenario as a previous question Digital Control of Analog Gauge but am still having trouble solving.

I have two (fuel and temp) old (circa 1973) electromechanical analog gauges made by VDO that I'd like to control digitally. They are 3 wire (12v, ground, and signal) gauges where the signal was originally connected to a sending unit (fuel float or temperature sender).

I've created a number of circuits and have had some success with the one shown below (using a low pass filter, operational amplifier, and MOSFET) but I haven't got it working well yet.

Digital to Analog Gauge circuit enter image description here

Because the original gauges use a logarithmic scale of some sort, I've measured and created a map in code that varies the PWM output based on the percentage of full (or hot) that I desire. The range of the pwm used is narrow but it works ok with just one gauge and a consistent voltage from the 12v power supply. However, any slight changes in voltage or resistance in the system, such as varying the input voltage from the 12v power supply, putting power to the instrument lights, or adding the second gauge, changes the calibration and makes the needle move more or less than previously. I am using a single 12v power supply for testing. I have a 12v to micro USB buck converter connected to power the Arduino. I share the ground from the power supply to the ground pin of the Arduino. I use the same 12v and ground from the P/S for power/gnd to the op amp.

Example videos moving through 5 or 6 distinct (cold, normal, half, 3/4, hot or empty, reserve 1/4, half, 3/4, full) steps: https://youtu.be/VGjDCAPXvEQ https://youtu.be/2KRYqxt8-eU

Any suggestions for how to make this reliable?

Components used: Arduino MKR Zero with 12-bit DAC, LM358 Op amp, 2N7000 MOSFET

I don't think the Arduino code is particularly relevant but I'll include it here for completeness. Obviously, this will eventually use fuel and temp info from my CANbus to write the appropriate PWM output but for now I'm just trying to calibrate the output with fixed steps.

int tempStep = 0;
int fuelStep = 0;
int tempIncrement = 1;
int fuelIncrement = 1;

int tempGaugeMap[] = {
  2500, // bottom of cold
  2560, // top of cold
  2600, // quarter
  2635, // half
  2655, // three quarters
  2680, // bottom of hot
  2695 // top of hot
unsigned int tempSteps = 6;

int fuelGaugeMap[] = {
  2710, // reserve
  2730, // empty
  2760, // 1/4
  2820, // half
  2900, // 3/4
  3500, //full
unsigned int fuelSteps = 5;

void setup() {
  // open a serial connection
  // make our DAC pin an output
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  // 12-bit DAC resolution

void loop() {
  int tempVal = tempGaugeMap[tempStep];
  int fuelVal = fuelGaugeMap[fuelStep];
  analogWrite(0, tempVal);
  analogWrite(1, fuelVal);
  if(tempStep >= tempSteps) { tempIncrement = -1; }
  if(tempStep == 0) { tempIncrement = 1; }
  tempStep = tempStep + tempIncrement;
  if(fuelStep >= fuelSteps) { fuelIncrement = -1; }
  if(fuelStep == 0) { fuelIncrement = 1; }
  fuelStep = fuelStep + fuelIncrement;

I've made some measurements of the gauges themselves as follows:

Temp Gauge Measurements

Fuel Gauge Measurements

  • \$\begingroup\$ Those "slight changes" seem like "big changes" to me. \$\endgroup\$ Apr 29, 2021 at 19:50

1 Answer 1


Your approach is ultra sensitive because you are driving the gauge open-loop. The opamp circuit has a fixed gain, but it is driving a FET running wide open. Its transconductance changes with temperature, the voltage from drain to source, the phase of the moon, etc, all adding up to no real stability.

There are several ways to improve things. One is to bring the FET inside the opamp control loop. You can do this by disconnecting the right side of R2 from the U1 output, and connecting it to the Q1 drain. <> Q1 is an inverter, so you have to swap the two opamp inputs to compensate for the extra signal inversiion. Also, we need to know the part number of the opamp because not all devices have the output voltage range to do what you want.

Separate from that, the values of R2 and R3 can be increased 10x or even 100x to lower the output stage current.

Another approach is driving the gauge with a current source rather than a voltage source. With the 12 V source and a resistor, determine the current through the gauge at the minimum and maximum indications. These can be used to reconfigure U1 as a voltage controlled current source (actually, current sink).

Update 1:

Another approach is to leave the opamp inputs alone, change Q1 to a bipolar transistor as an emitter follower, connect the collector to +12, connect R2 to the emitter, and move the gauge to between the emitter and GND. The voltage across the gauge will be the voltage at C1 times the opamp circuit gain. The transistor is just a current booster, and adds no voltage gain to the loop. If you know the min and max resistance values of the sender, the opamp gain should be easy to calculate. Note - you might have to add a DC offset, depending on the gauge.

Update 2:

The more I think about this, the more I prefer the Update 1 idea. It removes any sensitivity to the absolute value of the 12 V source. Both the filtered PWM signal and the signal to the gauge are referenced to GND only. My guess is that both the opamp circuit gain and the look-up tables will have to be adjusted, but this probably is the second-best way to go. First-best would be the same circuit modified to be a current source, but you might not need that level of complexity.

  • \$\begingroup\$ See the update ... \$\endgroup\$
    – AnalogKid
    Apr 29, 2021 at 20:19
  • \$\begingroup\$ I really appreciate your answer. I need to clarify a couple things that I think influence your response. First, I'm using LM258 op amps. More importantly, the gauge has internal voltage and resistance that appears on the signal wire. That's what R4 and V3 are representing. I tried the Update 1 approach but the trouble was you can't have a resistor on the collector or emitter side of the transistor because the signal wire needs to be fully shorted in order to get full range (full hot) of the needle. With that setup I could only get the gauge to 3/4s or so. \$\endgroup\$
    – jefflit
    May 2, 2021 at 20:18
  • \$\begingroup\$ I can't connect the collector to 12v because the 5.74 volts (v3) is the internal voltage on the signal wire. There's no way I can add an external voltage source because that one wire connects to the collector. \$\endgroup\$
    – jefflit
    May 2, 2021 at 20:20
  • \$\begingroup\$ I don't really understand your original comment wrt bringing the FET inside the opamp control loop. I tried simulating what I think you meant but it doesn't do anything. The idea I was trying for with the second stage in my circuit is just a voltage booster. Could you draw a circuit or explain more what you mean? Also I don't understand the idea of using a current source vs voltage source? \$\endgroup\$
    – jefflit
    May 2, 2021 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.