Analog input impedance and pull-up?

ChrisHell

New member
Hi!

I know there are some posts about the analog input of the Teensy 3.1 / 3.2 already, but I didn't find this specific problem.

When I try to read the voltage of a relatively high impedance source, I see jumps in the readings of the analog pin around midscale. Looking at the voltage on the pin, the jumps are visible, too. In my setup to look into this, I connected a signal generator over a resistor (first 10k, then 100k) to the chosen analog input. I monitored the signal of the generator and directly at the analog pin of the Teensy with an oscilloscope. With 10k the jumps in the signal are quite regularly and the . With 100k there seems to be some kind of "pull-up" because the signal on the pin is higher than the signal coming from the generator. I know that it would be better to use lower impedance sources, but anyways I would like to know, where this strange behaviour comes from.

Here is a minimal code example and two pictures of the oscilloscope.
Code:
int analogValue;

void setup() {
    // put your setup code here, to run once:
    pinMode(A1, INPUT);    
    analogReadRes(16);              
    analogReadAveraging(32);

    Serial.begin(9600);
}

void loop() {
    // put your main code here, to run repeatedly:
    analogValue = analogRead(A1);
    Serial.println(analogValue);
    delay(10);
}

10k series resistance:
scope_1.png

100k series resistance:
scope_0.png
 
Looking at your scope traces, I shall assume that the green trace is the output of your signal generator and the yellow trace is on the input of the Teensy. Looking at the lower photo with the 100K resistor, when your input gets to about 1.5v it appears there is some extra current coming from the Teensy causing the voltage at that point to rise as it is causing the voltage drop across the resistor to become greater. As the signal voltage approaches 3v the current from the Teensy become less and corrupts the measured value less too. As the signal approaches 0v it appears the cause of the extra current gets shut off again until the signal rises to 1.5v and the cycle starts over. I don't know if anyone on this forum has intimate circuit knowledge of the inputs on the Teensy and what the root cause of this leakage is, but it appears it is caused by the Teensy. Based on the differences in voltages and the values of the resistors I calculate the current to be from 0 to 15microAmps (uA). Using Ohms law E=I*R we can see that 100K Ohms at 10uA causes a 1v drop, while at 10K Ohms the same 10uA current causes 0.1v drop which could explain the differences in the voltages you are observing.

For most of my work, I always use an OP-Amp buffer, preceded with a voltage divider if needed, between my source and the analog input. As you have learned it is best to supply the analog inputs from a low impedance source to get the best results.
 
Thank you all for your help!

I wasn't aware that selecting pinMode(xx, INPUT) is only for digital usage. Deleting this line from the sketch did the trick :)

Just in case someone is interested, here is the display of the oscilloscope after deleting the pinMode-line. And yes, green is the signal generator, yellow is the Teensy-pin.

With 10k resistor in series:
R=10k_without_pinMode(input).png

With 100k resistor in series
R=100k_without_pinMode(input).png
 
What is the input resistance for analog inputs (A0 for example?)

That depends. If the pin is configured as digital input mode (but not pullup), the impedance can be a slight pullup over some parts of the voltage range. It can be as low as about 100K to 150K.

If the pin is disabled, either by writing 0 to its config register, or you simply never used pinMode (the default it disabled), the impedance is very high. I don't know how much, but I can tell you it's so high you'll only measure as open circuit using an ordinary multimeter.
 
Delete the pinMode line. You do NOT want to have the pin in digital mode when using it as analog input.
So... why are they always input in the example code? (analogRead, analogContinuousDifferentialRead, analogContinuousRead and so on)
And there is a typo in the comment, its obviously not pin 23 twice, its pin 23 for A9 but pin 16 for A2.
Code:
#include <ADC.h>

const int readPin = A9; // ADC0
const int readPin2 = A2; // ADC1

ADC *adc = new ADC(); // adc object;

void setup() {

    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(readPin, INPUT); //pin 23 single ended
    pinMode(readPin2, INPUT); //pin 23 single ended
 
That would be great.
I just run into that trap and was seriously confused how my voltage divider produced a weird voltage.
 
Teensyduino v 1.52 with Arduino 1.8.13 removed the pinMode(n, DISABLED).
Is there now an alternative setting to unlink any digital comparators from an analog signal pin?
 
Hi! Got interesting behaviour of Teensy 4.1 ADC. When the raw value from adc goes above half of the max value (above 500 for 10bit and above ~2000 in 12bit mode), the value it reads is much higher than it should be.
I have got a 12V input thru 67k/10k divider. The readed values are quite precise until the raw value from analogRead() is below half/2, then it reads much higher input voltage than it is in real life. It is like the reference value is changed or something like this.
Did anybody have similar experience?

Thanks
 
Hi! Got interesting behaviour of Teensy 4.1 ADC. When the raw value from adc goes above half of the max value (above 500 for 10bit and above ~2000 in 12bit mode), the value it reads is much higher than it should be.
I have got a 12V input thru 67k/10k divider. The readed values are quite precise until the raw value from analogRead() is below half/2, then it reads much higher input voltage than it is in real life. It is like the reference value is changed or something like this.
Did anybody have similar experience?

I would suggest (so others can see the problem is impedance matching, your impedance driving the source is TOO HIGH, most midro ADC inputs have input impedance of around 30 to 60 k ohms, so a 10k in parallel with this gives a domininant external impednace.

You need to buffer the signal with an op-amp, do a serach for UNITY GAIN AMPLIFIER this makes the input of the have much higher impedance than the 10k resistor, and it output iimpedance is less than 10 ohms, orders of magnitude less than the input impedance of the ADC.
 
Thank you, defragster. Actually, my first post about the problem was in mid 2022, so Your linked topic did not exist yet :) I got exactly the same problem. Thanks for the fix!
 
Thank you, defragster. Actually, my first post about the problem was in mid 2022, so Your linked topic did not exist yet :) I got exactly the same problem. Thanks for the fix!

Awesome - other posts link way farther back - so far back it didn't ring a bell until others found it - just linked to that one.

To work was pinMode used before and removed - or changed to using INPUT_DISABLE?
 
pinMode function was now used at all. I was just using analogRead(A16)
Thanks!

Thanks for clarifying. So analogRead current use on T_4.1 requires pinMode( ##, INPUT_DISABLE ) to disable the pin hysteresis [IIRC that is set on Reset to minimize current used from a floating pin].
 
Thanks for clarifying. So analogRead current use on T_4.1 requires pinMode( ##, INPUT_DISABLE ) to disable the pin hysteresis [IIRC that is set on Reset to minimize current used from a floating pin].

For T3.x analog (DAC) outputs, is any pinMode() setting required or recommended?
 
Back
Top