Teensy 4.0 Button Pin Reads High Constantly

Thundercat

Well-known member
Hi all,

I've got a sketch with 4 buttons. All using the same button code.

3 of them behave perfectly, but the 4th constantly outputs "high," as if I'm holding down the button, and measuring with a meter shows it's putting out 3.3v.

My first thought is, it's a hardware issue. Button is damage; or I got the wiring wrong or something.

So I stripped down the sketch to bare bones, and the button behaves perfectly, only going high when I press it, and low when I release it.

I feel like I'm losing my mind here, but doesn't that prove this is not a hardware problem, if a bare ones sketch works perfectly? :confused:

Thing is, I cannot find anything at all in the longer sketch that would cause the pin to read high, continuously. It's as if the button is held in, and it will not respond to button presses to go low/high; it just stays high.

Again, the other 3 buttons, using the same code, work perfectly in the longer sketch.

Posting the longer sketch is an issue because it's 30K lines, but can anyone think of something that would cause a pin to be held high continuously, besides the obvious digitalwrite command which I am not using? It's an input pin.

Thanks,

Mike

EDIT: I should add, I've got external pull-down resistors on all pins. Enabling/disabling internal pull-downs/ups has no effect on the outcome.
 
3 of them behave perfectly, but the 4th constantly outputs "high," as if I'm holding down the button, and measuring with a meter shows it's putting out 3.3v.

My first thought is, it's a hardware issue. Button is damage; or I got the wiring wrong or something.

So I stripped down the sketch to bare bones, and the button behaves perfectly, only going high when I press it, and low when I release it.

Your description seems inconsistent to me, if measuring with a meter shows its at 3.3 volts then it should read high.
 
Forum Rule: Always post complete source code & details to reproduce any issue!

Agreed. In this case, the short sketch works perfectly; no sense in posting it.

The long sketch, is utterly huge, and I cannot post commercial code.

Thanks,

Mike
 
but can anyone think of something that would cause a pin to be held high continuously, besides the obvious digitalwrite command which I am not using? It's an input pin.

Maybe a buffer overflow somewhere else in the program? Those cause all sorts of very mysterious issues.

Something I can confirm is (probably) isn't would be the pin reconfigured to control by a peripheral. We see this occasionally, where some library or other code turns on a peripheral feature. But that that happens, digitalRead() sees zero, even if the pin is physically 3.3V. For example

Code:
void setup() {
  pinMode(0, INPUT_PULLUP);
  Serial1.begin(9600);  // RX1 will have weak pullup
}

void loop() {
  Serial.print("pin is ");
  Serial.println(digitalRead(0));  // reads as zero
  delay(1000);
}
 
Your description seems inconsistent to me, if measuring with a meter shows its at 3.3 volts then it should read high.

With a meter on the pins, when not pressed, they all read 0v except for the offending pin 4. When I press a working button, the pin reads -3.3V. When it is not pressed, it reads 0v or thereabouts.

I initialized the buttons with this:

Code:
for (byte i = 0; i < 4; i++) {
    pinMode (BUTTON[i], INPUT);
}

I checked them with this:

Code:
void PinChecker() {

for (byte i = 0; i < 4; i++) {

   if (digitalRead (BUTTON[i]) == HIGH){    
      Pressed[i] = true;
      Serial.println("Pin " + String(i) + " is HIGH!");
   }
   else {
      Pressed[i] = false;
      Serial.println("Pin " + String(i) + " is LOW!");
   }
}
}

I had a thought; I will use this "pin checker code" to check pin state starting in the setup.

I already discovered that the pin reads LOW as it should right after initialization, so there is a clue here that I will follow.

Really I just wanted confirmation I'm not losing my mind because I've been at this for several days straight no results.

Thanks for any other thoughts.

Mike
 
Excellent suggestion Paul. I did just that - spent 2 hours last night doing just that.

After all that, the buttons worked perfectly again.

