Help! Reading Voltage with Arduino - Page 1
Forum section: electronics / general

author: akazemian
author_rank: Newbie
timestamp: February 05, 2016, 01:28:50 am
content: Hi guys! I'm trying to build a device to measure the electrical resistivity of a paste (cementitious materials) using Arduino Uno. Four steel probes are put inside the paste (jumper wires attached to them). Two outer probes apply AC signals (Square signals- Frequency 1 kHz- Voltage(peak to peak)= 14 V) and two inner probes should measure the potential difference. Then the resistivity could be calculated by a formula. I cannot change these since this is standard test procedure..Please take a look at pictures (also attached):https://www.dropbox.com/sh/a3ijaxgpmv45xf3/AAB2-HQxs8aqYsi3nWg8W8b4a?dl=0I managed to apply the desired AC signals, but the issue is about reading the potential difference (two inner probes) by Arduino. When I use a multimeter (set to AC mode) I read some values (voltage) which should be correct, but using Arduino as the same time I read different values! I cannot see why! I connected one of the two inner probes to Arduino ground pin, and the other probe to analogue pin (A0) to read values, convert it to voltage ( float voltage = sensorValue * (5.0 / 1023.0); ) and print it to serial monitor. I programmed Arduino to read values 10 times during a second and report the maximum value only. There is not even a relationship between values (Examples: (Multimeter: 0.712 V, Arduino: 1.15 V)-(Multimeter: 0.68V, Arduino: 1.10V)-(Multimeter: 0.67V, Arduino: 1.03V)). Could anyone suggest any modification to make to get correct values with Arduino? I would really appreciate any help!

author: alsetalokin4017
author_rank: Super Contributor
timestamp: February 05, 2016, 02:21:23 am
content: This sounds like a sampling error issue to me. Since the AC signal is at 1 kHz and you are sampling at only 10 times per second, there is no guarantee that you are catching the true maximum voltage value in your 10Hz sample rate. I think I'd try some signal conditioning (i.e. rectification + filtering) between the sample box and the Arduino's ADC inputs, so that the ADC is reading a DC voltage rather than a rapidly fluctuating AC voltage. Then you should be able to calibrate in software so that your final reading agrees with the multimeter reading.Or you could try sampling at a higher frequency than the input AC signal. If you can sample at, say, 5 kHz instead of 10 Hz, you can probably be assured that you are catching enough data to make a valid RMS voltage calculation in the software.

author: Paul Price
author_rank: Super Contributor
timestamp: February 05, 2016, 02:38:30 am
content: Your multimeter is likely floating while your MCU and the 1KHz signal source are probably connected to each other to earth or power ground either directly by ground through some low enough impedance and this causes a ground loop that affects the reference point of your MCU readings.Your signal sampling rates are inappropriately much too low and part of the cause of the problem.How you are number crunching your MCU readings is also suspect since your meter is likely averaging or reading rms but how can the results match in readings if your software is attempting to measure P-P?

