Impedance of analog inputs?

Hi,

I connected a 4K7 resistor from 3.3V to A1 and got a value of around 3890 from analogRead. This gives me an estimate for the input impedance of around 100K. Does this sound right?

Thanks

Paul

Can anyone else confirm this using their spark please?

I would have expected an impedance of between 10 and 100 times higher.

Could this be anything to do with the issue with ADC reported on that other thread?

Thanks!

I am not sure your measurement technique is really a valid way to get the data you are looking for. If we were able to change the sampling time of the ADC, you would see this number vary quite a bit.

The datasheet for the STM32F103 lists 50k ohm as the max external input impedance but goes on to say that it depends on how you set the clock divider for the ADC’s sampling rate (pp. 75-76). This is listed as the max external source impedance for an error below 1/4 LSB at 12-bit resolution. This means you need to drive the ADC with an impedance lower that the max spec given. Normally this is not a problem.

The values in Table 47 range from 50k ohm for ts=5.11us to a low of 400ohm for ts=0.11us and they give a formula.

According to the datasheet, the ADC input is primarily capacitive at 8pF max with a series switching resistance of a max of 1k ohm, the impedance changes with with sampling frequency and slower sampling rates have higher effective source impedance.

Like this: (hope the ASCII art works here, see Figure 38 in the datasheet):

.              Switch at Fs    1k
    ADC Input >------o/ o---/\/\/\/----+-------->
                                       |
                                      ---
                                      --- 8pF
                                       |
                                      GND

Hope this helps!

Hi @bko, thanks for taking the time for that thorough answer. To be honest, I didn’t set out to measure the impedance of the ADC input. I was working on my wind direction sensor. It contains 8 reed switches connected to 8 different resistors, activated by a magnet that swings around with the wind.

I chose a resistor value of 4K7 to form a voltage divider with the wind sensor, which worked well enough with an Arduino. However, with the Spark, I’m not sure it is reading all directions correctly. (I realise the Spark’s analogRead is 12 bits not 10 and returns a value up to 4095 not 1023.) During my investigations, I disconnected the wind senor, leaving only the 4K7 pulling the ADC input up to 3.3V. I expected to see a reading of 4095 to within a few units, but got the 3890-ish reading instead, which surprised me.

The resistor values in the wind sensor are:

N: 3.9K
NNE: 3.1K
NE: 16K
ENE: 14.1K
E: 120K
ESE: 42.2K
SE: 65.2K
SSE: 21.9K
S: 33K
SSW: 6.6K
SW: 8.2K
WSW: 0.9K
W: 1K
WNW: 0.7K
NW: 2.2K
NNW: 1.4K

(for the intermediate directions, the magnet is activating 2 adjacent reed switches, giving a combined resistance equal to two resistors in parrallel, e.g. WNW is 1K in parallel with 2.2K, giving ~0.7K)

What yould you recommend as a strategy for reading this sensor with Spark? Ideally I would like to distinguish all 16 directions, plus “sensor not connected”.

Thanks,

Paul

@PaulRB I'm not surprised it's coming in lower than expected. With the way the ADC is currently setup, you need to supply a low impedance connection to effectively charge the 8pF cap up fully.

See more info here:

Currently anything higher than 600 ohms impedance won't give correct readings.

Try adding a 0.1uF or 0.01uF cap between your analog input and ground to lower the impedance and improve your reading.

1 Like

You can certainly try adding a cap from the analog input to ground as @BDub said. That is cheap and easy to try.

Until the firmware allows us to set the sampling rate of the ADC, a better solution might be an op-amp, configured as a follower. In a follower, the negative input is tied directly to the output for a fixed gain of one and the positive input would connected to your wind sensor resistor network. With an op-amp, we get the benefit of a very low output impedance driving the ADC. Almost any single-supply 3.3V op-amp will work fine here–you could get a LM358 from Sparkfun (no relation to Spark.io) for $0.95. You might still want to filter or condition your sensor signal with a cap on the input side of the op-amp to low-pass filter noise.

Hope this helps!

Many thanks @BDub! 0.1uF works perfectly. The ADC reading now discriminates between the 16 wind directions and disconnected status.

1 Like

You stated "Currently", but that has been a long time back. Is this still the case for the Core, and the Photon ?

A lot has changed in the firmware in the last year and a half but the data sheet I quoted above is the same. Since you can now set the ADC sample rate, you can control the input impedance within the limits spelled out in the link above. The default setting yields around 40k ohm as I recall.

1 Like

thanks @bko. 40k is a lot easier to get to than 0.6k.

Sorry for asking so much, but, I thought the ADC only did one sample when you called it, and if you wanted more, you called it again.

Thanks for your info, Jack

Under the hood, analogRead(pin) does multiple ADC reads with averaging but you don’t really need to know that to use it.

You can call analogRead(pin) in a loop or in an unrolled loop like this:

a[0] = analogRead(pin);
a[1] = analogRead(pin);
//etc
1 Like

So, sounds like my code practice of taking multiple reads, and then calculating the average is not necessary, since the one call already does that.
Thanks, Jack