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: Extended Charlieplexing - LEDs and Multiplexing - Arduino Forum
Code:
#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;
}
