# One Key: Single Button Bluetooth Keyboard

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/143/828/medium800/3d_printing_onekey_actionb.jpg?1776209888)

Build a wireless, single button Bluetooth keyboard that you can use as a mute button, macro launcher, presentation clicker, and more. Plus, you can easily customize it from a WebSerial web page.

This project is inspired by the&nbsp;[Monokey on Kickstarter](https://www.kickstarter.com/projects/bigbadcult/monokey-one-key-bluetooth-keyboard/rewards) (which was made in a limited run and is not currently available).

https://youtu.be/JdmXTfZ0Hh0

![](https://cdn-learn.adafruit.com/assets/assets/000/143/827/medium800thumb/3d_printing_onekeydemo.jpg?1776209644)

## Features

- BLE HID keyboard with key combos, strings, media keys
- NVS persistence for all settings
- Configurable connected/pressed colors and brightness
- Auto sleep with user selected timeout
- Serial settings interface
- WebSerial interface web page

## Parts
Featured
### Adafruit QT Py ESP32 Pico - WiFi Dev Board with STEMMA QT

[Adafruit QT Py ESP32 Pico - WiFi Dev Board with STEMMA QT](https://www.adafruit.com/product/5395)
This dev board is like when you're watching a super-hero movie and the protagonist shows up in a totally amazing costume in the third act and you're like 'OMG! That's the hero and they're here to kick some serious butt!" but in this case its a...

In Stock
[Buy Now](https://www.adafruit.com/product/5395)
[Related Guides to the Product](https://learn.adafruit.com/products/5395/guides)
![Angled shot of purple square-shaped microcontroller.](https://cdn-shop.adafruit.com/640x480/5395-00.jpg)

Featured
### Adafruit NeoKey BFF for Mechanical Key Add-On for QT Py and Xiao

[Adafruit NeoKey BFF for Mechanical Key Add-On for QT Py and Xiao](https://www.adafruit.com/product/5695)
Our QT Py boards are a great way to make very small microcontroller projects that pack a ton of power - and now we have a way for you to quickly add a nice mechanical key that also can glow any color of the rainbow.&nbsp;

We call this the **Adafruit NeoKey&nbsp;BFF** - a...

In Stock
[Buy Now](https://www.adafruit.com/product/5695)
[Related Guides to the Product](https://learn.adafruit.com/products/5695/guides)
![Video of a white finger pressing a mechanical key switch on a breakout board. The RGB LED emits rainbow colors whenever the finger presses the key switch.](https://cdn-shop.adafruit.com/product-videos/640x480/5695-00.jpg)

Featured
### Kailh Mechanical Key Switch - Clicky Blue - Single Piece

[Kailh Mechanical Key Switch - Clicky Blue - Single Piece](https://www.adafruit.com/product/5123)
For crafting your very own custom keyboard, a **&nbsp;Kailh&nbsp;Blue Linear mechanical key switches** &nbsp;is deeee-luxe! With smooth actuation and Cherry MX compatibility, they're lovely when you want a **clicky tactile** keystroke with a snappy feel and an...

In Stock
[Buy Now](https://www.adafruit.com/product/5123)
[Related Guides to the Product](https://learn.adafruit.com/products/5123/guides)
![Single shot of 12 pack Blue Kailh Mechanical Key Switches ](https://cdn-shop.adafruit.com/640x480/5123-00.jpg)

Featured
### Orange MA Keycaps for MX Compatible Switches - 5 pack

[Orange MA Keycaps for MX Compatible Switches - 5 pack](https://www.adafruit.com/product/5175)
Dress up your mechanical keys in your favorite colors&nbsp;with a wide selection of gumdrop-like, retro, curvy, and stylish MA profile keycaps. Here is a 5 pack of **Orange MA Keycaps** for your next mechanical keyboard or&nbsp;<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5175)
[Related Guides to the Product](https://learn.adafruit.com/products/5175/guides)
![Angled shot of five orange MA keycaps.](https://cdn-shop.adafruit.com/640x480/5175-00.jpg)

Featured
### Adafruit LiIon or LiPoly Charger BFF Add-On for QT Py

[Adafruit LiIon or LiPoly Charger BFF Add-On for QT Py](https://www.adafruit.com/product/5397)
[Is your QT Py all alone](https://www.adafruit.com/?q=qt+py&sort=BestMatch), lacking a friend to travel the wide world with? When you were a kid you may have learned about the "buddy" system, well this product is kinda like that! A board that will watch your QT...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5397)
[Related Guides to the Product](https://learn.adafruit.com/products/5397/guides)
![Video of a person with white painted nails unplugging a USB cable from a small, black, square-shaped lipo battery breakout board soldered to a similarly shaped microcontroller, which is also connected to a monochrome OLED display breakout. The OLED breakout displays battery and power data.](https://cdn-shop.adafruit.com/product-videos/640x480/5397-05.jpg)

Featured
### Lithium Ion Polymer Battery - 3.7v 150mAh

[Lithium Ion Polymer Battery - 3.7v 150mAh](https://www.adafruit.com/product/1317)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 150mAh for a total of about 0.6 Wh. If you need a larger battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/1317)
[Related Guides to the Product](https://learn.adafruit.com/products/1317/guides)
![Angle Shot of Lithium Ion Polymer Battery 3.7v 150mAh with JST 2-PH connector](https://cdn-shop.adafruit.com/640x480/1317-03.jpg)

Featured
### Socket Headers for Raspberry Pi Pico - 2 x 20 pin Female Headers

[Socket Headers for Raspberry Pi Pico - 2 x 20 pin Female Headers](https://www.adafruit.com/product/5583)
These&nbsp; **Socket Headers** &nbsp;alone are, well, lonely. But pair them with the&nbsp;[Raspberry Pi Pico](https://www.adafruit.com/category/875), and you're in business!

Socket headers are like the duct tape of electronics. They're great for connecting...

In Stock
[Buy Now](https://www.adafruit.com/product/5583)
[Related Guides to the Product](https://learn.adafruit.com/products/5583/guides)
![Angled shot of two 20-pin socket headers.](https://cdn-shop.adafruit.com/640x480/5583-00.jpg)

Featured
### Short Plug Headers for Raspberry Pi Pico - 2 x 20 Male Headers

[Short Plug Headers for Raspberry Pi Pico - 2 x 20 Male Headers](https://www.adafruit.com/product/5584)
These two **Short** &nbsp; **Plug / Male Headers** &nbsp;alone are, well, lonely. But pair them with the [Raspberry Pi Pico](https://www.adafruit.com/category/875), and you're in business!

These 2.54mm / 0.1" pitch headers are particularly cute...

In Stock
[Buy Now](https://www.adafruit.com/product/5584)
[Related Guides to the Product](https://learn.adafruit.com/products/5584/guides)
![Angled shot of two 20-pin short male headers.](https://cdn-shop.adafruit.com/640x480/5584-00.jpg)

## 6mm x 3mm Neodymium Disc Magnets

Four magnets, such as [these](https://www.amazon.com/rhinocats-Magnets-Printing-Miniatures-Science/dp/B0FMP58G7B/?th=1), for securing the One Key case.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/399/medium640/3d_printing_magnets.jpg?1775076123)

# One Key: Single Button Bluetooth Keyboard

## Connect the Boards

![](https://cdn-learn.adafruit.com/assets/assets/000/143/488/medium800/3d_printing_onk-1.jpg?1775665323)

## NeoKey BFF Header Pins

Cut two 7-pin sections of short male header pins.

Solder them with the legs facing the underside of the NeoKey BFF as shown here.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/513/medium640/3d_printing_onk-20.jpg?1775666442)

## Lipoly BFF Headers

First cut two 7-pin sections of short female headers.

Solder them to the LiPoly BFF as shown.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/489/medium640/3d_printing_onk-2.jpg?1775665366)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/490/medium640/3d_printing_onk-3.jpg?1775665381)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/491/medium640/3d_printing_onk-4.jpg?1775665564)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/492/medium640/3d_printing_onk-6.jpg?1775665599)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/493/medium800/3d_printing_onk-5.jpg?1775665648)

## QT Py Connection

Here's a trick for making the shortest stack possible with our boards. The QT Py and BFF form factor includes castellated pads. We can tin those and solder short male header pins to join the QT Py and the LiPoly BFF!

First, cut two 7-pin sections of short male header pins.

Then, tin the outer pads of the LiPoly BFF.

Hold the pins with pliers or tweezers to prevent cursing, then heat the pins to join them to the solder pads.

Push the plastic spacer up as far as it'll go.

Repeat for the other side of the board.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/501/medium640/3d_printing_onk-7.jpg?1775665766)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/502/medium640/3d_printing_onk-9.jpg?1775665786)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/505/medium640/3d_printing_onk-11.jpg?1775666019)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/504/medium640/3d_printing_onk-13.jpg?1775665831)

Repeat the tinning on the QT Py, then arrange the boards as shown, belly-to-belly with the LiPoly BFF battery JST connector on the same end as the QT Py's USB C connector.

Heat the pins to solder join the two boards as shown.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/506/medium640/3d_printing_onk-14.jpg?1775666091)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/507/medium640/3d_printing_onk-17.jpg?1775666109)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/508/medium640/3d_printing_onk-18.jpg?1775666140)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/509/medium640/3d_printing_onk-19.jpg?1775666152)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/514/medium800/3d_printing_onk-21.jpg?1775666504)

## Stack 'em Up

Now you can connect the NeoKey BFF to the LiPoly BFF. Heed the `^USB This side to QT Py back` silkscreen and press the header pins into the sockets as shown. (The NeoPixel is on the left side of the stack as shown in the photo above, with the LiPo power switch at the bottom.)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/520/medium640/3d_printing_onk-22.jpg?1775667887)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/527/medium800/3d_printing_onk-24.jpg?1775668695)

The next step is to code the One Key.

# One Key: Single Button Bluetooth Keyboard

## Arduino IDE Setup

You need to install the right USB-to-serial driver for your chip in addition to the Arduino IDE. If you are unsure which is the right one, install both!

### Install Arduino IDE

The first thing you will need to do is to download the latest release of the Arduino IDE. You will need to&nbsp;be using&nbsp; **version 1.8** &nbsp;or higher for this guide

[Arduino IDE Download](http://www.arduino.cc/en/Main/Software)
### Install CP2104 / CP2102N USB Driver

The USB-to-Serial converter that talks to the ESP32 chip itself will need a driver on your computer's operating system. The driver is available for Mac and Windows. It is already built into Linux.

[Click here to download the CP2104 USB Driver](http://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)
### Install CH9102 / CH34X USB Driver

Newer ESP32 boards have a different USB-to-serial converter that talks to the chip itself, and will need a driver on your computer's operating system. The driver is available for Mac and Windows. It is already built into Linux.

If you would like more detail, check out [the guide on installing these drivers](https://learn.adafruit.com/how-to-install-drivers-for-wch-usb-to-serial-chips).

[Click here to download the Windows driver](http://www.wch-ic.com/downloads/CH341SER_ZIP.html)
[Click here to download the Mac driver](http://www.wch-ic.com/downloads/CH34XSER_MAC_ZIP.html)
### Install ESP32 Board Support Package

After you have downloaded and installed **&nbsp;the latest version of Arduino IDE** , you will need to start the IDE&nbsp;and navigate to&nbsp;the&nbsp; **Preferences** &nbsp;menu. You can access it from the&nbsp; **File** &nbsp;menu in&nbsp;_Windows_&nbsp;or&nbsp;_Linux_, or the&nbsp; **Arduino** &nbsp;menu on&nbsp;_OS X_.

![](https://cdn-learn.adafruit.com/assets/assets/000/101/639/medium800/esp32_s2_arduino_ide_setup_flora_prefs.png?1618870383)

A dialog will pop up just like the one shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/101/640/medium800/esp32_s2_arduino_ide_setup_flora_Screen_Shot_2015-05-07_at_9.07.21_AM.png?1618870405)

We will be adding a URL to the new&nbsp; **Additional Boards Manager URLs** &nbsp;option. The list of URLs is comma separated, and&nbsp;_you will only have to add each&nbsp;URL once._&nbsp;New Adafruit boards and updates to existing boards&nbsp;will automatically be picked up&nbsp;by the Board Manager each time&nbsp;it is opened. The URLs point to index files that the Board Manager uses to build the list of available & installed boards.

To find the most up to date list of URLs you can&nbsp;add, you can visit the list of&nbsp;[third party board URLs on the Arduino IDE wiki](https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls#list-of-3rd-party-boards-support-urls). We will only need to add one URL to the IDE in this example, but&nbsp;_ **you can add multiple URLS by separating them with commas** _. Copy and paste the link below into the&nbsp; **Additional Boards Manager URLs** &nbsp;option in the Arduino IDE preferences.

`https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json`

![](https://cdn-learn.adafruit.com/assets/assets/000/101/641/medium800/esp32_s2_arduino_ide_setup_Screen_Shot_2021-04-19_at_3.14.19_PM.png?1618870509)

If you have multiple boards you want to support, say ESP8266 and Adafruit, have both URLs in the text box separated by a comma (,)

Once done click&nbsp; **OK** &nbsp;to save the new preference settings.

The next step is to actually install the Board Support Package (BSP). Go to the **Tools → Board → Board Manager** &nbsp;submenu. A dialog should come up with various BSPs. Search for **esp32**.

![](https://cdn-learn.adafruit.com/assets/assets/000/107/162/medium800/esp32_s2_arduino_ide_setup_Screen_Shot_2021-12-09_at_9.58.40_AM.png?1639072797)

Click the **Install** button and wait for it to finish. Once it is finished, you can close the dialog.

In the **Tools → Board** submenu you should see **ESP32 Arduino** and in that dropdown it should contain the ESP32 boards along with all the latest ESP32 boards.

Look for the board called Adafruit QT Py ESP32.

![](https://cdn-learn.adafruit.com/assets/assets/000/112/089/medium800/adafruit_products_QTP_Arduino_choose_board.png?1653596988)

The upload speed can be changed: faster speed makes uploads take less time but sometimes can cause upload issues. **921600** should work fine, but if you're having issues, you can drop down lower.

# One Key: Single Button Bluetooth Keyboard

## Code the One Key

Now that you've got the Arduino IDE set up to use the QT Py ESP32, it's time to download the code, then you'll compile and upload it.

Download the Arduino file [here](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Onekey/onekey.ino). Then open the&nbsp; **onekey.ino** &nbsp;sketch in Arduino.

## Select Board & Port

On the QT Py,&nbsp; **hold** &nbsp;the&nbsp; **BOOT button** ,&nbsp; **click-and-release** &nbsp;the&nbsp; **Reset button&nbsp;** then let go of the&nbsp; **BOOT button**. This puts the board into ROM Bootloader mode.

Then in the Arduino IDE,&nbsp;click:&nbsp; **Tools \> Board \> esp32 \> Adafruit QT Py ESP32&nbsp;**

Then, select the port by clicking:&nbsp; **Tools \> Port** &nbsp;and then choose the port your Feather is on, in this case&nbsp; **/dev/cu.wchusbserial5AC0410531.&nbsp;** In Windows it will show up as a&nbsp; **COM** &nbsp;port.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/622/medium640/3d_printing_board.jpg?1775683667)

## Libraries

In Arduino, go to&nbsp; **Tools \> Manage Libraries** , then install this library:

- Adafruit NeoPixel&nbsp;

You'll also need to install the ESP32-BLE-Keyboard library from [here](github.com/sakul-the-one/sakuls-ESP32-BLE-Keyboard). To do so:

- Go to the releases page at [`github.com/sakul-the-one/sakuls-ESP32-BLE-Keyboard/releases`](github.com/sakul-the-one/sakuls-ESP32-BLE-Keyboard/releases) and download the ZIP from the latest release
- Unzip it
- Rename the folder to `ESP32_BLE_Keyboard`
- Drop that folder directly into your Arduino Libraries folder (such as `~/Documents/Arduino/libraries/` on Mac)
- Restart Arduino

![](https://cdn-learn.adafruit.com/assets/assets/000/143/623/medium640/3d_printing_hacks_lib3.jpg?1775683810)

## Compile the Sketch

In Arduino, click&nbsp; **Sketch \> Verify/Compile&nbsp;** to make sure everything can compile with the selected board and libraries.

When finished you should see a&nbsp; **Done compiling** &nbsp;message. Success!

## Upload

You can now prep the upload settings. Click: **Tools&nbsp;\>&nbsp;** and then set the following (the rest are defaults:

- **Partition Scheme: "Large SPIFFS (1.2MB APP / 5.3MB SPIFFS)**
- **PSRAM: "Enabled"**
- **Upload Speed: "921600"**

The other settings should be the defaults, but you can double check against the screenshot here.

Then, click **Sketch \> Upload** and it'll flash the board.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/624/medium640/3d_printing_tools.jpg?1775684316)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Onekey/onekey.ino

# How the Code Works

The One Key sketch handles Bluetooth LE keyboard emulation, NeoPixel status feedback, serial configuration, and deep sleep power management. Here's a walkthrough of how all the pieces fit together.

## Libraries

The sketch uses three libraries:

- **BleKeyboard** (`sakul-the-one` fork) handles all the Bluetooth LE HID protocol work, advertising the device as a keyboard and sending key reports to the connected host.
- **Adafruit NeoPixel** drives the two LEDs: one on the NeoKey BFF (pin A3) and one built into the QT Py board (PIN\_NEOPIXEL).
- **Preferences** provides easy read/write access to the ESP32's NVS (non-volatile storage) flash partition, where all user settings are saved.

## Key Combinations

Button press config is stored in a single `KeyCombo` struct. The `mode` field determines which kind of action is configured:

- **Mode 0** is a regular keypress, with optional modifier keys (Ctrl, Shift, Alt, GUI)
- **Mode 1** is a text string, with an optional trailing keypress (such as Return after a typed command)
- **Mode 2** is a media key (volume, playback, etc.)

This struct is what gets saved to and loaded from NVS on every boot.

## NVS Settings

All user-configurable settings are stored in the ESP32's NVS flash under the namespace `"neokey"`. The `loadSettings()` function reads everything at startup: the key combo fields, sleep timeout, brightness, and the RGB values for the connected and pressed LED colors. Individual save functions handle each category of setting so only the relevant NVS keys are written when something changes.

Because NVS is retained across power cycles and deep sleep reboots, the One Key always comes back with the last configuration you've set.

## NeoPixel Status Colors

Four pixel states give feedback about what the device is up to:

- `pixelWaiting()` shows red while the device is advertising and waiting for a BLE connection
- `pixelConnected()` shows the user selected connected color (green by default) once a host connects
- `pixelPressed()` shows the user selected pressed color (pink by default) while the button is held down
- `pixelYawn()` flashes blue for one second just before the device enters deep sleep

The connected and pressed colors are loaded from NVS at boot.

## Serial Configuration

The `checkSerial()` function is called every loop iteration. It reads a line from the serial port and parses it into one of several command formats.

String mode is detected by a leading quote character. The parser finds the closing quote, extracts the text, and then checks for an optional `+key` suffix after the closing quote.

For regular key and combo input, the parser splits on `+` characters and classifies each token. It checks for media key names first, then modifier names (ctrl, shift, alt, gui), and finally looks up the key name or treats a single character as a literal keypress.

LED and sleep commands use a simple prefix format: `color:connected:`, `color:pressed:`, `bright:`, and `sleep:` are each detected by `startsWith()` and parsed accordingly.

Every successful command saves to NVS immediately and prints a confirmation to serial so you know the change took effect.

## Sending Keystrokes

The `sendCombo()` function handles all three modes. For media keys, it presses and releases a `MediaKeyReport`. For strings, it calls `bleKeyboard.print()` and optionally follows up with a key press and `releaseAll()`. For regular keys, it presses any modifiers first, then the main key, then calls `releaseAll()`.

## Button Handling

The main loop reads the button pin (A2) every 10ms. The NeoKey BFF uses a pullup resistor, so the pin reads LOW when pressed. A state comparison between the current and previous reading detects press and release transitions without a debounce timer.

On press, the activity timer resets, the pixel changes to the pressed color, and&nbsp;`sendCombo()` is called if BLE is connected. On release, the pixel returns to the appropriate status color.

## Deep Sleep

If `sleepMinutes` is non-zero and no button press or serial input has occurred within the timeout period, `goToSleep()` is called. It prints a warning to serial, flashes the blue yawn color for one second, powers down the NeoPixel rail via the `NEOPIXEL_POWER` pin, and calls `esp_deep_sleep_start()` with no wakeup source configured. The device draws only a few hundred microamps in this state. To wake it, the user flips the power switch on the LiPo Charger BFF, which triggers a full reboot and runs `setup()` again, reloading all settings from NVS.

# One Key: Single Button Bluetooth Keyboard

## 3D Print and Assemble the Case

![](https://cdn-learn.adafruit.com/assets/assets/000/143/534/medium800/3d_printing_render.jpg?1775669220)

To 3D print the case, grab the 3MF file below and load it into a compatible slicer such as Bambu Studio. Or you can grab the individual STL files.

3MF and STL files for 3D printing are oriented to print "as-is" on FDM style machines. Some of the parts are designed to 3D print with tree supports material using PLA filament.&nbsp;

If you'd like to edit the model then grab the STEP file.&nbsp;

[onekey.3mf](https://cdn-learn.adafruit.com/assets/assets/000/143/474/original/onekey.3mf?1775663859)
[onekey STL](https://cdn-learn.adafruit.com/assets/assets/000/143/476/original/oneky-stls.zip?1775663949)
[onekey STEP](https://cdn-learn.adafruit.com/assets/assets/000/143/479/original/onekey.stp.zip?1775664159)
## 3D Print Settings

Print the models in the orientation shown here. I printed at 0.16mm layer height with supports turned on for the base and lid with a threshold angle of 25º. This allows the slicer to support just the internal parts without messing with the angled lid.

You can see the supports here, set to red just for illustration purposes.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/535/medium640/3d_printing_Screenshot_2026-04-08_at_10.28.54%E2%80%AFAM.jpg?1775669364)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/536/medium640/3d_printing_Screenshot_2026-04-08_at_10.34.53%E2%80%AFAM.jpg?1775669753)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/539/medium800/3d_printing_onkcase-1.jpg?1775669789)

Remove the supports with a pair of pliers or ask your pet sloth to gnaw them off for you.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/540/medium800/3d_printing_onkcase-2.jpg?1775669801)

## Battery Fit

Temporarily lift off the NeoKey BFF, then plug in the battery as shown. You can wrap some of the excess wire around the JST connector as shown, just make sure the power switch can still be accessed and flipped between positions.

Then re-connect the NeoKey BFF as before.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/541/medium640/3d_printing_IMG_1194.jpg?1775670109)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/542/medium800/3d_printing_onkcase-3.jpg?1775670262)

## Case Fit

Press the stack into the base as shown with the USB C port aligned with the case cutout -- it should snap into place.

You can then tuck the wire and battery into their cozy little nook.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/543/medium640/3d_printing_onkcase-4.jpg?1775670287)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/544/medium640/3d_printing_onkcase-5.jpg?1775670297)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/545/medium640/3d_printing_onkcase-6.jpg?1775670306)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/546/medium640/3d_printing_onkcase-7.jpg?1775670315)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/547/medium800/3d_printing_onkcase-8.jpg?1775670386)

## Magnets!

The case was designed to use two pairs of 6mm x 3mm magnets to keep it snapped closed. The posts on the opposing corners prevent it from shearing or rotating (these magnets are strongest on one axis), and in truth have tight enough tolerances that you may be able to skip the magnets. But magnets rule, so why would you want to!

![](https://cdn-learn.adafruit.com/assets/assets/000/143/548/medium800/3d_printing_onkcase-9.jpg?1775671150)

## Press Fit

Place two magnets in the lid, either north or south up is fine for these two, they don't need to agree with each other, since we'll set the other two magnets on them to set them properly on the base. That said it's good practice to have them aligned the same so we don't accidentally put the base magnets in backwards later.

With the magnets partly seated, press them in by pushing the lid down on your work surface, with even pressure, until they are flush with the lid's flat bottom.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/549/medium640/3d_printing_onkcase-10.jpg?1775671198)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/550/medium640/3d_printing_onkcase-11.jpg?1775671368)

## Prep Base Magnets

Set the two base magnets on the lid magnets. They will align automagically.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/551/medium640/3d_printing_onkcase-12.jpg?1775671523)

## Push Into Base

Now, set the lid over the base making sure the **power switch cutout of the lid is on the opposite side of the USB cutout of the base!**

Push the lid down evenly and firmly to seat the base magnets. You can either press them down fully or use a set of parallel jaw pliers or pliers wrench as shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/552/medium640/3d_printing_onkcase-13.jpg?1775671593)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/553/medium640/3d_printing_onkcase-14.jpg?1775671606)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/554/medium640/3d_printing_onkcase-15.jpg?1775671621)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/555/medium640/3d_printing_onkcase-16.jpg?1775671632)

Optionally, squeeze the magnets in fully flush with parallel jaw pliers or a pliers wrench.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/556/medium640/3d_printing_onkcase-19.jpg?1775671890)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/557/medium640/3d_printing_onkcase-20.jpg?1775671899)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/558/medium800/3d_printing_onkcase-21.jpg?1775671938)

## Power Switch

Extend the LiPoly BFF power switch using the 3D printed slide.

Align the cutout with the switch actuator as shown.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/559/medium640/3d_printing_onkcase-22.jpg?1775671961)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/560/medium640/3d_printing_onkcase-23.jpg?1775672030)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/561/medium640/3d_printing_onkcase-25.jpg?1775672039)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/562/medium640/3d_printing_onkcase-26.jpg?1775672047)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/563/medium800/3d_printing_onkcase-27.jpg?1775672067)

## Keyswitch

With the top lid aligned with the base as shown, snap the keyswitch into the lid so the two legs will fit into the NeoKey BFF sockets.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/564/medium640/3d_printing_onkcase-28.jpg?1775672097)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/565/medium640/3d_printing_onkcase-29.jpg?1775672182)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/566/medium640/3d_printing_onkcase-30.jpg?1775672203)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/567/medium640/3d_printing_onkcase-31.jpg?1775672213)

## Close It Up

Set the lid onto the base, being sure the two keyswitch legs are aligned with the BFF. You'll also need to align the power switch actuator with the groove.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/568/medium640/3d_printing_onkcase-32.jpg?1775672229)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/569/medium640/3d_printing_onkcase-33.jpg?1775672239)

## Test Power

Check that the power switch actuator can be pressed in to turn on the One Key, and pulled out to turn it off.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/570/medium640/3d_printing_onkcase-34.jpg?1775672341)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/571/medium640/3d_printing_onkcase-35.jpg?1775672347)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/574/medium800/3d_printing_onkcase-36.jpg?1775672440)

## Keycap

Now, press your keycap into place!

![](https://cdn-learn.adafruit.com/assets/assets/000/143/572/medium640/3d_printing_onkcase-37.jpg?1775672401)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/573/medium640/3d_printing_onkcase-38.jpg?1775672425)

If you want, make a few in different colors for different functions!

![](https://cdn-learn.adafruit.com/assets/assets/000/143/606/medium800/3d_printing_onkcase-53.jpg?1775674469)

# One Key: Single Button Bluetooth Keyboard

## Use the One Key

https://youtu.be/JdmXTfZ0Hh0

## Bluetooth Pairing

You can pair your One Key with your computer or mobile device in the usual ways. Here's an example of pairing it on a Windows laptop.

Go to **Windows \> Settings** and pick **Bluetooth & Devices.**

Click **Add device.**

![](https://cdn-learn.adafruit.com/assets/assets/000/143/659/medium640/3d_printing_win2.png?1775860917)

In the&nbsp; **Add a device&nbsp;** window, click on the **Bluetooth** option.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/660/medium640/3d_printing_win3.png?1775860966)

Turn on the One Key -- it will start up and the NeoPixels will display red, indicating it is unpaired.

The **ESP32 BLE KB3** device will show up in the list of available Bluetooth devices. Click it.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/661/medium640/3d_printing_win4.png?1775861094)

The devices will begin the connection secret handshake process.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/662/medium640/3d_printing_win5.png?1775861393)

The device is ready to go!

![](https://cdn-learn.adafruit.com/assets/assets/000/143/663/medium640/3d_printing_win6.png?1775861441)

You'll see the One Key in the **Input** device list, and it'll auto-connect until you decide to remove it.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/664/medium640/3d_printing_win7.png?1775861466)

## Serial Configuration
You will probably want to change features such as which key to press, NeoPixel color, and sleep timout at some point. Instead of editing the Arduino sketch, recompiling it, and uploading it to the One Key QT Py ESP32, you can use serial commands to do these things.

Configuration settings are stored in NVS (non-volatile storage in the ESP32's built-in flash) and can be changed via serial.

For example, with the One Key plugged in to your computer, open the Arduino Serial Monitor and type in **`x`** then press enter. The One Key will now send an 'x' key when pressed. This storage survives restarts and power cycling.

The One Key keyboard listens on the USB serial port at **115200 baud**. You can send commands from Arduino IDE's Serial Monitor, or any terminal app. Make sure line ending is set to **Newline** (not "No line ending" or "Both NL & CR").

**Key commands** Just type the key or combo and press Enter:

- `q` — single printable character
- `tab`, `return`, `esc`, `backspace`, `delete`, `space` : special keys
- `up`, `down`, `left`, `right`, `home`, `end`, `pageup`, `pagedown`, `insert` : navigation
- `f1` through `f24` : function keys
- `ctrl+z`, `alt+tab`, `shift+f5`, `ctrl+shift+z` : modifier combos (up to 2 modifiers)

**String commands**

- `"hello world"` — types a string
- `"git status"+return` — types a string then presses a key

**Media key commands**

- `volumeup`, `volumedown`, `mute`, `playpause`, `nexttrack`, `prevtrack`, `stop`

**LED commands**

- `color:connected:0,255,0` : set connected color as R,G,B (0–255 each)
- `color:pressed:255,20,100` : set pressed color as R,G,B
- `bright:128` : set brightness 0–255

**Sleep command**

- `sleep:5` : sleep after 5 minutes of inactivity
- `sleep:0` : disable sleep entirely

All settings are saved to NVS flash immediately and persist across power cycles. The device echoes a confirmation message after every successful command.

Primary: Battery life should be about 5 hours of continuous use (such as using it as a slide presentation clicker) if sleep mode isn't being entered. Intermittent use a few times a day with sleep after 1 minute enabled should provide about two weeks between charges. With no use but left in sleep mode you should get a few months of charge.

## WebSerial

After adding all of these commands, I figured I'd need a cheat sheet to remember them all, and that bummed me out. What if, I thought, what if there were a GUI for configuring it? WebSerial to the rescue!

I created this WebSerial web page that you can access [here](https://adafruit.github.io/onekey-keyboard/), or run locally with the included **index.html** file that acts as a front end for all of the above serial commands.

Yellow: Be sure to run the page in a WebSerial capable browser such as Firefox (at least 151) or Chrome (at least 89).

![](https://cdn-learn.adafruit.com/assets/assets/000/143/473/medium800/3d_printing_configurator.jpg?1775662142)

[One Key Web Serial Configurator](https://adafruit.github.io/onekey-keyboard/)
## Connect

Plug in the One Key over USB, then click the **Connect** button.

In the pop-up window, select your serial port, then press the pop-up window's **Connect** button.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/813/medium640/3d_printing_webapp2.jpg?1776201987)

You'll see the " **Connected**" light turn green, and the current configuration should be filled in.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/804/medium800/3d_printing_webapp3.jpg?1776201657)

## Single Key

To change a single key, click in the "Click to capture a keypress" box and type a key. Then click the **Send** button.

You can alternatively pick special keys it from the drop-down menu.

The One Key will now type your new single key.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/814/medium640/3d_printing_webapp4.jpg?1776202046)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/815/medium640/3d_printing_webapp5.jpg?1776202064)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/816/medium640/3d_printing_webapp6.jpg?1776202160)

## Key Combo

You can pick a key combo, such as `Ctrl-z / Command-z` for undo, or `Ctrl+Alt+Delete` by clicking the Key Combo button, and then picking modifiers (`Ctrl, Shift, Alt, GUI`) and a key or special key.

Then click **Send** to save it to the One Key.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/817/medium640/3d_printing_webapp7.jpg?1776205328)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/818/medium640/3d_printing_webapp8.jpg?1776205501)

## String

Have the One Key type out an entire message by using the **String** button and typing your characters (including alphabet, numerals, punctuation, symbols, and capitalization).

Click **Send** to save to the One Key.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/819/medium640/3d_printing_webapp9.jpg?1776205558)

