This discussion is locked.
You cannot post a reply to this discussion. If you have a question start a new discussion

Arduino ADC usage

Hey all, is anyone savvy with arduino boards? 

I'm looking to use one to perform an analog to digital conversion on a measurement signal coming from a sensor.

The signal range is up to around 9V so I've potential divided this down by half so any value should be readable by the adc.

I've then used the analog read function on a0 and then done some cals to work out the source voltage and corresponding sensor pressure. 

What I'm struggling with is the input to the arduino, because when using the serial monitor the ADC signal outputted is seemingly random, and goes up and up then begins at zero again. 

Is this pin float? I feel like it is.

Parents
  • Note that the arduino ADC inputs are high Z and  capacitive, and will drift all over if not solidly connected.  Also they will mis-read if the transient source impedance is not low enough, as the voltage then gets pulled about by the action of the internal ADC connecting its sampling capacitors  to the pin during the conversion cycles.

    So for tests to get stability to  bit 12, use a 1k pot between Vref and GND or if for power saving reasons your source impedance is more than a few k ohms decouple it with 10n or more to ground, so that during the read event, the voltage is still held more or less constant while the internal logic of the ADC switches things in and out to get its conversion compartors sorted.

  • The other thing I'm wondering about is "a sensor" - how noisy is the sensor (and as Mike suggests, what's its output impedance)? How noisy is the environment it's working in? E.g. if it's connected to a system involving a brushed motor (even if it's not directly connected to it) it won't be at all surprising if the signal bounces around like this. It's very typical that filtering, and possibly screening, is needed on the input and then averaging (effectively further filtering) needed on the ADC output. The sensor can, depending what and where it is, even pick up the clock frequencies from the arduino itself...

    What's also critical is how fast you need your result to be, crudely you want a big enough capacitor on the input so that the input rate of change is slowed down to the point where it's just not too slow!

    Welcome to the wonderful world of analogue Smiley 

    Thanks,

    Andy

  • further to that watch the voltage gradient along the earthing- just because on the circuit it is all shown connected together, note that the sensor outputs a voltage between its pins, i.e relative to 'earth' at its location. The ADC measures between its pins, so relative to 'earth' at the arduino location. These may well be at opposite ends of an accidental wire antenna, and to  anything  that can measure a voltage in micro-seconds, then the ends of  a few feet  of wire can easily be some tens to hundreds of mV apart. So if adding capacitance to the line to filter, it needs to be at the ADC end, and with a definite resistance in series to give it something to chew on. Or better bring the earth along the same path as the signal, concentrically (coax) so that the two sides of the signal experience pretty much  the same disturbances.
    There is a very good reason really delicate or fast signals are sent down lines as differential signals ;-)

    Mike.

  • It's a vacuum sensor, noise wise it's not in any kind of production environment, I'm testing it in an office environment at the minute. 

    I have now got it mostly running, 

    13:25:07.389 -> Vacuum Sensor Voltage :4.47
    13:25:08.420 -> ADC Value :906.00
    13:25:10.431 -> Vacuum Sensor Voltage :4.42
    13:25:11.503 -> ADC Value :914.00
    13:25:13.508 -> Vacuum Sensor Voltage :4.46
    13:25:14.536 -> ADC Value :920.00
    13:25:16.546 -> Vacuum Sensor Voltage :4.49
    13:25:17.575 -> ADC Value :922.00
    13:25:19.583 -> Vacuum Sensor Voltage :4.50
    13:25:20.655 -> ADC Value :918.00
    13:25:22.655 -> Vacuum Sensor Voltage :4.48
    13:25:23.683 -> ADC Value :905.00
    13:25:25.672 -> Vacuum Sensor Voltage :4.42
    13:25:26.739 -> ADC Value :920.00
    13:25:28.730 -> Vacuum Sensor Voltage :4.49
    13:25:29.796 -> ADC Value :910.00
    13:25:31.784 -> Vacuum Sensor Voltage :4.44
    13:25:32.847 -> ADC Value :895.00
    13:25:34.846 -> Vacuum Sensor Voltage :4.37
    13:25:35.874 -> ADC Value :915.00
    13:25:37.883 -> Vacuum Sensor Voltage :4.47
    13:25:38.958 -> ADC Value :908.00

    There's variability in the ADC value which is changing the perceived pressure a lot, presumably because it's a log scale, so I'm considering upping the ADC spec, I'm limited now to 10 bit resolution by the arduino but I can get hold of an adaptor board to up this to 16, which should smooth out a lot of the variability I'm seeing. 

    But I've taken on board everyone's comments and thrown a cap on the input. 

    At the minute the first one I came to was a 0.1uF 50V cap, with that it now looks like this: 

    13:30:18.637 -> Vacuum Sensor Voltage :4.46
    13:30:19.660 -> ADC Value :913.00
    13:30:21.663 -> Vacuum Sensor Voltage :4.46
    13:30:22.738 -> ADC Value :914.00
    13:30:24.736 -> Vacuum Sensor Voltage :4.46
    13:30:25.763 -> ADC Value :913.00
    13:30:27.768 -> Vacuum Sensor Voltage :4.46
    13:30:28.840 -> ADC Value :914.00
    13:30:30.806 -> Vacuum Sensor Voltage :4.46
    13:30:31.878 -> ADC Value :914.00
    13:30:33.886 -> Vacuum Sensor Voltage :4.46
    13:30:34.912 -> ADC Value :913.00
    13:30:36.914 -> Vacuum Sensor Voltage :4.46
    13:30:37.984 -> ADC Value :914.00
    13:30:39.987 -> Vacuum Sensor Voltage :4.46
    13:30:41.013 -> ADC Value :913.00

    HUGE DIFFERENCE. 

  • Haven't I got around that though by connecting one of the ground pins to the ground connection from the PSU? 

    The arduino is still connected via it's USB cable for power which will have a seperate ground, but by adding this wire I thought I'd be all good there, unless I've now created ground loops :/ 

  • Found another insight, if I add a delay after performing the analog read, the duration of the delay affects the variation in the output. 

    Maybe this is related to the effect mentioned about the adc sampling capacitors?

    with a 1500 ms delay, I've reduced the adc level variation from from 6 to around 3. 

  • Did you mean 1500ms (so 1.5 seconds)? That's a massive delay. But yes, if you can afford a delay it always helps. I'll admit I've barely used Arduinos, but with PICs I'd always try to put in a delay of tens of milliseconds if I possibly can (there's usually a recommended delay for the number of bits of accuracy you're trying to achieve). But if you're working that slowly I'd also recommend doing a rolling average - e.g. add together the last four readings and divide by 4 (or last 8 readings and divide by 8, or last 16 readings and divide by 16 - trading time against stability). 

    I thought I'd replied to your previous message but it looks like I didn't, I've been having IT issues today. Basically assuming your transducer doesn't have to have its return connection earthed at it's end (i.e. assuming it's not attached to a metal case which is earthed) then as long as the "cold" or "return" wire attaches close to the 0V connection of the ADC you should be ok irrespective of any other earths you have in your system. And as Mike says earlier, ideally run in screened cable, or next best twisted pair. 

    I can get hold of an adaptor board to up this to 16, which should smooth out a lot of the variability I'm seeing.

    Err, no...it might even appear to appear to make it worse! Let's say at the moment you're seeing a variation of 4, so two bits. With a 16 bit convertor you'll see a variation of 8 bits (so 256!) - your extra 6 bits will all be down in the noise. Actually it's no different, with a variation of 4 you have 8 stable bits now, and with a 16 bit convertor you would still have 8 stable bits. If your 10 bits was absolutely stable then moving to 16 bits would add more accuracy, down to the point where they get buried in the noise. Hope that makes sense?

    By the way all this advice from Mike and myself is going to be pretty simplistic and generic - I probably have more books and other info on grounding and shielding on my bookshelves than any other single topic, it's a huge subject! But it sounds like it's a fairly straightforward application, so hopefully this should all be enough to help.

  • Adding more delay  is related but it is not a good way to attack it. Unless the ADC is cycling round to scan many pins in turn , the cleanest way is to camp on the one input pin, wait for the analogue settling time, then acquire, from an impedance low enough to not twitch by more than perhaps half or quarter of an LSB on the largest credible  input impedance transient.
    If you do not do this the p-p variation will depend where you are on the transfer function. If you are near an MSB transition, then the load impedance step is largest, as that is the largest Cap being flicked in and out while the internal logic looks frantically  for a comparator transition.

    read here, or at least stare at the first figure ;-)   Atmel are not great on explanations but their ADC method is the same as that one.
    The ADCs inside Microchip  PICs are very similar. and have similar limitations on settling and conversion timings vs accuracy but only the  datasheets of the earlier devices bother to say so.

    Mike.

  • That is a really good point about the impedance. Personally I'd put in a buffer but I'm guessing that would be a step too far.

  • caps are cheaper and use less power ;-)   The Atmel data sheet does not make it clear that the operation of the ADC pushes and pulls current in and out of the input pin wrt local gnd and Vref  as part of the sampling and conversion process - and the exact amount of charge on the move also depends on the residual charges left  over from the previous conversion result, which in some cases may not even have been an analogue quantity on  the same pin, and to a lesser extent  how long ago it was, as the on-chip caps leak a bit. Luckily those internal caps can only be a fraction of a pF per LSB so an external nano-farad or ten as near as poss to the chip is usually enough to make that bounce causing self interfering between readings negligibly small. (and another larger cap between Vref and ground always helps as well please. )
    Note that in a modern CMOS process you cannot make large capacitors economically, even 1 or 2 pf take up the area of many hundreds of gates. So normally anything more than about 20pF needs to be off-chip.


    M.

Reply
  • caps are cheaper and use less power ;-)   The Atmel data sheet does not make it clear that the operation of the ADC pushes and pulls current in and out of the input pin wrt local gnd and Vref  as part of the sampling and conversion process - and the exact amount of charge on the move also depends on the residual charges left  over from the previous conversion result, which in some cases may not even have been an analogue quantity on  the same pin, and to a lesser extent  how long ago it was, as the on-chip caps leak a bit. Luckily those internal caps can only be a fraction of a pF per LSB so an external nano-farad or ten as near as poss to the chip is usually enough to make that bounce causing self interfering between readings negligibly small. (and another larger cap between Vref and ground always helps as well please. )
    Note that in a modern CMOS process you cannot make large capacitors economically, even 1 or 2 pf take up the area of many hundreds of gates. So normally anything more than about 20pF needs to be off-chip.


    M.

Children
No Data