Introduction: How to Make a Arduino HID Keyboard
Controller by picklesandicecream
In this tutorial I shall explain how you can turn your Arduino chip into a HID keyboard device.
This is done by updating the Firmware on your chip with FLIP.
The cool thing about this trick is that you can make your own game controller or macro keyboard with the power of the Arduino coding method, so possibility are endless for great prototypes.
I have put all files into a Google Drive map for you to download.
link: https://drive.google.com/open?id=1jfOJmFf9C6QCb8I_...
I also have made a youtube Video for the coding part.
Supplies
Arduino UNO or Mega
4 push buttons
4 resitors 1k ohm
Jumper cables
Step 1: Setup of the Arduino
The basic setup of the Arduino for this example. (This can also be done with the Arduino Mega if more pin inputs are required) Note that we use the 3.3v of the Arduino as the input current of the push buttons onto the Digital-pins. The resistors used for this example are 1k ohm resistors.
Step 2: CODE - How to Code a Key Press Onto the Arduino
Video link: https://www.youtube.com/watch?v=j05vj8zRP1o
Step 3: CODE - Write a Keyboard Buffer
First we initialize a keyboard buffer, this is required for the Arduino to send a bit register as a HID Keyboard.
Step 4: CODE - Define the Pins for Input Into the Arduino
Define the pins of the Arduino, you can also use (const int PIN_W = 4;) but I prefer the #define method.
Step 5: CODE - Write the Setup Function
Write the setup function, as with every Arduino code project the setup is pretty much the same except that setting the Baud rate and serial communication with the (Serial.begin(9600)) function is required for the Arduino to communicate with your computer.
Step 6: CODE - Write a Button Release
Write an end buffer method to send a bit when button is released, this step is required to end the data stream of the HID keyboard. For this example we send the key code through buf[2] so we need to reset them to 0 when the button on the Arduino is released. Note: Without this step you’re HID keyboard can start sending button inputs but it will never stop sending bits until the HID keyboard (Arduino) USB is unplugged.
Step 7: CODE - Write a Keypress
This step is done in the Loop() function to be updated every cycle the Arduino get through checking if a button is pressed.
Step 8: Complete Code for Reference
uint8_t buf[8] = { 0 }; //Keyboard report buffer
#define PIN_W 4 // Pin for w
#define PIN_A 5 // Pin for a
#define PIN_S 6 // Pin for s
#define PIN_D 7 // Pin for d
void setup() {
Serial.begin(9600); // Setup Serial communication
//Set pinmode of Input pins
pinMode(PIN_W, INPUT);
pinMode(PIN_A, INPUT);
pinMode(PIN_S, INPUT);
pinMode(PIN_D, INPUT);
}
void loop() {
//When button representing W is pressed
if (digitalRead(PIN_W) == HIGH) {
buf[2] = 26; // W keycode
Serial.write(buf, 8); // Send keypress
releaseKey();
}
//When button representing A is pressed
if (digitalRead(PIN_A) == HIGH) { buf[2] = 4; // A keycode
Serial.write(buf, 8); // Send keypress
releaseKey();
}
//When button representing S is pressed
if (digitalRead(PIN_S) == HIGH) { buf[2] = 22; // S keycode
Serial.write(buf, 8); // Send keypress
releaseKey();
}
//When button representing D is pressed
if (digitalRead(PIN_D) == HIGH) { buf[2] = 7; // D keycode
Serial.write(buf, 8); // Send keypress
releaseKey();
}
}
// Function for Key Release
void releaseKey() {
buf[0] = 0;
buf[2] = 0;
Serial.write(buf, 8); // Send Release key
}
Step 9: Install Flip
To install FLIP please install JRE - Flip Installer - 3.4.7.112.exe provided in the Google Drive link
Note: When starting up you get the error "AtLibUsbDfu.dll not found" you have to install a driver.
Here is a solution made by MDGrein link: https://www.youtube.com/watch?v=KQ9BjKjGnIc
Step 10: FLIP - Device Selection
Press the Highlighted chip button, then Select ATmega16u2 and then the button OK. As this is the chipset for the Arduino Uno R3 and the Arduino Mega R3.
And now you are done with setting up flip and we can go to the Next step of Flashing the Arduino.
Step 11: Upload Your Arduino Code
You will get a message at the bottom from the Arduino IDE saying done Uploading
Note: if uploading fails
Check 1 COM port under Tools>port if none is available unplug and replug USB or check device manager. Check 2 if you have the correct board selected in Tools>board.
Step 12: Arduino Into DFU Mode
short the 2 ICSP2 pins as shown in the image
To put the Arduino in the DFU (Device Firmware Update) mode, so that FLIP can access the Firmware
on the Arduino Chip. More info on this reference link: https://www.arduino.cc/en/Hacking/DFUProgramming8...
Step 13: FLIP - Press the USB Icon in FLIP and Then Open
Step 14: FLIP - Parse the Firmware HEX
Load the arduino-keyboard.hex into FLIP
You will see at the bottom USB ON, this is that the Arduino is connected through DFU Mode.
Step 15: FLIP - Press RUN Not Start Application
Step 16: FLIP - Unplug and Replug USB
You will see this all in green if not close FLIP and return to step 12 Arduino into DFU mode.
Step 17: How to Check If the Flash Worked.
From now on the Arduino is a HID Keyboard Congratulations!
The only thing now is that the Arduino IDE does not support your Arduino anymore. So to check if your HID keyboard works we open Notepad, or any other text editor.
Step 18: Want Your Arduino Back :(
You can do that by repeating the steps after Step 12 Arduino into DFU mode,
only then chose Arduino-usbserial-uno.hex instead of arduino-keyboard.hex
29 Comments
11 months ago
Mr. Eward Hage, i would like to know about more key codes like volume +, Volume - , Mute, etc. because i want to use those keys. please provide a list of them because some keys are not inn your image of keycodes.Thankyou!
Question 2 years ago
In this example you are using the W,A,S,D keys and using certain keycodes for each. Sorry to comment on an old post but i couldnt figure out a pattern for the keycodes, how can I find out what keycode each key has? I want to make some modifications for it to suit my needs but i need other/more keys.
Answer 2 years ago
No problem, happy to help.
https://drive.google.com/open?id=1jfOJmFf9C6QCb8I_...
Link was also in the description, there is an image with HID keycode. Good luck!
Reply 2 years ago
I get a 404 page not found error, also i made a prototype using only one button and it didnt work, it would write the letter like the button was pressed down when i wasnt even near the circuit, i made sure everything was wired correctly and still had the same problem, also it stopped and started writing again without me interacting with it.
Reply 11 months ago
this image might help you. It is made by Eward Hage
1 year ago
What is the code for the left windows key?
Reply 11 months ago
this image might help you. It is made by Eward Hage by the way, windows key code is 227
Question 2 years ago
Is there any way to code it so it only sends one input when held instead of it repeatedly when held?
Answer 1 year ago
Hey. Did you manage to find a solution? I have the same problem...
Reply 1 year ago
To do that, you're going to have to keep track of the last state of the pressed key and not let it do the send again until it was released and pressed again. If you only need to support one key down at a time, you might be able to get away with just adding code after each of the calls to "release key" like this: "while (digitalRead(PIN_D) == HIGH) { };" (replace the "PIN_D" with each pin as appropriate for each section. This line will sit and do nothing "while" the key is still held, so it can't go around the loop again and press the key again. There are way more efficient ways to do it, but it would take more than a response to a comment to show the whole code.. You'd have to keep track of which keys were pressed last time through the loop and detect only if it changed, vs. just seeing if it was pressed. In this way, you could even implement key repeat if you held down the key, just like a real keyboard would do..
1 year ago
This looks like exactly what I've been looking for.. BUT I have a couple questions. First.. You compiled your arduino code and loaded it up and then flashed the arduino with the keyboard hex.. I assume this is not overwriting your arduino code? If you wanted to change your arduino code, for example to change the keys you are sending, would you have to flash the arduino back to arduino mode, then save the new program, and then re-flash the keyboard hex onto it again? Second, you mention shorting 2 ISCP pins on the header, but you have the TX/RX lights circled on your pictures with a note about shorting too.. So I have to do anything with those Tx/Rx lights/pads? And third - For my application, I want to simulate pressing and releasing CTRL. I dont need to press a key while it's pressed, so I'm not using it as a modifier - I just want to press and release ctrl. This is a hotkey for my KVM, although another use for this would be to use the fire button on MAME. To do the press/release of the CTRL without it being a modifier, I assume I use "KEY_LEFTCTRL 0xe0" in buf[2] vs. using the modifer code in buf[0]? Thank you so much for an awesome project. I am hoping to integrate this with a PiKVM to allow me to switch an otherwise unsupported KVM for multiaccess..
1 year ago
Thanks for the very useful tutorial, it will help me, an absolute beginner, a lot!
Is there an easier way to change the keys than to update the firmware again and again whenever I want to change them?
Is this tutorial also works with mechanical switches attached via 3.5 jack, instead of the push buttons?
Question 2 years ago
Is this possible to do the same steps with Leonardo?
Answer 2 years ago
It's much easier with the leonardo - it has built in support for being used as a keyboard device. You can use the Keyboard API too .(https://www.arduino.cc/reference/en/language/funct...) You can plug it into any computer and it just works.
I'm not sure if it would support the above code, however.
Question 2 years ago
I am having an issue opening the HEX file(s). Getting Cannot open file error (see the screenshot).
Running Win10, FLIP from the archive and the HEX as well.
Tried different boards but it looks like the issue is somewhere else. :/
Any idea? Thanks in advance!
3 years ago on Step 7
Why is buf[2] used? Why not buf[3] or other indices?
Reply 3 years ago
So you can use shift+f for example to get F.
Note the shift needs to be in buf[2] and f in buf[3]
So shift before the letter key
Reply 3 years ago
Thanks. Must buf[2] be involved in sending the characters?
Reply 3 years ago
Thanks once again. If one number can send the characters, then what's the purpose of the other numbers in the array
Reply 3 years ago
Alright :)