#include <ESP32Encoder.h> //
https://github.com/madhephaestus/ESP32Encoder/
#include <Keypad.h> //
https://github.com/Chris--A/Keypad
#include <BleGamepad.h> //
https://github.com/MagnusThome/ESP32-BLE-Gamepad
BleGamepad bleGamepad("WirelessGameHub", "breeze", 100);
////////////////////// BUTTON MATRIX //////////////////////
#define ROWS 5
#define COLS 4
uint8_t rowPins[ROWS] = {13, 14, 15, 16, 33};
uint8_t colPins[COLS] = {17, 18, 19, 21};
uint8_t keymap[ROWS][COLS] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11},
{12,13,14,15},
{24,25,26,27}
};
Keypad customKeypad = Keypad( makeKeymap(keymap), rowPins, colPins, ROWS, COLS);
//////////// ROTARY ENCODERS (WITH PUSH SWITCHES) ////////////
#define MAXENC 4
uint8_t uppPin[MAXENC] = {22, 25, 27, 04};
uint8_t dwnPin[MAXENC] = {23, 26, 32, 05};
uint8_t encoderUpp[MAXENC] = {16,18,20,22};
uint8_t encoderDwn[MAXENC] = {17,19,21,23};
ESP32Encoder encoder[MAXENC];
unsigned long holdoff[MAXENC] = {0,0,0,0};
int32_t prevenccntr[MAXENC] = {0,0,0,0};
bool prevprs[MAXENC] = {0,0,0,0};
#define HOLDOFFTIME 150
////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
for (uint8_t i=0; i<MAXENC; i++) {
encoder
.clearCount();
encoder.attachSingleEdge(dwnPin, uppPin);
}
customKeypad.addEventListener(keypadEvent);
customKeypad.setHoldTime(1);
bleGamepad.begin();
Serial.println("Booted!");
}
////////////////////////////////////////////////////////////////////////////////////////
void loop() {
unsigned long now = millis();
// -- ROTARY ENCODERS : ROTATION -- //
for (uint8_t i=0; i<MAXENC; i++) {
int32_t cntr = encoder.getCount();
if (cntr!=prevenccntr) {
if (!holdoff) {
if (cntr>prevenccntr) { sendKey(encoderUpp); }
if (cntr<prevenccntr) { sendKey(encoderDwn); }
holdoff = now;
if (holdoff==0) holdoff = 1; // SAFEGUARD WRAP AROUND OF millis() (WHICH IS TO 0) SINCE holdoff==0 HAS A SPECIAL MEANING ABOVE
}
else if (now-holdoff > HOLDOFFTIME) {
prevenccntr = encoder.getCount();
holdoff = 0;
}
}
// -- ROTARY ENCODERS : PUSH SWITCH -- //
}
customKeypad.getKey(); // READ BUTTON MATRIX (EVENT CALLBACK SETUP)
//delay(10);
}
////////////////////////////////////////////////////////////////////////////////////////
void keypadEvent(KeypadEvent key){
uint8_t keystate = customKeypad.getState();
if (keystate==PRESSED) { pressKey(key); }
if (keystate==RELEASED) { releaseKey(key); }
}
////////////////////////////////////////////////////////////////////////////////////////
void sendKey(uint8_t key) {
uint32_t gamepadbutton = pow(2,key); // CONVERT TO THE BINARY MAPPING GAMEPAD KEYS USE
Serial.print("pulse\t");
Serial.println(key);
if(bleGamepad.isConnected()) {
bleGamepad.press(gamepadbutton);
delay(150);
bleGamepad.release(gamepadbutton);
}
}
void pressKey(uint8_t key) {
uint32_t gamepadbutton = pow(2,key); // CONVERT TO THE BINARY MAPPING GAMEPAD KEYS USE
Serial.print("hold\t");
Serial.println(key);
if(bleGamepad.isConnected()) {
bleGamepad.press(gamepadbutton);
}
}
void releaseKey(uint8_t key) {
uint32_t gamepadbutton = pow(2,key); // CONVERT TO THE BINARY MAPPING GAMEPAD KEYS USE
Serial.print("release\t");
Serial.println(key);
if(bleGamepad.isConnected()) {
bleGamepad.release(gamepadbutton);
}
}
////////////////////////////////////////////////////////////////////////////////////////