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

基于Arduino的四路交通灯系统LED异常问题求助

四路交通灯移位寄存器异常排查与解决

问题描述

使用Arduino Uno R3 + 2个74HC595移位寄存器搭建四路交通灯系统(每路红黄绿3个LED,共12个),当前用默认序列测试代码,未接入红外传感器。测试中发现第二个移位寄存器控制的Road3、Road4存在以下异常:

  • 默认状态下Road3黄灯亮起而非红灯
  • Road3轮到通行时,红黄灯同时点亮,绿灯始终不亮;直至进入Road4阶段后,Road3绿灯才亮起

测试代码(原代码)

// Pin Definitions
const int dataPin = 10;  // DS
const int clockPin = 8; // SH_CP
const int latchPin = 9; // ST_CP

// Sensors
const int sensor1 = A0, sensor2 = A1, sensor3 = A2, sensor4 = A3;

// LED States (12 LEDs controlled via 2 shift registers)
byte road1 = 0b001; // Red: 1, Yellow: 0, Green: 0
byte road2 = 0b001;
byte road3 = 0b001;
byte road4 = 0b001;

void setup() {
  // Setup Serial monitor
  Serial.begin(9600);
  // Shift register pins
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  
  // Sensor pins
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor4, INPUT);
}

void loop() {
  defaultSequence();
}

void updateTraffic(int road) {
  // Set all roads to red
  road1 = 0b001; road2 = 0b001; road3 = 0b001; road4 = 0b001;
  // Update the road based on priority
  switch (road) {
    case 1: road1 = 0b100; break; // Green for Road 1
    case 2: road2 = 0b100; break; // Green for Road 2
    case 3: road3 = 0b100; break; // Green for Road 3
    case 4: road4 = 0b100; break; // Green for Road 4
  }

  writeShiftRegisters();
  delay(10000); // Green light duration
  setYellow(road);
  //delay(1000);
  //setRed(road);
}

void setYellow(int road) {
  // Set the selected road to yellow
  switch (road) {
    case 1: road1 = 0b010; break;
    case 2: road2 = 0b010; break;
    case 3: road3 = 0b010; break;
    case 4: road4 = 0b010; break;
  }

  writeShiftRegisters();
  delay(2000); // Yellow light duration
}

void setRed(int road) {
    // Set the selected road to red
  switch (road) {
    case 1: road1 = 0b001; break;
    case 2: road2 = 0b001; break;
    case 3: road3 = 0b001; break;
    case 4: road4 = 0b001; break;
  }

  writeShiftRegisters();
}

void defaultSequence() {
  for (int i = 1; i <= 4; i++) {
    Serial.print("Road: ");
    Serial.println(i);
    updateTraffic(i);
    delay(10000); // Delay for default traffic
  }
}

void writeShiftRegisters() {
  // Combine all roads into a 16-bit data word
  unsigned int allRoads = (road4 << 9) | (road3 << 6) | (road2 << 3) | road1;
  Serial.print("allRoads (binary): ");
  for (int i = 15; i >= 0; i--) {
    Serial.print((allRoads >> i) & 1);
  }
  Serial.println();
  // Send data to shift registers
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, highByte(allRoads)); // First register
  delay(10);
  shiftOut(dataPin, clockPin, MSBFIRST, lowByte(allRoads));  // Second register
  digitalWrite(latchPin, HIGH);
}

问题根源分析

  1. 移位寄存器级联的位顺序不匹配:使用MSBFIRST发送数据时,第一个发送的比特会最终落在第二个移位寄存器的最高位(Q7),但原代码的位拼接逻辑未匹配该硬件级联顺序,导致Road3、Road4的灯位完全错位。
  2. 位拼接偏移计算错误:原代码中road4 << 9、road3 << 6的偏移量未对应实际硬件连接的移位寄存器输出位,造成灯状态映射混乱。
  3. 冗余延迟导致逻辑混乱:defaultSequence中额外的delay(10000)与updateTraffic内的延迟重复,导致路口切换逻辑出现不必要的等待。

