├── README.md └── ble_keyboard.ino /README.md: -------------------------------------------------------------------------------- 1 | # ESP32_USB_to_BLE_HID 2 | USB Keyboard to bluetooth(wireless) keyboard using ESP32 dev board. 3 | 4 | 5 | ### required 6 | 1. ESP32 dev board 7 | 2. USB Host shield 8 | 9 | ### libraries 10 | - [T-vK/ESP32-BLE-Keyboard](https://github.com/T-vK/ESP32-BLE-Keyboard) 11 | - [felis/USB_Host_Shield_2.0](https://github.com/felis/USB_Host_Shield_2.0) 12 | -------------------------------------------------------------------------------- /ble_keyboard.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 키보드 USB 연결 3 | -> ESP32에서 전력 공급 4 | -> 데이터 수신(USB Host Shield 2.0 라이브러리) 5 | -> 수신한 데이터 블루투스 HID로 전송 (BleKeyboard 라이브러리) 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | BleKeyboard bleKeyboard; 13 | 14 | class KbdRptParser : public KeyboardReportParser 15 | { 16 | void PrintKey(uint8_t mod, uint8_t key); 17 | 18 | protected: 19 | void OnControlKeysChanged(uint8_t before, uint8_t after); 20 | 21 | void OnKeyDown(uint8_t mod, uint8_t key); 22 | void OnKeyUp(uint8_t mod, uint8_t key); 23 | void OnKeyPressed(uint8_t key); 24 | }; 25 | 26 | void KbdRptParser::PrintKey(uint8_t m, uint8_t key) 27 | { 28 | MODIFIERKEYS mod; 29 | *((uint8_t *)&mod) = m; 30 | Serial.print((mod.bmLeftCtrl == 1) ? "C" : " "); 31 | Serial.print((mod.bmLeftShift == 1) ? "S" : " "); 32 | Serial.print((mod.bmLeftAlt == 1) ? "A" : " "); 33 | Serial.print((mod.bmLeftGUI == 1) ? "G" : " "); 34 | 35 | Serial.print(" >"); 36 | PrintHex(key, 0x80); 37 | Serial.print("< "); 38 | 39 | Serial.print((mod.bmRightCtrl == 1) ? "C" : " "); 40 | Serial.print((mod.bmRightShift == 1) ? "S" : " "); 41 | Serial.print((mod.bmRightAlt == 1) ? "A" : " "); 42 | Serial.println((mod.bmRightGUI == 1) ? "G" : " "); 43 | }; 44 | 45 | void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) 46 | { 47 | Serial.print("DN "); 48 | PrintKey(mod, key); 49 | uint8_t c = OemToAscii(mod, key); 50 | Serial.print("\n=============="); 51 | Serial.println((int)key); 52 | 53 | if (key == 42) //backspace 54 | bleKeyboard.press(KEY_BACKSPACE); 55 | else if (key == 43) // TAB 56 | bleKeyboard.press(KEY_TAB); 57 | else if (key == 41) // ESC 58 | bleKeyboard.write(KEY_ESC); 59 | else if (key == 40) // Enter 60 | bleKeyboard.press(KEY_RETURN); 61 | 62 | else if (key == 76) // Delete 63 | bleKeyboard.write(KEY_DELETE); 64 | else if (key == 73) // Insert 65 | bleKeyboard.write(KEY_INSERT); 66 | else if (key == 74) // Home 67 | bleKeyboard.write(KEY_HOME); 68 | else if (key == 77) // End 69 | bleKeyboard.write(KEY_END); 70 | else if (key == 75) // Page Up 71 | bleKeyboard.write(KEY_PAGE_UP); 72 | else if (key == 78) // Page Down 73 | bleKeyboard.write(KEY_PAGE_DOWN); 74 | 75 | /* 방향키(Arrow Key) */ 76 | else if (key == 82) // Arrow up 77 | bleKeyboard.press(KEY_UP_ARROW); 78 | else if (key == 81) // Arrow down 79 | bleKeyboard.press(KEY_DOWN_ARROW); 80 | else if (key == 80) // Arrow left 81 | bleKeyboard.press(KEY_LEFT_ARROW); 82 | else if (key == 79) // Arrow right 83 | bleKeyboard.press(KEY_RIGHT_ARROW); 84 | 85 | /* 기능키(Function Key) */ 86 | else if (key == 58) // F1 87 | bleKeyboard.write(KEY_F1); 88 | else if (key == 59) // F2 89 | bleKeyboard.write(KEY_F2); 90 | else if (key == 60) // F3 91 | bleKeyboard.write(KEY_F3); 92 | else if (key == 61) // F4 93 | bleKeyboard.write(KEY_F4); 94 | else if (key == 62) // F5 95 | bleKeyboard.write(KEY_F5); 96 | else if (key == 63) // F6 97 | bleKeyboard.write(KEY_F6); 98 | else if (key == 64) // F7 99 | bleKeyboard.write(KEY_F7); 100 | else if (key == 65) // F8 101 | bleKeyboard.write(KEY_F8); 102 | else if (key == 66) // F9 103 | bleKeyboard.write(KEY_F9); 104 | else if (key == 67) // F10 105 | bleKeyboard.write(KEY_F10); 106 | else if (key == 68) // F11 107 | bleKeyboard.write(KEY_F11); 108 | else if (key == 69) // F12 109 | bleKeyboard.write(KEY_F12); 110 | 111 | bleKeyboard.releaseAll(); 112 | if (c) 113 | OnKeyPressed(c); 114 | } 115 | 116 | boolean controlKeyPressed = false; 117 | void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) 118 | { 119 | MODIFIERKEYS beforeMod; 120 | *((uint8_t *)&beforeMod) = before; 121 | 122 | MODIFIERKEYS afterMod; 123 | *((uint8_t *)&afterMod) = after; 124 | if (!controlKeyPressed) 125 | { 126 | controlKeyPressed = true; 127 | if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) 128 | { 129 | bleKeyboard.press(KEY_LEFT_CTRL); 130 | Serial.println("LeftCtrl changed"); 131 | } 132 | if (beforeMod.bmLeftShift != afterMod.bmLeftShift) 133 | { 134 | bleKeyboard.press(KEY_LEFT_SHIFT); 135 | Serial.println("LeftShift changed"); 136 | } 137 | if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) 138 | { 139 | bleKeyboard.release(KEY_LEFT_ALT); 140 | Serial.println("LeftAlt changed"); 141 | } 142 | if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) 143 | { 144 | bleKeyboard.press(KEY_LEFT_GUI); 145 | Serial.println("release changed"); 146 | } 147 | 148 | if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) 149 | { 150 | bleKeyboard.release(KEY_RIGHT_CTRL); 151 | Serial.println("RightCtrl changed"); 152 | } 153 | if (beforeMod.bmRightShift != afterMod.bmRightShift) 154 | { 155 | bleKeyboard.release(KEY_RIGHT_SHIFT); 156 | Serial.println("RightShift changed"); 157 | } 158 | if (beforeMod.bmRightAlt != afterMod.bmRightAlt) 159 | { 160 | bleKeyboard.press(KEY_RIGHT_ALT); 161 | Serial.println("RightAlt changed"); 162 | } 163 | if (beforeMod.bmRightGUI != afterMod.bmRightGUI) 164 | { 165 | bleKeyboard.release(KEY_RIGHT_GUI); 166 | Serial.println("RightGUI changed"); 167 | } 168 | } 169 | else 170 | { 171 | controlKeyPressed = false; 172 | bleKeyboard.releaseAll(); 173 | } 174 | } 175 | 176 | void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) 177 | { 178 | Serial.print("UP "); 179 | PrintKey(mod, key); 180 | } 181 | 182 | void KbdRptParser::OnKeyPressed(uint8_t key) 183 | { 184 | Serial.print("ASCII: "); 185 | Serial.println((char)key); 186 | bleKeyboard.write((char)key); 187 | }; 188 | 189 | USB Usb; 190 | //USBHub Hub(&Usb); 191 | HIDBoot HidKeyboard(&Usb); 192 | 193 | KbdRptParser Prs; 194 | 195 | void setup() 196 | { 197 | /* begin USB Host Shield */ 198 | Serial.begin(115200); 199 | #if !defined(__MIPSEL__) 200 | while (!Serial) 201 | ; // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection 202 | #endif 203 | Serial.println("Starting USB Host Shield work"); 204 | if (Usb.Init() == -1) 205 | Serial.println("OSC did not start."); 206 | delay(200); 207 | HidKeyboard.SetReportParser(0, &Prs); 208 | 209 | /* begin BLE Keyboard */ 210 | bleKeyboard.begin(); 211 | Serial.println("Starting BLE Keyboard work"); 212 | } 213 | 214 | void loop() 215 | { 216 | if (bleKeyboard.isConnected()) 217 | { 218 | Usb.Task(); 219 | } 220 | } 221 | --------------------------------------------------------------------------------