USB Pedal HID Keyboard With Arduino Leonardo

13,743

26

13

Introduction: USB Pedal HID Keyboard With Arduino Leonardo

This Instructable describes how to build a USB pedal with an Arduino Leonardo board.

When you press the pedal with your foot, a keyboard keystroke will be send to your computer, smartphone or tablet over USB.

The possibilities are endless! Some examples:

  • Start / stop photo slideshow.
  • Next slide Powerpoint presentation.
  • Scroll webpages up or down.
  • Flip a page forward / backward in a PDF reader. (Useful for musicians!)
  • Start / stop audio recording. (Useful for musicians!)
  • Other custom keyboard actions.

This project describes how to send [Page down] and [Page up] keys for two pedals, but you can use one pedal for one keystroke as well.
Adding additional pedals allows you to send more keystrokes.
It can be used on Windows, Linux and Android smartphones or tables.
The Leonardo board is equivalent to a standard HID (Human Interface Device Class) USB keyboard.


Project level:
Easy Difficult


Prerequisites:

  • A computer with Arduino IDE version 1.6 or higher installed.
  • An Arduino board with HID USB keyboard support is required.
  • Some hardware components and tools. (Described in next chapters).

There are plenty of commercial USB foot pedals available for 200 Euro's/Dollars or more. DIY projects are customizable and a lot of fun to build!


Let's start!

Step 1: Components

