Closed XiaoShiZi closed 2 years ago
@XiaoShiZi Sorry for the late response, somehow I missed this issue. I am busy upgrading the build-CI of all my libraries for a few weeks now. Today this library will be done and after that I will dive into your question.
@XiaoShiZi The keypad library does not know which keys are on the keypad, it just returns 0..15 or 16 =NOKEY (17 = FAIL)
I will try to write an example that uses the I2CKeypad and does also some keymapping. (There will be a new develop branch asap)
@XiaoShiZi
As I have no hardware nearby, can you please
so I can add it as example.
//
// FILE: I2Ckeypad_readKeyUntil.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo reading until specific keyPress
// URL: https://github.com/RobTillaart/I2CKeyPad
//
// PCF8574
// pin p0-p3 rows
// pin p4-p7 colums
// 4x4 or smaller keypad.
#include "Wire.h"
#include "I2CKeyPad.h"
const uint8_t KEYPAD_ADDRESS = 0x38;
I2CKeyPad keyPad(KEYPAD_ADDRESS);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Wire.begin();
Wire.setClock(400000);
if (keyPad.begin() == false)
{
Serial.println("\nERROR: cannot communicate to keypad.\nPlease reboot.\n");
while (1);
}
}
void loop()
{
char buf[20];
int result = readKeyPad('#', buf, 20, 10000);
if (result == 0)
{
Serial.print("SUCCESS: ");
Serial.println(buf);
}
if (result == -1)
{
Serial.print("FAILURE: ");
Serial.println(buf);
}
if (result == -2)
{
Serial.print("TIMEOUT: ");
Serial.println(buf);
}
}
//
// until = end character
// buffer = buffer to fill
// length = length of buffer (incl '\0'
// timeout = timeout in milliseconds
// returns false if until character is not read.
//
int readKeyPad(char until, char * buffer, uint8_t length, uint16_t timeout)
{
char keymap[19] = "123A456B789C*0#DNF"; // ... None Fail }
uint8_t bufferIndex = 0;
uint32_t start = millis();
// empty buffer
buffer[bufferIndex] = 0;
while (true)
{
// while no key is pressed wait
while (keymap[keyPad.getKey()] == 'N')
{
yield();
if (millis() - start > timeout) return -2;
}
// get the key pressed
uint8_t raw = keyPad.getLastKey();
// process key pressed
uint8_t key = keymap[raw];
// handle end conditions
if ( key == until) return 0;
if ( key == 'F') return -1; // failed to read;
if (bufferIndex == length) return false;
// add key to buffer
buffer[bufferIndex++] = key;
buffer[bufferIndex] = 0;
// while key is pressed wait
while (keymap[keyPad.getKey()] == key)
{
yield();
if (millis() - start > timeout) return -2;
}
}
}
// -- END OF FILE --
added example to branch - https://github.com/RobTillaart/I2CKeyPad/tree/develop
Hi Rob Tillaart, Thanks for the look into this adding functionality. On your request : As I have no hardware nearby, can you please
V verify the following test sketch? +/- confirm this matches the needed functionality? V it compiles so I can add it as example.
Tested your example and indeed it will do the trick ;-) Thank youfor adding this into your library! Kind Regards, XiaoShiZi
So you can add it to the list of interface now. Thanks Rob Tillaart!
Thanks for testing. I will merge the example asap.
I am working on another issue in this library to add mapping of the buttons to characters of choice. See #9 After that I will publish a new release.
Example merged into master.
@XiaoShiZi A slightly simpler readUntil() as it is only one loop - please verify. might save a few bytes.
int readKeyPadUntil(char until, char * buffer, uint8_t length, uint16_t timeout)
{
char keymap[19] = "123A456B789C*0#DNF"; // ... NoKey Fail }
uint8_t bufferIndex = 0;
uint32_t start = millis();
uint8_t lastKey = 'N';
// empty the return buffer
buffer[bufferIndex] = 0;
while (millis() - start < timeout)
{
uint8_t key = keymap[keyPad.getKey()];
if (key == 'N') lastKey = 'N';
else if (key == until) return 0;
else if (key == 'F') return -1;
else
{
if (key != lastKey)
{
lastKey = key;
// add key to buffer
buffer[bufferIndex++] = key;
buffer[bufferIndex] = 0;
if ( bufferIndex == length - 1 ) return -3;
}
}
yield();
}
return -2; // timeout
}
Dear Rob Tillaart,
I like the lib you made especialy the fact that you just put the keytop into 1 array. Any change you could expand this lib with a function like the Serial.readBytesUntil(character, buffer, length, time) but then for a I2C Keyboard (like the 4x4 matrix)? So that we can easily get our char/String/Array with values till "#" or "*" or "A-D" is pressed, length, buffer size or time.
I2CKeypad::getKeyUntil(char, buffer, length, time)
Kind regards and a lot of appreciation for your work on this library. P.S. If there's another lib capable to give this functionality please be kind and let us know.
XiaoShiZi
Arduino Serial readBytesUntil