You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino Uno刷写为USB HID后如何发送Scroll Lock键?

解决USB HID键盘发送Scroll Lock错误触发修饰键的问题

看起来你踩了USB HID键盘报告结构的典型坑——把功能键的代码放错了缓冲区位置!咱们一步步理清问题并修复:

问题根源:HID键盘报告的结构误解

USB HID键盘的8字节报告缓冲区有固定的用途:

  • buf[0]:修饰键掩码(仅用于Ctrl、Alt、Shift、GUI这类组合键,每一位对应一个修饰键)
  • buf[1]:保留位,必须设为0
  • buf[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);
}

关键修改点说明

  1. 调整键码位置:把SCRLCK从buf[0]移到buf[2],这是单个按键发送的标准位置
  2. 清空整个缓冲区:在releaseKey里用memset清空整个buf,避免残留的键码导致异常
  3. 保留修饰键为0:因为Scroll Lock不需要和其他修饰键组合,所以buf[0]保持0

额外说明

Scroll Lock是状态切换类按键,发送一次"按下+释放"的报告,主机就会自动切换Scroll Lock的LED状态和功能状态,用PassMark KeyboardTest应该能看到Scroll Lock的LED点亮/熄灭,同时检测到正确的Scroll Lock按键事件。

内容的提问来源于stack exchange,提问作者mold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:35:45