mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
148 lines
2.9 KiB
C++
148 lines
2.9 KiB
C++
//
|
|
// FILE: I2CKeyPad8x8.cpp
|
|
// AUTHOR: Rob Tillaart
|
|
// VERSION: 0.1.1
|
|
// PURPOSE: Arduino library for 8x8 or smaller KeyPad connected to an I2C PCF8575.
|
|
// URL: https://github.com/RobTillaart/I2CKeyPad8x8
|
|
//
|
|
// HISTORY: see changelog.md
|
|
|
|
|
|
#include "I2CKeyPad8x8.h"
|
|
|
|
|
|
I2CKeyPad8x8::I2CKeyPad8x8(const uint8_t deviceAddress, TwoWire *wire)
|
|
{
|
|
_lastKey = I2C_KEYPAD8x8_NOKEY;
|
|
_address = deviceAddress;
|
|
_wire = wire;
|
|
}
|
|
|
|
|
|
#if defined(ESP8266) || defined(ESP32)
|
|
bool I2CKeyPad8x8::begin(uint8_t sda, uint8_t scl)
|
|
{
|
|
_wire->begin(sda, scl);
|
|
// enable interrupts
|
|
_read(0xFF00);
|
|
return isConnected();
|
|
}
|
|
#endif
|
|
|
|
|
|
bool I2CKeyPad8x8::begin()
|
|
{
|
|
_wire->begin();
|
|
// enable interrupts
|
|
_read(0xFF00);
|
|
return isConnected();
|
|
}
|
|
|
|
|
|
uint8_t I2CKeyPad8x8::getKey()
|
|
{
|
|
// key = row + 8 x col
|
|
uint8_t key = 0;
|
|
|
|
// mask = 8 rows as input pull up, 8 columns as output
|
|
uint16_t rows = _read(0xFF00);
|
|
|
|
// check if single line has gone low.
|
|
if (rows == 0xFF00) return I2C_KEYPAD8x8_NOKEY;
|
|
else if (rows == 0xFE00) key = 0;
|
|
else if (rows == 0xFD00) key = 1;
|
|
else if (rows == 0xFB00) key = 2;
|
|
else if (rows == 0xF700) key = 3;
|
|
else if (rows == 0xEF00) key = 4;
|
|
else if (rows == 0xDF00) key = 5;
|
|
else if (rows == 0xBF00) key = 6;
|
|
else if (rows == 0x7F00) key = 7;
|
|
else return I2C_KEYPAD8x8_FAIL;
|
|
|
|
// 8 columns as input pull up, 8 rows as output
|
|
uint16_t cols = _read(0x00FF);
|
|
// check if single line has gone low.
|
|
if (cols == 0x00FF) return I2C_KEYPAD8x8_NOKEY;
|
|
else if (cols == 0x00FE) key += 0;
|
|
else if (cols == 0x00FD) key += 8;
|
|
else if (cols == 0x00FB) key += 16;
|
|
else if (cols == 0x00F7) key += 24;
|
|
else if (cols == 0x00EF) key += 32;
|
|
else if (cols == 0x00DF) key += 40;
|
|
else if (cols == 0x00BF) key += 48;
|
|
else if (cols == 0x007F) key += 56;
|
|
else return I2C_KEYPAD8x8_FAIL;
|
|
|
|
_lastKey = key;
|
|
|
|
return key; // 0..65
|
|
}
|
|
|
|
|
|
uint8_t I2CKeyPad8x8::getLastKey()
|
|
{
|
|
return _lastKey;
|
|
};
|
|
|
|
|
|
// to check "press any key"
|
|
bool I2CKeyPad8x8::isPressed()
|
|
{
|
|
uint16_t a = _read(0xFF00);
|
|
if (a == 0xFF00) return false;
|
|
return (a != 0xFF00);
|
|
}
|
|
|
|
|
|
bool I2CKeyPad8x8::isConnected()
|
|
{
|
|
_wire->beginTransmission(_address);
|
|
return (_wire->endTransmission() == 0);
|
|
}
|
|
|
|
|
|
uint8_t I2CKeyPad8x8::getChar()
|
|
{
|
|
return _keyMap[getKey()];
|
|
};
|
|
|
|
|
|
uint8_t I2CKeyPad8x8::getLastChar()
|
|
{
|
|
return _keyMap[_lastKey];
|
|
};
|
|
|
|
|
|
void I2CKeyPad8x8::loadKeyMap(char * keyMap)
|
|
{
|
|
_keyMap = keyMap;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// PROTECTED
|
|
//
|
|
uint16_t I2CKeyPad8x8::_read(uint16_t mask)
|
|
{
|
|
// improve the odds that IO will not interrupted.
|
|
yield();
|
|
|
|
_wire->beginTransmission(_address);
|
|
_wire->write(mask >> 8);
|
|
_wire->write(mask & 0xFF);
|
|
if (_wire->endTransmission() != 0)
|
|
{
|
|
// set communication error
|
|
return 0xFFFF;
|
|
}
|
|
_wire->requestFrom(_address, (uint8_t)2);
|
|
uint16_t value = _wire->read() << 8;
|
|
value += _wire->read();
|
|
return value;
|
|
}
|
|
|
|
|
|
// -- END OF FILE --
|
|
|