author: Morgoroth
author_rank: Regular Contributor
timestamp: February 05, 2016, 06:02:27 am
content: Arduinos in general are not the best option ADC, for some reason are noisy and even have some special features to 'sleep' the processor while take measurements (http://forum.arduino.cc/index.php?topic=45949.0), suggesting a problem in AVR architecture in general for that purpose, and maybe for other uC brands too, not sure.Take few opamps and build an RMS filter for the original signal and the signal that comes from the tested material, and use a instrumentation amplifier to calculate the resistance.I attach you a simulation file on LTSpice to get an idea. The opamps are quite random, was for a test for a project what I'm working on, probably the multimeter is using a similar RMS circuit.Hope it help to get an idea how to solve your problem.good luck.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: February 05, 2016, 08:42:39 am
content: First thing I thought reading this:Is that 1KHz AC 14V pp crossing the zero (is it really AC) or is it just a DC block wave?If it is AC you need to either rectify it or transpose it to make it DC. Then you have to divide it to make from 14V pp -> 5V pp.Then the 10-bit ADC in the Arduino should at least give you a ball-park measurement.

author: RFZ
author_rank: Regular Contributor
timestamp: February 05, 2016, 01:57:35 pm
content: Hmm... interesting way to calculate resistance... When I look at your test setup, I see a simple voltage divider... The inner two probes should always measure about one third of your applied voltage. Am I missing sth?

author: mikerj
author_rank: Super Contributor
timestamp: February 05, 2016, 01:58:41 pm
content: Quote from: alsetalokin4017 on February 05, 2016, 02:21:23 amExactly this, you are sampling asynchronously to the applied waveform which negates the entire purpose of the scheme. You probably don't need to go as fast as 1KHz, but even if you did you could use a timer interrupt to sample the voltage, calculate the difference from the previous sample, add the new result to a filter and then change the drive pin levels with pretty low CPU overhead.Quote from: RFZ on February 05, 2016, 01:57:35 pmLooks that way. Not sure why four probes are needed.

author: Seekonk
author_rank: Super Contributor
timestamp: February 05, 2016, 02:01:17 pm
content: My first thought.....Why do you think the Arduino is wrong? It is certainly as capable of measuring voltage as anything. A multimeter is certainly more capable of adding error to a reading. Take a moment to step back and look at the methodology. Post a real schematic and the problem will be obvious. It sounds like a great project for this device.

author: akazemian
author_rank: Newbie
timestamp: February 12, 2016, 07:02:34 pm
content: Thanks for your comments... To clarify what is happening I got an oscilloscope and repeated the test this time with sin waves (instead of square wave)... I modified the arduino code to sample 2500 times during a second and report the maximum value... Now Oscope, MM, and Arduino give me three different numbers: Oscope(Vp-p): 2.5V, Multimeter: 0.7V, Arduino: 1.55VI will be grateful if you can comment on this and how these values are related. Thanks.Arduino Code:/*ReadAnalogVoltageReads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.*/// the setup routine runs once when you press reset:void setup() {// initialize serial communication at 9600 bits per second:Serial.begin(9600);}void loop() {// read the input on analog pin 0:int sensorValue = analogRead(A0);// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):float voltage = sensorValue * (5.0 / 1023.0);// print out the value you read:float max_volt = voltage;for (int i=0; i<2500;i++){sensorValue = analogRead(A0);voltage = sensorValue * (5.0 / 1023.0);if (voltage > max_volt){max_volt = voltage;}delayMicroseconds(5);}Serial.print(max_volt);Serial.println(" V");delay(1000);}

author: Aodhan145
author_rank: Frequent Contributor
timestamp: February 12, 2016, 07:18:07 pm
content: first of all set A0 as an input in your setup.

author: Morgoroth
author_rank: Regular Contributor
timestamp: February 12, 2016, 08:38:49 pm
content: and careful of pull up resistorshttps://www.arduino.cc/en/Tutorial/AnalogInputPins

author: ozwolf
author_rank: Regular Contributor
timestamp: February 12, 2016, 08:46:09 pm
content: Quote from: Morgoroth on February 12, 2016, 08:38:49 pmHmmmm, interesting.Ozwolf

author: Seekonk
author_rank: Super Contributor
timestamp: February 13, 2016, 08:52:12 am
content: You still haven't provided a schematic of what you are doing. Offhand reading a lot of values, picking the highest and assuming that is the highest isn't a good plan. You should sync a reading to the appropriate time.Be aware of ghosting. More than once I have hooked to the wrong pin and read the voltage of an adjacent channel. A floating pin can be 70% of the adjacent value.I did a microprocessor pump system for a customer. He came back saying it was all wrong. The sensors were 1% and the system was perfect. His reference for the system was a $5 water pump gauge he got at a hardware store. Be careful what you use as a reference. I have great trust in the numbers I get from a micro assuming nothing stupid was done. So far the information provided hasn't merited serious consideration.

author: dannyf
author_rank: Super Contributor
timestamp: February 13, 2016, 12:57:17 pm
content: A few ways to approach.For minimum external hardware, you need an avr with differential adc inout. I would set up the adc for periodic sampling, this can be done by using a timer for example.The result can be processed in software (ieee1057 for example). Dft or fft works too.You can also use zero crossing to trigger an adc.Alternatively, use a difference amplifier plus a synchronous detector or multiplier to get yourself the average or peak. The mcu can then adc that average or peak.This approach has the most external hardware but the software side is the simplest.

author: dannyf
author_rank: Super Contributor
timestamp: February 13, 2016, 02:57:05 pm
content: "Two outer probes apply AC signals (Square signals- Frequency 1 kHz- Voltage(peak to peak)= 14 V) and two inner probes should measure the potential difference. "That kind of set up is quite unusual. Usually it is the other way around: the two enerfyinzing probes in the middle and the two measurement probes on the outside.

author: Seekonk
author_rank: Super Contributor
timestamp: February 13, 2016, 03:18:13 pm
content: Floating point in a micro is a mortal sin.

author: Cerebus
author_rank: Super Contributor
timestamp: February 15, 2016, 01:33:05 am
content: Quote from: akazemian on February 12, 2016, 07:02:34 pmOK. That 2.5V peak to peak equates to 1.25V peak (rectified) which equates to 0.88 V rms (sine wave, so divide peak by square root 2). So your scope and multimeter roughly agree - assuming that, as you stated before, you're using rms on the multimeter. What you're measuring with the Arduino is essentially random points in the wave. Add to that the likelyhood that the ground reference your Arduino is using almost certainly isn't floating like the multimeter. Further you look as if you're using the default voltage reference for the Arduino ADC which is just the 5 volt rail for the Arduino and is VERY poorly specified - I've seen under 4.5V on the input of an Arduino that's getting its power from the USB port.So, you need to sort out:-1) Getting your Arduino powered from a floating supply. That is, you don't want your measurement referenced to ground. You can just hook a 9V battery up to the Vin and GND pins on most flavours of Arduino. Obviously you CAN'T do this and use the USB port for serial output at the same time and that will ground reference the whole setup again.2) Getting a reliable voltage reference on the Arduino. Feed the VREF pin on the Arduino from a stable reliable source such as a proper voltage reference chip, or a decent calibrated (floating) bench power supply. Then use analogReference(EXTERNAL) to tell the Arduino to use that.3) Hunt down some code that lets you read the ADC in a reliable SYNCHRONOUS fashion using accurately timed reads. Using analogRead() and delay() means that you've no real idea at what time each sample is taken. There are plenty of examples out there.4) Make your ADC readings at LEAST twice as fast as your 1kHz stimulation signal, i.e 2kHz or greater. Dr Nyquist is your friend here.5) Convert your stream of data into an rms value by doing the arithmetic. You won't be able to do this in real time. Buffer a few samples (say 50-100) and then post process them to rms.6) In the absence of any evidence to the contrary I suspect that you've got no circuitry between your probes and the Arduinos ADC input. You're going to need some signal conditioning here and some input protection as well. Your 14V peak-to-peak stimulus easily exceeds the maximum rating for the Arduino input and that could lead to the escape of magic smoke.Ian

