This is a very compelling argument. It seems that I was trying to fix a problem that didn't exist.
I think the often used expression is "a solution looking for a problem" applies. Not unlike the new Serial.flush command that is so popular with beginner programmers.
Actually I think the INPUT_PULLUP is a very good thing and it does solve real-world problems.
In fact, I wish it had been accepted by the Arduino team sooner.
Without it, code that needs pullups enabled, is having to step outside Arduino and do AVR register specific operations
which makes the code non portable to other processors.
It always struck me as odd that the point of Arduino was to try to abstract the hardware away from the sketch
and yet turning on the pullup without something like INPUT_PULLUP is not supported by Arduino
and therefore becomes a processor specific non portable operation that is outside the
scope of Arduino.
Not sure why the Arduino team never saw it that way.
The real problem is it wasn't accepted as a solution to a real problem and implemented soon
enough in the mainline arduino core code so it didn't make it into the flagship 1.0 release
(It was added in 1.0.1 )
It has now now created a difficult backward compatibility issue
for porting existing arduino code that runs on AVR to non AVR like ARM and PIC.
The non AVR processor core code writers have two choices.
- Emulate the AVR pullup enable capability in s/w as well as support INPUT_PULLUP
- Only support the new INPUT_PULLUP and break any code using the AVR specific
pullup enable method which is what all AVR Arduino code did prior to INPUT_PULLUP
The issue with emulating the AVR pullup enables in s/w is that it slows down the digital write code
by having to look to see if it is a write to an input pin vs just being able to write directly to the hardware.
It is really sad because other processor like the ARM and PIC have better i/o capabilities than
the AVR yet they can't be fully utilized when s/w has to do this AVR emulation.
From a library portability standpoint, the ideal solution would be to use ifdefs so
the code would use INPUT_PULLUP if it exists and not do the extra write to the input pin.
If it doesn't exist, assume AVR or AVR emulation is
available and drop back to INPUT and do the AVR specific method of writing to the input pin
to turn on the pullup.
It's a bit ugly but it would then be fully compatible with pretty much anything out there.
As and alternative,
you could actually hide it pretty well by playing a few games with macros.
#warning "Using pinMode() INPUT_PULLUP AVR emulation"
#define INPUT_PULLUP 0x2
#define pinMode(_pin, _mode) _mypinMode(_pin, _mode)
#define _mypinMode(_pin, _mode) \
pinMode(_pin, INPUT); \
if(_mode == INPUT_PULLUP) \
digitalWrite(_pin, 1); \
This allows code to always pinMode() with INPUT_PULLUP regardless of whether the
core code supports it.
The tricky part with the keypad library is that the pin mode is done through a virtual function which
can be remapped.
If the virtual function may need to know if the pin is INPUT or INPUT_PULLUP.
Using the above macros may be a better solution than simply eliminating the INPUT_PULLUP
because the virtual function can now receive a 2 (INPUT_PULLUP) rather than a INPUT which
is currently defined as 0
Just keep in mind that to do this, the code implementing the virtual function would also need
to have something like the above macros to ensure the INPUT_PULLUP is defined to the same value in
pre 1.0.1 environments.