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

Arduino UNO C++桌式足球项目新增客队进球计数功能咨询

Arduino UNO 迷你桌式足球双队计分整合实现方案

核心卡点根源

你遇到的判断拦截问题本质非常直接:原有逻辑是为单队计数写的,用了全局单计数变量+单if分支的结构,没有给客队逻辑留独立的平行执行空间——只要首个if的主队判断成立,嵌套在里面的客队代码根本不会被执行。你之前尝试的数组封装思路方向完全正确,不需要推翻现有代码重来。

基础可运行版本(零代码重构,快速跑通)

先不用上复杂封装,先把双计数、双平行判断的逻辑跑通,确认硬件触发正常后再做优化。

1. 替换原有全局变量

删掉之前的单全局进球计数变量,替换为:

  • 独立队计数变量:int homeScore = 0; int awayScore = 0;
  • 硬件引脚常量(避免代码里硬编码引脚号):
    • 主队传感器引脚:const int HOME_SENSOR_PIN = A1;
    • 客队传感器引脚:const int AWAY_SENSOR_PIN = A2;
    • 独立防抖状态变量:bool homeLastTriggered = false; bool awayLastTriggered = false;

2. 修正loop内的判断结构

把原来的单if分支拆成两个完全平行、互不嵌套的独立判断块,从根源上解决首个if拦截客队逻辑的问题:

void loop() {
  // 读取传感器状态,阈值根据你之前调试主队逻辑的实际值修改
  bool homeTrigger = analogRead(HOME_SENSOR_PIN) < 500;
  bool awayTrigger = analogRead(AWAY_SENSOR_PIN) < 500;

  // 主队独立判断分支
  if (homeTrigger != homeLastTriggered) {
    if (homeTrigger) { // 检测触发沿,避免球停在传感器上连续重复计数
      homeScore++;
      // 复用你已有的主队触发逻辑:更新OLED、点亮主队提示LED
      updateOLED(homeScore, awayScore);
      triggerHomeLED();
    }
    homeLastTriggered = homeTrigger;
  }

  // 客队独立判断分支(和主队分支同级,千万不要嵌在上一个if的大括号里)
  if (awayTrigger != awayLastTriggered) {
    if (awayTrigger) {
      awayScore++;
      // 新增客队触发逻辑:同屏更新比分、点亮客队提示LED
      updateOLED(homeScore, awayScore);
      triggerAwayLED();
    }
    awayLastTriggered = awayTrigger;
  }

  delay(50); // 基础防抖延时,根据传感器响应速度调整
}

数组封装优化版本(匹配你初步尝试的思路)

论坛建议的数组封装方案没有问题,能帮你删掉重复的判断代码,后续要加额外提示、甚至扩展第三队计分的时候只需要改数组配置,不用翻遍整个逻辑改分支。
核心实现思路是把每个队的硬件参数、计数变量、防抖状态封装成结构化数组,用循环遍历统一处理:

// 定义单队的参数结构
struct TeamInfo {
  int sensorPin;    // 对应队的进球传感器引脚
  int ledPin;       // 对应队的提示LED引脚
  int score;        // 对应队的当前计分
  bool lastState;   // 对应队的防抖状态变量
};

// 初始化两队的所有参数,存在数组里
TeamInfo teams[2] = {
  {A1, 2, 0, false}, // 主队:传感器A1,LED接D2,初始分0
  {A2, 3, 0, false}  // 客队:传感器A2,LED接D3,初始分0
};

void loop() {
  // 循环遍历处理两个队的判断逻辑,不用写两遍重复代码
  for (int teamIdx = 0; teamIdx < 2; teamIdx++) {
    bool currentTrigger = analogRead(teams[teamIdx].sensorPin) < 500;
    
    if (currentTrigger != teams[teamIdx].lastState) {
      if (currentTrigger) {
        teams[teamIdx].score++;
        // 统一刷新OLED,传入两队当前的计分
        updateOLED(teams[0].score, teams[1].score);
        // 触发对应队的LED提示
        digitalWrite(teams[teamIdx].ledPin, HIGH);
        delay(200);
        digitalWrite(teams[teamIdx].ledPin, LOW);
      }
      teams[teamIdx].lastState = currentTrigger;
    }
  }
  delay(50);
}

新手常见避坑点

  • 绝对不要把客队的判断逻辑嵌在主队if的大括号内部,平行同级的判断才能让两个传感器的触发互不干扰
  • 不要共用同一个防抖状态变量,不然两个队的触发边沿检测会互相覆盖,导致计数跳变
  • 调用OLED刷新函数的时候,要同时传入主、客队两个独立的计分变量,不要只传之前的主队计数,不然客队得分时屏幕不会同步更新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 05:54:03