Ok so I have a broken toy keyboard that I am using its key matrix for a project. the keyboard is 37 keys, 5x8 matrix. I am using the keypad library and some example code that has been modified to do produce some sort of sound when I press a key. all the notes are correct and such, but here is the problem.
If I hold one key down, and then press and hold another, then let go of the second keypress, they both stop. I would like it to be so the first key starts again when I drop the second key. another thing id like to implement is 5 key polyphony (a little overkill I know, but why not) which means I would maybe need to have 5 different output pins on the UNO, which I just have space for. if I did this, I would probably create an external mixer circuit to mix them all into one voice, which i could do easily.
#include <Keypad.h>
const byte ROWS = 5;
const byte COLS = 8;
char keys[ROWS][COLS] = {
{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'},
{'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'},
{'q', 'r', 's', 't', 'u', 'v', 'w', 'x'},
{'y', 'z', '0', '1', '2', '3', '4', '5'},
{'6', '7', '8', '9', '+', '&', '@', '='},
};
byte rowPins[ROWS] = {A1, A2, A3, A4, A5}; //connect to the row pinouts of the kpd
byte colPins[COLS] = {2, 3, 4, 5, 6, 7, 8, 9}; //connect to the column pinouts of the kpd
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
unsigned long loopCount;
unsigned long startTime;
String msg;
void setup()
{
Serial.begin(9600);
loopCount = 0;
startTime = millis();
msg = "";
}
void loop()
{
loopCount++;
if ((millis() - startTime) > 5000)
{
//Serial.print("Average loops per second = ");
// Serial.println(loopCount/5);
startTime = millis();
loopCount = 0;
}
// Fills kpd.key[ ] array with up-to 10 active keys.
// Returns true if there are ANY active keys.
if (kpd.getKeys())
{
for (int i = 0; i < LIST_MAX; i++)
{ // Scan the whole key list.
if (kpd.key[i].stateChanged)
{ // Only find keys that have changed state.
float note;
switch (kpd.key[i].kstate)
{ // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " PRESSED.";
switch(kpd.key[i].kchar) {
case 'a':
note = 65.41;
break;
case 'b':
note = 69.30;
break;
case 'c':
note = 73.42;
break;
case 'd':
note = 77.78;
break;
case 'e':
note = 82.41;
break;
case 'f':
note = 87.31;
break;
case 'g':
note = 92.50;
break;
case 'h':
note = 98.00;
break;
case 'i':
note = 103.83;
break;
case 'j':
note = 110.00;
break;
case 'k':
note = 116.54;
break;
case 'l':
note = 123.47;
break;
case 'm':
note = 130.81;
break;
case 'n':
note = 138.59;
break;
case 'o':
note = 146.83;
break;
case 'p':
note = 155.56;
break;
case 'q':
note = 164.81;
break;
case 'r':
note = 174.61;
break;
case 's':
note = 185.00;
break;
case 't':
note = 196.00;
break;
case 'u':
note = 207.65;
break;
case 'v':
note = 220.00;
break;
case 'w':
note = 233.08;
break;
case 'x':
note = 246.94;
break;
case 'y':
note = 261.63;
break;
case 'z':
note = 277.18;
break;
case '0':
note = 293.66;
break;
case '1':
note = 311.13;
break;
case '2':
note = 329.63;
break;
case '3':
note = 349.23;
break;
case '4':
note = 369.99;
break;
case '5':
note = 392.00;
break;
case '6':
note = 415.30;
break;
case '7':
note = 440.00;
break;
case '8':
note = 466.16;
break;
case '9':
note = 493.88;
break;
case '+':
note = 523.25;
break;
}
tone(12, note);
break;
case RELEASED:
msg = " RELEASED.";
noTone(12);
break;
;
}
Serial.print("Key ");
Serial.print(kpd.key[i].kchar);
Serial.println(msg);
}
}
}
}
I need something like this ⇓ to go in place of the crazy switch statement with 37 cases lol
if(aKey == pressed) {
if(anotherKey == pressed) {
playTheCorrespondingNote(12); // on pin 12
} else {
playTheCorrespondingNote(12); // probably use tone()
}
}
/* then vary the output pins from 9-13 in sequence */
thanks for the help in advance.
PD