char I2CDecodedKeypad::getKeyStroke()
{
int tmpKey;
tmpKey = i2cRead();
if ((decoderDataAvailable == 1) && (tmpKey > -1 && tmpKey < 20))
// if ((decoderDataAvailable == 1)&&((tmpKey & 0x10) == 0))
{
// tmpKey &= 0x0F;
// OK. A key has been pressed and released, so return the value.
beep(25, 00, 1);
decoderDataAvailable = 0;
return charSet[tmpKey];
}
else if ((tmpKey & 0x10) > 0)
{
decoderDataAvailable = 1;
}
// Otherwise nothing happened...
return 0;
}
But, I still can't get the code to recognise keys 17, 18, 19, and 20. Andrew has the test condition of checking the value in tmpKey with logical AND 16 [0x10] to filter out anything other than keys [0..15], but changing this to say 32 does not solve my problem. I was wondering if anyone else has used the 74C923 with a 20-key keypad and what they did to recognise all the keys?
Koepel:
Did you connect the DataReady (or DataAvailable) to P7 ?
Yes
Koepel:
And the extra signal to P4 ?
Yes
Koepel:
That is why you test with 0x10 to see if data is ready ?
You should mask the data with 0x1F. Get four bits with 0x0F and get five bits with 0x1F.
I've tried masking the test for data ready with logical AND 0x10, but this masks out the keys >= 16
That selects the 4 lower bits, and removes the other bits. You have commented it out, but the DataReady will not be removed and perhaps there is noise on a open input ?
Can you make 0x1F of that ?
It will be a lot easier of you send a lot of data (for example tmpKey) to the serial monitor.
char I2CDecodedKeypad::getKeyStroke()
{
int tmpKey;
tmpKey = i2cRead();
if (temp != tmpKey)
{
temp = tmpKey;
Serial.print("i2cRead: ");
Serial.println(temp);
}
if ((decoderDataAvailable == 1)&&((tmpKey & 0x20) == 0))
{
tmpKey &= 0x1F;
// OK. A key has been pressed and released, so return the value.
Serial.print("Key: ");
Serial.println(tmpKey);
beep(25, 00, 1);
decoderDataAvailable = 0;
return charSet[tmpKey];
}
else if ((tmpKey ^ 0xFF) == 0)
{
decoderDataAvailable = 1;
}
// Otherwise nothing happened...
return 0;
}
As I found that the keydown event generated a value of 255. My data-available is now indicating, and I can normally read the index of the key pressed for each key [0..19].
This all works up to a point, when suddenly the I will start to get the output:
DataReady to bit P7, that is 0x80.
Data to P0, P1, P2, P3, P4, those are the bits 0x1F.
In the code you have tmpKey & 0x20. That would be okay of the the DataReady would be connected to P5.
Use 0x80 everywhere 0x10 was used, because the DataReady is now P7.
Replace 0x0F with 0x1F because now also P5 is used for data.
Remove the '< 20', and use the original line.
I'm sorry for not giving a clear answer right away in my Reply #1, I'm confused by the code.
There is also a ^ with 0xFF, that is a XOR. Are all the lines high when no key is pressed ? I still don't understand everything.
A huge thank you for your help. I changed the code to as below, ensuring that the Data Available from the 74C923 is going to P7 of the 8574, and P5 and P7 are connected to ground.
char I2CDecodedKeypad::getKeyStroke()
{
int tmpKey;
tmpKey = i2cRead();
if (temp != tmpKey)
{
temp = tmpKey;
Serial.print("i2cRead: ");
Serial.println(temp);
}
if ((decoderDataAvailable == 1) && ((tmpKey & 0x80) == 0))
{
tmpKey &= 0x1F;
// OK. A key has been pressed and released, so return the value.
Serial.print("Key: ");
Serial.println(tmpKey);
beep(25, 00, 1);
decoderDataAvailable = 0;
return charSet[tmpKey];
}
else if ((tmpKey & 0x80) > 0)
{
decoderDataAvailable = 1;
}
// Otherwise nothing happened...
return 0;
}
I now get:
Key index Key down Key up
0 128 0
1 129 1
2 130 2
...
18 146 18