Suppose I have two voltages to measure 1.5v and 1.4v. SInce the difference between these two is very small, arduino sometimes gives readings that are very similar, e.g 1.45v for both voltage measurements, which is clearly wrong. Now my question is, how do i precisely measure the two levels with an accuracy of say 0.1%? Is this even possible?
Very unlikely. If you have an Arduino Uno, the ADC gives 1024 voltage steps from 0 to 5V, or about 0.005 V per step (5 mV per step). That is typical resolution, and gives about 0.1% measurement precision.
Use something like Serial.print(voltage, 3); to see 3 decimal places in the measurement.
ADCs on other microprocessors have higher resolution, typically 4096 or more steps over the allowed voltage input range.
Yes. You need to use an A/D that has more bits but you also need to be careful of the circuit etc as the finer the resolution the more difficult and critical the analog portion becomes. The voltage per step is critical, so measuring with a 5V reference (granularity) as in the Arduino will give you 5/1023 = 0.004887586V , changing the reference to 1V will give you 1/1023 = 0.000977517 volts per step. Take a look at this: Keithley Model 2000 6 1/2-Digit Multimeter I have that one as my portable standard for 5 1/2 digit meters.
Another option would be to build a small amplifier that gives you an output of the difference between the two signals, an provides that to the ADC of the Arduino for conversion, if that's all you're interested in. But since you've given us next to no information about the application, just your interpretation, that's just an option who's applicability is unknown.
That's a 100mV difference so you should be able to do a LOT better than that.
There's probably something wrong with your calculation or you are limiting/rounding/truncating your print statement.
Do you see a difference in the raw readings, before calculating voltage?
The readings are fluctuating due to maybe loose breadboard connections or some random noise. I may have to solder to see if it does anything with the readings. I usually have no problems measuring voltages that are 1 or more volts apart from each other, they are easily distinguishable.
Use the internal 1.1 volt internal reference and a potential divider so that 1.5v scales to 1.1v. ( so 1.5v becomes the full scale voltage ).
Your resolution is then 1.5/1024 which is roughly 1.5 mV .
.1% is achievable with the arduino ADC. - Which is 1 part in 1024.
You can get even better by oversampling as described here
Do you want to measure both levels, or just the difference between them? If the latter a difference amplifier like this would be appropriate.
But then you cannot measure 4V without a voltage divider...
Put a 100nF capacitor from the input pin to ground close to the input pin.
Keep wires together.
Keep wires short.
Use shielded wire.
I'm thinking of the ADS1115 using two inputs, possibly using differential mode depending on what exact information you're after. Its 15-bit resolution should be good enough for this.
Do you have an accurate voltage standard you can use for calibration of your measuring devices?
Here is a diagram of my circuit...I am basically trying to build a positive/negative voltage measurement tool. The signal is scaled down using voltage divider the output of which is fed to op amp voltage follower then to a negative voltage shifter circuit and finally to arduino adc. The result is scaled back up to original voltage level.
And how is this better than a direct measurement with the arduino analog input?
The drawing is pretty bad. You are supposed to try to minimize crossings...
Voltage divider for the ground is usually to the left of the opamp...
The opamp is there to create low impedence output..1M is pretty high...and I want to cover dc voltages in the range 1 V to around 20V taking into account the loading effect of the test circuitry. What is minimizing crossings? Some explanation will help...
Crossing is lines that cross..
It is also good to minimize bends... ( there is one line with 7 unneccasary bends in your drawing...).
The input impedance of the arduino input is around 20 MegaOhms...
Also your midpoint should have resistors significantly smaller than the resistors on the output...
Otherwise it will not be in the middle....
So we began with this:
Somehow we evolved into this:
Which has nothing to do with the thread starter. Actually if I wanted to measure positive and negative voltages I would use an ADS1115 setup for differential measurements. Anyway...
You are using a LM324 as your operational amplifier. The same LM324 that was great in my 1980s Op Amp cookbooks. While it was great in the 80s and even 90s but today there are dozens of better op amps including rail to rail. Speaking of rail to rail you are powering your op amp with what is + and - 6 volts splitting 6 volts fron a 12 volt supply. Since the LM324 is not a rail to rail operational amplifier the best output with your configuration will be Vcc minus 1.5 volts or the best voltage swing you will see is negative 4.5 to plus 4.5 volts. Then you run the LM324 out through a divider and you want to offset it since the Adruino can't measure a negative voltage. It's not a “rail-to-rail” op amp, so the maximum output voltage is 1.5V below VCC (or 2V below VCC with a 2K load impedance). You can't design using a LM324 and expect to see In and Out the same when the LM324 is configured as a buffer. When all is said and done you still end up going into a 10 bit A to D on the Arduino. Since you have nothing actually going negative the LM324 is a buffer, that's all it is and I see no pots in your circuit to true your Vout?
I would be using an ADS1115 . That gives you 15 bit A/D and a default range of -6.xx to 6.xx volts using 2/3 default gain. You can easily do any math in the code. The ADS1115 affords you either two differential channels or four single ended channels.
Ron
Since OP wants to measure differences smaller than 0.1V, I still do not see why he does not simply use the analog input. That will be 0.004V accurate....
At no costs, without the hassle with external circuitry.
Also OP says his 0.1V reading is not stable. I do not see how a 15bit ADC would solve that...
The presented circuit (with its many design flaws) was meant to produce a low impedance output from a high impedance output. So it is a solution to a not existing problem as the analog input is high impedance.
I read somewhere that adding extra input impedence > 10k will slow down capacitor charge rate, thus the adc will not give the "full" reading? How do i tackle this problem?...and I also dont want to load the external circuitry..
A filter will always lead to slower response.
You need to compromize (more noise vs. slower response = smaller vs. larger capacitor).
Best is of course to keep the noise out so that you do not need a filter... And before adding more accuracy you should first have a look at that...
I do not understand your last sentence...
