Voltmeter accuracy.

I wish to build a simple voltmeter, comprising a MCP3301 12-bit ADC accepting an analog input taken from the center of a voltage divider. The ADC has its own reference input, for which I am currently using a voltage obtained from a zener diode in series with a resistor. So the components which affect accuracy would appear to be the two resistors in the voltage divider, and the zener and its current-limiting resistor.

But if temperature changes, the components will vary a little in value. If the voltage divider resistors are of the same type (e.g., metal film), I would assume that the divider ratio would remain constant, and accuracy would not vary with temperature. If anyone knows why this is not so, I'd sure like to hear from you.

Relative to the use of a zener as a voltage reference, I know that they are not all that stable with temperature, and can be compenstaed to some extent by being placed in series with a standard diode. Does anybody know of a fairly inexpensive voltage reference that is very temperature stable?

Thanks in advance for any help.

Why not use an A/D with inbuild reference voltage.

The ADS1015 (12-bit) or ADS1115 (16-bit) seems to be commonly used for that.

Leo..

Thanks, Leo.

I also need a VRef for the Nano, so I'll probably use one external reference for both the ADC and the Nano.

Arduino has it's own internal voltage reference. It is not calibrated but should be stable. If you calibrate it and safe the calibration data you can ise it for both the Arduino and your ADC.

You're using an ADC with a 12 bit resolution or 1 part in 4096, so 0.025% resolution

What resistors do you intend to use, because if they are not better than 0.025% tolerance then you are wasting your time with such an ADC. Hanging a high resolution ADC onto the end of a low accuracy resistor chain does not give you a quality measurement.

Similarly the thermal drift for 'normal' ambient temperature ranges isn't worth bothering about for a "simple" voltmeter.

True.
Arduino's A/D, with the internal 1.1volt Aref enabled, is good enough for "simple" voltage measurements.
e.g. a 30volt range with 0.1volt resolution should not be a problem.
Try this sketch I wrote some time ago for a 12volt lead/acid battery.
Leo..

/*
  0 - ~16volt voltmeter for 3.3volt and 5volt Arduinos
  uses the stable internal 1.1volt reference
  6k8 resistor from A0 to ground, and 100k resistor from A0 to +batt
  100n capacitor from A0 to ground for stable readings
  (100k + 6k8) / 6k8 = 15.70588 | used in formula
*/
float Aref = 1.075; // ***calibrate here*** | change this to the actual Aref voltage of ---YOUR--- Arduino
unsigned int total; // can hold max 64 readings
float voltage; // converted to volt

void setup() {
  analogReference(INTERNAL); // use the internal ~1.1volt reference  | change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(9600); // set serial monitor to this value
}

void loop() {
  for (int x = 0; x < 64; x++) { // multiple analogue readings for averaging
    total = total + analogRead(A0); // add each value to a total
  }
  voltage = (total / 64.0) * 15.70588 * Aref / 1024 ; // convert readings to volt
  // print to serial monitor
  if (total == (1023 * 64)) { // if overflow
    Serial.print("voltage too high");
  }
  else {
    Serial.print("The battery is ");
    Serial.print(voltage);
    Serial.println(" volt");
  }
  total = 0; // reset value
  delay(1000); // one second between measurements
}

Wawa:
True.
Arduino's A/D, with the internal 1.1volt Aref enabled, is good enough for "simple" voltage measurements.
e.g. a 30volt range with 0.1volt resolution should not be a problem.
Try this sketch I wrote some time ago for a 12volt lead/acid battery.
Leo..

/*

0 - ~16volt voltmeter for 3.3volt and 5volt Arduinos
  uses the stable internal 1.1volt reference
  6k8 resistor from A0 to ground, and 100k resistor from A0 to +batt
  100n capacitor from A0 to ground for stable readings
  (100k + 6k8) / 6k8 = 15.70588 | used in formula
*/
float Aref = 1.075; // calibrate here | change this to the actual Aref voltage of ---YOUR--- Arduino
unsigned int total; // can hold max 64 readings
float voltage; // converted to volt

void setup() {
  analogReference(INTERNAL); // use the internal ~1.1volt reference  | change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(9600); // set serial monitor to this value
}

void loop() {
  for (int x = 0; x < 64; x++) { // multiple analogue readings for averaging
    total = total + analogRead(A0); // add each value to a total
  }
  voltage = (total / 64.0) * 15.70588 * Aref / 1024 ; // convert readings to volt
  // print to serial monitor
  if (total == (1023 * 64)) { // if overflow
    Serial.print("voltage too high");
  }
  else {
    Serial.print("The battery is ");
    Serial.print(voltage);
    Serial.println(" volt");
  }
  total = 0; // reset value
  delay(1000); // one second between measurements
}

jackrae:
You're using an ADC with a 12 bit resolution or 1 part in 4096, so 0.025% resolution

What resistors do you intend to use, because if they are not better than 0.025% tolerance then you are wasting your time with such an ADC. Hanging a high resolution ADC onto the end of a low accuracy resistor chain does not give you a quality measurement.

Similarly the thermal drift for 'normal' ambient temperature ranges isn't worth bothering about for a "simple" voltmeter.

Tolerance isn't nearly that important, since that can be corrected with calibration and a little math in the software. What really matters is stability in the value over time and temperature. If the values of the reference and divider are a little off nominal but barely drift, you're golden as long as you have known references that you can calibrate it against.

These MCP1541 are a good compromise between accuracy, stability and price.
You can do better, but the price starts to rocket.

mauried:
These http://www.microchip.com/wwwproducts/en/MCP1541 are a good compromise between accuracy, stability and price.
You can do better, but the price starts to rocket.

I know this is an old post, but what better chips can you recommend?

Hi,

What level voltage are you measuring with the divider?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

I'm a fan of Delta-Sigma A/D converters for low speed use. While they are often considered overkill because they often go to 24 bits the real benefit is noise rejection.

I have found that high speed A/D is prone to picking up and converting noise on the incoming waveform. The Delta-Sigma converter inherently averages out the noise and give more repeatable results.

BTW most D-S converters can be set to convert fewer bits.

Here here are two, there are likely others.

https://www.ebay.com/itm/MCP3421-Delta-Sigma-Analog-to-Digital-Converter-SOT23-6-ADC-Evaluation-Board/292595393583?hash=item44200b642f:g:hicAAOSwzHRbGV3F

https://www.ebay.com/itm/CJMCU-1118-ADS1118-16-bit-ADC-ADC-SPI-Communication-Module-Development-Board/401190789132?hash=item5d68d5a00c:g:ljwAAOSwAuZX3o72