Created
April 25, 2023 12:55
-
-
Save tomhermans/83eb8d9cf1aa557fd9a597676628b0cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* based on @file MultiKey.ino || @version 1.0 || @author Mark Stanley|| @contact [email protected] | |
|| @description This sketch is an example of how you can get multiple key presses from a keypad or keyboard. | |
|| # | |
*/ | |
#include <Keypad.h> | |
#include <BleKeyboard.h> | |
// 135x240px display | |
#include <SPI.h> | |
#include <TFT_eSPI.h> // Hardware-specific | |
TFT_eSPI tft = TFT_eSPI(135, 240); | |
TFT_eSprite img = TFT_eSprite(&tft); | |
BleKeyboard bleKeyboard("Toms-Buttons"); | |
// define rotary encoder | |
#define outputA 36 | |
#define outputB 37 | |
#define rotSwitch 32 | |
// define joystick | |
#define joyVRX 15 | |
#define joyVRX 13 | |
#define joySW 12 | |
int deltaX = 0; | |
int deltaY = 0; | |
char joyDirX[] = "Center"; | |
char joyDirY[] = "Center"; | |
// array technique to debounce the joystick switch | |
const unsigned int numReadings = 3; | |
unsigned int analogVals[numReadings]; | |
unsigned int i = 0; | |
int counter = 0; | |
int aState; | |
int aLastState; | |
int lastMillis = 0; | |
int w = 135; | |
int h = 240; | |
int bg = TFT_BLACK; | |
char keys[4][4] = { | |
{'T', '0', 'M', 'A'}, | |
{'7', '8', '9', 'B'}, | |
{'4', '5', '6', 'C'}, | |
{'1', '2', '3', 'D'} | |
}; | |
// BLUE | |
byte rowPins[4] = {33, 25, 26, 27}; //connect to the row pinouts of the keypad | |
// ORANGE | |
byte colPins[4] = {21, 22, 17, 2}; //connect to the column pinouts of the keypad | |
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, 4, 4 ); | |
//unsigned long loopCount; | |
//unsigned long startTime; | |
String msg; | |
int states[4] = { TFT_PURPLE, TFT_MAROON, TFT_BLACK, TFT_RED }; | |
int curState = 0; | |
void setup() { | |
Serial.begin(115200); | |
tft.begin(); | |
tft.setRotation(0); // 0 & 2 Portrait. 1 & 3 landscape | |
tft.fillScreen(bg); | |
// | |
img.createSprite(w, h); | |
img.setTextColor(TFT_WHITE); | |
img.drawString("MultiKey", 10, 50, 4); | |
img.pushSprite(0, 0); | |
pinMode (outputA, INPUT); | |
pinMode (outputB, INPUT); | |
pinMode (rotSwitch, INPUT_PULLUP); | |
aLastState = digitalRead(outputA); | |
bleKeyboard.begin(); | |
Serial.println("bleKeyb setup"); | |
// loopCount = 0; | |
// startTime = millis(); | |
msg = ""; | |
} | |
void loop() { | |
getJoyStick(); | |
// loopCount++; | |
// if ( (millis() - startTime) > 5000 ) { | |
// Serial.print("Average loops per second = "); | |
// Serial.println(loopCount / 5); | |
// startTime = millis(); | |
// loopCount = 0; | |
// } | |
aState = digitalRead(outputA); | |
if(digitalRead(rotSwitch) < 1) { // reset counter on rotary press | |
counter = 0; | |
Serial.print("rot Switch pressed, counter reset. Counter = "); | |
Serial.println(counter); | |
bleKeyboard.write(KEY_NUM_ENTER); | |
} | |
int interval = millis()-lastMillis; //interval = time between 2 correct cycles in milliseconds. | |
lastMillis = millis(); | |
if (aStat44e != aLastState) { | |
Serial.print(interval); | |
Serial.println(" - pulse"); | |
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise | |
if (interval > 1) { | |
Serial.println("OKAY"); | |
if (digitalRead(outputB) != aState) { | |
Serial.println("PLUS"); | |
bleKeyboard.write(KEY_UP_ARROW); | |
delay(30); | |
counter ++; | |
changeScreenBottom("rotary", String(counter), 0); | |
} else { | |
Serial.println("MINUS"); | |
bleKeyboard.write(KEY_DOWN_ARROW); | |
delay(30); | |
counter --; | |
changeScreenBottom("rotary", String(counter), 0); | |
} | |
// Serial.println(aState, aLastState, digitalRead(outputB), digitalRead(outputA)); | |
Serial.print("Position: "); | |
Serial.println(counter); | |
} else { | |
Serial.println("too fast"); | |
} | |
} | |
// Fills kpd.key[ ] array with up-to 10 active keys. | |
// Returns true if there are ANY active keys. | |
if (kpd.getKeys()) | |
{ | |
for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list. | |
{ | |
if ( kpd.key[i].stateChanged ) // Only find keys that have changed state. | |
{ | |
switch (kpd.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED | |
case PRESSED: | |
msg = " PRESSED."; | |
break; | |
case HOLD: | |
msg = " HOLD."; | |
break; | |
case RELEASED: | |
msg = " RELEASED."; | |
break; | |
case IDLE: | |
msg = " IDLE."; | |
} | |
// Serial.print("Key "); | |
// Serial.print(kpd.key[i].kchar); | |
// Serial.println(msg); | |
Serial.println(kpd.key[i].kchar); | |
if (bleKeyboard.isConnected()) { | |
if (msg == " PRESSED." || msg == " HOLD.") { | |
if (kpd.key[i].kchar == 'A') { | |
Serial.println('A'); | |
curState = curState + 1; | |
if (curState > 4) { | |
curState = 0; | |
} | |
bg = states[curState]; | |
break; | |
} | |
if (kpd.key[i].kchar == 'B') { | |
Serial.println('B'); | |
Serial.println(KEY_TAB); | |
bleKeyboard.write(KEY_TAB); | |
} | |
if (kpd.key[i].kchar == 'C') { | |
Serial.println('C'); | |
Serial.println(KEY_TAB); | |
bleKeyboard.press(KEY_LEFT_SHIFT); | |
bleKeyboard.press(KEY_TAB); | |
delay(100); | |
bleKeyboard.releaseAll(); | |
} | |
if (kpd.key[i].kchar == 'T') { | |
Serial.println(KEY_F11); | |
bleKeyboard.write(KEY_F11); | |
} | |
if (kpd.key[i].kchar == '0') { | |
Serial.println(KEY_F12); | |
bleKeyboard.write(KEY_F12); | |
} | |
if (kpd.key[i].kchar == 'M') { | |
Serial.println(KEY_F13); | |
bleKeyboard.write(KEY_F13); | |
} | |
if (kpd.key[i].kchar != 'T' | |
&& kpd.key[i].kchar != '0' | |
&& kpd.key[i].kchar != 'M' | |
&& kpd.key[i].kchar != 'A' | |
&& kpd.key[i].kchar != 'C' | |
&& kpd.key[i].kchar != 'B' | |
) { | |
bleKeyboard.write(kpd.key[i].kchar); | |
} | |
} | |
changeScreen(String(curState), String(kpd.key[i].kchar), 20); | |
} | |
} | |
} | |
} | |
} // End loop | |
void getJoyStick() { | |
deltaX = 0; | |
deltaY = 0; | |
if(analogRead(15) < 10) { | |
Serial.println(" - RIGHT"); deltaX = w / 3; strcpy(joyDirX, "RIGHT"); | |
bleKeyboard.write(KEY_RIGHT_ARROW); | |
delay(20); | |
} | |
else if(analogRead(15) < 1840) { Serial.println(" - slight right"); deltaX = w / 6; strcpy(joyDirX, "right"); } | |
else if(analogRead(15) > 4050) { | |
Serial.println(" - LEFT"); deltaX = w / 3 * -1; strcpy(joyDirX, "LEFT"); | |
bleKeyboard.write(KEY_LEFT_ARROW); | |
delay(20); | |
} | |
else if(analogRead(15) > 1920) { Serial.println(" - slight left"); deltaX = w / 6 * -1; strcpy(joyDirX, "left");} | |
else { strcpy(joyDirX, "- C -"); } | |
if(analogRead(13) < 10) { | |
Serial.println(" - BOTTOM"); deltaY = h / 3; | |
strcpy(joyDirY, "BOTTOM"); | |
bleKeyboard.write(KEY_DOWN_ARROW); | |
delay(20); | |
} | |
else if (analogRead(13) < 1840) { | |
Serial.println(" - slight bottom"); deltaY = h / 6; strcpy(joyDirY, "bottom"); | |
bleKeyboard.write(KEY_DOWN_ARROW); | |
delay(20); | |
} | |
else if(analogRead(13) > 4050) { | |
Serial.println(" - TOP"); deltaY = h / 3 * -1; strcpy(joyDirY, "TOP"); | |
Serial.println(KEY_UP_ARROW); | |
bleKeyboard.write(KEY_UP_ARROW); | |
delay(20); | |
} | |
else if (analogRead(13) > 1920) { Serial.println(" - slight top"); deltaY = h / 6 * -1; strcpy(joyDirY, "top"); } | |
else { strcpy(joyDirY, "- C -"); } | |
analogVals[i] = analogRead(12); | |
i++; | |
if (i>=numReadings) | |
{ | |
i=0; //reset to beginning of array, so you don't try to save readings outside of the bounds of the array | |
} | |
if(average(analogVals, numReadings) == 0) { Serial.println(" - SW PRESSED"); } else { Serial.println(" - ");} | |
changeScreenBottom(String(joyDirX), String(joyDirY), 60); | |
} | |
void changeScreen(String curState, String keychar, int y) { | |
img.fillRect(0, 0, w, 80, bg); | |
img.drawString(String(curState), 10, y, 4); | |
img.drawString(String(keychar), 10, 20 + y, 4); | |
img.pushSprite(0, 0); | |
} | |
void changeScreenBottom(String curState, String keychar, int y) { | |
img.fillRect(0, 90 + y, w, h, bg); | |
img.drawString(String(curState), 10, 90 + y, 4); | |
img.drawString(String(keychar), 10, 90 + 20 + y, 4); | |
img.pushSprite(0, 0); | |
} | |
float average (unsigned int * array, int len) // assuming array is int. | |
{ | |
long sum = 0L ; // sum will be larger than an item, long for safety. | |
for (int i = 0 ; i < len ; i++) | |
sum += array [i] ; | |
return ((float) sum) / len ; // average will be fractional, so float may be appropriate. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment