├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── include
├── bt_keyboard.hpp
├── esp32-ps2dev.h
├── globals.hpp
├── scan_codes_set_2.h
└── serial_mouse.h
├── main
├── CMakeLists.txt
├── bt_keyboard.cpp
├── esp32-ps2dev.cpp
├── main.cpp
└── serial_mouse.cpp
├── sdkconfig
├── sdkconfig.defaults
└── sdkconfig.old
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | sdkconfig
3 | sdkconfig.old
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about build system see
2 | # https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
3 | # The following five lines of boilerplate have to be in your project's
4 | # CMakeLists in this exact order for cmake to work correctly
5 | cmake_minimum_required(VERSION 3.5)
6 |
7 | include($ENV{IDF_PATH}/tools/cmake/project.cmake)
8 | project(esp32-bt2ps2)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2008-2023 Humberto Möckel, Chris J. Kiick, Gene E. Scogin, Tomas Mudrunka
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 1/9/24: Serial Mouse support is out for v0.7! Check notes on release
2 |
3 | 24/8/24: Mouse and Multimedia Key support is out for v0.6! Check notes on release
4 |
5 | Tested Bluetooth Keyboards and Mice (Please add your own!): [Excel spreadsheet](https://1drv.ms/x/c/496a36eb8f7bab52/EVKre4_rNmoggEllRQIAAAABdvU2lrtNIQN1tRJOs5V3sw?e=jx4JUH)
6 |
7 | FreeRTOS ticking rate of 1000hz and other configs are critical. Be sure to use the default SDKconfig.defaults file included!
8 |
9 | # ESP32 Bluetooth/BLE to PS/2 keyboard/mouse adapter
10 |
11 | Project to adapt a Bluetooth or BLE keyboard and/or mouse to use on a computer with compatible PS/2 keyboard/mouse connector/s, wirelessly.
12 | Note that big DIN 5 pin connectors ("AT" keyboard) and Mini-DINs (the violet ones) are equally supported.
13 |
14 | YouTube demo: https://youtu.be/2PVjWfAAJFE
15 |
16 |
17 |
18 |
19 |
20 | # Compatibility
21 |
22 | Tested Bluetooth Keyboards and Mice (Please add your own!): https://1drv.ms/x/s!AlKre4_rNmpJiYpl1v4KcbK1Pm77zA?e=0I6QRB
23 |
24 | Working under latest ESP-IDF v5.3, compiled on Visual Studio Code. Multi-device support may not work on lower versions of the SDK.
25 |
26 | **Developed and tested on the ESP32 DevKit rev 1 board, other variants may not work!**
27 |
28 | WARNING: This project is for use in a plain ESP-32 module with BLE and BT Classic support and dual core processor. If you have another variant like C3, you'll have to adapt the code.
29 |
30 | * ESP32 S3/C3 (BLE only boards): Check https://github.com/Hamberthm/esp32-bt2ps2/issues/3
31 | * USB-HID instead of PS/2: Check https://github.com/Hamberthm/esp32-bt2ps2/issues/4
32 |
33 | # Electrical connections
34 |
35 | DIN and Mini-DIN connectors have similar pinout but in different arrangements.
36 |
37 | Please use a multimeter and online info to make your cable. Beware of voltage present on the port, you can short and fry things!
38 |
39 | Connections:
40 |
41 | | ESP32 pin | PS/2 pin | example color | Notes |
42 | | --------- | -------- | ------------- | --------------------------------- |
43 | | 23 or any | DATA | orange | Repeat on other pin for mouse bus |
44 | | 22 or any | CLK | white | Repeat on other pin for mouse bus |
45 | | GND | GND | black | Always connect! |
46 | | Vin | +5v | red | Disconnect if using USB power! |
47 |
48 | You can change the DATA and CLK pins to whatever suits your fancy using these lines in the main.cpp file:
49 |
50 | ```cpp
51 | const int KB_CLK_PIN = 22;
52 | const int KB_DATA_PIN = 23;
53 |
54 | const int MOUSE_CLK_PIN = 26;
55 | const int MOUSE_DATA_PIN = 25;
56 | ```
57 | Note: Pin 12 & 13 are ideal to solder a connector so you can use Vin, GND, 13 and 12 all in a row (ESP32 DevKit rev 1 boards). BEWARE that pin 12 is a strapping pin on the ESP32 and the module will FAIL to boot due to high signals from the PS/2 port. You can remove the strapping function of pin 12 by blowing an [eFuse](https://docs.espressif.com/projects/esptool/en/latest/esp32s2/espefuse/index.html) on your board. Use the following command:
58 |
59 | ```
60 | python espefuse.py --port COM4 set_flash_voltage 3.3V
61 | ```
62 |
63 | Also, applying voltage to pins 1 & 3 (U0 TXD and RXD) could cause the serial communication not to work, thus making serial console output impossible. Be careful on the ones you choose!
64 |
65 | There is no need to connect the 5 volts from the port if you wish to power the board over USB. For debugging I recommend you leave it disconnected, as you can end up back-feeding 5 volts back to the PS/2 port, bad things can happen. Once all is working and you don't want to debug anymore, the 5 volts from the port are enough to power the board over the Vin (regulated) pin, making this a pretty neat standalone device!
66 |
67 | NOTE: Don't leave the GND cable from the PS2 port floating, otherwise communication won't work! Always connect GND cable to the board even if you're using external power.
68 |
69 | Note: ESP32 is **unofficially** 5V tolerant, so you can directly connect PS/2 pins to the board, that's my setup on my rev v1 board and I had no problems. However, you may use a logic level converter.
70 |
71 | # Building and flashing
72 |
73 | *Note there's a binary release available!
74 |
75 | Project works as-is under Visual Studio Code (2024). You need to have the Espressif IDF extension installed and the v5.3 of the ESP-IDF SDK. Workflow is as follows:
76 |
77 | 1- Install Visual Studio Code
78 |
79 | 2- On the left, open the extensions panel
80 |
81 | 3- Search and install the Espressif IDF extension
82 |
83 | 4- Open the command prompt pressing Ctrl+Shift+P
84 |
85 | 5- Execute command "ESP-IDF: Configure ESP-IDF extension"
86 |
87 | 6- Select Express, and under "Select ESP-IDF version" choose v5.3
88 |
89 | 7- After installation, select File > Open Folder and open the ESP32-BT2PS2 project folder
90 |
91 | 8- Start building by pressing Ctrl+E and then B, or using the Build button in the bottom bar
92 |
93 | 9- If succesfully built, connect and flash your ESP32 board (Ctrl+E then F, or the flash button)
94 |
95 | Refer to the following link for more instructions:
96 |
97 | * https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/tutorial/install.md
98 |
99 | Once succesfully built and flashed, you're ready to rock! (your BLE keyboard on an ancient computer, that is).
100 |
101 |
102 | # Usage and debugging
103 |
104 | Once powered up and first of all, the code will create and init an `esp32_ps2dev::PS2Keyboard` object, so it can start to talk to the computer as soon as possible. This is critical because during boot the BIOS can send different commands to the module to test the presence of the keyboard.
105 |
106 | After PS/2 init, the module scans for nearby Bluetooth and BLE devices. If the last bonded keyboard is in range, it will try to connect to it using the keys stored on the NVS flash, so no pairing is needed for every connection. If it doesn't detect a previously bonded device, it will try to connect to the nearest keyboard in pairing mode. If both processes fail, it will wait one second and scan again until it finds anything.
107 |
108 | IMPORTANT: Is recommended to do the pairing to the keyboard BEFORE connecing the board to a PS/2 port. For this, connect a charger or power bank to the ESP's USB port and pair your device more comfortably.
109 |
110 | For v0.6, you can invoke pairing during execution (blue LED on) at any time. Press the "BOOT" button on the rev v1 board, essentially shorting GPIO_0 to ground. LED will go off and enter pairing mode. To cancel pairing, press and hold for 3 seconds (pairing aborting does not work on startup pairing).
111 |
112 | **LED off: Pairing mode activated. LED on: normal execution, only previously paired devices can connect at any time.**
113 |
114 | ### >> BLE KEYBOARD OR MOUSE PAIRING:
115 | Set keyboard or mouse in pairing mode and power on the board. No code entry required.
116 |
117 | ### >> BLUETOOTH CLASSIC KEYBOARD PAIRING (code pairing):
118 |
119 | 1- Set keyboard in pairing mode and power on the board.
120 |
121 | 2- Wait until you see a short blast of quick flashes, then pay attention:
122 |
123 | 3- For each code digit, the board will flash the LED the number of times equal to the digit.
124 |
125 | 4- Press each digit on the keyboard as you read them (do not wait until it finishes! Some keyboards have a timeout).
126 |
127 | 5- If the digit is 0, a steady light will show for 1.5 seconds instead of the digit.
128 |
129 | 6- When you see the blast of quick flashes again, press ENTER.
130 |
131 | OR you can always look at the code using the Serial monitor console, whatever you find easier, you fancy boy.
132 |
133 | ### >> BLUETOOTH CLASSIC KEYBOARD PAIRING, LEGACY PROCEDURE (legacy code pairing):
134 |
135 | In older keyboards, the user must enter a custom code on the host device and then on the keyboard. Since we can't input it easily on the ESP32, the code is fixed to 1234.
136 |
137 | 1- Set keyboard in pairing mode and power on the board
138 |
139 | 2- Watch the Serial Ouput Console. Wait for the board finishing the scan and for the message "Waiting pairing code entry..."
140 |
141 | 3- Type 1234 on the keyboard then press ENTER.
142 |
143 | Note: For Legacy Mode, no LED output is possible at the moment, so we need to check the serial console for the right time to enter the code.
144 |
145 | ---
146 |
147 | - If paired and working correctly, the board should blink the LED with each key press on the keyboard, or with each click on the mouse
148 |
149 | Once connected you can start using your keyboard and mouse, blue LED should be on. Remove any USB power source and connect the board to the PS/2 compatible system and enjoy. Remember PS/2 is NOT a HOT-SWAP protocol, please only connect the board with the system totally OFF.
150 |
151 | You can hot-disconnect the keyboard and mouse for models that support multiple devices hopping. The module will detect the disconnection and repeatedly try to reconnect while you're using other systems, so it will be back online as soon as the keyboard gets up to the ESP32 again. This is critical for keyboards/mouses that go to sleep and disconnect, or if you swap between computers using a multi-connection keyboard.
152 |
153 | Please note that pairing is only done after power up. If you wish to pair a new device, please reset the module with the reset button or power off and on the computer (not just reset it, because we need a power cycle). Note that if a previously paired device is on and in range, it will always connect to it first. Also invoke pairing after power on (LED on) by using the BOOT button or shorting GPIO_0 to ground.
154 |
155 | In case something doesn't work, you'll need to debug.
156 |
157 | If the blue light on the module lights up and your keyboard connects, but it doesn't work, first of all reset your system. If it still doesn't work, then you'll need to enable debugging in the `esp32-ps2dev.cpp` file using `#DEFINE _ESP32_PS2DEV_DEBUG_`. Check for "PS/2 command received" messages and see where it hangs, or what the BIOS doesn't like. This is advanced so if you need help, make a new issue.
158 |
159 | # TODO
160 | * Test on many keyboards and mouses.
161 | * Improve stability.
162 | * Clean up the code.
163 | * Test against various hosts.
164 |
165 | # Reference
166 | - http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Protocol.htm
167 | - http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Mouse%20Protocol.htm
168 | - http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm
169 |
170 | # History
171 | Using code and hard work from these folks:
172 |
173 | * https://playground.arduino.cc/ComponentLib/Ps2mouse/
174 | * https://github.com/grappendorf/arduino-framework/tree/master/ps2dev
175 | * https://github.com/dpavlin/Arduino-projects/tree/master/libraries/ps2dev
176 | * ps2 library Written by Chris J. Kiick, January 2008. https://github.com/ckiick
177 | * modified by Gene E. Scogin, August 2008.
178 | * modified by Tomas 'Harvie' Mudrunka 2019. https://github.com/harvie/ps2dev
179 | * modified for ESP32 by hrko 2022. https://github.com/hrko/esp32-ps2dev
180 | * fixed for PC compatibility and stability by Hambert, 2023. https://github.com/Hamberthm/esp32-ps2dev
181 | * bt-keyboard library by Guy Turcotte, 2022. https://github.com/turgu1/bt-keyboard
182 | * adapted to Arduino IDE and added improvements by Hambert, 2023. https://github.com/Hamberthm/bt-keyboard
183 |
--------------------------------------------------------------------------------
/include/bt_keyboard.hpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2020 Guy Turcotte
2 | //
3 | // MIT License. Look at file licenses.txt for details.
4 | //
5 | // -----
6 | //
7 | // Original code from the bluetooth/esp_hid_host example of ESP-IDF license:
8 | //
9 | // Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
10 | //
11 | // Licensed under the Apache License, Version 2.0 (the "License");
12 | // you may not use this file except in compliance with the License.
13 | // You may obtain a copy of the License at
14 |
15 | // http://www.apache.org/licenses/LICENSE-2.0
16 | //
17 | // Unless required by applicable law or agreed to in writing, software
18 | // distributed under the License is distributed on an "AS IS" BASIS,
19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | // See the License for the specific language governing permissions and
21 | // limitations under the License.
22 |
23 | #pragma once
24 |
25 | #include "freertos/FreeRTOS.h"
26 | #include "freertos/task.h"
27 | #include "freertos/semphr.h"
28 | #include "freertos/event_groups.h"
29 | #include "esp_err.h"
30 | #include "esp_log.h"
31 | #include "esp_system.h"
32 | #include "esp_event.h"
33 | #include "esp_bt.h"
34 | #include "esp_bt_defs.h"
35 | #include "esp_bt_device.h"
36 | #include "esp_bt_main.h"
37 | #include "esp_hidh.h"
38 | #include "esp_hid_common.h"
39 | #include "esp_gap_bt_api.h"
40 | #include "esp_gap_ble_api.h"
41 | #include "esp_gatts_api.h"
42 | #include "esp_gatt_defs.h"
43 | #include "esp_wifi.h"
44 |
45 | #include
46 | #include