In this tutorial we are going to take a look at using the built-in Bluetooth of the ESP32 to emulate a Bluetooth Keyboard.
Bluetooth HID (Human Interface Device) is the protocol used by regular Bluetooth keyboard and mice and its possible to emulate this with just an ESP32, which is great!
With some ESP32 development boards starting at less than $5* delivered, this is a really inexpensive and simple way to create wireless custom keyboards such as a macro keypads. Macro keypads can be used for controlling various application like video editors or Photoshop, personally I use mine for controlling scenes in OBS when I am making videos or streaming.
We’ll first look at how to use the ESP32 HID keyboard library and then I will show you how I used this to build a battery powered Bluetooth macro keypad.
Supplies:You will also need a lipo battery, I just used a random one I had laying around so I can't link to it!
If your PC doesn't have Bluetooth you can use a dongle like this one:
Amazon.co.uk*: https://amzn.to/2uuZovu
Amazon.com*: https://amzn.to/39oGvtg
Amazon.de*: https://amzn.to/2S9DS8C
* = Affiliate
Check Out the VideoI have made a video that covers the same thing as this tutorial, so if you are interested, please check it out! I also make videos around ESP8266 and ESP32 projects regularly so maybe there are other videos on my channel you might find interesting!
[Optional] Getting Started With an ESP32ESP32s are microcontrollers that are compatible with the Arduino IDE and come with WiFi and Bluetooth included. They are also quite cheap so they are very useful chips for your projects.
You will need to add the ESP32 board definition to your Arduino IDE, to this you can follow the steps listed on the ESP32 Arduino projects GitHub Page
Installing the ESP32 Ble Keyboard LibraryIt is possible to use Bluethooth HID on the ESP32 with no external library, but GitHub user T-Vk has written a library called ESP32-BLE-Keyboard that makes it more like the standard Arduino keyboard library which makes it much easier to use.
This library is not available on the library manager so you will need to download it from GitHub.
Go the projects releases page and download the latest ESP32-BLE-Keyboard.zip
Once downloaded, you can add it to your Arduino IDE but going to Sketch -> Include Library and then Add Zip to library and select the ESP32-BLE-Keyboard.zip from the previous step.
Once that’s added we can open up the example that comes with it. It’s a pretty nice example as it demonstrates a few different things you can achieve with the library but I’ll also add in a little more detail where I think it would be useful.
You can access the example by going to File -> Examples -> ESP32 BLE Keyboard -> SendKeyStrokes
Setting up a Bluetooth connection
In the setup it begins the Bluetooth connection, at this stage it should be available to pair with on your device.
bleKeyboard.begin();
Inside the loop it also checks if it's connected to a device
bleKeyboard.isConnected()
Typing
The first thing the example shows is how you can type out text once it’s connected it will first type “Hello world” using
bleKeyboard.print("Hello world");
Single button presses
It then show how you can “write” the return key, this is basically emulating a single key press of this button.
bleKeyboard.write(KEY_RETURN);
You can open up the BleKeyboard.h file of the library to see all the keys that are defined like this. You can also send ascii characters by putting them in single commas.
bleKeyboard.write('A');
Media Keys
It also demonstrates how you can send media keys, this is similar to how you can control the volume or skip tracks with your Bluetooth headphones. The example shows the play/pause key, but again you can open BleKeyboard.h to see the other options available.
bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
Pressing and releasing keys
The final thing the example shows us is how you can press and hold keys, this is useful for creating macro keyboards. The example shown here is for Ctrl + Alt + Delete
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_DELETE);
It then calls releaseAll, which as you can probably guess by the name releases all the pressed keys.
bleKeyboard.releaseAll();
You can also release specific keys if you want either by using the release command with the key you want to release
bleKeyboard.release(KEY_DELETE);
Other Tips for the LibraryWe covered the main functionality of the library in the previous step, but here are some extra things that I think might be useful to know
Use an External Trigger
It’s always best to control a HID device like this using an external trigger such as a button press. If you use a timer and something goes wrong it might make it awkward to disconnect. Imagine having to try shut off your Bluetooth if you accidentally programmed it to press Ctrl+Alt+Del every 100mS!
Changing the device name
By default the device name will show up as “ESP32 BLE Keyboard”, this can be changed when you are creating an instance of the library. You can set the device name, manufacturer and the initial battery level.
BleKeyboard bleKeyboard("Bluetooth Device Name", "Bluetooth Device Manufacturer", 100);
Setting the battery level (not working for me at least)
The library claims you can also set the battery level but it didn’t work for me on my Windows PC (it stayed with whatever the initial value was) and my android phone didn’t show the level of it all. Here is the command for it in case it works for you
bleKeyboard.setBatteryLevel(50)
Device Compatibility
I ran successfully ran the example on my Windows 10 PC, Android phone and my Mac (although it's still running Sierra somehow!)
It also can only be connected to one device at a time.
Troubleshooting Pairing
If you are having some issues pairing, try restarting the ESP32 while your device is searching. I also once had to turn on and off my bluetooth on my PC to get it to pair.
Step 6: The Macro KeypadNow that we have the basics out of the way, let's make something practical out of it!
In a previous guide I showed how to make the simplest macro keypad out of a Arduino pro Micro and cheap keypad. For each button on the keypad it sends a different combination of button which could be used to control applications, personally I use it for OBS, the software I use for recording videos and for when I stream. This seems like a good project to port over the the ESP32 so we can make a wireless version.
For this build I’m going to use Unexpected Maker’s TinyPICO ESP32 board. The main reason for choosing it is a very power efficient board and has the circuitry for running off and charging a Lipo battery built in, so all I need to do is plug a battery in.
I’d be lying if the fact that it has the same row spacing as the Pro Micro and I could make use of the already made breakout board I made previously wasn't also appealing!
The keypad requires 8 GPIO pins to operate, and the TinyPICO has 8 GPIO pins in a row so we’ll use them. You can simple connect the keypad to the TinyPICO as shown in the below image.
The code for the macro Keypad sketch can be found on my GitHub.
As well as the BleKeyboard library that was installed in a previous step, you will also need to install the library for the keypad, you can do this by opening the library manager by going to Sketch -> Include Library -> Manage Libraries
Inside the library manager, search for "keypad" and install the one by Mark Stanley and Alexander Brevig
One configuration change you may need to make if you are using a different ESP32 than the TinyPICO is the keypad pins, they are set in the rowPins and colPins array. When looking at the front of the keypad and starting from the left, the first 4 pins are the row pins (highlighted red) and the second 4 are the col pins (highlighted green).
Once that's done, upload the code to the board and you should test at this stage it's working.
Step 8: Let's Make It Wireless!As mentioned earlier, the TinyPICO has circuitry for handling a Lipo built in so all we need to do is connect it. It comes with JST connectors that can be soldered to the bottom, or you could use the Bat and GND pins if you wanted to do it via the pins.
If you are using the JST connectors please double check the polarity of your battery matches the TinyPICO, there is no standard for how these should be wired so there is a good chance your battery might not match.
Check the voltage of your lipo battery before using it, a healthy batter should be 3V or higher, the battery I found with the correct JST connector was reading 0V!
I ended up using an 18650 cell in an holder and soldering it to the JST connector of the dead battery.
The TinyPICO reduces its power consumption when running off battery by not powering any of it’s LEDs, so even if it doesn’t look on, hopefully it is! A future improvement of the project might be to pulse the onboard dotstar LED on startup just to let you know it actually turned on and maybe again when it connects. For now you can check in your systems Bluetooth menu that it is on and connected ok.
Let’s test it out, if I open the hotkeys portion of OBS I can click on different actions to record a button combination that will control it, for this we can just click on the button on our keypad and it will update.
After you click apply, you should not be able to use your keypad to control your scene in OBS.
Thanks for Reading!Hopefully you found this tutorial useful. I'd love to hear about what you would make with this type of setup. Please let me know in the comments below, or join me and a bunch of other makers on my Discord server, where we can discuss this topic or any other maker related one you have, people are really helpful there so it’s a great place to hang out
I would also like to give a huge thanks to my Github Sponsors who help support what I do, I really do appreciate it. If you don’t know, Github are matching sponsorships for the first year, so if you make a sponsorship they will match it 100% for the next few months.
Thanks for reading!
Comments