From 9d8169a1c446ad496a65b91b738ce10ae9bce390 Mon Sep 17 00:00:00 2001 From: Robbie Boucher Date: Tue, 7 May 2019 11:30:11 -0400 Subject: [PATCH] updates for digital keyboard mode with modifier key --- joy.ino | 426 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 306 insertions(+), 120 deletions(-) diff --git a/joy.ino b/joy.ino index 1f12fd5..c4eb933 100644 --- a/joy.ino +++ b/joy.ino @@ -1,3 +1,9 @@ +#include + +/** + * Start - PIN defines + */ + /** Analog pin # for the joystick X axis */ #define STICK_X 9 @@ -5,29 +11,89 @@ #define STICK_Y 8 /** Digital pin # for the joystick button */ -#define BUTTON_PIN 0 +#define JOYSTICK_1_BUTTON_PIN 0 + +/** Pin # for the extra signal LED. Set to a valid pin # if you have an extra LED wired to said pin. (HINT: -1 isn't a valid pin #) */ +#define ALT_LED_PIN -1 + +/** + * Stop - PIN defines + */ + + /** +* Start - Binding defines +*/ + +#define BUTTON_JOYSTICK_1_KEY KEY_ESC +#define KEYBOARD_MODE_STICK_UP_KEY KEY_I +#define KEYBOARD_MODE_STICK_DOWN_KEY KEY_K +#define KEYBOARD_MODE_STICK_LEFT_KEY KEY_J +#define KEYBOARD_MODE_STICK_RIGHT_KEY KEY_L +#define KEYBOARD_MODE_MODIFIER_KEY KEY_LEFT_SHIFT + +/** +* Stop - Binding defines +*/ /** * High and low values for both of the joystick axes. Get these values from the output of the * doMinMaxAccumulationAndOutput() function. */ -#define X_FROM_LOW 289 -#define X_FROM_HIGH 750 -#define Y_FROM_LOW 245 -#define Y_FROM_HIGH 720 +#define X_FROM_LOW 196 +#define X_FROM_HIGH 845 +#define Y_FROM_LOW 230 +#define Y_FROM_HIGH 856 + +/** +* Start - Keyboard mode defines +*/ + +#define KEYBOARD_MODE_X_START_OFFSET 0 +#define KEYBOARD_MODE_Y_START_OFFSET 0 +#define KEYBOARD_MODE_X_MODIFIER_SCALE .6 +#define KEYBOARD_MODE_Y_MODIFIER_SCALE .6 +/** +* Stop - Keyboard mode defines +*/ + +int Xstick; +int Ystick; int deadzone; int upperBound; int lowerBound; bool isKeyboardMode; -bool lastKeyboardModeKeys[5] = {false, false, false, false, false}; // up, down, left, right, select +bool isHoldToWalk; +bool isHoldToRun; +int keyboardModeXUpperModifierOffset; +int keyboardModeXLowerModifierOffset; +int keyboardModeYUpperModifierOffset; +int keyboardModeYLowerModifierOffset; + +// up, down, left, right, modifier +bool keyboardModeKeyStatus[5] = {false, false, false, false, false}; +Bounce joystickButton1 = Bounce(JOYSTICK_1_BUTTON_PIN, 10); void setup() { Joystick.useManualSend(true); pinMode(13, OUTPUT); + + if (ALT_LED_PIN > 0) { + pinMode(ALT_LED_PIN, OUTPUT); + } + setDeadzone(); setBounds(); - pinMode(BUTTON_PIN, INPUT_PULLUP); + pinMode(JOYSTICK_1_BUTTON_PIN, INPUT_PULLUP); + + Xstick = 512; + Ystick = 512; + + isKeyboardMode = false; + isHoldToWalk = false; + isHoldToRun = false; + detectStartupFlags(); + calculateKeyboardModeOffsets(); /** * Uncomment these two function when initially setting up the teensy + joystick. Have a text @@ -40,119 +106,130 @@ void setup() { //outputInitialState(); //doMinMaxAccumulationAndOutput(); - isKeyboardMode = false; - detectStartupFlags(); + Xstick = 512; + Ystick = 512; } -void loop() { - int Xstick = analogRead(STICK_X); - int Ystick = analogRead(STICK_Y); - - if (isInsideDeadzone(Xstick)) { - Xstick = 512; - } else { - Xstick = constrain(map(Xstick, X_FROM_LOW, X_FROM_HIGH, 0, 1023), 0, 1023); - } - - if (isInsideDeadzone(Ystick)) { - Ystick = 512; - } else { - Ystick = constrain(map(Ystick, Y_FROM_LOW, Y_FROM_HIGH, 0, 1023), 0, 1023); +void setLedState(int state) { + digitalWrite(13, state); + + if (ALT_LED_PIN > 0) { + digitalWrite(ALT_LED_PIN, state); } +} - if (isKeyboardMode) { - bool keyboardModeKeys[5] = {false, false, false, false, false}; // up, down, left, right, select - - if (Xstick < 612 && Xstick > 412) { - keyboardModeKeys[2] = false; - keyboardModeKeys[3] = false; - } else if (Xstick > 612) { - keyboardModeKeys[2] = false; - keyboardModeKeys[3] = true; +void doStickCalculations(bool constrainDeadzone = false) { + Xstick = analogRead(STICK_X); + Ystick = 1023 - analogRead(STICK_Y); + + if (constrainDeadzone) { + if (isInsideDeadzone(Xstick)) { + Xstick = 512; } else { - keyboardModeKeys[2] = true; - keyboardModeKeys[3] = false; + if (Xstick > 512) { + Xstick = constrain(map((Xstick - deadzone), 513, X_FROM_HIGH, 513, 1023), 513, 1023); + } else { + Xstick = constrain(map((Xstick + deadzone), X_FROM_LOW, 511, 0, 511), 0, 511); + } } - - if (Ystick < 612 && Ystick > 412) { - keyboardModeKeys[0] = false; - keyboardModeKeys[1] = false; - } else if (Ystick < 412) { - keyboardModeKeys[0] = true; - keyboardModeKeys[1] = false; + + if (isInsideDeadzone(Ystick)) { + Ystick = 512; } else { - keyboardModeKeys[0] = false; - keyboardModeKeys[1] = true; + if (Ystick > 512) { + Ystick = constrain(map((Ystick - deadzone), 513, Y_FROM_HIGH, 513, 1023), 513, 1023); + } else { + Ystick = constrain(map((Ystick + deadzone), Y_FROM_LOW, 511, 0, 511), 0, 511); + } } + } +} - if (!digitalRead(BUTTON_PIN)) { - keyboardModeKeys[5] = true; - } else { - keyboardModeKeys[5] = false; +void loop() { + doStickCalculations(true); + joystickButton1.update(); + + if (isKeyboardMode) { + // up, down, left, right, modifier + bool keyboardModeKeyPress[5] = {false, false, false, false, false}; + + if (Xstick > (512 + KEYBOARD_MODE_X_START_OFFSET)) { + keyboardModeKeyPress[3] = true; + + if (Xstick < (512 + keyboardModeXUpperModifierOffset)) { + if (isHoldToWalk) { + keyboardModeKeyPress[4] = true; + } + } else { + if (isHoldToRun) { + keyboardModeKeyPress[4] = true; + } + } + } else if (Xstick < (512 - KEYBOARD_MODE_X_START_OFFSET)) { + keyboardModeKeyPress[2] = true; + + if (Xstick > (512 - keyboardModeXLowerModifierOffset)) { + if (isHoldToWalk) { + keyboardModeKeyPress[4] = true; + } + } else { + if (isHoldToRun) { + keyboardModeKeyPress[4] = true; + } + } } - bool isDifferent = false; - - for (int i = 0; i < 5; i++) { - bool last = lastKeyboardModeKeys[i]; - bool current = keyboardModeKeys[i]; - - if (current != last) { - lastKeyboardModeKeys[i] = current; - isDifferent = true; - - switch (i) { - case 0: - if (current) { - Keyboard.set_key1(KEY_W); - } else { - Keyboard.set_key1(0); - } - - break; - case 1: - if (current) { - Keyboard.set_key2(KEY_S); - } else { - Keyboard.set_key2(0); - } - - break; - case 2: - if (current) { - Keyboard.set_key3(KEY_A); - } else { - Keyboard.set_key3(0); - } - - break; - case 3: - if (current) { - Keyboard.set_key4(KEY_D); - } else { - Keyboard.set_key4(0); - } - - break; - case 4: - if (current) { - Keyboard.set_key5(KEY_P); - } else { - Keyboard.set_key5(0); - } - - break; + if (Ystick < (512 - KEYBOARD_MODE_Y_START_OFFSET)) { + keyboardModeKeyPress[0] = true; + + if (Ystick > (512 - keyboardModeYLowerModifierOffset)) { + if (isHoldToWalk) { + keyboardModeKeyPress[4] = true; + } + } else { + if (isHoldToRun) { + keyboardModeKeyPress[4] = true; + } + } + } else if (Ystick > (512 + KEYBOARD_MODE_Y_START_OFFSET)) { + keyboardModeKeyPress[1] = true; + + if (Ystick < (512 + keyboardModeYUpperModifierOffset)) { + if (isHoldToWalk) { + keyboardModeKeyPress[4] = true; + } + } else { + if (isHoldToRun) { + keyboardModeKeyPress[4] = true; } } } - if (isDifferent) { - Keyboard.send_now(); + handleKeyboundModeKey(KEYBOARD_MODE_STICK_UP_KEY, keyboardModeKeyPress[0]); + handleKeyboundModeKey(KEYBOARD_MODE_STICK_DOWN_KEY, keyboardModeKeyPress[1]); + handleKeyboundModeKey(KEYBOARD_MODE_STICK_LEFT_KEY, keyboardModeKeyPress[2]); + handleKeyboundModeKey(KEYBOARD_MODE_STICK_RIGHT_KEY, keyboardModeKeyPress[3]); + handleKeyboundModeKey(KEYBOARD_MODE_MODIFIER_KEY, keyboardModeKeyPress[4]); + + if (joystickButton1.fallingEdge()) { + Keyboard.press(BUTTON_JOYSTICK_1_KEY); + } + + if (joystickButton1.risingEdge()) { + Keyboard.release(BUTTON_JOYSTICK_1_KEY); } } else { Joystick.X(Xstick); Joystick.Y(Ystick); - Joystick.button(1, !digitalRead(BUTTON_PIN)); + + if (joystickButton1.fallingEdge()) { + Joystick.button(1, 1); + } + + if (joystickButton1.risingEdge()) { + Joystick.button(1, 0); + } + Joystick.Z(512); Joystick.Zrotate(512); Joystick.sliderLeft(0); @@ -162,6 +239,42 @@ void loop() { } } +void handleKeyboundModeKey(int key, bool isPress) { + int keyIndex = -1; + + switch (key) { + case KEYBOARD_MODE_STICK_UP_KEY: + keyIndex = 0; + break; + case KEYBOARD_MODE_STICK_DOWN_KEY: + keyIndex = 1; + break; + case KEYBOARD_MODE_STICK_LEFT_KEY: + keyIndex = 2; + break; + case KEYBOARD_MODE_STICK_RIGHT_KEY: + keyIndex = 3; + break; + case KEYBOARD_MODE_MODIFIER_KEY: + keyIndex = 4; + break; + } + + if (keyIndex > -1) { + if (isPress) { + if (keyboardModeKeyStatus[keyIndex] == false) { + Keyboard.press(key); + keyboardModeKeyStatus[keyIndex] = true; + } + } else { + if (keyboardModeKeyStatus[keyIndex] == true) { + Keyboard.release(key); + keyboardModeKeyStatus[keyIndex] = false; + } + } + } +} + bool isInsideDeadzone(int rawStickValue) { bool returnValue = false; @@ -174,33 +287,47 @@ bool isInsideDeadzone(int rawStickValue) { return returnValue; } +int getDeadzoneAdjustedValue(int value) { + if (value > 512) { + value = value - deadzone; + } + + if (value < 512) { + value = value + deadzone; + } + + return value; +} + void setDeadzone() { - digitalWrite(13, HIGH); + setLedState(HIGH); deadzone = 0; unsigned long startTime = millis(); unsigned long highValue = 0; while ((millis() - startTime) < 5000) { - int Xstick = abs(analogRead(STICK_X)); - int Ystick = abs(analogRead(STICK_Y)); + doStickCalculations(); + + int localXstick = abs(Xstick); + int localYstick = abs(Ystick); int diffX = 0; int diffY = 0; - if (Xstick < 512) { - diffX = 512 - Xstick; + if (localXstick < 512) { + diffX = 512 - localXstick; } - if (Xstick > 512) { - diffX = Xstick - 512; + if (localXstick > 512) { + diffX = localXstick - 512; } - if (Ystick < 512) { - diffY = 512 - Ystick; + if (localYstick < 512) { + diffY = 512 - localYstick; } - if (Ystick > 512) { - diffY = Ystick - 512; + if (localYstick > 512) { + diffY = localYstick - 512; } if (diffX >= diffY) { @@ -218,25 +345,77 @@ void setBounds() { upperBound = 512 + deadzone; lowerBound = 512 - deadzone; - digitalWrite(13, LOW); + setLedState(LOW); } void detectStartupFlags() { unsigned long startTime = millis(); + unsigned long lastBlink = 0; + int ledState = LOW; + int yUpperBounds = ((Y_FROM_HIGH - 512) * .8) + 512; + int yLowerBounds = 512 - ((512 - Y_FROM_LOW) * .8); while ((millis() - startTime) < 5000) { - if (!digitalRead(BUTTON_PIN)) { - digitalWrite(13, HIGH); + unsigned long now = millis(); + + joystickButton1.update(); + + if (now - lastBlink >= 500) { + lastBlink = now; + + if (ledState == LOW) { + ledState = HIGH; + } else { + ledState = LOW; + } + + setLedState(ledState); + } + + if (joystickButton1.fallingEdge()) { + setLedState(HIGH); + isKeyboardMode = true; + isHoldToWalk = false; + isHoldToRun = false; + + break; + } + + doStickCalculations(); + + if (Ystick > yUpperBounds) { + setLedState(HIGH); + isKeyboardMode = true; + isHoldToWalk = false; + isHoldToRun = true; + + break; + } + + if (Ystick < yLowerBounds) { + setLedState(HIGH); isKeyboardMode = true; - + isHoldToWalk = true; + isHoldToRun = false; + break; } } + + if (!isKeyboardMode) { + setLedState(LOW); + } +} + +void calculateKeyboardModeOffsets() { + keyboardModeXUpperModifierOffset = abs((map(X_FROM_HIGH, 513, X_FROM_HIGH, 513, 1023) - (513 + KEYBOARD_MODE_X_START_OFFSET)) * KEYBOARD_MODE_X_MODIFIER_SCALE); + keyboardModeXLowerModifierOffset = abs((map(X_FROM_LOW, X_FROM_LOW, 511, 0, 511) - (511 - KEYBOARD_MODE_X_START_OFFSET)) * KEYBOARD_MODE_X_MODIFIER_SCALE); + keyboardModeYUpperModifierOffset = abs((map(Y_FROM_HIGH, 513, Y_FROM_HIGH, 513, 1023) - (513 + KEYBOARD_MODE_Y_START_OFFSET)) * KEYBOARD_MODE_Y_MODIFIER_SCALE); + keyboardModeYLowerModifierOffset = abs((map(Y_FROM_LOW, Y_FROM_LOW, 511, 0, 511) - (511 - KEYBOARD_MODE_Y_START_OFFSET)) * KEYBOARD_MODE_Y_MODIFIER_SCALE); } void outputInitialState() { - int Xstick = analogRead(STICK_X); - int Ystick = analogRead(STICK_Y); + doStickCalculations(); Keyboard.print("Deadzone: "); Keyboard.println(deadzone); @@ -261,6 +440,14 @@ void outputInitialState() { Keyboard.println(Xstick); Keyboard.print("Adjusted Y Rest: "); Keyboard.println(Ystick); + Keyboard.print("Keyboard Mode X Upper Modifier Offset: "); + Keyboard.println(keyboardModeXUpperModifierOffset); + Keyboard.print("Keyboard Mode X Lower Modifier Offset: "); + Keyboard.println(keyboardModeXLowerModifierOffset); + Keyboard.print("Keyboard Mode Y Upper Modifier Offset: "); + Keyboard.println(keyboardModeYUpperModifierOffset); + Keyboard.print("Keyboard Mode Y Lower Modifier Offset: "); + Keyboard.println(keyboardModeYLowerModifierOffset); } void doMinMaxAccumulationAndOutput() { @@ -271,8 +458,7 @@ void doMinMaxAccumulationAndOutput() { int lowestY = 512; while ((millis() - startTime) < 5000) { - int Xstick = analogRead(STICK_X); - int Ystick = analogRead(STICK_Y); + doStickCalculations(); if (Xstick < lowestX) { lowestX = Xstick;