Need help - Double 4x4 keyboard charlieplexing

Hello! :slight_smile: I really really need some help with interfacing two 4x4 keyboards.

I have stumbled upon this example and code of a 4x4 keyboard being charlieplexed. I really need to use two 4x4 keyboards for my project and this solution fits my needs perfectly since I would like to spare some pins on my arduino. Sadly I have a slight problem that I'm not sure how to solve. I have written in on the topic itself but there is no response (it's an old topic)...

I duplicated the code, renamed all the integers and the code generally works, but only if I use one or the other "half" of the code seperately - meaning I comment one or the other part of the code (one or the other keyboard).
My problem is that when I uncomment the code and join the two pieces together, the code does not read the keyboards at all.

I don't understand what is wrong, so if someone can shed any light on this it would be awesome! ..and probably usefull to others also...

Thanks for any insights!

#define RK1_0 B10000100
#define RK1_1 B00011000
#define RK1_2 B00011100
#define RK1_3 B00010110
#define RK1_4 B00101001
#define RK1_5 B00101100
#define RK1_6 B00100100
#define RK1_7 B01001001
#define RK1_8 B01001000
#define RK1_9 B01000010
#define RK1_NUM B10000110
#define RK1_STAR B10000001
#define RK1_A B00010010
#define RK1_B B00100001
#define RK1_C B01000011
#define RK1_D B10000011


#define RK2_0 B10000100
#define RK2_1 B00011000
#define RK2_2 B00011100
#define RK2_3 B00010110
#define RK2_4 B00101001
#define RK2_5 B00101100
#define RK2_6 B00100100
#define RK2_7 B01001001
#define RK2_8 B01001000
#define RK2_9 B01000010
#define RK2_NUM B10000110
#define RK2_STAR B10000001
#define RK2_A B00010010
#define RK2_B B00100001
#define RK2_C B01000011
#define RK2_D B10000011


const int PinKM1[] = {4, 5, 6, 7}; // four pins to Keyboard Matrix

const int PinKM2[] = {8, 9, 10, 11}; // four pins to Keyboard Matrix



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


void loop(void) {
  char c1 = ReadKey1();
  Serial.println(c1);
  
delay (10);


  char c2 = ReadKey2();
  Serial.println(c2);

delay (10);
}



// -------------------  ReadKey -------------------
// wait for a key to be pressed
char ReadKey1(void) {
  char c1;
  byte r1;

  unsigned long ti = millis() + 2000;          // simple autorepeat
  while (0 != ReadKeyboardRaw1() && ti > millis()); // wait for previeus key to be unpressed..

  do {
    while (0 == (r1 = ReadKeyboardRaw1()));
    delay(10);
  }
  while ( r1 != ReadKeyboardRaw1() );
  switch (r1) {
    case RK1_0: c1 = '0'; break;
    case RK1_1: c1 = '1'; break;
    case RK1_2: c1 = '2'; break;
    case RK1_3: c1 = '3'; break;
    case RK1_4: c1 = '4'; break;
    case RK1_5: c1 = '5'; break;
    case RK1_6: c1 = '6'; break;
    case RK1_7: c1 = '7'; break;
    case RK1_8: c1 = '8'; break;
    case RK1_9: c1 = '9'; break;
    case RK1_NUM: c1 = '#'; break;
    case RK1_STAR: c1 = '*'; break;
    case RK1_A: c1 = 'A'; break;
    case RK1_B: c1 = 'B'; break;
    case RK1_C: c1 = 'C'; break;
    case RK1_D: c1 = 'D'; break;
    default: c1 = '?';
  }
  return c1;
}


