Pages: [1]   Go Down
Author Topic: Extended Charlieplexing  (Read 1589 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I do not have any problem but I found a solution to a problem I have had - hopefully someone else will find it useful.
I have bought some 4x4 16 key matrix membrane keypads - see image. They are very cheap and very useful – but interface to them require normally 4+4=8 ports.
I can use normal charlieplexing and then only use 4 ports but then I cannot use the diagonal keys! 



I tried use the analog method connecting seven resistor coupled as a voltage divider and use only one AD ports – it works but I’m not sure have stable it is. 
After some thinking and investigating I found out that it was possible to extend the charlieplexing by adding an extra diode for every column. Using 8 diodes instead of 4. See the sketch. The tricks is to pull two lines low at key press instead of one line - except for the diagonal where only one line is pulled low.



If you use normal charlieplexing and have n ports you can use these n ports to manage (n*n)-n keys using n diodes. At my method, the extended charlieplexing, you can with n ports manage n*n keys but it require additional n diodes total of 2*n diodes.
Sample code to test the extended charlieplexing:

Code:
#define RK_0 B10000100
#define RK_1 B00011000
#define RK_2 B00011100
#define RK_3 B00010110
#define RK_4 B00101001
#define RK_5 B00101100
#define RK_6 B00100100
#define RK_7 B01001001
#define RK_8 B01001000
#define RK_9 B01000010
#define RK_NUM B10000110
#define RK_STAR B10000001
#define RK_A B00010010
#define RK_B B00100001
#define RK_C B01000011
#define RK_D B10000011

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

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

void loop(void) {

  char c = ReadKey(); 
  Serial.println(c);
}

// -------------------  ReadKey -------------------
// wait for a key to be pressed
char ReadKey(void) {
  char c;
  byte r;

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

  do {
    while (0==(r=ReadKeyboardRaw()));
    delay(10);
  }
  while( r!=ReadKeyboardRaw() );
  switch(r) {
    case RK_0: c = '0'; break;   
    case RK_1: c = '1'; break;
    case RK_2: c = '2'; break;   
    case RK_3: c = '3'; break;       
    case RK_4: c = '4'; break;       
    case RK_5: c = '5'; break;   
    case RK_6: c = '6'; break;   
    case RK_7: c = '7'; break;   
    case RK_8: c = '8'; break;   
    case RK_9: c = '9'; break;   
    case RK_NUM: c = '#'; break;
    case RK_STAR:c = '*'; break;
    case RK_A: c = 'A'; break;
    case RK_B: c = 'B'; break;
    case RK_C: c = 'C'; break;
    case RK_D: c = 'D'; break;   
    default: c = '?';
  }
  return c;
}

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


Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thought this was worth bringing to the top. Excellent schematic, description and code.
Logged

Lacey, Washington, USA
Offline Offline
Edison Member
*
Karma: 155
Posts: 2362
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice!
Logged

Steve Greenfield AE7HD
CET Consumer Electronics and Computer
Please don't read your attitudes into my messages

Offline Offline
Jr. Member
**
Karma: 0
Posts: 52
Listen to the wind singing in the grass my love, as you lay yourself down to rest. Listen to the cry of the river in autumn cold, my dear.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have seen this before and it's great. Good job !
Logged

Pages: [1]   Go Up
Jump to: