Go Down

Topic: Charlieplex 4x3 Keypad (Read 1 time) previous topic - next topic

tcox8

I am attempting to convert a 4x4 charlieplex keypad schematic to a 4x3 keypad. The keypad plays sounds that mimic the touch-tone sounds from a telephone. Currently I can detect what buttons are being pressed (all 12 of them) but when I try to play a sound it only plays on the first row (buttons 1 through 3). It also reads those buttons faster than any of the other buttons. I can tell because it outputs to the serial monitor. I'm hoping someone can look at my code and schematic (attached) to help point me in the right direction. Thanks!


Link to original 4x4 charlieplex: http://forum.arduino.cc/index.php?topic=141978.0;topicseen

Code:
Code: [Select]

#include <SdFat.h>      //sd card library
SdFat sd;
#include <TMRpcm.h>  //Sound library
#include <SPI.h>



#define RK_0 B10000100
#define RK_1 B00011010 //26/00011000
#define RK_2 B00011100
#define RK_3 B00010110
#define RK_4 B00101000 //40/00101001
#define RK_5 B00101100
#define RK_6 B00100100
#define RK_7 B01001010  //74/01001001
#define RK_8 B01001000 //48/72
#define RK_9 B01000010 //42/66
#define RK_NUM B10000110
#define RK_STAR B10000010 //130/10000001




#define SD_ChipSelectPin 4 //sd shield uses pin 4 for CS

const int pinKM[] = {4,5,6,7};  // four pins to Keyboard Matrix
TMRpcm tmrpcm;   // create an object for use in this sketch

void setup()
{
  Serial.begin(9600);
  tmrpcm.speakerPin = 9;
  //tmrpcm.quality(1);
  tmrpcm.setVolume(0);

  if (!sd.begin(SD_ChipSelectPin, SPI_FULL_SPEED)) {  // see if the card is present and can be initialized:
    Serial.println("SD fail"); 
    return;   // don't do anything more if not
  }
  //tmrpcm.play("9.wav"); //play this sound at bootup/reset
  tmrpcm.play("5.wav");
}

void loop(void) {

  if (!tmrpcm.isPlaying()) {  //if no sound is playing disable the speaker to prevent the annoying high pitch noise
    tmrpcm.disable();
   }

  char c = ReadKey();
  Serial.println(c); //prints the character pressed on keypad 
}





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

  unsigned long ti=millis()+500;              // 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';
      tmrpcm.play("0.wav");
      break;   
    case RK_1: c = '1';
      tmrpcm.play("4.wav");
      break;
    case RK_2: c = '2';
      tmrpcm.play("2.wav");
      break;   
    case RK_3: c = '3';
      tmrpcm.play("3.wav");
      break;       
    case RK_4: c = '4';
      tmrpcm.play("4.wav");
      break;       
    case RK_5: c = '5';
      tmrpcm.play("5.wav");
      break;   
    case RK_6: c = '6';
      tmrpcm.play("6.wav");
      break;   
    case RK_7: c = '7';
      tmrpcm.play("7.wav");
      break;   
    case RK_8: c = '8';
      tmrpcm.play("8.wav");
      break;   
    case RK_9: c = '9';
      tmrpcm.play("9.wav");
      break;   
    case RK_NUM: c = '#';
      tmrpcm.play("#.wav");
      break;
    case RK_STAR: c = '*';
      tmrpcm.play("star.wav");
      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);
      //Serial.println(rawkey);
      break; //return rawkey;     
    }
  }
  return rawkey;
}

Grumpy_Mike

Your code does not attempt to read the keypad or generate a sound. The loop function does not address this problem.

Please post the code you are having a problem with.

tcox8

It indeed does.

Code: [Select]
char c = ReadKey();

This breaks to the ReadKey function. Within the ReadKey it breaks to another function that sets the ports and reads the ports accordingly. That is returned back to ReadKey where a SwitchCase determines what sound to play.

PaulRB

Try this. Not sure it will make any difference...
Code: [Select]

#include <SdFat.h>      //sd card library
SdFat sd;
#include <TMRpcm.h>  //Sound library
#include <SPI.h>



#define RK_0 B10000100
#define RK_1 B00011010 //26/00011000
#define RK_2 B00011100
#define RK_3 B00010110
#define RK_4 B00101000 //40/00101001
#define RK_5 B00101100
#define RK_6 B00100100
#define RK_7 B01001010  //74/01001001
#define RK_8 B01001000 //48/72
#define RK_9 B01000010 //42/66
#define RK_NUM B10000110
#define RK_STAR B10000010 //130/10000001




#define SD_ChipSelectPin 4 //sd shield uses pin 4 for CS

const int pinKM[] = {4, 5, 6, 7}; // four pins to Keyboard Matrix
TMRpcm tmrpcm;   // create an object for use in this sketch

void setup()
{
  Serial.begin(9600);
  tmrpcm.speakerPin = 9;
  //tmrpcm.quality(1);
  tmrpcm.setVolume(0);

  if (!sd.begin(SD_ChipSelectPin, SPI_FULL_SPEED)) {  // see if the card is present and can be initialized:
    Serial.println("SD fail");
    return;   // don't do anything more if not
  }
  //tmrpcm.play("9.wav"); //play this sound at bootup/reset
  tmrpcm.play("5.wav");
}

void loop(void) {

  if (!tmrpcm.isPlaying()) {  //if no sound is playing disable the speaker to prevent the annoying high pitch noise
    tmrpcm.disable();
  }

  char c = ReadKey();
  Serial.println(c); //prints the character pressed on keypad
 
  switch (c) {
    case '0': tmrpcm.play("0.wav"); break;
    case '1': tmrpcm.play("4.wav"); break;
    case '2': tmrpcm.play("2.wav"); break;
    case '3': tmrpcm.play("3.wav"); break;
    case '4': tmrpcm.play("4.wav"); break;
    case '5': tmrpcm.play("5.wav"); break;
    case '6': tmrpcm.play("6.wav"); break;
    case '7': tmrpcm.play("7.wav"); break;
    case '8': tmrpcm.play("8.wav"); break;
    case '9': tmrpcm.play("9.wav"); break;
    case '#': tmrpcm.play("#.wav"); break;
    case '*': tmrpcm.play("star.wav"); break;
  }
}





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

  unsigned long ti = millis() + 500;          // 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;
    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);
      //Serial.println(rawkey);
      break; //return rawkey;
    }
  }
  return rawkey;
}

tcox8

no difference with that code.  :(

tcox8

If anyone is interested... I found the solution. I had a hair line solder short. The code and wiring works great. Stupid short was causing this problem as well as other problems. Thanks all!

AL1eNQQ

I have a question about ascii coding of individual buttons. I have tried to reverse engineer it but it's so random i can't figure out the logic behind it.

I want to use 2 of these keyboards in a project but can't seem to run them in "parallel" since defining new buttons also requires to define them with some other ascii code than the one already used.


If anyone has any idea on how to run two keyboards on the sam arduino i would be most happy if you would share it.


Thanks!

Go Up