Как отобразить «аварийное оповещение» на ЖК-дисплее после истечения времени таймера

#c #arduino #lcd

#c #arduino #ЖК-дисплей

Вопрос:

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

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

1) Написанный вами код повторяет цикл за 42 секунды. Таким образом, вы проверяете, завершилось ли оповещение один раз за 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)amp;amp;(!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)amp;amp;(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 in выполняется почти каждую секунду вместе с проверкой сбоя.
Кроме того, я установил бит, который сообщает коду, что задержка оповещения уже началась, что гарантирует, что ваш код не сбросит его.

Комментарии:

1. Эй, Нитро, спасибо за ваше предложение, код отлично работает для зацикливания датчика и отображает пересечение до завершения оповещения. Однако, когда оповещение завершается, оно не отображает «Сбой впереди, соблюдайте осторожность», он отображает («intersectionad clearaution», это смешивает предупреждение. Он также не сбрасывает дисплей обратно на «Пересечение ясно» после устранения препятствия.

2. Похоже, я оставил функцию LCD.clear прокомментированной ранее. Попробуйте раскомментировать его. Кофе должен работать нормально