Setup (Arduino Pro Mini ATmega328p 16MHz, 5V, no pin connected):
When called from the setup()
, this works:
pinMode(11, INPUT_PULLUP);
bool identifiesAsFast = digitalRead(11); // always true
This doesn't:
const uint8_t identificationPinBitNumber = PB3; // pin 11
const byte identificationPinBit = bit(identificationPinBitNumber);
DDRB &= ~identificationPinBit;
PORTB |= identificationPinBit;
bool identifiesAsFast = PINB & identificationPinBit; // occasionally false
Pin 11 is not connected, but - as you can see above - I have it pulled high. So I would expect it to always have a value of 1.
What am I missing when doing direct port manipulation?
I get the behavior with four different Arduino Pro Minis. All are original Pro Minis, designed by Sparkfun, made in the USA and bought from Digi-Key. One of them I pulled freshly out of the original bag. I may have to remove and insert the FTDI adapter around thirty times, but eventually I am able to reproduce the issue.
Adding a delay of 100 ms in between pulling pin 11 high and reading it seems to resolve the issue. However, I don't understand why that delay would be necessary.
PB3
for pin 11 is correct, as I verified by connecting an LED and making it blink. See also the pin mapping diagram which can be found elsewhere on the web:
Full code:
// Felix E. Klee <[email protected]>
const uint8_t ledPinBitNumber = PB5; // pin 13
const byte ledPinBit = bit(ledPinBitNumber);
const uint8_t identificationPinBitNumber = PB3; // pin 11
const byte identificationPinBit = bit(identificationPinBitNumber);
unsigned long delayDuration; // ms
void turnLedOn() {
PORTB |= ledPinBit;
}
void turnLedOff() {
PORTB &= ~ledPinBit;
}
void setDelayDuration() {
#if 0
pinMode(11, INPUT_PULLUP);
bool identifiesAsFast = digitalRead(11); // always true
#else
// Input pullup:
DDRB &= ~identificationPinBit;
PORTB |= identificationPinBit;
bool identifiesAsFast = PINB & identificationPinBit; // occasionally false
#endif
delayDuration = identifiesAsFast ? 300 : 3000;
}
void setup() {
DDRB |= ledPinBit; // Set up LED pin for output
setDelayDuration();
}
void loop() {
turnLedOn();
delay(delayDuration);
turnLedOff();
delay(delayDuration);
}