## String + Key

To have the One Key enter a full command, use **String + Key**. Then, type in your text and then a **Followed by key** , such as **Return / Enter**.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/820/medium640/3d_printing_webapp10.jpg?1776205673)

## Media Keys

The Media Key section allows you to pick consumer controls:

- Volume Up
- Volume Down
- Mute
- Play / Pause
- Next Track
- Previous Track
- Stop

![](https://cdn-learn.adafruit.com/assets/assets/000/143/821/medium640/3d_printing_webapp11.jpg?1776205752)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/822/medium640/3d_printing_webapp11b.jpg?1776205827)

## NeoPixel LED Settings

Adjust the **connected color** and **pressed color** as well as **brightness** for the NeoKey BFF NeoPixel and the QT PY ESP32 on-board NeoPixel in the **Led Settings** section. Press **Apply** when done.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/823/medium640/3d_printing_webapp12.jpg?1776205929)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/824/medium640/3d_printing_webapp13.jpg?1776205945)

![](https://cdn-learn.adafruit.com/assets/assets/000/143/825/medium640/3d_printing_webapp14.jpg?1776205970)

## Sleep Timeout

Change the number of minutes of inactivity before the One Key goes to sleep here. Using a setting of `0` will disable sleep entirely. Click **Set** to send to the One Key.

![](https://cdn-learn.adafruit.com/assets/assets/000/143/826/medium640/3d_printing_webapp15.jpg?1776206088)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Onekey/index.html


## Guide Products

### Adafruit QT Py ESP32 Pico - WiFi Dev Board with STEMMA QT

[Adafruit QT Py ESP32 Pico - WiFi Dev Board with STEMMA QT](https://www.adafruit.com/product/5395)
This dev board is like when you're watching a super-hero movie and the protagonist shows up in a totally amazing costume in the third act and you're like 'OMG! That's the hero and they're here to kick some serious butt!" but in this case its a...

In Stock
[Buy Now](https://www.adafruit.com/product/5395)
[Related Guides to the Product](https://learn.adafruit.com/products/5395/guides)
### Adafruit NeoKey BFF for Mechanical Key Add-On for QT Py and Xiao

[Adafruit NeoKey BFF for Mechanical Key Add-On for QT Py and Xiao](https://www.adafruit.com/product/5695)
Our QT Py boards are a great way to make very small microcontroller projects that pack a ton of power - and now we have a way for you to quickly add a nice mechanical key that also can glow any color of the rainbow.&nbsp;

We call this the **Adafruit NeoKey&nbsp;BFF** - a...

In Stock
[Buy Now](https://www.adafruit.com/product/5695)
[Related Guides to the Product](https://learn.adafruit.com/products/5695/guides)
### Kailh Mechanical Key Switch - Clicky Blue - Single Piece

[Kailh Mechanical Key Switch - Clicky Blue - Single Piece](https://www.adafruit.com/product/5123)
For crafting your very own custom keyboard, a **&nbsp;Kailh&nbsp;Blue Linear mechanical key switches** &nbsp;is deeee-luxe! With smooth actuation and Cherry MX compatibility, they're lovely when you want a **clicky tactile** keystroke with a snappy feel and an...

In Stock
[Buy Now](https://www.adafruit.com/product/5123)
[Related Guides to the Product](https://learn.adafruit.com/products/5123/guides)
### Orange MA Keycaps for MX Compatible Switches - 5 pack

[Orange MA Keycaps for MX Compatible Switches - 5 pack](https://www.adafruit.com/product/5175)
Dress up your mechanical keys in your favorite colors&nbsp;with a wide selection of gumdrop-like, retro, curvy, and stylish MA profile keycaps. Here is a 5 pack of **Orange MA Keycaps** for your next mechanical keyboard or&nbsp;<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5175)
[Related Guides to the Product](https://learn.adafruit.com/products/5175/guides)
### Adafruit LiIon or LiPoly Charger BFF Add-On for QT Py

[Adafruit LiIon or LiPoly Charger BFF Add-On for QT Py](https://www.adafruit.com/product/5397)
[Is your QT Py all alone](https://www.adafruit.com/?q=qt+py&sort=BestMatch), lacking a friend to travel the wide world with? When you were a kid you may have learned about the "buddy" system, well this product is kinda like that! A board that will watch your QT...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5397)
[Related Guides to the Product](https://learn.adafruit.com/products/5397/guides)
### Lithium Ion Polymer Battery - 3.7v 150mAh

[Lithium Ion Polymer Battery - 3.7v 150mAh](https://www.adafruit.com/product/1317)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 150mAh for a total of about 0.6 Wh. If you need a larger battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/1317)
[Related Guides to the Product](https://learn.adafruit.com/products/1317/guides)
### Socket Headers for Raspberry Pi Pico - 2 x 20 pin Female Headers

[Socket Headers for Raspberry Pi Pico - 2 x 20 pin Female Headers](https://www.adafruit.com/product/5583)
These&nbsp; **Socket Headers** &nbsp;alone are, well, lonely. But pair them with the&nbsp;[Raspberry Pi Pico](https://www.adafruit.com/category/875), and you're in business!

Socket headers are like the duct tape of electronics. They're great for connecting...

In Stock
[Buy Now](https://www.adafruit.com/product/5583)
[Related Guides to the Product](https://learn.adafruit.com/products/5583/guides)
### Short Plug Headers for Raspberry Pi Pico - 2 x 20 Male Headers

[Short Plug Headers for Raspberry Pi Pico - 2 x 20 Male Headers](https://www.adafruit.com/product/5584)
These two **Short** &nbsp; **Plug / Male Headers** &nbsp;alone are, well, lonely. But pair them with the [Raspberry Pi Pico](https://www.adafruit.com/category/875), and you're in business!

These 2.54mm / 0.1" pitch headers are particularly cute...

In Stock
[Buy Now](https://www.adafruit.com/product/5584)
[Related Guides to the Product](https://learn.adafruit.com/products/5584/guides)

## Related Guides

- [Adafruit LiIon or LiPoly Charger BFF Add-On for QT Py](https://learn.adafruit.com/adafruit-qt-py-charger-bff.md)
- [Adafruit QT Py ESP32 Pico](https://learn.adafruit.com/adafruit-qt-py-esp32-pico.md)
- [Adafruit NeoKey BFF](https://learn.adafruit.com/adafruit-neokey-bff.md)
- [Light-Up Costumes in Harsh Environments](https://learn.adafruit.com/light-up-costumes-in-harsh-environments.md)
- [Guardian Robot with LEDs](https://learn.adafruit.com/guardian-robot-with-leds.md)
- [Severance Portable Macrodata Refinement Terminal](https://learn.adafruit.com/portable-macrodata-refinement-terminal.md)
- [Icicle Crown with Pebble Pixels & WLED](https://learn.adafruit.com/icicle-crown-with-pebble-pixels-wled.md)
- [Pico Four Keypad](https://learn.adafruit.com/pico-four-key-macropad.md)
- [Wireless Control Button for WLED Projects](https://learn.adafruit.com/wireless-control-button-for-wled-projects.md)
- [Sound Reactive LED Top Hat](https://learn.adafruit.com/sound-reactive-led-top-hat.md)
- [Fog Machine with Motion Sensor and Adafruit IO](https://learn.adafruit.com/fog-machine-remote-trigger.md)
- [Paper-Craft Crystal Gem Lantern](https://learn.adafruit.com/paper-craft-crystal-gem-lantern.md)
- [Circuit Playground Express Compass](https://learn.adafruit.com/circuit-playground-express-compass.md)
- [Pico W PiCowBell Case](https://learn.adafruit.com/pico-w-picowbell-case.md)
- [Tiny LED WiFi Companion Cube](https://learn.adafruit.com/tiny-led-wifi-cube.md)
- [3D Scans for Low Poly Statues](https://learn.adafruit.com/low-poly-3d-scans-for-3d-printing.md)
- [Floor Lamp with NeoPixels and WLED Custom Animations](https://learn.adafruit.com/floor-lamp-with-wled.md)
- [EPCOT Spaceship Earth with WLED](https://learn.adafruit.com/epcot-spaceship-earth-with-wled.md)