So I guess I'm wasting all your time here, as obviously there's just something somewhere that is causing this, and it's not the hardware or the wiring, it's the code.

I will report back any success and what I find out, which I will find out, because I must find out.

Thanks you guys.
 
Maybe a buffer overflow somewhere else in the program? Those cause all sorts of very mysterious issues.

Something I can confirm is (probably) isn't would be the pin reconfigured to control by a peripheral. We see this occasionally, where some library or other code turns on a peripheral feature. But that that happens, digitalRead() sees zero, even if the pin is physically 3.3V. For example

Code:
void setup() {
  pinMode(0, INPUT_PULLUP);
  Serial1.begin(9600);  // RX1 will have weak pullup
}

void loop() {
  Serial.print("pin is ");
  Serial.println(digitalRead(0));  // reads as zero
  delay(1000);
}

Thank-you Paul. That's another thing to investigate. Many kind thanks.
 
Well this is a bizarre twist. I've narrowed it down to the tft.init command! I'm truly stumped.

Here's the code:

Code:
void setup() {

Serial.begin(115200);

  delay(100); //stabilize everything

  for (byte i = 0; i < 4; i++) {
    pinMode (BUTTON[i], INPUT);
  }
 
  PinChecker();

  tft.init();

  PinChecker();

And the PinChecker code again:

Code:
void PinChecker() {

for (byte i = 0; i < 4; i++) {
   if (digitalRead (BUTTON[i]) == HIGH){    
      Pressed[i] = true;
      Serial.println("Pin " + String(i) + " is HIGH!");
    }
    else {
      Pressed[i] = false;
      Serial.println("Pin " + String(i) + " is LOW!");
    }
}
}

Here is what outputs in the serial monitor:

Code:
Pin 0 is LOW!
Pin 1 is LOW!
Pin 2 is LOW!
Pin 3 is LOW!

Pin 0 is LOW!
Pin 1 is LOW!
Pin 2 is HIGH!
Pin 3 is LOW!

This is the output of the PinChecker void, and as you can see, it outputs correctly just before the tft.init, and incorrectly after the tft.init.

Does that mean there's an issue with the library I'm using? It's the Bodmer TFT lib.

Thanks for any insights.

Mike
 
OK, I now have the distilled issue for clarity. Anyone can upload this sketch and reproduce the problem if you have the Bodmer TFT library installed. I will amend this post with the library version number shortly.

Here's the code:

Code:
#include <TFT_eSPI.h>
 
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library

const byte BUTTON[4] = {5, 7, 4, 6};

void setup() {

  Serial.begin(115200); 
  delay(100);
  
  for (byte i = 0; i < 4; i++) {
    pinMode (BUTTON[i], INPUT);
  }

PinChecker();
  tft.init();
PinChecker();
  

} //end void setup


void loop() {

 
} //end of void loop

void PinChecker() {

Serial.println(" ");

for (byte i = 0; i < 4; i++) {
   if (digitalRead (BUTTON[i]) == HIGH){    
      Serial.println("Pin " + String(i) + " is HIGH!");
    }
    else {
      Serial.println("Pin " + String(i) + " is LOW!");
    }
}
}

Here's the output from the Serial Monitor:

Code:
Pin 0 is LOW!
Pin 1 is LOW!
Pin 2 is LOW!
Pin 3 is LOW!
 
Pin 0 is LOW!
Pin 1 is LOW!
Pin 2 is HIGH!
Pin 3 is LOW!

Question is, now what?

Thanks,

Mike
 
Maybe configure the pins as INPUT_PULLDOWN...



Does the problem happen if you run it on a Teensy without the display or anything else (except the USB cable) connected?

Thank you Paul.

Also, I do have an external pull-down resistor 10k on every button, and power going to every button. This is on a PCB. It was before I understood this was not necessary, so I'm not sure the command will work.

I will try both suggestions and report back.

Thanks much!!

Mike
 
I ran this here on a Teensy 4.1 with nothing connected. Prints LOW for all the pins.

Can't look any farther without this TFT_eSPI.h library.

Code:
//#include <TFT_eSPI.h>

//TFT_eSPI tft = TFT_eSPI();  // Invoke custom library

const byte BUTTON[4] = { 5, 7, 4, 6 };

void setup() {
  Serial.begin(115200);
  delay(100);
  for (byte i = 0; i < 4; i++) {
    pinMode(BUTTON[i], INPUT_PULLDOWN);
  }
  PinChecker();
  //tft.init();
  PinChecker();
}  //end void setup

void loop() {
}  //end of void loop

void PinChecker() {
  Serial.println(" ");

  for (byte i = 0; i < 4; i++) {
    if (digitalRead(BUTTON[i]) == HIGH) {
      Serial.println("Pin " + String(i) + " is HIGH!");
    } else {
      Serial.println("Pin " + String(i) + " is LOW!");
    }
  }
}
 
Hi Paul,

I cracked open a brand new Teensy 4.0 out of the package, and connected it up.

Nothing connected to it at all but the USB cable.

Same exact results.

I changed the button code to INPUT_PULLDOWN

Code:
for (byte i = 0; i < 4; i++) {
    pinMode (BUTTON[i], INPUT_PULLDOWN);
}

Same results.
 
I ran this here on a Teensy 4.1 with nothing connected. Prints LOW for all the pins.

Can't look any farther without this TFT_eSPI.h library.

Code:
//#include <TFT_eSPI.h>

//TFT_eSPI tft = TFT_eSPI();  // Invoke custom library

const byte BUTTON[4] = { 5, 7, 4, 6 };

void setup() {
  Serial.begin(115200);
  delay(100);
  for (byte i = 0; i < 4; i++) {
    pinMode(BUTTON[i], INPUT_PULLDOWN);
  }
  PinChecker();
  //tft.init();
  PinChecker();
}  //end void setup

void loop() {
}  //end of void loop

void PinChecker() {
  Serial.println(" ");

  for (byte i = 0; i < 4; i++) {
    if (digitalRead(BUTTON[i]) == HIGH) {
      Serial.println("Pin " + String(i) + " is HIGH!");
    } else {
      Serial.println("Pin " + String(i) + " is LOW!");
    }
  }
}

Understood.

It's available in the Manage Libraries if you look for TFT_eSPI.

I'm currently using version 2.4.79, and I see he has a version 2.5 which I will try. It will take a little bit to update because I have to carefully reconfigure the config files each time.

I will report back again, and if the issue persists, I'll reach out to the developer. He's a super genius like you Paul, and also a great guy like you.

Thanks,

Mike
 
It's available in the Manage Libraries if you look for TFT_eSPI.

I'm currently using version 2.4.79,

This is the closest I could find. Can't reproduce the problem, as you can see in this screenshot.

screenshot.png
 
OK now for the resolution, which I couldn't have done without your help Paul, and the help of BriComp and rcar:

The library has a config file. I had left pin 4 defined for Touch Screen, because the library generates errors if you don't have that pin enabled and it was annoying, even though it's not a touch screen.

So it comes down to, as in most cases, "USER ERROR!"

It was quite a trick to chase down, many many hours, but at the end of it I can only say thank-you so much for your patience.

The buttons behave perfectly now :)

Heartfelt thanks.

Mike
 
FYI if anyone is curious this is the line in the User_Setup.h file that I needed to disable:

#define TOUCH_CS PIN_D2 // Chip select pin (T_CS) of touch screen

Lesson learned that libraries assign pins that you may not be aware of. In this case it was me who enabled the line ages ago due to the fact that I was getting a persistent error when compiling that was annoying (it just kept saying the Touch Pin was not enabled).

Thanks to you all

Mike
 
Back
Top