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

Arduino带LCD交通灯倒计时10-0秒全红逻辑失效问题求助

Arduino交通灯模拟项目故障排查

项目预期逻辑

基于Arduino+LCD屏制作的60秒周期交通灯模拟场景,逻辑要求:

  • 倒计时59秒-11秒区间:交通灯按正常通行规则轮询放行
  • 倒计时10秒-0秒区间:所有方向信号灯切换为全红状态,禁止通行

相关材料

  • 电路接线截图:Arduino电路接线截图
  • 原始交通灯逻辑代码:
void loop() { 
  
    //   road - 1
 
    // 第一方向绿灯放行
    digitalWrite(g1, HIGH);
  
    digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH);
    digitalWrite(r4, HIGH);
  
  
    // 原注释标注红灯延时9秒,实际写为10秒
    delay(10000);
  
    // 关闭第一方向绿灯
    digitalWrite(g1, LOW);
  
    // 第一、第二方向黄灯亮3秒
    digitalWrite(r2, LOW);
    digitalWrite(y1, HIGH);
    digitalWrite(y2, HIGH);
    delay(3000);
  
    // 第二方向绿灯放行,关闭黄灯
    digitalWrite(y1, LOW);
    digitalWrite(y2, LOW);
  
    // 其余三个方向逻辑省略
    //   road - 2
    ...
    //   road - 3
    ...
    //   road - 4
    ...
}
  • 自行编写的分段测试代码:
for (int seconds = 60; seconds >= 11; seconds--)
{
    // 方向1逻辑
    digitalWrite(g1, HIGH);
        :
        :
    // 方向4逻辑

    if(seconds==11){
        for (int j = 10; j >= 0; j--)
        {
            // 方向1全红
            digitalWrite(r1, HIGH);
                :
                :
            // 方向4全红
        }
    }
}

故障现象

代码烧录后,10秒-0秒区间的全红逻辑不生效,达不到预期效果。


故障原因

三个硬伤导致逻辑失效:

  1. 外层倒计时循环没有加1秒基准延时,seconds变量会在几毫秒内从60递减到11,和真实时间完全脱节,正常灯序根本来不及稳定显示
  2. 正常通行阶段没有做时长拆分,原始代码单方向绿灯+黄灯就占13秒,4个方向一轮总时长早就超过59-11秒对应的49秒区间,时序完全错乱
  3. 切换全红状态前没有拉低之前点亮的绿灯、黄灯引脚,会出现灯组状态冲突,且内层全红循环也没加1秒延时,全红状态会瞬间执行完,肉眼根本捕捉不到

修正代码

直接使用下面的框架,引脚编号按你实际接线修改即可,每个灯组的亮灯时长可以根据需求微调,只要保证第一阶段总时长49秒、第二阶段全红总时长11秒即可:

// 按实际接线修改引脚编号
const int r1 = 2, y1 = 3, g1 = 4;
const int r2 = 5, y2 = 6, g2 = 7;
const int r3 = 8, y3 = 9, g3 = 10;
const int r4 = 11, y4 = 12, g4 = 13;

// 工具函数:关闭所有方向信号灯,避免状态冲突
void clearAllLights() {
  digitalWrite(r1, LOW); digitalWrite(y1, LOW); digitalWrite(g1, LOW);
  digitalWrite(r2, LOW); digitalWrite(y2, LOW); digitalWrite(g2, LOW);
  digitalWrite(r3, LOW); digitalWrite(y3, LOW); digitalWrite(g3, LOW);
  digitalWrite(r4, LOW); digitalWrite(y4, LOW); digitalWrite(g4, LOW);
}

// 工具函数:所有方向切红灯
void setAllRed() {
  clearAllLights();
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(r4, HIGH);
}

void setup() {
  // 初始化所有信号灯引脚为输出模式
  pinMode(r1, OUTPUT); pinMode(y1, OUTPUT); pinMode(g1, OUTPUT);
  pinMode(r2, OUTPUT); pinMode(y2, OUTPUT); pinMode(g2, OUTPUT);
  pinMode(r3, OUTPUT); pinMode(y3, OUTPUT); pinMode(g3, OUTPUT);
  pinMode(r4, OUTPUT); pinMode(y4, OUTPUT); pinMode(g4, OUTPUT);
}

void loop() {
  // -------------------- 第一阶段:59s-11s 共49秒正常通行 --------------------
  // 方向1放行:绿灯9秒,黄灯3秒
  clearAllLights();
  digitalWrite(g1, HIGH);
  digitalWrite(r2, HIGH); digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);
  for (int i = 0; i < 9; i++) {
    delay(1000);
    // 此处插入LCD刷新倒计时代码
  }
  digitalWrite(g1, LOW);
  digitalWrite(y1, HIGH); digitalWrite(y2, HIGH);
  for (int i = 0; i < 3; i++) {
    delay(1000);
    // 此处插入LCD刷新倒计时代码
  }
  digitalWrite(y1, LOW); digitalWrite(y2, LOW); digitalWrite(r2, LOW);

  // 方向2放行:绿灯9秒,黄灯3秒
  digitalWrite(g2, HIGH);
  digitalWrite(r1, HIGH); digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);
  for (int i = 0; i < 9; i++) {
    delay(1000);
    // 此处插入LCD刷新倒计时代码
  }
  digitalWrite(g2, LOW);
  digitalWrite(y2, HIGH); digitalWrite(y3, HIGH);
  for (int i = 0; i < 3; i++) {
    delay(1000);
    // 此处插入LCD刷新倒计时代码
  }
  digitalWrite(y2, LOW); digitalWrite(y3, LOW); digitalWrite(r3, LOW);

  // 方向3放行:绿灯9秒,黄灯3秒
  digitalWrite(g3, HIGH);
  digitalWrite(r1, HIGH); digitalWrite(r2, HIGH); digitalWrite(r4, HIGH);
  for (int i = 0; i < 9; i++) {
    delay(1000);
    // 此处插入LCD刷新倒计时代码
  }
  digitalWrite(g3, LOW);
  digitalWrite(y3, HIGH); digitalWrite(y4, HIGH);
  for (int i = 0; i < 1; i++) { // 此处延时可根据总时长自行调整,凑够49秒即可
    delay(1000);
    // 此处插入LCD刷新倒计时代码
  }
  digitalWrite(y3, LOW); digitalWrite(y4, LOW); digitalWrite(r4, LOW);

  // 方向4放行逻辑可参考上面三个方向补全,注意总时长对齐49秒

  // -------------------- 第二阶段:10s-0s 共11秒全红 --------------------
  setAllRed();
  for (int j = 10; j >= 0; j--) {
    delay(1000);
    // 此处插入LCD刷新全红倒计时代码
  }
  // 一轮60秒周期结束,自动进入下一轮循环
}

调试提示

  • 不要用一次delay(10000)的长延时写法,拆成1秒的循环方便插入LCD刷新逻辑,倒计时数值可以直接用循环变量传递
  • 每次切换灯态前必须清空上一阶段的灯组状态,避免出现同方向红绿同亮的错误
  • 两个阶段顺序执行即可,不需要嵌套循环,Arduino的loop()函数本身就是无限循环,跑完一轮会自动重启周期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:57:22