Well, I've done it again. With all the bells and whistles, I don't have enough GPIO pins on the NodeMCU. Here's what I need right now:
4 outputs with PWM
8 inputs with interrupts
2 outputs with simple on/off
That's 14 pins, but the NodeMCU only has 13 available. If I deduct the two pins used for the serial console (in case I need that for debugging), there are only 11 available.
Here are some strategies I am contemplating for handling this:
- The NodeMCU 12E has 4 pins dedicated to an SPI interface. So far, I'm not using SPI. Is there a way I can repurpose those pins for the types of GPIOs that I need? From my quick look at the ESP8266EX datasheet, this might be possible. Have to figure out if the board makes any difference and then figure out if the software environment makes it inconvenient.
- Is there another ESP8266 or even another micro available in a similar small form factor that has more GPIOs available? SparkFun ESP8266 Thing seems about the same (or maybe a GPIO or 2 fewer). Adafruit Huzzah looks like it has 9 GPIOs; I didn't drill down to see if more could be squeezed out because it's still not close. Wemos D1 mini and mini Pro have 11 GPIOs, but that includes the two serial pins..
- Maybe it's just time to switch over to an ESP32 board. Those seem to have a couple dozen GPIOs even though they are not much different in physical form factor (just a little longer). They can be had for under $10. I'm not sure, but there might be some incompatibilities in the Lua API.
Before I started pondering the above, more fruitful, options, I was thinking about more traditional pin count solutions. I could mux the plain on/off outputs with a SIPO shift register, but that's pretty boring since there are only 2 of those outputs. I thought about some way of multiplexing the PWM outputs but didn't get very far down that path.
The 8 inputs that need interrupts seem ripe for consolidation. There is such a thing as an 8-input OR gate in a 16-pin package (for example http://www.ti.com/product/cd4048b). That could tell me if some interrupt occurred. I could run the same 8 inputs to a PISO shift register and read them out as the first part of the response to an interrupt. That's pretty simple, but also simple-minded because it ignores a few edge cases. Luckily, in this application, I can tolerate a lost interrupt here and there. (I also briefly looked for an interrupt controller, but it seems the world didn't any simpler than the Intel 8259. Besides being a pretty big chip, it also seems pretty complicated. I grant you, it does some pretty sophisticated things. I just don't need those things.)