You need the following components:

  • Arduino Leonardo board.
  • Micro USB cable.
  • Black and yellow wires (Inside: LIY 26 AWG, 18 x 0.1mm, outer diameter: 1.20mm).
  • Female TS mono plug (1/4" 6.35mm).
  • 2x Dupont male DIY connector (inside and outside).
  • One or more foot switches / pedals. (I use a M-Audio SP-2 sustain pedal)

Tip: You can use other Arduino boards with an ATmega32U4 chip such as the Leonardo Pro Micro, as long as the chip supports on-chip USB with HID keyboard.


Warning: The Arduino UNO board does not support USB HID keyboard and cannot be used with this project.

Step 2: Tools

You need the following tools:

  • Soldering station.
  • Tin.
  • Dupont crimper tool.
  • Pliers (a pair of flat tongs) tool.
  • Multimeter (Optional)

Step 3: Hardware

At least one pedal (switch) should be connected to an Arduino Leonardo board.

Connect the switch between GND and digital pin 2.
If you have a second pedal, connect it between GND and digital pin 3.


Note: I use a N.O. (normally open) switches.

Step 4: Create a Custom Cable With Connectors

In this step a custom cable will be created to connect the pedal to the Arduino board.

  1. Cut two wires at around 10cm.
  2. Strip the wire ends (4mm coper).
  3. Cut the connector from the strip and keep the attachment at the end of the connector.
  4. Put the wires into the Dupont male header.
  5. Fold the pull relief with a flat plier to keep the wire in position.
  6. Put the wire with connector into the Dupont crimp tool.
  7. Shrink the Dupont connector with the crimper tool.
  8. Remove the attachment from the connector.
  9. Mount the connector in the housing.

Tip: Please refer to my other Instructable how to create a custom cable with Dupont connectors:
https://www.instructables.com/id/Dupont-Crimp-Tool-Tutorial/

Step 5: Solder the Cable

Solder the wires to the female TS connector.

Step 6: Arduino Sketch

The Arduino sketch below sends a [Page Down] keyboard keystroke by pressing the pedal with your foot on digital pin 2.

An optional second pedal can be connected to GND and digital pin 3 to send a [Page Up] key.

Connect a (micro) USB cable between the Arduino Leonardo board and your computer. Open the Arduino IDE and copy-paste the following code:


#include "Keyboard.h"

#define PEDAL1_PIN   2
#define PEDAL2_PIN   3

// Works on the Leonardo board only to simulate 
// a HID keyboard over USB

static void Pedal1Down(void)
{
    Keyboard.press(KEY_PAGE_DOWN);
}

static void Pedal2Down(void)
{
    Keyboard.press(KEY_PAGE_UP);
}

void setup(void)
{
    Keyboard.begin();

    // Set pin to input
    pinMode(PEDAL1_PIN, INPUT);
    // Enable pullup resistor
    digitalWrite(PEDAL1_PIN, HIGH);

    // Set pin to input
    pinMode(PEDAL2_PIN, INPUT);
    // Enable pullup resistor
    digitalWrite(PEDAL2_PIN, HIGH);
}

void loop(void)
{
    static uint8_t pedal1StateLast = 0;
    static uint8_t pedal2StateLast = 0;
    uint8_t pedalState;

    pedalState = digitalRead(PEDAL1_PIN);
    if (pedalState != pedal1StateLast) {
        pedal1StateLast = pedalState;

        if (pedalState == 0) {
            Pedal1Down();
            delay(100);
            Keyboard.releaseAll();
        }
    }

    pedalState = digitalRead(PEDAL2_PIN);
    if (pedalState != pedal2StateLast) {
        pedal2StateLast = pedalState;

        if (pedalState == 0) {
            Pedal2Down();
            delay(100);
            Keyboard.releaseAll();
        }
    }

    delay(50);
}

Select your board (Arduino Leonardo) with corresponding Serial port and press the Upload button.

Another sketch using shift key and multiple keys:

#include <Keyboard.h>

typedef struct {
    uint8_t pin;
    bool    shift;
    uint8_t key;
    uint8_t pinStateLast;
} pinKey_t;

pinKey_t pinKey[] = {
    { 2, false, KEY_PAGE_DOWN, 0 }, // Pin 2 sends page down
    { 3, false, KEY_PAGE_UP, 0 },   // Pin 3 sends page up
    { 6, false, 'a', 0 },           // Pin 6 sends a
    { 7, true, 'a', 0 }             // Pin 6 sends SHIFT + a
}; 

void setup() 
{
    // Initialize keyboard
    Keyboard.begin();

    // Initialize pins
    for (uint8_t i = 0; i < sizeof(pinKey) / sizeof(pinKey_t); i++) {
        // Set pin to input
        pinMode(pinKey[i].pin, INPUT_PULLUP);

        // Set current pin state
        pinKey[i].pinStateLast = digitalRead(pinKey[i].pin);
    }
}

void loop() 
{
    uint8_t pinState;
    
    // Check which pins changed
    for (uint8_t i = 0; i < sizeof(pinKey) / sizeof(pinKey_t); i++) {
        // Read current pin state
        pinState = digitalRead(pinKey[i].pin);

        // Check if pin changed since last read
        if (pinKey[i].pinStateLast != pinState) {
            pinKey[i].pinStateLast = pinState;

            if (pinState == 0) {
                if (pinKey[i].shift) {
                    // Send shift
                    Keyboard.press(KEY_LEFT_SHIFT);
                }
                // Send key
                Keyboard.press(pinKey[i].key);
                delay(100);
                Keyboard.releaseAll();
            }
        }
    }

    // Wait 50ms
    delay(50);
}

Tip: Feel free to customize your key strokes!

More documentation about keyboard / mouse for Leonardo (ATMega32U4 compatible) boards can be found at the Arduino site: KeyboardModifiers, keyboardpress and KeyboardAndMouseControl.

Step 7: Test With a Windows or Linux Computer

1. Connect the pedal to your Arduino board.

2. Make sure your pedal is set in N.O. (Normally Open) mode. Some pedals have a switch at the bottom of the pedal.

3. Connect the Arduino board to your computer.

Open a PDF reader and press the pedal. It scrolls down when everything works correctly!

If you have one pedal, move digital pin 2 to digital pin 3 if you want to test page up.

Step 8: Test With an Android Tablet

Connect the Arduino USB cable via a USB OTG cable to your tablet or phone.

Open a web browser or PDF reader and press the pedal. This should scroll down when it works correctly!

Step 9: Finished!

Congratulations! Your experimental USB pedal has been finished!

Next step is to build a nice case which is beyond the scope of this Instructable.

Feel free to leave a comment with feedback or your success story. :-)
Thanks!

1 Person Made This Project!

Recommendations

  • Leather Challenge

    Leather Challenge
  • Build a Tool Contest

    Build a Tool Contest
  • Colors of the Rainbow Contest

    Colors of the Rainbow Contest

13 Comments

0
josephchrzempiec
josephchrzempiec

Question 1 year ago

