When designing this project, I had erroneously assumed that GPIO16 had a pullup resistor. It does not. The NodeMCU board I used to design this project has a red LED connected to GPIO, which serendipitously pulled the pin up enough to register HIGH when the switch was open, and leading me to believe that my call to pinMode(16, INPUT_PULLUP) had in fact implemented a pullup resistor.
The actual NodeMCU board calls for a blue LED, as shown below, which makes a critical difference here. When closing the switch, the blue LED lights up and GPIO reads LOW. When opening the switch back up, the blue LED stays dimly lit, and the forward voltage on the LED is large enough to bring the GPIO16 pin to 0.9V, which remains as LOW.
Normally, I would just reassign to another pin (or put in my own pullup resistor). Unfortunately, this is a small project for a group of people, and I have 30 PCBs already ready to go. I'm too impatient and cheap to have them remade, so I'm looking for an acceptable workaround.
I have found (as suggested at http://www.esp8266.com/viewtopic.php?f=13&t=3725) a solution that seems to work on the boards with blue LEDs. The snippet of code below briefly turns GPIO16 to an output and sets it HIGH for 1 msec before switching it back to an input. I've been running with this for a day and everything seems to work. The following function is called once every 100 msec.
int readStatus() {
pinMode(16,OUTPUT);
digitalWrite(16,HIGH);
delay(1);
pinMode(16,INPUT);
return(digitalRead(16));
}
My concern about this approach is that when the switch is closed, I am ever so briefly tying 3.3V to ground. Even though this seems to work, am I possibly shortening the life of my ESP8266 chip? Are there other recommended software solutions? I am trying to avoid ordering new PCBs, but also don't want to compromise the health of the device.