How to wire/interface a 4×3 membrane keypad

breadboardgpiokeyboardstm32

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
  start_clocks();

  // Configure outputs
  init_outputs();

  // Configure inputs
  init_inputs();

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

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

  while(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
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOB, ENABLE);
}

Best Answer

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.