Arduino键盘模拟器新增按键后无输入自动输出字符故障求助
问题描述
我使用Arduino制作了一款键盘模拟器,外接开关按键,原计划在OSU游戏中测试使用。OSU虽支持单键游玩,但双键操作体验更佳,因此我尝试为模拟器新增第二个开关/按键,此次改动后模拟器完全失效,在无任何输入的情况下持续自动输出字符。我已两次重写脚本代码,若代码逻辑稍显杂乱还请谅解,恳请各位帮忙定位故障原因。
原始故障代码
#include <Keyboard.h> void setup() { // put your setup code here, to run once: pinMode (2, INPUT_PULLUP); pinMode (5, INPUT_PULLUP); Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: bool keyL = false; bool keyR = false; Keyboard.begin(); if (digitalRead (2) == 0){ //if switch 2 is activated keyL = true; } else{ }//do nothing if (digitalRead (5) == 0){ keyR = true; } else{ }//do nothing if (keyR = true){ Keyboard.press ('c'); delay (50); if (digitalRead (5) == 1){ keyR = false; Keyboard.releaseAll(); } } if (keyL = true){ Keyboard.press ('z'); delay (50); if (digitalRead (2) == 0){ keyL = false; Keyboard.releaseAll(); } } }
核心故障原因
- 最致命的语法错误:判断按键状态时把相等比较运算符
==写成了赋值运算符=。if (keyR = true)和if (keyL = true)这两行根本不是在判断变量值,而是直接把keyR、keyL强制赋值为true,判断条件永远成立,所以不管有没有按键按下,程序都会一直执行按键按下的逻辑,这就是无输入时持续自动输出字符的核心原因。 - 初始化逻辑位置错误:
Keyboard.begin()是键盘功能的初始化函数,只需要在setup()里执行一次即可,放在loop()里会反复初始化键盘设备,导致按键状态混乱。 - 按键逻辑混乱:代码使用
INPUT_PULLUP上拉输入模式,按键按下时引脚读值为0,松开时读值为1。但左键的释放判断写的是if (digitalRead (2) == 0),等于按住按键时才触发释放,松开时反而不释放,和右键的释放判断逻辑都不一致。 - 释放逻辑不符合双键使用需求:用
Keyboard.releaseAll()释放所有按键,当两个键同时按下时,松开任意一个键都会把另一个按住的键也一起释放,双键操作时会出现断触。另外逻辑里嵌套的delay(50)会阻塞整个程序循环,导致按键响应延迟高,跟不上游戏的高速操作。
修复后可用代码
#include <Keyboard.h> // 引脚、键值、消抖参数常量定义,后续修改无需翻找核心逻辑 const int LEFT_KEY_PIN = 2; const int RIGHT_KEY_PIN = 5; const char LEFT_KEY_MAP = 'z'; const char RIGHT_KEY_MAP = 'c'; const int DEBOUNCE_DELAY = 20; void setup() { pinMode(LEFT_KEY_PIN, INPUT_PULLUP); pinMode(RIGHT_KEY_PIN, INPUT_PULLUP); Serial.begin(9600); // 键盘初始化仅在setup执行一次 Keyboard.begin(); } void loop() { // 左键状态检测 static bool lastLeftState = HIGH; bool currentLeftState = digitalRead(LEFT_KEY_PIN); if (currentLeftState != lastLeftState) { delay(DEBOUNCE_DELAY); currentLeftState = digitalRead(LEFT_KEY_PIN); if (currentLeftState == LOW) { Keyboard.press(LEFT_KEY_MAP); } else { Keyboard.release(LEFT_KEY_MAP); } lastLeftState = currentLeftState; } // 右键状态检测 static bool lastRightState = HIGH; bool currentRightState = digitalRead(RIGHT_KEY_PIN); if (currentRightState != lastRightState) { delay(DEBOUNCE_DELAY); currentRightState = digitalRead(RIGHT_KEY_PIN); if (currentRightState == LOW) { Keyboard.press(RIGHT_KEY_MAP); } else { Keyboard.release(RIGHT_KEY_MAP); } lastRightState = currentRightState; } }
修复对应调整:
- 将
Keyboard.begin()移至setup(),避免重复初始化 - 所有条件判断修正为比较运算符
== - 对齐上拉输入的电平判断逻辑,按下触发对应按键
press、松开触发对应按键release,不再使用releaseAll,避免双键同时按时误释放 - 用状态变化检测+短消抖代替原有的阻塞式长延时,按键响应速度更快,不会卡住主循环
内容的提问来源于stack exchange,提问作者DogshitProgrammer
相关产品推荐
相关产品推荐

