I am trying to get wio terminal working as a hid bluetooth device.
I tried to use ESP32-BLE-Keyboard, but failed.
And I have just found the code about Bluetooth HID devices in the wio terminal official Bluetooth library. But I didn’t see any documents about them. How do I use official libraries to create HID devices?
I’m also trying to use the Wio Terminal as a hid bluetooth device with no success.
Like @Zhou mentioned, is it possible to provide an example on how to use the Seeed_Arduino_rpcBLE
and the Seeed_Arduino_rpcUnified
libraries in order to do that?
My understanding was that the two libraries mentioned above were supposed to “implement BLE function compatibility with Arduino-ESP32” in order to enable code written for the ESP32’s bluetooth feature to run in the Wio Terminal. However, it does not seem to be that simple and details are not provided on how to make it work. @edw brought up the same issue on another post. Are there any guides on how to use ESP32 HID bluetooth code with the Wio Terminal?
Just like Zhou, I tried to use ESP32-BLE-Keyboard but had many compilation errors. For example, the library BLEUtils.h
and driver/adc.h
are missing from rpcBLE
and rpcUnified
. I found a version of BLEUtils.h
in the dev-server
branch of rpcBLE
but when I imported it to my project I got a few errors such as BLEUtils.h:21:28: error: expected ';' at end of member declaration static const char* addressTypeToString(esp_ble_addr_type_t type);
. The syntax looks ok to me so I don’t know how to move forward.
Any help is greatly appreciated. Thanks.
Just to follow up, I found code from Github user manuelbl for the ESP32 that seems to almost work. However, I cannot pair the Wio Terminal and it keeps disconnecting. I’m suspecting it’s a security or bonding issue. I had to comment out the lines with:
BLESecurity *security = new BLESecurity(); security->setAuthenticationMode(ESP_LE_AUTH_BOND);
because the library BLESecurity is not implemented for Seeed’s rpcUnified or rpcBLE. I’ll post my code below, if anyone had an idea that would be greatly appreciated.
/*
Based on Github user manuelbl: https://gist.github.com/manuelbl/66f059effc8a7be148adb1f104666467
*/
#include <HIDTypes.h>
#include <rpcBLEDevice.h>
#include <BLEServer.h>
#include <BLEHIDDevice.h>
#include <HIDKeyboardTypes.h>
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define US_KEYBOARD 1
#define MESSAGE "Hello from Wio Terminal\n"
#define DEVICE_NAME "Wio Terminal"
bool isBleConnected = false;
BLEHIDDevice *hid;
BLECharacteristic *input;
BLECharacteristic *output;
struct InputReport
{
uint8_t modifiers; // bitmask: CTRL = 1, SHIFT = 2, ALT = 4
uint8_t reserved; // must be 0
uint8_t pressedKeys[6]; // up to six concurrenlty pressed keys
};
// Message (report) received when an LED's state changed
struct OutputReport
{
uint8_t leds; // bitmask: num lock = 1, caps lock = 2, scroll lock = 4, compose = 8, kana = 16
};
const InputReport NO_KEY_PRESSED = {};
/*
* Callbacks related to BLE connection
*/
class BleKeyboardCallbacks : public BLEServerCallbacks
{
void onConnect(BLEServer *server)
{
isBleConnected = true;
// Allow notifications for characteristics
BLE2902 *cccDesc = (BLE2902 *)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
cccDesc->setNotifications(true);
Serial.println("Client has connected");
}
void onDisconnect(BLEServer *server)
{
isBleConnected = false;
// Disallow notifications for characteristics
BLE2902 *cccDesc = (BLE2902 *)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
cccDesc->setNotifications(false);
Serial.println("Client has disconnected");
}
};
/*
* Called when the client (computer, smart phone) wants to turn on or off
* the LEDs in the keyboard.
*
* bit 0 - NUM LOCK
* bit 1 - CAPS LOCK
* bit 2 - SCROLL LOCK
*/
class OutputCallbacks : public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *characteristic)
{
OutputReport *report = (OutputReport *)characteristic->getData();
Serial.println("Value received from Host");
Serial.print("LED state: ");
Serial.print((int)report->leds);
Serial.println();
}
};
// The report map describes the HID device (a keyboard in this case) and
// the messages (reports in HID terms) sent and received.
static const uint8_t REPORT_MAP[] = {
USAGE_PAGE(1), 0x01, // Generic Desktop Controls
USAGE(1), 0x06, // Keyboard
COLLECTION(1), 0x01, // Application
REPORT_ID(1), 0x01, // Report ID (1)
USAGE_PAGE(1), 0x07, // Keyboard/Keypad
USAGE_MINIMUM(1), 0xE0, // Keyboard Left Control
USAGE_MAXIMUM(1), 0xE7, // Keyboard Right Control
LOGICAL_MINIMUM(1), 0x00, // Each bit is either 0 or 1
LOGICAL_MAXIMUM(1), 0x01,
REPORT_COUNT(1), 0x08, // 8 bits for the modifier keys
REPORT_SIZE(1), 0x01,
HIDINPUT(1), 0x02, // Data, Var, Abs
REPORT_COUNT(1), 0x01, // 1 byte (unused)
REPORT_SIZE(1), 0x08,
HIDINPUT(1), 0x01, // Const, Array, Abs
REPORT_COUNT(1), 0x06, // 6 bytes (for up to 6 concurrently pressed keys)
REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x65, // 101 keys
USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(1), 0x65,
HIDINPUT(1), 0x00, // Data, Array, Abs
REPORT_COUNT(1), 0x05, // 5 bits (Num lock, Caps lock, Scroll lock, Compose, Kana)
REPORT_SIZE(1), 0x01,
USAGE_PAGE(1), 0x08, // LEDs
USAGE_MINIMUM(1), 0x01, // Num Lock
USAGE_MAXIMUM(1), 0x05, // Kana
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
HIDOUTPUT(1), 0x02, // Data, Var, Abs
REPORT_COUNT(1), 0x01, // 3 bits (Padding)
REPORT_SIZE(1), 0x03,
HIDOUTPUT(1), 0x01, // Const, Array, Abs
END_COLLECTION(0) // End application collection
};
void setup()
{
Serial.begin(115200);
while (!Serial)
{
};
Serial.println("Starting BLE work!");
pinMode(WIO_KEY_A, INPUT_PULLUP);
BLEDevice::init(DEVICE_NAME);
BLEServer *server = BLEDevice::createServer();
server->setCallbacks(new BleKeyboardCallbacks());
// create an HID device
hid = new BLEHIDDevice(server);
input = hid->inputReport(1); // report ID
output = hid->outputReport(1); // report ID
output->setCallbacks(new OutputCallbacks());
// set manufacturer name
hid->manufacturer()->setValue("Maker Community");
// set USB vendor and product ID
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
// information about HID device: device is not localized, device can be connected
hid->hidInfo(0x00, 0x02);
// Security: device requires bonding
// BLESecurity *security = new BLESecurity();
// security->setAuthenticationMode(ESP_LE_AUTH_BOND);
// set report map
hid->reportMap((uint8_t *)REPORT_MAP, sizeof(REPORT_MAP));
hid->startServices();
// set battery level to 100%
hid->setBatteryLevel(100);
// advertise the services
BLEAdvertising *advertising = server->getAdvertising();
advertising->setAppearance(HID_KEYBOARD);
advertising->addServiceUUID(hid->hidService()->getUUID());
advertising->addServiceUUID(hid->deviceInfo()->getUUID());
advertising->addServiceUUID(hid->batteryService()->getUUID());
advertising->start();
Serial.println("Characteristic defined! Now you can read it in your phone!");
Serial.println("BLE ready");
delay(portMAX_DELAY);
}
void loop()
{
Serial.print("BLE Conneciton state: ");
Serial.println(isBleConnected);
if (isBleConnected && digitalRead(WIO_KEY_A) == LOW)
{
// button has been pressed: type message
Serial.println(MESSAGE);
typeText(MESSAGE);
}
delay(100);
}
void typeText(const char *text)
{
int len = strlen(text);
for (int i = 0; i < len; i++)
{
// translate character to key combination
uint8_t val = (uint8_t)text[i];
if (val > KEYMAP_SIZE)
continue; // character not available on keyboard - skip
KEYMAP map = keymap[val];
// create input report
InputReport report = {
.modifiers = map.modifier,
.reserved = 0,
.pressedKeys = {
map.usage,
0, 0, 0, 0, 0}};
// send the input report
input->setValue((uint8_t *)&report, sizeof(report));
input->notify();
delay(5);
// release all keys between two characters; otherwise two identical
// consecutive characters are treated as just one key press
input->setValue((uint8_t *)&NO_KEY_PRESSED, sizeof(NO_KEY_PRESSED));
input->notify();
delay(5);
}
}
I had this problem too…
It looks like seeed just have given up technical support for wio terminal
Wio Terminal is currently our key product and will not stop its technical support. You can see an example of Wio Termianl using Bluetooth on this page: Bluetooth Overview | Seeed Studio Wiki
In the Bluetooth library of ESP32, “BLESecurity” calls “esp_gap_ble_api”, which seems to be related to ESP32 hardware. So now Seeed may need to adapt BLESecurity for wio terminal.
But this issue has been raised for more than three months and it is obvious that no one has tried to answer us
I consulted related colleagues. They said that Wio Terminal no longer supports Bluetooth HID content due to the firmware upgrade, and may not do the development of this part in the future, please understand.