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

Arduino UNO 5x7 LED矩阵乒乓球游戏Y轴弹跳异常求助

Arduino UNO 5x7 LED矩阵乒乓球游戏Y轴弹跳异常排查求助

我正在做基于Arduino UNO的5x7 LED矩阵乒乓球游戏课程项目,X轴弹跳功能正常,但Y轴存在异常:当ballPosY的值为B0111111时,switch语句无法识别该值,导致ballDirY无法切换方向。我试过替换switch为if、交换case顺序、用延迟替代异步逻辑、用十进制或0b前缀表示二进制值等方法,都没解决。LED矩阵对应行能收到信号,说明ballPosY确实等于B0111111,但方向切换逻辑失效,求帮忙排查。

问题代码

long prevMoveTime = millis(), currentMoveTime; // Variables for asynchronous drawBall method.
int ballPosX = B00100, ballPosY = B1110111; // X & Y positions of the ball with their initial values.
bool ballDirX = true, ballDirY = true; // Direction on the ball (true = left/up, false = right/down).

void setup() {
  for (int i = 0; i <= 13; i++) { pinMode(i, OUTPUT); }

  PORTB = ballPosX;
  PORTD = ballPosY;
}

void drawBall() {
  currentMoveTime = millis();

  switch (ballPosX) {
    case B10000: ballDirX = true; break;
    case B00001: ballDirX = false; break;
  }

  switch (ballPosY) {
    case B0111111: ballDirY = true; break;
    case B1111110: ballDirY = false; break;
  }

  if (currentMoveTime - prevMoveTime > 1000) {
    if (ballDirX) { ballPosX >>= 1; }
    else { ballPosX <<= 1; }

    PORTB = ballPosX;

    if (ballDirY) { ballPosY >>= 1; ballPosY |= B1000000; }
    else { ballPosY <<= 1; ballPosY |= B0000001; }

    PORTD = ballPosY;

    prevMoveTime = currentMoveTime;
  }
}

void loop() {
  drawBall();
}

问题根源

ballPosY被定义为int类型,Arduino的int是16位有符号整数。当执行右移操作时,有符号数会保留符号位,导致ballPosY的高位被填充1,最终存储的是16位数值(比如你预期的B0111111实际可能是0xFFBF,对应十进制-65),和case中B0111111(十进制63)的8位无符号值不相等,因此switch无法匹配。

修复方案

  1. 修改变量类型:将ballPosX和ballPosY改为byte类型(8位无符号整数),避免符号位扩展干扰。
  2. 保持原有逻辑不变,仅调整变量类型即可解决匹配问题。

修改后的代码

long prevMoveTime = millis(), currentMoveTime;
byte ballPosX = B00100, ballPosY = B1110111;
bool ballDirX = true, ballDirY = true;

void setup() {
  for (int i = 0; i <= 13; i++) { pinMode(i, OUTPUT); }

  PORTB = ballPosX;
  PORTD = ballPosY;
}

void drawBall() {
  currentMoveTime = millis();

  switch (ballPosX) {
    case B10000: ballDirX = true; break;
    case B00001: ballDirX = false; break;
  }

  switch (ballPosY) {
    case B0111111: ballDirY = true; break;
    case B1111110: ballDirY = false; break;
  }

  if (currentMoveTime - prevMoveTime > 1000) {
    if (ballDirX) { ballPosX >>= 1; }
    else { ballPosX <<= 1; }

    PORTB = ballPosX;

    if (ballDirY) { 
      ballPosY >>= 1; 
      ballPosY |= B1000000; 
    } else { 
      ballPosY <<= 1; 
      ballPosY |= B0000001; 
    }

    PORTD = ballPosY;

    prevMoveTime = currentMoveTime;
  }
}

void loop() {
  drawBall();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 02:13:14