Hello all
I am almost at the end of my first project, but I must admit, I am in way over my head. I am hoping that someone here might be able to help.
I am working on a project that has 8 push buttons, each creating a different keyboard.press. I have that part working fine, but the next part is giving me a headache trying to work out.
I would like to also add a rotary encoder to mimic a mouse wheel (scroll up/down), but I have absolutely no idea where to start. Could somebody be kind enough to help?
Below is a really bad mockup of how I have the hardware layed out (I really am sorry for how bad it is), and also I have added the sketch that I am using. As you will see, I have modified an example sketch found on another website. I know there are bits of code in there that arent needed and looks messy. If you could help tidy it up and remove un-needed parts at the same time, it would be greatly appreciated.
Hardware Layout
Sketch
#include "Keyboard.h"
const int buttonPin[] = {2, 3, 4, 5, 6, 7, 8, 9,};
int pinCount = 8;
int potPin = 2;
int prevPotState = -1;
int potState = -1;
int potTolerance = 1;
long potDebounceDelay = 20;
int buttonState[] = {1, 1, 1, 1, 1, 1, 1, 1};
int prevButtonState[] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
long startedPressing[] = {0, 0, 0, 0, 0, 0, 0, 0};
boolean longPressing[] = {false, false, false, false, false, false, false, false};
long lastDebounceTime[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // 1 more for the pot
long debounceDelay = 0;
boolean testHardware = false;
int keyComb(char key1 = 0, char key2 = 0, char key3 = 0, char key4 = 0) {
if (key1 != 0) { Keyboard.press(key1); }
if (key2 != 0) { Keyboard.press(key2); }
if (key3 != 0) { Keyboard.press(key3); }
if (key4 != 0) { Keyboard.press(key4); }
delay(100);
Keyboard.releaseAll();
}
int sendLine(char const * line) {
Keyboard.print(line);
delay(750);
keyComb(KEY_RETURN);
}
// Output actions. Probably the only part that you need to change
int outputAction(int currentButton, int typeOfPress = 0) {
// typeOfPress 1: on push; 2: on release; 3: on long press; 4: on lingering press.
// actions on release, on long press and lingering press include the action press. Action lingering press cancels action release and long press.
if (testHardware) {
Keyboard.print(currentButton + 1);
if (typeOfPress == 1) {
Keyboard.print(" pressed ");
}
if (typeOfPress == 2) {
Keyboard.print(" released ");
}
if (typeOfPress == 3) {
Keyboard.print(" long ");
}
if (typeOfPress == 4) {
Keyboard.print(" lingering ");
}
Keyboard.print(millis());
Keyboard.print(" ");
Keyboard.print(lastDebounceTime[currentButton]);
keyComb(KEY_RETURN);
} else {
if (currentButton + 1 == 1) {
if (typeOfPress == 1) {
Keyboard.press('n'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 2) {
if (typeOfPress == 1) {
Keyboard.press('a'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 3) {
if (typeOfPress == 1) {
Keyboard.press('l'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 4) {
if (typeOfPress == 1) {
Keyboard.press('u'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 5) {
if (typeOfPress == 1) {
Keyboard.press('w'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 6) {
if (typeOfPress == 1) {
Keyboard.press('d'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 7) {
if (typeOfPress == 1) {
Keyboard.press('c'); // Keystroke
Keyboard.releaseAll();
}
}
if (currentButton + 1 == 8) {
if (typeOfPress == 1) {
Keyboard.press('r'); // Keystroke
Keyboard.releaseAll();
}
}
}
}
void setup() {
for (int thisPin = pinCount - 1; thisPin >= 0; thisPin--) {
pinMode(buttonPin[thisPin], INPUT_PULLUP);
digitalWrite(buttonPin[thisPin], HIGH); // In some versions use INPUT_PULLUP to use the built-in pull up resistor
}
Keyboard.begin();
}
void loop() {
for (int thisPin = pinCount - 1; thisPin >= 0; thisPin--) {
buttonState[thisPin] = digitalRead(buttonPin[thisPin]);
// HIGH = state 1 <- button not pressed
// LOW = state 0 <- button pressed
// On longer press
if ((startedPressing[thisPin] == 0) || ((millis() - startedPressing[thisPin]) <= 1200)) {
if (((buttonState[thisPin] != prevButtonState[thisPin])) && ((millis() - lastDebounceTime[thisPin]) > debounceDelay)) {
if ((buttonState[thisPin] != prevButtonState[thisPin])) {
if (buttonState[thisPin] == 0) {
// Standard press action
startedPressing[thisPin] = millis();
outputAction(thisPin, 1);
} else {
if (!longPressing[thisPin]) {
if ((millis() - startedPressing[thisPin]) < 500) {
// On release (to avoid standard action if is incompatible with Long or Longer action)
outputAction(thisPin, 2);
} else {
// Long action (+standard action already sent)
outputAction(thisPin, 3);
}
}
startedPressing[thisPin] = 0;
longPressing[thisPin] = false;
}
lastDebounceTime[thisPin] = millis();
}
} else {
outputAction(thisPin, 4);
longPressing[thisPin] = true;
startedPressing[thisPin] = 0;
}
prevButtonState[thisPin] = buttonState[thisPin];
}
}
}
If someone could please help with adding the encoder (what pins to connect to, and also code), I would very much appreciate it.
Thanks for reading
Tim