author: Morgoroth
author_rank: Regular Contributor
timestamp: February 15, 2016, 02:24:10 am
content: there is a bunch of dedicated chips for that.http://www.chipcatalog.com/Cat/83.htmhttp://www.analog.com/media/en/technical-documentation/data-sheets/AD536A.pdfhttps://www.qrz.ru/reference/micro/analog/ad637.pdf

author: Seekonk
author_rank: Super Contributor
timestamp: February 15, 2016, 05:43:59 am
content: I always put a marker in the program. Set a bit high at the start of A/D and low after. That will show you exactly how fast and when it is sampled. Doing the same thing with on board LED every so many program loops is also a good reality check.

author: Cerebus
author_rank: Super Contributor
timestamp: February 15, 2016, 08:11:15 pm
content: Quote from: Seekonk on February 15, 2016, 05:43:59 amIn general, if you're using a 'scope to debug your micro-based project it's worth using a spare output as you suggest and wiring it into the external trigger input of your 'scope - voila, instant stable reference point for your waveforms.

author: RFZ
author_rank: Regular Contributor
timestamp: February 19, 2016, 07:46:43 am
content: I still can't get over the fact that he is measuring voltage on a voltage divider with fixed ratio. Why on earth should the reading ever change? Can someone explain that to me please?

author: Cerebus
author_rank: Super Contributor
timestamp: February 19, 2016, 03:06:05 pm
content: Quote from: RFZ on February 19, 2016, 07:46:43 amI don't think he is quite finished yet. I suspect that the ACvoltagestimulus will get replaced with acurrentstimulus once he's figured out why he's getting different readings from his micro and standard instruments.