设计一个用于十字路口的交通灯控制器,能显示十字路口东西、南北两个方向的红、黄、绿的指示状态;具有倒计时的功能,用两组数码管作为东西和南北方向的倒计时显示,主干道直行(绿灯)60秒后,左转(绿灯)40秒;支干道直行(绿灯)45秒后,左转(绿灯)30秒,在每次绿灯变成红灯的转换过程中,要亮黄灯5秒作为过渡。黄灯每秒闪亮一次。只考虑直行和左转车辆控制信号灯,右转车辆不受信号灯控制, 南北向车辆与东西向车辆交替方向,同方向等待车辆应先方向直行车辆而后放行左转车辆。
时间: 2023-06-02 22:02:36 浏览: 266
以下是一个简单的交通灯控制器的代码示例:
```arduino
#include <TM1637Display.h>
// 定义数码管引脚
#define EAST_WEST_CLK 2
#define EAST_WEST_DIO 3
#define NORTH_SOUTH_CLK 4
#define NORTH_SOUTH_DIO 5
// 定义信号灯引脚
#define EAST_WEST_GREEN 6
#define EAST_WEST_YELLOW 7
#define EAST_WEST_RED 8
#define NORTH_SOUTH_GREEN 9
#define NORTH_SOUTH_YELLOW 10
#define NORTH_SOUTH_RED 11
// 定义倒计时时间
#define EAST_WEST_STRAIGHT_GREEN_TIME 60000 // 东西直行绿灯60秒
#define EAST_WEST_LEFT_GREEN_TIME 40000 // 东西左转绿灯40秒
#define NORTH_SOUTH_STRAIGHT_GREEN_TIME 45000 // 南北直行绿灯45秒
#define NORTH_SOUTH_LEFT_GREEN_TIME 30000 // 南北左转绿灯30秒
#define YELLOW_TIME 5000 // 黄灯5秒
// 定义数码管显示对象
TM1637Display eastWestDisplay(EAST_WEST_CLK, EAST_WEST_DIO);
TM1637Display northSouthDisplay(NORTH_SOUTH_CLK, NORTH_SOUTH_DIO);
// 定义倒计时计数器
unsigned long eastWestStraightGreenTimeLeft = 0;
unsigned long eastWestLeftGreenTimeLeft = 0;
unsigned long northSouthStraightGreenTimeLeft = 0;
unsigned long northSouthLeftGreenTimeLeft = 0;
unsigned long yellowTimeLeft = 0;
// 定义信号灯状态枚举
enum TrafficLightState {
GREEN,
YELLOW,
RED
};
// 定义东西向和南北向信号灯状态
TrafficLightState eastWestState = GREEN;
TrafficLightState northSouthState = RED;
// 点亮指定方向的绿灯,同时关闭其他方向的绿灯和所有黄灯
void turnOnGreenLight(TrafficLightState &state, int greenPin, int yellowPin, int redPin) {
digitalWrite(greenPin, HIGH);
digitalWrite(yellowPin, LOW);
digitalWrite(redPin, LOW);
state = GREEN;
}
// 点亮指定方向的黄灯,同时关闭其他方向的绿灯和所有黄灯
void turnOnYellowLight(TrafficLightState &state, int greenPin, int yellowPin, int redPin) {
digitalWrite(greenPin, LOW);
digitalWrite(yellowPin, HIGH);
digitalWrite(redPin, LOW);
state = YELLOW;
}
// 点亮指定方向的红灯,同时关闭其他方向的绿灯和所有黄灯
void turnOnRedLight(TrafficLightState &state, int greenPin, int yellowPin, int redPin) {
digitalWrite(greenPin, LOW);
digitalWrite(yellowPin, LOW);
digitalWrite(redPin, HIGH);
state = RED;
}
void setup() {
// 初始化信号灯引脚
pinMode(EAST_WEST_GREEN, OUTPUT);
pinMode(EAST_WEST_YELLOW, OUTPUT);
pinMode(EAST_WEST_RED, OUTPUT);
pinMode(NORTH_SOUTH_GREEN, OUTPUT);
pinMode(NORTH_SOUTH_YELLOW, OUTPUT);
pinMode(NORTH_SOUTH_RED, OUTPUT);
// 初始化数码管
eastWestDisplay.setBrightness(0x0f);
northSouthDisplay.setBrightness(0x0f);
}
void loop() {
// 检查是否需要切换信号灯状态
if (eastWestStraightGreenTimeLeft == 0 && eastWestLeftGreenTimeLeft == 0 && northSouthStraightGreenTimeLeft == 0 && northSouthLeftGreenTimeLeft == 0 && yellowTimeLeft == 0) {
switch (eastWestState) {
case GREEN:
turnOnYellowLight(eastWestState, EAST_WEST_GREEN, EAST_WEST_YELLOW, EAST_WEST_RED);
yellowTimeLeft = YELLOW_TIME;
break;
case YELLOW:
turnOnRedLight(eastWestState, EAST_WEST_GREEN, EAST_WEST_YELLOW, EAST_WEST_RED);
if (northSouthState == RED) {
turnOnGreenLight(northSouthState, NORTH_SOUTH_GREEN, NORTH_SOUTH_YELLOW, NORTH_SOUTH_RED);
northSouthStraightGreenTimeLeft = NORTH_SOUTH_STRAIGHT_GREEN_TIME;
} else {
turnOnYellowLight(northSouthState, NORTH_SOUTH_GREEN, NORTH_SOUTH_YELLOW, NORTH_SOUTH_RED);
yellowTimeLeft = YELLOW_TIME;
}
break;
case RED:
turnOnGreenLight(eastWestState, EAST_WEST_GREEN, EAST_WEST_YELLOW, EAST_WEST_RED);
eastWestStraightGreenTimeLeft = EAST_WEST_STRAIGHT_GREEN_TIME;
break;
}
}
// 更新倒计时数码管显示
eastWestDisplay.showNumberDec(eastWestStraightGreenTimeLeft / 1000, true);
northSouthDisplay.showNumberDec(northSouthStraightGreenTimeLeft / 1000, true);
// 更新倒计时计数器
if (eastWestStraightGreenTimeLeft > 0) {
eastWestStraightGreenTimeLeft -= min(eastWestStraightGreenTimeLeft, 1000ul);
if (eastWestStraightGreenTimeLeft == 0) {
turnOnYellowLight(eastWestState, EAST_WEST_GREEN, EAST_WEST_YELLOW, EAST_WEST_RED);
yellowTimeLeft = YELLOW_TIME;
}
} else if (eastWestLeftGreenTimeLeft > 0) {
eastWestLeftGreenTimeLeft -= min(eastWestLeftGreenTimeLeft, 1000ul);
if (eastWestLeftGreenTimeLeft == 0) {
turnOnYellowLight(eastWestState, EAST_WEST_GREEN, EAST_WEST_YELLOW, EAST_WEST_RED);
yellowTimeLeft = YELLOW_TIME;
}
} else if (northSouthStraightGreenTimeLeft > 0) {
northSouthStraightGreenTimeLeft -= min(northSouthStraightGreenTimeLeft, 1000ul);
if (northSouthStraightGreenTimeLeft == 0) {
turnOnYellowLight(northSouthState, NORTH_SOUTH_GREEN, NORTH_SOUTH_YELLOW, NORTH_SOUTH_RED);
yellowTimeLeft = YELLOW_TIME;
}
} else if (northSouthLeftGreenTimeLeft > 0) {
northSouthLeftGreenTimeLeft -= min(northSouthLeftGreenTimeLeft, 1000ul);
if (northSouthLeftGreenTimeLeft == 0) {
turnOnYellowLight(northSouthState, NORTH_SOUTH_GREEN, NORTH_SOUTH_YELLOW, NORTH_SOUTH_RED);
yellowTimeLeft = YELLOW_TIME;
}
} else if (yellowTimeLeft > 0) {
yellowTimeLeft -= min(yellowTimeLeft, 1000ul);
}
// 控制黄灯闪烁
if (yellowTimeLeft > 0) {
if (yellowTimeLeft % 500 < 250) {
digitalWrite(EAST_WEST_YELLOW, LOW);
digitalWrite(NORTH_SOUTH_YELLOW, LOW);
} else {
digitalWrite(EAST_WEST_YELLOW, HIGH);
digitalWrite(NORTH_SOUTH_YELLOW, HIGH);
}
}
}
```
需要注意的是,该示例只是一个简单的实现,可能并不完美,实际应用时需要根据具体情况进行适当调整和优化。同时,为了简化代码,该示例没有考虑多个车辆同时通过的情况,实际应用需要根据实际情况进行调整。
阅读全文