// -------------------  ReadKey -------------------
// wait for a key to be pressed
char ReadKey2(void) {
  char c2;
  byte r2;

  unsigned long tm = millis() + 2000;          // simple autorepeat
  while (0 != ReadKeyboardRaw2() && tm > millis()); // wait for previeus key to be unpressed..

  do {
    while (0 == (r2 = ReadKeyboardRaw2()));
    delay(10);
  }
  while (r2 != ReadKeyboardRaw2());
  switch (r2) {
    case RK2_0: c2 = '0'; break;
    case RK2_1: c2 = '1'; break;
    case RK2_2: c2 = '2'; break;
    case RK2_3: c2 = '3'; break;
    case RK2_4: c2 = '4'; break;
    case RK2_5: c2 = '5'; break;
    case RK2_6: c2 = '6'; break;
    case RK2_7: c2 = '7'; break;
    case RK2_8: c2 = '8'; break;
    case RK2_9: c2 = '9'; break;
    case RK2_NUM: c2 = '#'; break;
    case RK2_STAR: c2 = '*'; break;
    case RK2_A: c2 = 'A'; break;
    case RK2_B: c2 = 'B'; break;
    case RK2_C: c2 = 'C'; break;
    case RK2_D: c2 = 'D'; break;
    default: c2 = '?';
  }
  return c2;
}



// -------------------  ReadKeyboardRaw -------------------
byte ReadKeyboardRaw1(void) {
  byte RawKey1 = 0;

  for (byte i = 0; i < 4; i++) {
    // setup ports..
    for (byte j = 0; j < 4; j++) {
      if (i == j) {  // output '0'
        pinMode(PinKM1[j], OUTPUT);
        digitalWrite( PinKM1[j], LOW);
      }
      else { // input
        pinMode(PinKM1[j], INPUT);
        digitalWrite( PinKM1[j], HIGH);
      }
    }
    delay(1);
    // read ports..
    for (byte j = 0; j < 4; j++) {
      if (i != j) {
        if (LOW == digitalRead(PinKM1[j])) {
          bitSet(RawKey1, j);
        }
      }
    }
    if (RawKey1 != 0x0) { // key pressed, return key
      bitSet(RawKey1, i + 4);
      break; //return RawKey1;
    }
  }
  //  Serial.println(RawKey1);
  return RawKey1;
}





// -------------------  ReadKeyboardRaw -------------------
byte ReadKeyboardRaw2(void) {
  byte RawKey2 = 0;

  for (byte k = 0; k < 4; k++) {
    // setup ports..
    for (byte l = 0; l < 4; l++) {
      if (k == l) {  // output '0'
        pinMode(PinKM2[l], OUTPUT);
        digitalWrite( PinKM2[l], LOW);
      }
      else { // input
        pinMode(PinKM2[l], INPUT);
        digitalWrite( PinKM2[l], HIGH);
      }
    }
    delay(1);
    // read ports..
    for (byte l = 0; l < 4; l++) {
      if (k != l) {
        if (LOW == digitalRead(PinKM2[l])) {
          bitSet(RawKey2, l);
        }
      }
    }
    if (RawKey2 != 0x0) { // key pressed, return key
      bitSet(RawKey2, k + 4);
      break; //return RawKey2;
    }
  }
  //  Serial.println(RawKey2);
  return RawKey2;
}

This Arduino - Keypad tutorial may be useful for you.

Is this the same as your previous thread?

the code does not read the keyboards at all.

Are you sure that's what's going on?

Reading your code, I would expect it to wait for a key to be pressed on keypad #1 (while ignoring keypad #2), then wait for a key to be pressed on keypad #2 (while ignoring keypad #1). Then back to keypad #1...

Do you really need to get into the complexities of charlieplexing ? You can read two 4 by 4 keypads using 12 pins by treating them as two halves of an 8 by 4 keypad with common rows or columns

It's also easy to read both keypads with just 2 pins. Or zero pins, if your circuit is already using other i2c devices. You can use a pcf8574 chip to connect to each keypad. The pcf chips connect back to the SDA & SCL pins on the Arduino. You give each pcf chip a different address on the i2c bus by connecting the 3 x ADRS pins to a unique combination of 5V & GND.