Arduino Uno刷写为USB HID后如何发送Scroll Lock键?
解决USB HID键盘发送Scroll Lock错误触发修饰键的问题
看起来你踩了USB HID键盘报告结构的典型坑——把功能键的代码放错了缓冲区位置!咱们一步步理清问题并修复:
问题根源:HID键盘报告的结构误解
USB HID键盘的8字节报告缓冲区有固定的用途:
buf[0]:修饰键掩码(仅用于Ctrl、Alt、Shift、GUI这类组合键,每一位对应一个修饰键)buf[1]:保留位,必须设为0buf[2]到buf[7]:普通按键/功能键的位置,最多可以同时发送6个按键码
你之前把Scroll Lock的键码0x47放到了buf[0],而0x47的二进制是01000111,对应修饰键位的:
- 第0位(0x01):左Ctrl
- 第2位(0x04):左Alt
- 第6位(0x40):右Alt
这就是为什么检测到的是这些修饰键,而不是Scroll Lock。
修复方案:正确放置Scroll Lock键码
首先,你的SCRLCK 0x47定义是对的(符合HID设备规范里Scroll Lock的Usage ID),只需要调整它在缓冲区的位置,同时修正释放按键的逻辑:
修改后的完整代码
/* Arduino USB Keyboard HID demo * Send Scroll Lock */ #define SCRLCK 0x47 uint8_t buf[8] = { 0 }; /* Keyboard report buffer */ #define PIN_PTT 2 int state = 1; int prevState; void setup() { Serial.begin(9600); pinMode(PIN_PTT, INPUT); // Enable internal pull-ups digitalWrite(PIN_PTT, 1); delay(200); } void loop() { state = digitalRead(PIN_PTT); if (prevState != state) { buf[0] = 0; // 无修饰键,设为0 buf[2] = SCRLCK; // 将Scroll Lock键码放到正确的按键位置 Serial.write(buf, 8); // 发送按键按下事件 prevState = state; releaseKey(); } } void releaseKey() { memset(buf, 0, sizeof(buf)); // 清空整个缓冲区,确保所有按键都释放 Serial.write(buf, 8); // 发送按键释放事件 delay(100); }
关键修改点说明
- 调整键码位置:把
SCRLCK从buf[0]移到buf[2],这是单个按键发送的标准位置 - 清空整个缓冲区:在
releaseKey里用memset清空整个buf,避免残留的键码导致异常 - 保留修饰键为0:因为Scroll Lock不需要和其他修饰键组合,所以
buf[0]保持0
额外说明
Scroll Lock是状态切换类按键,发送一次"按下+释放"的报告,主机就会自动切换Scroll Lock的LED状态和功能状态,用PassMark KeyboardTest应该能看到Scroll Lock的LED点亮/熄灭,同时检测到正确的Scroll Lock按键事件。
内容的提问来源于stack exchange,提问作者mold
相关产品推荐
相关产品推荐

