Bug in Analog Read for Teensy 3.5

fkeel

Member
Hi Everyone

Me and colleagues were having problems with reading analog signals on the teensy 3.5. There seemed to be a 'jump' around the mid-way point, if moving from 0 to ~512, the value would jump up to ~560. If moving from 1023 to ~512, the value would jump down to ~550.

See the below image, the green line is the raw sensor data (ignore the red, it is a filtered signal which we initially used to fix this issue, before we fully understood it). What you are seeing is me gradually & continuously twisting the knob of a linear potentiometer. I promise I did not jerk it.

Screen Shot 2022-07-22 at 14.24.51.jpg

We tested this with multiple Teensy 3.5 boards and always had this problem. With a Teensy 4.1 board this problem did not exist.
After reading a thread on this forum (which sadly I can no longer find) we suspected that this might be caused by incorrect pin configuration.

We found that we could fix the problem by editing pins_teensy.c:

Lines 1110 - 1117:

Code:
if (mode == INPUT) {
    //*config = PORT_PCR_MUX(1);
    *config = PORT_PCR_MUX(0);  // <--------------------------- Value changed from 1 to 0
} else if (mode == INPUT_PULLUP) {
    *config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
} else if (mode == INPUT_PULLDOWN) {
    *config = PORT_PCR_MUX(1) | PORT_PCR_PE;
} else { // INPUT_DISABLE
    *config = 0;
}

It appears that analog read requires PORT_PCR_MUX(0); (rather than PORT_PCR_MUX(1);

It also appears that this might have already been addressed/identified. We found reference to an INPUT_ANALOG command, but it does not appear to actually be implemented.

For now our fix is to add this after our pin configurations for all analog pins:

Code:
volatile uint32_t *config;
  config = portConfigRegister(_the_input_pin);
  *config = PORT_PCR_MUX(0);
  initialized_ = true;

That's pretty much it. My theory is that without proper configuration the output is somehow biased to its equivalent digital output. That's what got us to explore this. This fix works well for us, so maybe the INPUT_ANALOG option really is required. I wonder if this bug exists for all Teensy3.x if so, its kind of mindblowing to me.
 
There has been some prior discussion on this forum (one example <here>...this is specifically for T4.x, but there are other examples for T3.x...search for "INPUT_DISABLE") which seems to be related to what you are seeing. Try this to see if it "fixes" your problem:

Code:
  pinMode(testpin, INPUT_DISABLE); // shut off pin-keeper resistors

Mark J Culross
KD5RXT
 
Back
Top