Hello how do i do a CTRL and A to select things? i see you have a { 7, true, 'a', 0 } // Pin 6 sends SHIFT + a.

0
gwynethh15
gwynethh15

Question 2 years ago on Step 6

Link to other key strokes is non fuctional

0
Erriez
Erriez

Reply 1 year ago

Thanks for your feedback, @paulbonnett. I've included your suggested link in step 6.

0
Erriez
Erriez

Answer 1 year ago

Thanks for your feedback. I've updated the link again.

0
168charlie
168charlie

Question 1 year ago

Hi
How can I add more buttons for more keystrokes with the Leonardo
I have used the code from the tutorial by Erriez and the code works for pins 2 and 3 for two buttons but how can I add more as there are 13 digital pins ( 3,5,6,10,11,13 state PWM )
Just tried adding more similar code for each button but no joy
Ideally I would like 7 buttons to include SHIFT key and to be able to press two keys ie SHIFT and another
Thanks in advance

0
Erriez
Erriez

Answer 1 year ago

Hi @168charlie,

Thanks for your feedback. You have an interesting question which is probably useful for other projects as well. Can you test the second new sketch in step 6 and let me know if it works for you?

0
168charlie
168charlie

Reply 1 year ago

Hi
I have played around with step 6 using 2 pedals (or buttons in my case). As I stated it works fine - Page Up and Page Down. Then, I changed the pins from 2 and 3 to: 3 and 4, 4 and 5, 5 and 6, 6 and 7 - each successive pins change it work fine.
I could also change the keystrokes to 'a' and 'b' or whatever ....and I could type out in "Pages" aaaabbbbbbababab etc
But, when I add another button so I have pins 2, 3 and 4 set up (just cmdC then cmdV to copy and paste) and alter the numbers for button 3 (PEDAL3) pedal1 and pedal2 work fine but not pedal3
If I add another pedal (PEDAL4) again that does not work!
So it seems the code works in pairs ?

0
Erriez
Erriez

Reply 1 year ago

It looks like something wrong with the button on pin 3.

Can you run the following sketch, open a serial terminal at 115200 and press the button?

> So it seems the code works in pairs ?
Digital pins 2..13 can be used as button/pedal/inputs. Not in pairs.

#define TEST_PIN 3

void setup()
{
Serial.begin(115200);
Serial.begin(F("Pin test"));

pinMode(TEST_PIN, INPUT_PULLUP);
}

void loop()
{
Serial.println(digitalRead(TEST_PIN));

delay(250);
}

0
168charlie
168charlie

Reply 1 year ago

Hi Erriez

I tested the pins 3 to 7 and all send to serial : 1
Then I added a button and pressed and the result in serial : 0
So all pins work .... thus I looked at my circuit....
Resolved:
I have made a fundamental oversight :
The breadboard I am using has pins holes A-E and F-J and 0-60
But the rails either side break at 30 !
So I have added another GND wire and now my extension to your code works for all 4 buttons
Thank you for such a simple code to use buttons
I am going to experiment with the SHIFT key to see if I can use two buttons together for capital letters etc
Is this possible with the Leonardo ?
Is it simple to make the buttons work as a mouse ?

Thanks for your quick replies to what actually is my mistake in building the circuit
Regards
Charles

0
Erriez
Erriez

Reply 1 year ago

Hi Charles,

Good to hear that it works for you.

> I am going to experiment with the SHIFT key to see if I can use two buttons together for capital letters etc

Yes, that's possible with a modification of the code for the Leonardo board.

> Is it simple to make the buttons work as a mouse ?

The Leonardo supports keyboard functions with include file Keyboard.h and mouse movement/buttons in Mouse.h. They can be used at the same time. Documentation is located here: https://www.arduino.cc/en/Reference.MouseKeyboard

> Thanks for your quick replies to what actually is my mistake in building the circuit

You're welcome. It happens to professionals as well. :-)

Regards,
Erriez

0
168charlie
168charlie

Reply 1 year ago

Hi Erriez
Just competed your test
I had no leads attached to the Leonardo
Serial monitor scrolls: 1

Screenshot 2021-02-04 at 09.44.35.png
0
Erriez
Erriez

Reply 1 year ago

FYI: If you want to send two keys, then you can use:

Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press(key);
delay(100);
Keyboard.releaseAll();