解决方法

1. 修正位拼接与移位发送逻辑

重新构造移位寄存器的输出字节,改用LSBFIRST发送,确保每路LED的位与移位寄存器的输出引脚一一对应:

  • 第二个移位寄存器控制Road3(Q0-Q2)、Road4(Q3-Q5)
  • 第一个移位寄存器控制Road1(Q0-Q2)、Road2(Q3-Q5)

2. 移除冗余延迟

删除defaultSequence中重复的delay(10000),避免路口切换逻辑混乱。

3. 验证硬件连接

确认第二个移位寄存器的DS引脚连接到第一个移位寄存器的Q7'引脚,LED引脚对应关系与代码逻辑一致。

修正后的完整代码

// Pin Definitions
const int dataPin = 10;  // DS
const int clockPin = 8; // SH_CP
const int latchPin = 9; // ST_CP

// Sensors
const int sensor1 = A0, sensor2 = A1, sensor3 = A2, sensor4 = A3;

// LED States (12 LEDs controlled via 2 shift registers)
byte road1 = 0b001; // Red: bit0=1, Yellow: bit1=1, Green: bit2=1
byte road2 = 0b001;
byte road3 = 0b001;
byte road4 = 0b001;

void setup() {
  // Setup Serial monitor
  Serial.begin(9600);
  // Shift register pins
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  
  // Sensor pins
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor4, INPUT);
}

void loop() {
  defaultSequence();
}

void updateTraffic(int road) {
  // Set all roads to red
  road1 = 0b001; road2 = 0b001; road3 = 0b001; road4 = 0b001;
  // Update the road based on priority
  switch (road) {
    case 1: road1 = 0b100; break; // Green for Road 1
    case 2: road2 = 0b100; break; // Green for Road 2
    case 3: road3 = 0b100; break; // Green for Road 3
    case 4: road4 = 0b100; break; // Green for Road 4
  }

  writeShiftRegisters();
  delay(10000); // Green light duration
  setYellow(road);
}

void setYellow(int road) {
  // Set the selected road to yellow
  switch (road) {
    case 1: road1 = 0b010; break;
    case 2: road2 = 0b010; break;
    case 3: road3 = 0b010; break;
    case 4: road4 = 0b010; break;
  }

  writeShiftRegisters();
  delay(2000); // Yellow light duration
}

void setRed(int road) {
    // Set the selected road to red
  switch (road) {
    case 1: road1 = 0b001; break;
    case 2: road2 = 0b001; break;
    case 3: road3 = 0b001; break;
    case 4: road4 = 0b001; break;
  }

  writeShiftRegisters();
}

void defaultSequence() {
  for (int i = 1; i <= 4; i++) {
    Serial.print("Road: ");
    Serial.println(i);
    updateTraffic(i);
  }
}

void writeShiftRegisters() {
  // 构造两个移位寄存器的输出字节
  // reg2控制第二个移位寄存器:Road3(bit0-2)、Road4(bit3-5)
  byte reg2 = (road4 << 3) | road3;
  // reg1控制第一个移位寄存器:Road1(bit0-2)、Road2(bit3-5)
  byte reg1 = (road2 << 3) | road1;

  // 打印调试信息
  Serial.print("reg2 (Road3/Road4): ");
  for (int i = 7; i >= 0; i--) {
    Serial.print((reg2 >> i) & 1);
  }
  Serial.print(" | reg1 (Road1/Road2): ");
  for (int i = 7; i >= 0; i--) {
    Serial.print((reg1 >> i) & 1);
  }
  Serial.println();

  // 发送数据到移位寄存器
  digitalWrite(latchPin, LOW);
  // 级联时先发送第二个寄存器的内容(LSBFIRST让最低位对应Q0)
  shiftOut(dataPin, clockPin, LSBFIRST, reg2);
  shiftOut(dataPin, clockPin, LSBFIRST, reg1);
  digitalWrite(latchPin, HIGH);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:24:55