Как отобразить «предупреждение об аварии» на ЖК-дисплее после истечения таймера - PullRequest
0 голосов
/ 05 апреля 2019

Я делаю простую программу, которая запускает светофор в цикле, имеет ультразвуковой датчик и ЖК-дисплей 16x2. Концепция заключается в том, что если ультразвуковой датчик считывает значение расстояния, равное или меньшее предварительно установленного значения, он обнаруживает препятствие на перекрестке и запускает таймер. По истечении этого таймера на ЖК-дисплее появляется предупреждение. Но если значение расстояния превышает заданное значение во время работы таймера, оно останавливается. Для петли светофора я использую стандартную функцию задержки Arduino, например, Задержка (3000) ;. У меня проблема в том, что когда таймер заканчивает работу, на ЖК-дисплее ничего не отображается. Для таймера оповещения в программе я использую библиотеку с именем 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 Ответ

0 голосов
/ 05 апреля 2019

Это проблемы с тем, что вы делаете.

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;
}

Что делает этот код, так это то, что он никогда не блокирует функцию цикла, поэтому ваша функция pusle выполняется почти каждую секунду вместе с проверкой на сбой. Кроме того, я установил бит, который сообщает коду, что задержка оповещения уже началась, что гарантирует, что ваш код не сбрасывает его.

...