#include "Keyboard.h" //#define DEBUG #define PIN_WIRE_SDA D3 #define PIN_WIRE_SCL D4 Keyboard::Keyboard(uint8_t _debounce) { this->keybind.insert({ {1, '1'}, {2, '4'}, {3, '7'}, {4, 'O'}, {5, '2'}, {6, '5'}, {7, '8'}, {8, '0'}, {9, '3'}, {10, '6'}, {11, '9'}, {12, 'X'}, }); this->_debounce = _debounce; } void Keyboard::begin(TwoWire *databus) { pcf8574 = new PCF8574(databus, 0x21, PIN_WIRE_SDA, PIN_WIRE_SCL); pcf8574->pinMode(0, OUTPUT); for (int i = 1; i < 8; i++) { if (i < 5) pcf8574->pinMode(i, INPUT_PULLUP); else pcf8574->pinMode(i, OUTPUT); } if (pcf8574->begin()) Serial.println("Keyboard connected"); else Serial.println("Keyboard missing"); pcf8574->digitalWrite(1, HIGH); for (int i = 5; i < 8; i++) pcf8574->digitalWrite(i, HIGH); } Keyboard::~Keyboard() { if (pcf8574 != nullptr) delete pcf8574; } void Keyboard::scan() { if (millis() < _timeElapsed + this->_debounce) return; uint8_t key = 0; for (int i = 7; i > 4; i--) // Columns { pcf8574->digitalWrite(i, LOW); delay(15); scanColumn(&key, 1, 4); pcf8574->digitalWrite(i, HIGH); } } void Keyboard::scanAsync() { /** Without delay - scanning only one column per cycle **/ if (millis() < _timeElapsed + this->_debounce) return; uint8_t key = 4 * _current_scan_col; scanColumn(&key, 1, 4); pcf8574->digitalWrite(7 - (_current_scan_col + 1) % 3, LOW); pcf8574->digitalWrite(7 - _current_scan_col, HIGH); _current_scan_col++; if (_current_scan_col > 2) _current_scan_col = 0; } void Keyboard::scanColumn(uint8_t *key_ptr, uint8_t start, uint8_t stop) { for (int j = start; j <= stop; j++) { // Rows (*key_ptr)++; uint8_t val = pcf8574->digitalRead(j); if (val == 0) { _timeElapsed = millis(); this->_lastKey = *key_ptr; this->_buffer.push_back(mapChr(*key_ptr)); #ifdef DEBUG Serial.print(*key_ptr); #endif return; } } } char Keyboard::mapChr(uint8_t key) { return this->keybind[key]; } char Keyboard::getLastChr() { return this->mapChr(this->_lastKey); } bool Keyboard::available() { return (!this->_buffer.empty()); } void Keyboard::clear() { this->_buffer.clear(); } String Keyboard::getString() { String out; for (auto &&i : this->_buffer) { out.concat(i); } this->_buffer.clear(); return out; }