Go Down

Topic: How to use 4x4 membrane keypad with 16channel multiplexer? (Read 565 times) previous topic - next topic

samuelgregorovic

Oct 22, 2018, 05:31 pm Last Edit: Oct 22, 2018, 06:04 pm by samuelgregorovic
I´m working on an Arduino project, and i have ran out of usable pins.To put it simple, i need to find a way to use traditional 4x4 membrane keyboard through 16-channel multiplexor 74HC4067. So far, i searched along the internet but have not found any solution at all. Thank you for any hints. Here is what i have, i need this to be changed for use with multiplexor. i can process everything afterwards, i just cant get the keypad work over the multiplexor. It works when i connect it directly to arduino pins.  I tried a lot of things but no luck.  This code works when i connect the keypad directly to arduino.
Code: [Select]

/*4x4 Matrix Keypad connected to Arduino
This code prints the key pressed on the keypad to the serial port*/

#include <Keypad.h>

const byte numRows= 4; //number of rows on the keypad
const byte numCols= 4; //number of columns on the keypad

//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols]=
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {9,8,7,6}; //Rows 0 to 3
byte colPins[numCols]= {5,4,3,2}; //Columns 0 to 3

//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup()
{
Serial.begin(9600);
}

char getPin(char array[]){
  int possition=0;
 
  while(possition < 8 ){
    char keypressed = myKeypad.getKey();
    if (keypressed != NO_KEY ){
         if(keypressed>47 && keypressed<58){
            Serial.print("*"); //prints * on LCD (for every press)
            array[possition]=keypressed; //saves char to array
            possition++;
          }
     }
  }
  return* array;
  }
 

void loop(){
    char PUK[8];
    getPin(PUK);
    Serial.print("Entered PIN is: ");
    for(int a=0;a<8;a++){
        Serial.print(PUK[a]);
    }
}



PaulRB

I don't think 74hc4067 is going to be much help. You would need 8 Arduino pins to read the keypad directly. With the multiplexer, you can reduce that to... 7 pins. 4 for keypad column selection, 2 for controlling the multiplexer to select a keypad row and one to read the multiplexer output. Maybe there is a better way, but I can't think of one at the moment.

I would recommend a pcf8574 chip. You need to free up the SDA & SCL pins (A4 & A5 on Uno/Nano).

Tell us what other components you want to connect and we can advise how to use fewer pins. I will take a guess that one of the components is a 16x2 LCD display, using 6 or 7 pins?

DrAzzy

You can't, because you need to monitor 4 pins, while keeping the other 4 pulled up, then when you get a signal, you know the row - then manipulate the other 4 pins while watching the one that changed in order to see which column (or vise versa). A 16-1 multiplexer only allows you to manipulate one pin at a time (and takes 5 pins to use!)

You can do it with a 8-bit port expander (and control said port expander with just the two I2C pins), though.
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

samuelgregorovic

Thanks for replies, even though it is not ideal, i need to use it this way. I can´t use I2C pins, so is there ANY way to acomplish this using this multiplexer?

PaulRB

is there ANY way to acomplish this using this multiplexer?
Yes, you can do it like I explained before. You will need 7 Arduino pins.

Or you make a keypad from 16 separate buttons. Then, using the multiplexer, you will need only 5 Arduino pins.

Or use your 4x4 keypad and two 74hc4067. You will need 5 Arduino pins.


Grumpy_Mike

Quote
and i have ran out of usable pins
That implies you have pins free but you can not use them. Do you know the analogue input pins can be used for digital I/O?


samuelgregorovic

#7
Oct 23, 2018, 09:21 am Last Edit: Oct 23, 2018, 09:23 am by samuelgregorovic
I don't think 74hc4067 is going to be much help. You would need 8 Arduino pins to read the keypad directly. With the multiplexer, you can reduce that to... 7 pins. 4 for keypad column selection, 2 for controlling the multiplexer to select a keypad row and one to read the multiplexer output. Maybe there is a better way, but I can't think of one at the moment.

I would recommend a pcf8574 chip. You need to free up the SDA & SCL pins (A4 & A5 on Uno/Nano).

Tell us what other components you want to connect and we can advise how to use fewer pins. I will take a guess that one of the components is a 16x2 LCD display, using 6 or 7 pins?
This is what i use:
                 I2C 16x2 LCD( SCL and SDA pins + GND + VCC)
                 MFRC522 RFID Card Reader(5 pins+GND+VCC)
                 4x4 Keypad(8pins)
               
I also need to use microSD card reader using 4 pins(CS,SCK,MOSI,MISO+GND+VCC)
and a classic servo motor and 2 RGB leds . Do you have any ideas how to pack all of this in one arduino UNO? GND and VCC are of course not a problem, i can use a  breadboard to solve that.

samuelgregorovic

Yes, you can do it like I explained before. You will need 7 Arduino pins.

can you help me with it? I understand how multiplexor works, i just dont really get how to use this piece of code anywhere in my program(not in this loop()), and how to talk to these channels. thank you

Code: [Select]
#include "MUX74HC4067.h"
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

 
 LiquidCrystal_I2C lcd(0x27,16,2);


const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keymap[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

MUX74HC4067 mux(7, 8, 9, 10, 11);
byte rowPins[4] = ???????
  byte colPins[4]= ???????
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, ROWS, COLS);
void setup(){
   lcd.init();
      lcd.begin(16,2);
      lcd.backlight();
      lcd.setCursor(0,0);
   Serial.begin(9600);
    mux.signalPin(3, INPUT, DIGITAL);
     lcd.setCursor(0,0);
}
 
void loop(){
 
 
char keypressed = myKeypad.getKey();
  lcd.print(keypressed);
   
}

Paul__B

This is what i use:
                 I2C 16x2 LCD( SCL and SDA pins + GND + VCC)
                 MFRC522 RFID Card Reader(5 pins+GND+VCC)
                 4x4 Keypad(8pins)
So you are already using the I2C bus for a "backpack" which uses a PCF8574 chip, so your "I can´t use I2C pins" is in fact, total nonsense!  :smiley-eek:

That means you can use another seven PCF8574 port expander chips (they come on modules ready to use, just like the LCD backpack) for anything you want - you could read seven 4 by 4 matrix keyboards if you needed to with no trouble at all.  :smiley-roll:

I don't think we need waste our time with any further suggestions about "alternatives".

Go Up