Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 22 of 22

Thread: Analog input impedance and pull-up?

  1. #1
    Junior Member
    Join Date
    Apr 2016
    Location
    Germany
    Posts
    4

    Analog input impedance and pull-up?

    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:
    Click image for larger version. 

Name:	scope_1.png 
Views:	378 
Size:	27.0 KB 
ID:	7057

    100k series resistance:
    Click image for larger version. 

Name:	scope_0.png 
Views:	270 
Size:	29.7 KB 
ID:	7056

  2. #2
    Senior Member
    Join Date
    Nov 2015
    Location
    Cold hollow VT
    Posts
    212
    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.

  3. #3
    Check out this thread: https://forum.pjrc.com/threads/33799...e-with-50k-pot ... it may be the same thing you're experiencing.

    Pat

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,468
    Delete the pinMode line. You do NOT want to have the pin in digital mode when using it as analog input.

  5. #5
    Junior Member
    Join Date
    Apr 2016
    Location
    Germany
    Posts
    4
    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:
    Click image for larger version. 

Name:	R=10k_without_pinMode(input).png 
Views:	238 
Size:	28.0 KB 
ID:	7075

    With 100k resistor in series
    Click image for larger version. 

Name:	R=100k_without_pinMode(input).png 
Views:	243 
Size:	31.2 KB 
ID:	7076

  6. #6
    Junior Member
    Join Date
    May 2016
    Posts
    6
    Hi Paul,

    What is the input resistance for analog inputs (A0 for example?)

    Thanks...Ness

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,468
    Quote Originally Posted by ness View Post
    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.

  8. #8
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,089
    Sounds like pinMode(n, DISABLED) would be useful (for other use cases).

  9. #9
    Junior Member
    Join Date
    Feb 2017
    Posts
    12
    Quote Originally Posted by PaulStoffregen View Post
    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

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,468
    Those examples were originally created for other non-Teensy boards.

    I should probably update them at some point....

  11. #11
    Junior Member
    Join Date
    Feb 2017
    Posts
    12
    That would be great.
    I just run into that trap and was seriously confused how my voltage divider produced a weird voltage.

  12. #12
    Junior Member
    Join Date
    Feb 2021
    Posts
    1

    Angry

    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?

  13. #13
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    Quote Originally Posted by Jürgen View Post
    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?
    Try pinMode(n, INPUT_DISABLE)

  14. #14
    Junior Member
    Join Date
    Apr 2020
    Posts
    19
    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

  15. #15
    Junior Member
    Join Date
    Jun 2023
    Posts
    2
    Quote Originally Posted by aleglakov View Post
    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.

  16. #16
    Junior Member
    Join Date
    Apr 2020
    Posts
    19
    Thanks you for advice! Will dive into that some day

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,433
    No code provided to confirm ...

    This has come up before and again in past day - when pin hysteresis is enabled the midrange gets a sticky bias and that may be what is happening here.

    If any pinMode() is used - and seems it should not be - it should be: pinMode(<pin>, INPUT_DISABLE);

  18. #18
    Junior Member
    Join Date
    Apr 2020
    Posts
    19
    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!

  19. #19
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,433
    Quote Originally Posted by aleglakov View Post
    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?

  20. #20
    Junior Member
    Join Date
    Apr 2020
    Posts
    19
    pinMode function was now used at all. I was just using analogRead(A16)
    Thanks!

  21. #21
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,433
    Quote Originally Posted by aleglakov View Post
    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].

  22. #22
    Senior Member
    Join Date
    Oct 2016
    Posts
    1,221
    Quote Originally Posted by defragster View Post
    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?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •