我正在制作一个简单的程序,它可以在循环中运行交通信号灯,并配有超声波传感器和16x2 LCD。该概念是如果超声波读取等于或低于预设值的距离值,则它检测交叉路口中的障碍物并且它启动计时器。当该计时器到期时,LCD显示屏会发出警报。但是,如果在计时器处于活动状态时距离值超过预设值,则会停止。对于交通灯循环,我使用标准的Arduino“延迟”功能,例如延迟(3000);.我遇到的问题是一旦定时器完成,LCD就不会显示任何内容。对于程序中的警报计时器,我正在使用名为millisDelay的库。该库允许计时器在不停止程序的情况下运行。
我尝试使用millisDelay库来运行交通灯而不是标准延迟功能。但这不起作用,因为它将交通信号灯置于一个恒定的循环中。
使用的库:
millisDelay.h和liquidCrystal.h
#include <millisDelay.h>
#include <LiquidCrystal.h>
int red = 22;
int yellow = 23;
int green = 24;
int red2 = 25;
int yellow2 = 26;
int green2 = 27;
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
long duration, inches, cm;
millisDelay alertdelay;
millisDelay ledDelay;
const int rs = 36, en = 38, d4 = 40, d5 = 42, d6 = 44, d7 = 46;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600); // Starting Serial Terminal
}
void loop() {
lcd.clear();
lcd.begin(16,2);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
if (cm>=11){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
}
else if (cm<7){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
alertdelay.start(7000);
Serial.println("delay started");
}
if (alertdelay.isFinished()) {
Serial.println("There is a crash up ahead");
lcd.setCursor(0,0);
lcd.print("Crash Up Ahead");
lcd.setCursor(0,1);
lcd.print("Use Caution");
}
delay(1000);
//'2'refers to intersection number 2
//green off,red2 on, yellow on for 3 seconds
digitalWrite(red2, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay(3000);
// turn off yellow1, then turn red on for 3 seconds
digitalWrite(yellow, LOW);
digitalWrite(red, HIGH);
delay(3000);
//after 3 seconds keep red 1 on and turn red2 off and green2 on,
//green2 stays on for 15 seconds to let traffic through
digitalWrite(red2, LOW);
digitalWrite(green2, HIGH);
delay(15000);
//after 15 seconds green2 turns off, yellow 2 turns on
//yellow2 turns on for 3 seconds,
digitalWrite(green2, LOW);
digitalWrite(yellow2, HIGH);
delay(3000);
//after 3 seconds, yellow2 turns off, and red 2 turns on
digitalWrite(yellow2, LOW);
digitalWrite(red2, HIGH);
delay(3000);
//3 seconds after red2 turns on, red 1 turns off and
//green 1 turns on for 3 seconds
//red2 stays on
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay(14000);
}
long microsecondsToCentimeters(long microseconds) {
return microseconds / 29 / 2;
}
这些是你正在做的事情的问题。
1)您编写的代码需要42秒才能循环遍历循环。因此,您检查alertDelay是否已经完成了42秒。 2)代码第二次到达循环开始时,你首先在检查它是否正在运行或结束之前再次设置alertDelay,这会重置它,因此,你的代码永远不会到达它显示崩溃。
这就是我要做的事情
#include <LiquidCrystal.h>
int red = 22;
int yellow = 23;
int green = 24;
int red2 = 25;
int yellow2 = 26;
int green2 = 27;
const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor
long duration, inches, cm;
long alertDisplayTime = millis(), nextLedSwitchTime = millis();
bool displayAlert = false;
int switch_number=-1;
const int rs = 36, en = 38, d4 = 40, d5 = 42, d6 = 44, d7 = 46;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
lcd.begin(16,2);
Serial.begin(9600); // Starting Serial Terminal
nextLedSwitchTime=1000+millis();
}
void loop() {
lcd.clear();
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
if (cm>=11){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
displayAlert=false;
}
else if ((cm<7)&&(!displayAlert)){
lcd.setCursor(0,0);
lcd.print("Intersection");
lcd.setCursor(0, 1);
lcd.print("Clear");
alertDisplayTime = millis()+7000;
displayAlert=true;
Serial.println("delay started");
}
if ((displayAlert==true)&&(alertDisplayTime<millis())) {
Serial.println("There is a crash up ahead");
lcd.setCursor(0,0);
lcd.print("Crash Up Ahead");
lcd.setCursor(0,1);
lcd.print("Use Caution");
displayAlert=false;
}
if(nextLedSwitchTime>=millis()){
return;
}
long delay_time=0;
switch_number++;
switch(switch_number){
case 0:
//'2'refers to intersection number 2
//green off,red2 on, yellow on for 3 seconds
digitalWrite(red2, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay_time=3000;
break;
case 1:
// turn off yellow1, then turn red on for 3 seconds
digitalWrite(yellow, LOW);
digitalWrite(red, HIGH);
delay_time=3000;
//after 3 seconds keep red 1 on and turn red2 off and green2 on,
break;
case 2:
//green2 stays on for 15 seconds to let traffic through
digitalWrite(red2, LOW);
digitalWrite(green2, HIGH);
//after 15 seconds green2 turns off, yellow 2 turns on
delay_time=15000;
break;
case 3:
//yellow2 turns on for 3 seconds,
digitalWrite(green2, LOW);
digitalWrite(yellow2, HIGH);
//after 3 seconds, yellow2 turns off, and red 2 turns on
delay_time=3000;
break;
case 4:
digitalWrite(yellow2, LOW);
digitalWrite(red2, HIGH);
//3 seconds after red2 turns on, red 1 turns off and
delay_time=3000;
break;
case 5:
//green 1 turns on for 3 seconds
//red2 stays on
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay_time = 14000;
switch_number=-1;
}
nextLedSwitchTime = millis()+delay_time;
}
long microsecondsToCentimeters(long microseconds) {
return microseconds / 29 / 2;
}
这段代码的作用是它永远不会阻塞循环函数,所以你的函数几乎每秒都执行一次,同时检查崩溃。此外,我已经设置了一个位,告诉代码警报延迟已经开始,这可以确保您的代码不会重置它。