Hey all! By now you should have heard about all the wonderful Teensy Boards produced by Paul Stoffregen and the PJRC team but, in case you haven't, they're a collection of high-speed, ARM-based microcontrollers that have the ability to act as a variety of native USB devices. If you'd like to learn more about the Teensy platform, there are plenty of tutorials where it's explained in more depth.
This tutorial uses the Teensy's native USB functionality to act as both a Keyboard and Mouse. This is a great project idea for anyone who works with applications or programs that require excessive hotkey or shortcut use. The code in this tutorial is designed to be used with the 3D design program Autodesk Inventor Professional 2018 but can be modified to fit any key/mouse input. If you'd like to see an extreme of this application, check out this Emoji Keyboard.
The Setup
For this project, I'll be using the Teensy 3.2 due to it's smaller size and price. This Teensy has a whopping 33 digital pins available on-chip, allowing us to connect a huge amount of inputs should we require them. This project, however, is quite simple; we require:
- 4 Non-Latching Pushbuttons
- A Slide - Potentiometer
- A Joystick.
These components have enough versatility to enact 8 different, user-set commands as well as move the cursor around via the Joystick. If you'd like, you can encase the assembled project within an enclosure or keep them on a prototyping breadboard for frequent modifications and input additions. The assembly of the pieces above should look like the photo below (disregard the Teensy Model Name)..
For this program to work, we must install the TeensyDuino Application from the PJRC website. The installation process, along with a walkthrough of the changes to the Arduino IDE, can be found in the Using Teensy with Arduino IDE tutorial.
Code
As mentioned previously, the example code for this tutorial is centred around a 3D design program but can be modified to suit any application or program which incorporates hotkeys or shortcuts. The .ino file can be found on GitHub and also appears below.
void setup() { /* 3D Mouse * Created by Christian @ Core Electronics on 27/06/18 * Buttons: * 1 Save 1' Measure * 2 Redo 2' Wheel * 3 Undo 3' Orbit * 4 Delete 4' Upload */ // Include Relevant Libraries #include // Declare Pin Assignments // The linear slide pot is here const int potSlider = A2; // The x and y components from the joystick are here const int yPin = A1; const int xPin = A0; // The internal built LED is here const int ledPin = 13; // The click functionality of the joystick is here const int shiftPin = 12; // The buttons are here const int buttonFour = 6; const int buttonThree = 5; const int buttonTwo = 4; const int buttonOne = 3; // Declare Variables bool shiftState = false; float joySpeed = 0; float xMovement = 0; float yMovement = 0; // Define Constants // The debounce library constants are here const int BUTTON_NUM = 4; const int DEBOUNCE_TIME = 5; // The normal (letter/number) keybinds are here for shift pressed (P) and // shift not pressed (NP) const int KEYBIND_SHIFT_P[BUTTON_NUM] = {KEY_S, KEY_Y, KEY_Z, KEY_DELETE}; const int KEYBIND_SHIFT_NP[BUTTON_NUM] = {KEY_M, KEY_W, 0, KEY_U}; // The modifier (shift, ctrl, etc.) keybinds are here for shift pressed (P) // and shift not pressed (NP) const int KEYBIND_MOD_SHIFT_P[BUTTON_NUM] = {MODIFIERKEY_CTRL, MODIFIERKEY_CTRL, MODIFIERKEY_CTRL, 0}; const int KEYBIND_MOD_SHIFT_NP[BUTTON_NUM] = {0, MODIFIERKEY_CTRL, 0, MODIFIERKEY_CTRL}; // Create the push-button bounce instances Bounce buttonArray[BUTTON_NUM] = { Bounce(buttonOne, DEBOUNCE_TIME), Bounce(buttonTwo, DEBOUNCE_TIME), Bounce(buttonThree, DEBOUNCE_TIME), Bounce(buttonFour, DEBOUNCE_TIME) }; // Create the joystick bounce instance Bounce shiftButton = Bounce(shiftPin, DEBOUNCE_TIME); void setup() { // Define the Pullup configuration for each button pinMode(buttonOne, INPUT_PULLUP); pinMode(buttonTwo, INPUT_PULLUP); pinMode(buttonThree, INPUT_PULLUP); pinMode(buttonFour, INPUT_PULLUP); pinMode(shiftPin, INPUT_PULLUP); // Define the pinMode for the led pinMode(ledPin, OUTPUT); } void loop() { // Update the button states shiftButton.update(); for(int i = 0; i < BUTTON_NUM; i++){ buttonArray[i].update(); } // Measure and scale the value of the slidePot // and joystick joySpeed = map(analogRead(potSlider), 0 , 1023, 1, 3); xMovement = map(analogRead(xPin), 0, 1023, -2, 2); yMovement = map(analogRead(yPin), 0, 1023, -2, 2); // Make the mouse move Mouse.move(joySpeed*xMovement, -joySpeed*yMovement); // For loop to scan through the buttons and apply the // required state for(int i = 0; i < BUTTON_NUM; i++){ if(buttonArray[i].fallingEdge()){ // Check to see if the shiftState is NOT active if(!shiftState){ // Apply the normal state keybinds Keyboard.set_modifier(KEYBIND_MOD_SHIFT_P[i]); Keyboard.set_key1(KEYBIND_SHIFT_P[i]); Keyboard.send_now(); Serial.println(KEYBIND_MOD_SHIFT_P[i]); Serial.println(KEYBIND_SHIFT_P[i]); }else{ // Apply the shift state keybinds Keyboard.set_modifier(KEYBIND_MOD_SHIFT_NP[i]); Keyboard.set_key1(KEYBIND_SHIFT_NP[i]); Keyboard.send_now(); Serial.println(KEYBIND_MOD_SHIFT_NP[i]); Serial.println(KEYBIND_SHIFT_NP[i]); } }else if(buttonArray[i].risingEdge()){ // If no buttons are pressed, send nothing Keyboard.set_modifier(0); Keyboard.set_key1(0); Keyboard.send_now(); Serial.println("Reset"); } } // For Orbit control. This is different as it includes a middle mouse click if(buttonArray[2].fallingEdge()){ Keyboard.set_modifier(MODIFIERKEY_SHIFT); Keyboard.send_now(); Mouse.set_buttons(0,1,0); } else if(buttonArray[2].risingEdge()){ Keyboard.set_modifier(0); Keyboard.send_now(); Mouse.set_buttons(0,0,0); } // Check the state of the 'shift' button if(shiftButton.fallingEdge()){ shiftState = shiftState ^ 1; digitalWrite(ledPin, shiftState); } }
Uploading and First Run
As mentioned underneath the schematic, the TeensyDuino application must be installed before the code can be uploaded to the board. From there, the board's preferences must be configured as shown below, excepting maybe the COM port, which should be selected to match your computer's setup. Once that's done, hit the upload button and watch as your Teensy becomes a handy shortcut-keyboard/mouse! The shortcuts are specified in the comments at the top of the program and are suited to work with Autodesk Inventor Professional 2018 as mentioned previously.
Personalising your Teensy Keyboard/Mouse
Now that you've had some fun inspecting and editing your 3D models with your Teensy powered Keyboard-Mouse, it's time to modify the code to suit your personality. If you find yourself using a shortcut more frequently than you'd like, you can edit the KEYBIND_SHIFT_P[BUTTON_NUM] array as well as the KEYBIND_MOD_SHIFT_P[BUTTON_NUM] array and replace them with the new shortcut key and modifier respectively. A list of each of these keys and modifiers can be found on the PJRC website. If you have any questions about building this handy project, don't hesitate to consult our forum.