How to wire/interface a 4x3 membrane keypad

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:

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:

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);
}


1 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.

• But is my wiring correct ? Because I'm unsure what is causing the problem I want to be sure I wired this correctly. – Sterling Duchess Jan 19 '14 at 14:24
• @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) – RedGrittyBrick Jan 19 '14 at 14:25