编写一个Arduino的FSM关于十字路口红绿灯并且有两个开管控制还要包括turnNSred(),turnNSamber(),turnNSgreen(),trunEWred (),turnEWgreen(),turnEWamber (),restratTimer(1000)函数
时间: 2023-11-12 21:03:38 浏览: 131
基于Arduino的红绿灯+C++源码+文档说明
好的,以下是一个简单的Arduino FSM关于十字路口红绿灯控制,并且有两个开管控制的示例代码:
```
// 定义状态枚举值
enum State {
NS_GREEN,
NS_AMBER,
NS_RED,
EW_GREEN,
EW_AMBER,
EW_RED
};
// 定义常量
const int NS_GREEN_PIN = 2;
const int NS_AMBER_PIN = 3;
const int NS_RED_PIN = 4;
const int EW_GREEN_PIN = 5;
const int EW_AMBER_PIN = 6;
const int EW_RED_PIN = 7;
const int OPEN_SWITCH_PIN = 8;
const int CLOSE_SWITCH_PIN = 9;
const int TIMER_INTERVAL = 1000;
// 初始化状态和计时器
State currentState;
unsigned long timer;
// 定义函数
void turnNSred() {
digitalWrite(NS_GREEN_PIN, LOW);
digitalWrite(NS_AMBER_PIN, LOW);
digitalWrite(NS_RED_PIN, HIGH);
}
void turnNSamber() {
digitalWrite(NS_GREEN_PIN, LOW);
digitalWrite(NS_AMBER_PIN, HIGH);
digitalWrite(NS_RED_PIN, LOW);
}
void turnNSgreen() {
digitalWrite(NS_GREEN_PIN, HIGH);
digitalWrite(NS_AMBER_PIN, LOW);
digitalWrite(NS_RED_PIN, LOW);
}
void turnEWred() {
digitalWrite(EW_GREEN_PIN, LOW);
digitalWrite(EW_AMBER_PIN, LOW);
digitalWrite(EW_RED_PIN, HIGH);
}
void turnEWgreen() {
digitalWrite(EW_GREEN_PIN, HIGH);
digitalWrite(EW_AMBER_PIN, LOW);
digitalWrite(EW_RED_PIN, LOW);
}
void turnEWamber() {
digitalWrite(EW_GREEN_PIN, LOW);
digitalWrite(EW_AMBER_PIN, HIGH);
digitalWrite(EW_RED_PIN, LOW);
}
void restartTimer(int interval) {
timer = millis() + interval;
}
void setup() {
// 设置引脚模式
pinMode(NS_GREEN_PIN, OUTPUT);
pinMode(NS_AMBER_PIN, OUTPUT);
pinMode(NS_RED_PIN, OUTPUT);
pinMode(EW_GREEN_PIN, OUTPUT);
pinMode(EW_AMBER_PIN, OUTPUT);
pinMode(EW_RED_PIN, OUTPUT);
pinMode(OPEN_SWITCH_PIN, INPUT_PULLUP);
pinMode(CLOSE_SWITCH_PIN, INPUT_PULLUP);
// 初始化状态和计时器
currentState = NS_GREEN;
timer = millis() + TIMER_INTERVAL;
}
void loop() {
// 获取开关状态
boolean isOpen = digitalRead(OPEN_SWITCH_PIN) == LOW;
boolean isClose = digitalRead(CLOSE_SWITCH_PIN) == LOW;
// 如果开启开关,切换到EW_GREEN状态
if (isOpen) {
currentState = EW_GREEN;
}
// 如果关闭开关,切换到NS_GREEN状态
if (isClose) {
currentState = NS_GREEN;
}
// 根据当前状态执行相应操作
switch (currentState) {
case NS_GREEN:
turnNSgreen();
turnEWred();
if (millis() >= timer) {
currentState = NS_AMBER;
restartTimer(TIMER_INTERVAL);
}
break;
case NS_AMBER:
turnNSamber();
turnEWred();
if (millis() >= timer) {
currentState = NS_RED;
restartTimer(TIMER_INTERVAL);
}
break;
case NS_RED:
turnNSred();
turnEWgreen();
if (millis() >= timer) {
currentState = EW_AMBER;
restartTimer(TIMER_INTERVAL);
}
break;
case EW_GREEN:
turnNSred();
turnEWgreen();
if (millis() >= timer) {
currentState = EW_AMBER;
restartTimer(TIMER_INTERVAL);
}
break;
case EW_AMBER:
turnNSred();
turnEWamber();
if (millis() >= timer) {
currentState = EW_RED;
restartTimer(TIMER_INTERVAL);
}
break;
case EW_RED:
turnNSgreen();
turnEWred();
if (millis() >= timer) {
currentState = NS_AMBER;
restartTimer(TIMER_INTERVAL);
}
break;
}
}
```
在以上代码中,我们定义了一个状态机,有6个不同的状态:
- NS_GREEN:北南方向绿灯
- NS_AMBER:北南方向黄灯
- NS_RED:北南方向红灯
- EW_GREEN:东西方向绿灯
- EW_AMBER:东西方向黄灯
- EW_RED:东西方向红灯
根据当前状态,执行相应的操作,包括开灯、关灯和重启计时器。在每个状态之间切换时,我们还检查了两个开关的状态,以便手动切换状态。
此外,我们还定义了一些常量,包括引脚号、计时器间隔和状态。在设置中,我们将所有输出引脚设置为输出,并将所有输入引脚设置为内部上拉电阻输入。我们还初始化了状态和计时器。
在主循环中,我们在每个状态之间切换,并执行相应的操作。我们还检查了两个开关的状态,并根据需要切换状态。
请注意,此示例代码可能需要进行一些调整才能适应您的硬件配置。
阅读全文