Ch554 制作USB Host 实现USB键盘转蓝牙
之前使用Ch9350制作过一个 USBHost Shield 【参考1】,能够读取USB键盘鼠标的输入。最近在研究 Ch554 ,使用Ch554e制作了一个同样功能的Shield,配合ESP32-C3 能够实现USB 键盘转蓝牙的功能。使用 Ch554 的有优点如下:1. 价格较低,相对于Ch935010元的价格,最便宜的Ch554e 只要不到1.5元;2. 焊接友好,对于TSSOP-20/SOP-16或者MSOP-10普通人都能够很好的进行焊接;3. 如果你的设计对于体积敏感,可以选择MSOP-10封装的 Ch554e;4. 外围电路简单,只需要2个电容和1个电阻缺点:1. 需要自己使用keil 编写程序;2. 兼容性比不上Ch9350,可能出现无法驱动的USB设备;这次带来就是基于Ch554e的设计。硬件部分设计如下:下方就是CH554e的最小系统,外部配合2个0.1uf电容,以及1个10K电阻即可工作。下载方法是:上电之前短接 DL 位置,然后再上电使用WCHISPStudio即可。不过在研发阶段建议专门准备一个开发板便于操作。同时,官方的例子都是用第一个UART作为调试输出,而Ch554只有第2个 Uart可供使用。根据上述电路设计的PCB如下:
这是一个底板,上面直接连接DFRobot ESP32-C3即可。焊接后的板卡如下:
直接安装在ESP32-C3上即可使用:
接下来开始代码的设计,首先设计的是Ch554的代码,这里直接使用官方的代码进行简单修改。为了便于使用我们使用和Ch9350相同的输出格式:
0-157 AB数据头,固定数值
0288表示有效帧值
03NN后续数据长度,从04开始到最后的校验和
0410 固定值:00 - 保留:01 - 鼠标:0- 保留:00 - 未知:0- 端口1
05-AA BB CC…..MM键盘数据,例如:08 00 00 00 00 00 00 00
XXNum帧序列号
XXCheckSum校验和,从05开始的数据和
例如:实际发送的一个数据:57 AB 88 0B 10 08 00 00 00 00 00 00 0000 08 代码是基于WCH 官方修改而来的,基本原理是:比较每一次收到的数据(RxBuffer)是否和上一次(LastBuffer)相同,如果不同,那么进行上报。使用上面介绍的数据报文格式:
IsSame=TRUE; for ( i = 0; i < len; i ++ ){ if (LastBuffer!=RxBuffer) { IsSame=FALSE; LastBuffer=RxBuffer; } } //只有与前一次不同才进行输出 if (IsSame==FALSE) { checksum=0x00; CH554UART1SendByte(0x57);CH554UART1SendByte(0xAB);CH554UART1SendByte(0x88);CH554UART1SendByte(len+3);CH554UART1SendByte(0x10); for ( i = 0; i < len; i ++ ){ CH554UART1SendByte(RxBuffer); checksum=checksum+RxBuffer; } checksum=checksum+counter; CH554UART1SendByte(counter);CH554UART1SendByte(checksum); counter++; }
代码使用 Keil4编译通过。ESP32-C3代码如下:
#include <Arduino.h>
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
#define DEBUGMODE 0
void setup() {
Serial.begin(115200);
Serial1.begin(115200, SERIAL_8N1, RX, TX);
bleKeyboard.begin();
}
void loop() {
while (Serial.available()) {
char c = Serial.read();
if (c == '1') {
Serial.println("get1");
}
if (c == '3') {
ESP.restart();
}
}
//根据 CH9350 Spec 每次最多输出 72Bytes
byte Data;
unsigned int CounterLast = Serial1.available();
unsigned int CounterCurrent = 0;
// 如果当前串口有数据
if (CounterLast != 0) {
// 进行简单测试,如果当前还在传输数据那么持续接收
while (CounterCurrent != CounterLast) {
CounterLast = Serial1.available();
delayMicroseconds(500);
CounterCurrent = Serial1.available();
}
}
if (CounterCurrent > 0) {
// 一次性将数据收取下来
Serial1.readBytes(Data, CounterCurrent);
unsigned int i = 0;
unsigned int Length;
while (i < CounterCurrent) {
// 识别帧头
if ((Data == 0x57) && (Data == 0xAB)) {
// 有效键值帧
if (Data == 0x88) {
// 获得数据长度
Length = Data;
if (DEBUGMODE) {
//Serial.print("Ln:");Serial.print(Length);
for (int j = 1; j < Length + 1; j++) {
if (Data < 16) {
Serial.print("0");
}
Serial.print(Data, HEX);
Serial.print(" ");
}
Serial.println(" ");
}
//如果是键盘
if (Data == 0x10) {
if (DEBUGMODE) {
Serial.print("Key");
for (int j = 1; j < Length + 1; j++) {
Serial.print(Data, HEX);
Serial.print(" ");
}
Serial.println(" ");
}
//判断为Dostyle键盘
if (Data == 0x10) {
if (bleKeyboard.isConnected() == true) {
bleKeyboard.sendReport((KeyReport*)(&Data));
}
}
}
i = i + 3 + Length;
} else if (Data == 0x82) {
i = i + 3; // 跳过
}
}
i++;
} // while (i < Counter)
}
}
使用时,只需要给ESP32-C3供电,连接好USB键盘后就可以搜索蓝牙键盘进行连接使用了。工作的测试视频在:
完整代码和测试视频可以在这里看到
工作的视频https://www.bilibili.com/video/BV1zi421a7NM/?vd_source=cf6121716e06cb669a27c10276f9c920Ch554的代码:
ESP32-C3 的代码:
参考:1. https://mc.dfrobot.com.cn/thread-316678-1-1.html
页:
[1]