如何为按键检测的keypressed和keyreleased变量实现一次性赋值?
如何实现按键按下/释放的一次性赋值逻辑?
需求说明
需要让keypressed仅在按键按下瞬间获取对应按键值,其余时刻为nokey;keyreleased仅在按键释放瞬间获取对应按键值,其余时刻为nokey。预期状态变化如下:
keypressed = nokey //按键未按下 keyreleased = nokey keypressed = "被按下按键的值" //按键按下瞬间 keyreleased = nokey keypressed = nokey //按键持续按下 keyreleased = nokey keypressed = nokey keyreleased = "被释放按键的值" //按键释放瞬间 keypressed = nokey keyreleased = nokey
注:按下和释放的按键值为同一键的对应值。
当前代码(可移除lastKey变量)
nokey = 255; byte keyreleased = nokey; byte keypressed = nokey; byte lastKey = keypressed; void loop() { int analogVal = analogRead(A0); //读取A0引脚的模拟电压值 if (analogVal < 325) keypressed = instrkey; //值与变量的对应关系 if (analogVal < 300) keypressed = keyB4; if (analogVal < 275) keypressed = keyA4s; if (analogVal < 250) keypressed = keyA4; if (analogVal < 225) keypressed = keyG4s; if (analogVal < 200) keypressed = keyG4; if (analogVal < 175) keypressed = keyF4s; if (analogVal < 150) keypressed = keyF4; if (analogVal < 125) keypressed = keyE4; if (analogVal < 100) keypressed = keyD4s; if (analogVal < 75) keypressed = keyD4; if (analogVal < 50) keypressed = keyC4s; if (analogVal < 25) keypressed = keyC4; if (analogVal > 1000) keypressed = nokey; if (lastKey != keypressed) { //按键释放检测 keyreleased=lastKey; lastKey=keypressed; } }
解决方案
实现思路
核心是通过跟踪上一次按键状态,对比当前状态的变化来触发瞬间赋值:
- 每次循环先重置
keypressed和keyreleased为nokey,确保非触发时刻为默认值 - 读取当前按键的实际状态
- 对比前后状态:
- 上一次无按键、当前有按键 → 触发按下事件,给
keypressed赋值 - 上一次有按键、当前无按键 → 触发释放事件,给
keyreleased赋值
- 上一次无按键、当前有按键 → 触发按下事件,给
- 更新上一次状态,供下一次循环对比
修改后的代码
const byte nokey = 255; byte keyreleased = nokey; byte keypressed = nokey; byte lastKeyState = nokey; // 跟踪上一次的按键状态 void loop() { // 1. 重置本次循环的触发变量为默认值 keypressed = nokey; keyreleased = nokey; // 2. 读取当前按键的实际值(用else if避免条件覆盖) int analogVal = analogRead(A0); byte currentKey = nokey; if (analogVal < 25) currentKey = keyC4; else if (analogVal < 50) currentKey = keyC4s; else if (analogVal < 75) currentKey = keyD4; else if (analogVal < 100) currentKey = keyD4s; else if (analogVal < 125) currentKey = keyE4; else if (analogVal < 150) currentKey = keyF4; else if (analogVal < 175) currentKey = keyF4s; else if (analogVal < 200) currentKey = keyG4; else if (analogVal < 225) currentKey = keyG4s; else if (analogVal < 250) currentKey = keyA4; else if (analogVal < 275) currentKey = keyA4s; else if (analogVal < 300) currentKey = keyB4; else if (analogVal < 325) currentKey = instrkey; else if (analogVal > 1000) currentKey = nokey; // 3. 对比状态变化,触发对应事件 if (lastKeyState == nokey && currentKey != nokey) { // 从无按键到有按键 → 按下瞬间 keypressed = currentKey; } else if (lastKeyState != nokey && currentKey == nokey) { // 从有按键到无按键 → 释放瞬间 keyreleased = lastKeyState; } // 4. 更新上一次的状态 lastKeyState = currentKey; // 此处可添加业务逻辑,比如根据keypressed/keyreleased执行操作 }
代码说明
- 将原连续
if改为else if,避免低区间的按键值被高区间条件覆盖 - 每次循环先重置触发变量,确保只有状态变化瞬间才会有非
nokey的值 - 通过
lastKeyState跟踪状态变化,精准捕捉按下/释放的瞬间触发点
内容的提问来源于stack exchange,提问作者Vatro
相关产品推荐
相关产品推荐

