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

如何为按键检测的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;
  }
}

解决方案

实现思路

核心是通过跟踪上一次按键状态,对比当前状态的变化来触发瞬间赋值:

  1. 每次循环先重置keypressed和keyreleased为nokey,确保非触发时刻为默认值
  2. 读取当前按键的实际状态
  3. 对比前后状态:
    • 上一次无按键、当前有按键 → 触发按下事件,给keypressed赋值
    • 上一次有按键、当前无按键 → 触发释放事件,给keyreleased赋值
  4. 更新上一次状态,供下一次循环对比

修改后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:29:58