I followed this example to wire my keypad to my STM32F4 Discovery board. However any way I read data on the pins I keep getting same data which leads me to believe I wired something wrong.

Here is the image how I had it wired:
enter image description here

I the red line (+) on the breadboard is wired to a +5V pin on my STM32F4 and the blue one (-) is wired to GND on my STM32F4 board.

The first 4 wires are for rows they are wired directly yo + line and right after them there are wired wired to pins from 4-7 like the image bellow shows:

enter image description here

I also tried it by now wiring the keypad to +5. Anyhow I keep getting the following output from my pins: 1 1 0 1 1 1 1 Meaning all but Pin 3 are returning 1 (High).

As far as code goes I initialize all pins for INPUT so I'm reading the value from the PINs. I have Pull UP/DOWN resistor set to NOPULL. However it's always this output.

What is the proper way to wire/interface these keyboards ?

Expanded question:

I wired all 7 pins to my GPIO pins.
- I set all 4 rows to HIGH 1
- I set all 3 columns to LOW + PULL DOWN + Input

Now when I read state of all pins I get: 1111 for the output pins and for the input pins I get 000 and when I press a button on the keypad the corresponding column make one of the 000 to 1.

The problem is this only tells me which column is selected how to I find out which row is selected if they are all set to 1.

My code:

void start_clocks();
void init_outputs();
void init_inputs();

volatile int a, b, c;
volatile int e, f, g, h;

void main(void)
  // Start clocks

  // Configure outputs

  // Configure inputs

  // Configure abc
  a = -1; b = -1; c = -1; 

  e = -1; f = -1; g = -1; h = -1; 

    a = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_11);
    b = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_9);
    c = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_7);

    e = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
    f = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
    g = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_15);
    h = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_13);


void init_inputs()
  GPIO_InitTypeDef Keypad;

  Keypad.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_9|GPIO_Pin_7;
  Keypad.GPIO_Mode = GPIO_Mode_IN;
  Keypad.GPIO_OType = GPIO_OType_PP;
  Keypad.GPIO_PuPd = GPIO_PuPd_DOWN;
  Keypad.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_Init(GPIOE, &Keypad); 


void init_outputs()
  GPIO_InitTypeDef Keypad;

  Keypad.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_11;
  Keypad.GPIO_Mode = GPIO_Mode_OUT;
  Keypad.GPIO_OType = GPIO_OType_PP;
  Keypad.GPIO_PuPd = GPIO_PuPd_UP;
  Keypad.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_Init(GPIOB, &Keypad);

  Keypad.GPIO_Pin = GPIO_Pin_15|GPIO_Pin_13;

  GPIO_Init(GPIOE, &Keypad);

  GPIO_SetBits(GPIOB, GPIO_Pin_13);
  GPIO_SetBits(GPIOB, GPIO_Pin_11);

  GPIO_SetBits(GPIOE, GPIO_Pin_15);
  GPIO_SetBits(GPIOE, GPIO_Pin_13);

void start_clocks()
  // Start clocks for GPIO B and GPIO E

1 Answer 1


You have to poll the rows one at a time. Set the voltage high on only one row at a time. After trying each row, you'll have seen a high on only one column. The combination of active row and responding column tells you which button is pressed.

  • \$\begingroup\$ But is my wiring correct ? Because I'm unsure what is causing the problem I want to be sure I wired this correctly. \$\endgroup\$ Commented Jan 19, 2014 at 14:24
  • \$\begingroup\$ @kellax: Noit isn't correct, you have all 4 rows permanently high. You should control them using GPIO outputs. Your GPIO inputs should be connected to the columns not the rows (or do it completely vice-versa) \$\endgroup\$ Commented Jan 19, 2014 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.