Pro Micro Internal Pullup Problems

I can’t seem to get internal pullups working for pins D3 and D5 on my Pro Micro 5V. I have pushbutton switches connected to D2-D7, and the only ones that don’t work are 3 and 5. I have verified switch operation by using an ohmeter, but when I plug in the micro and probe the voltage at the digital pins, they all read 5V except for 3 and 5. This happens whether the switch wires are connected to the board or not. I get the feeling that something like an internal PWM register might be messing with this, but I can’t tell.

Any help is appreciated, thanks!

bmnz:
I get the feeling that something like an internal PWM register might be messing with this, but I can’t tell.

Any help is appreciated, thanks!

If you post your code perhaps someone can help. Otherwise you're not likely to get much of an answer.

My final code ended up working on an Arduino Leonardo, so I am kind of fishing for any known oddities in the Pro Micro platform. My apologies for being brief; I’ll be back later (after work) with the full code. The summary of my code really just follows http://arduino.cc/en/Tutorial/Debounce with a few changes for the Pro Micro (i.e. changing the buttonPin, and the ledPin = 17) as well as enabling INPUT_PULLUPS on the pinMode call for buttonPin. In this case I was trying to get each button to work on a known “good” pin (like pin D2), and then I followed up with trying to get one button to work on each of the other pins that I wanted to use (pins D3-D7). Like I said, I’ll be back later with the full code, so don’t feel a rush to reply unless something jumps out.

As always, thanks for the help.

Okay, here’s the code. I took awhile to put it up here, because I received my Leonardo in the mail. The following code works exactly as intended on said Leonardo, but not on the Pro Micro.

/*

Kellen Manning
August 31, 2012
rev. 0
Arcade to MAME interface.

Hardware:
- Arcade pushbuttons on D2,D3
- 4-position Joystick on D4,D5,D6,D7

MAME Keyboard Config:
a=LEFT (D4)
s=DOWN (D5)
d=RIGHT (D6)
w=UP (D7)
j=Button 1 (D2)
k=Button 2 (D3)

Credits: 
http://www.arduino.cc/en/Tutorial/Debounce

*/

//Define pin/array locations
#define PINB1 2
#define PINB2 3
#define PINL 4
#define PIND 5
#define PINR 6
#define PINU 7
#define DEBOUNCEDELAY 50

//Define variables
// "Buttons" 0,1 unused
int buttonState[13];
int lastState[13];
char keybrd[13];
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
int lastTime[13];  // the last time the output pin was toggled

void setup() {
  //
  //For debug
  //Serial.begin(9600);
  
  //configure pins:
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  
  //LED for testing
  pinMode(13, OUTPUT);
  digitalWrite(13,LOW);
  
  //Default to "not-pressed"
  for(int x = 0; x < 13; x++) {
    buttonState[x] = HIGH;
    lastState[x] = HIGH;
    lastTime[x] = 0;
  }
  
  //Set keyboard mapping
  keybrd[0] = '<';
  keybrd[1] = '>';
  keybrd[2] = 'j';
  keybrd[3] = 'k';
  keybrd[4] = 'd';
  keybrd[5] = 'a';
  keybrd[6] = 's';
  keybrd[7] = 'w';
  
  
}

void loop() {
  for(int x = 2; x < 8; x++){
    checkState(x);
    
    if(buttonState[x] == LOW) {
      Keyboard.press(keybrd[x]);
      digitalWrite(13,HIGH);
      //Serial.println(keybrd[x]);
    }
    else {
      Keyboard.release(keybrd[x]);
      digitalWrite(13,LOW);
    }
  }
}

boolean checkState(int pin) {
  // read the state of the switch into a local variable:
  int reading = digitalRead(pin);

  // check to see if you just pressed the button 
  // (i.e. the input went from LOW to HIGH),  and you've waited 
  // long enough since the last press to ignore any noise:  

  // If the switch changed, due to noise or pressing:
  if (reading != lastState[pin]) {
    // reset the debouncing timer
    lastTime[pin] = millis();
  } 
  
  if ((millis() - lastTime[pin]) > DEBOUNCEDELAY) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
    buttonState[pin] = reading;
  }
  
  // set the LED using the state of the button:
  //digitalWrite(ledPin, buttonState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastState[pin] = reading;
}

Strange. I took a quick look at the schematic for the Pro and saw that both D3 and D5 had a # next to them. Does that denote active low or negative polarity?

I think they may denote PWM-capable pins. My current best-guess is that a PWM register is auto-disabling the internal pullups. I haven’t dug into the datasheet to fiddle with it since I got it working with the Leonardo. Does the Pro Micro use the Leonardo bootloader? If they are the same, then I would think this would get rid of the PWM hypothesis.

Looking at the Pro Micro page, it looks like there are special config files you need to download from SFE to get it to work properly. I assume you did all that? The # for PWM makes sense. I was not willing to believe they had some pins of opposite polarity but had to mention it to be safe.

Yes, I was able to successfully install the add-on files from the Sparkfun product page, such that when I programmed it I was using that specific board in the Arduino IDE.

The note for this mentioned: “As of June 19, 2012 these boards will be shipping with a slightly modified version of the same bootloader included with the Arduino Leonardo. It’s modified to use our own VID and PID”

My thoughts: if the bootloader really is a copy of Leonardo’s but with a new VID & PID, then I don’t see why the two boards are behaving differently for me. But, maybe there are other changes in the bootloader itself that require extra PWM configuration (to disable them)? I haven’t gotten into these files (and in fact, would have just bought a breakout board had I been willing to do so), but I can try messing around with the internal registers myself if that’s the case.