0

I'm trying to read voltage using Arduino, here's the code:

float r1 = 99700;
float r2 = 10004;
float adc, voltage;
unsigned long analog;
void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
  pinMode(A0, INPUT);
}

void loop() {
  for (int i = 0; i < 64; ++i) {
    analog += analogRead(A0);
    delay(1);
  }
  analog = analog / 64;
  adc = (analog * 2.441) / 1024;
  voltage = adc / (r2 / (r1 + r2));
  Serial.print(analog);
  Serial.print(", ");
  Serial.print(adc);
  Serial.print(", ");
  Serial.print(voltage);
  Serial.println(" ");
}

Had a VERY noisy reading and what I did was adding an external voltage reference (TL431) and also connected a 9V switching adapter to Arduino UNO. But I still had some noise in analog readings so as you can see in the code I'm taking 64 sample and averaging them.

After doing all those noise reduced a lot but not completely:

console

What else should one do to get an steady reading?

By taking 1024 sample noise will be removed but then I'm sacrificing performance...

  • your 0.46 looks very steady :) SCNR. You might look at the sensor itself and it's wiring. Add capacitors ... – DataFiddler Oct 6 at 9:19
  • @DataFiddler it looks steady in that screenshot but it's not, after all the value IS depended on the raw analogRead... – Hamed Oct 6 at 9:23
  • the range of analogRead is 0 to 1023. you read 190. what are the magic numbers? – Juraj Oct 6 at 9:41
  • @Juraj the numbers doesn't matter i can calibrate it one way or other, what i want is an steady reading. – Hamed Oct 6 at 9:43
  • common ground is connected? – Juraj Oct 6 at 9:46
1

I solved the problem by adding 3 capacitors:

  1. 220uF on the Arduino power supply.

  2. 100uF on TL431 output.

  3. 1uF on A0 input.

I also increased the sampling rate to 128 times (and removed the delay).

Here's the result, as accurate as my multimeter:

concole

result

There's still 2mV difference in higher voltages which is because of my 2.5V reference voltage and Arduino ADC 10bit resolution (2.5 / 1024 = 0.002).

  • 1
    Effectively, Serial.begin(9600); and the lots of output control speed. – DataFiddler Oct 6 at 13:12
  • 1
    A/D converters are always noisy. If you dive into the specific processor's specifications you may find a 10 bit A/D converter only has, maybe, 8 bits of meaningful data. 1) Have you verified the processor is tracking the voltage as expected by changing the voltage at the A/D converter's input? 2) What are you using as a reference voltage. And, consider using exponential averaging instead of averaging a fixed group of A/D conversions. – st2000 Oct 6 at 14:04
  • @st2000 yeah it shows the correct voltages with ~2mV difference, the voltage reference is TL431. i don't even know what exponential averaging is! gonna google it now. thanks. – Hamed Oct 6 at 14:34
  • 1
    Looks like wikipedia calls it exponential smoothing, not exponential averaging. Pick values based on powers of 2's to keep the math simple and adapt to embedded programming. – st2000 Oct 6 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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