Включение подсветки на 5 секунд по событию без dellay

itehno
Offline
Зарегистрирован: 18.04.2015

Приветствую всех.

Прошу помощи в данном вопросе. У меня есть программа, где требуется включать подсветку дисплея на некоторое время, после срабатывания определенного условия.

Есть массив, в уоторый постоянно записывается 1, но изредка меняется на 0. Нужно сделать так, что бы при кратковременном изменении 1 на 0 включалась подсветка, но при этом не останавливалось выполение основного кода.

Смотрел примерры ООП со светодиодами, но так и не смог в связи с недостатком знаний адаптировать его под себя.

Вот короткий необходимый пример моего кода:

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27);
unsigned long a[5] = {-1,-1,-1,-1,-1};  // Переменная для хранения данных буфера функции Wire.read

void setup() {
  Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера
  lcd.begin(16, 2); // Количество символов и строк дисплея
  lcd.setBacklight(0);  // Устанавливаем яркость подсветки
  lcd.clear();  // Очищаемь экран и устанавливаем курсор в позицию 0, 0
}

void loop() {

    if(a[1] == 0){print_read = "Unstable";} else {print_read = "";}

    if(a[1] == 0){lcd.setBacklight(1);}else{lcd.setBacklight(0);}
   
    lcd.setCursor(2,0); lcd.print("                ");
    lcd.setCursor(4,0); lcd.print(print_read);
    lcd.setCursor(0,1); lcd.print("TMP = ");
    lcd.setCursor(6,1); lcd.print("     ");
    lcd.setCursor(6,1); lcd.print(VES);


    delay(400);
}

Условие if(a[1] == 0){lcd.setBacklight(1);}else{lcd.setBacklight(0);} включает подсветку, но только на тот период времени, пока в массиве a[1] 0 меняется на 1.

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ну как-то так, навскидку:

uint8_t lastState;

void setup()
{
	lastState = a[1];
}

void loop()
{
	uint8_t curState = a[1];

	if(lastState != curState)
	{
		// изменение 1 на 0 - включаем подсветку
		if(lastState == 1 && curState == 0) { lcd.setBacklight(1); }
		else { lcd.setBacklight(0); } // выключаем подсветку

		lastState = curState;
	}
}

 

itehno
Offline
Зарегистрирован: 18.04.2015

DIYMan пишет:

Ну как-то так, навскидку:

uint8_t lastState;

void setup()
{
	lastState = a[1];
}

void loop()
{
	uint8_t curState = a[1];

	if(lastState != curState)
	{
		// изменение 1 на 0 - включаем подсветку
		if(lastState == 1 && curState == 0) { lcd.setBacklight(1); }
		else { lcd.setBacklight(0); } // выключаем подсветку

		lastState = curState;
	}
}

 

 

Спасибо за оперативный ответ, но разве моё условие не делает ту же самую задачу?

В вашем решении нет задержки выключения подсветки. В массиве значение с 1 на 0 меняется кратковременно, следовательно и подсветка включается кратковременно на этот период. При создании темы допустил ошибку. Должно было быть так: if(a[1] != 0){lcd.setBacklight(1);}else{lcd.setBacklight(0);}

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

itehno пишет:

В вашем решении нет задержки выключения подсветки. В массиве значение с 1 на 0 меняется кратковременно, следовательно и подсветка включается кратковременно на этот период. 

Ошибаетесь - есть. Подсветка включается именно тогда, когда происходит переход 1 => 0, в противных случаях - она выключается. Причём проверка происходит ТОЛЬКО при смене состояния, если состояние не меняется - ничего не происходит. Именно для этого там есть дополнительная переменная. 

itehno
Offline
Зарегистрирован: 18.04.2015

DIYMan пишет:

itehno пишет:

В вашем решении нет задержки выключения подсветки. В массиве значение с 1 на 0 меняется кратковременно, следовательно и подсветка включается кратковременно на этот период. 

Ошибаетесь - есть. Подсветка включается именно тогда, когда происходит переход 1 => 0, в противных случаях - она выключается. Причём проверка происходит ТОЛЬКО при смене состояния, если состояние не меняется - ничего не происходит. Именно для этого там есть дополнительная переменная. 

Все верно, но нет задержки в 5 секунд. 1 на 0 меняется кратковременно. Буквально на 1/2 секунды.

Муж_Долговой
Муж_Долговой аватар
Offline
Зарегистрирован: 07.10.2018
[code]
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27);
unsigned long a[5] = {-1,-1,-1,-1,-1};  // Переменная для хранения данных буфера функции Wire.read
int flag = 0; //Для Запоминания события
void setup() {
  Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера
  lcd.begin(16, 2); // Количество символов и строк дисплея
  lcd.setBacklight(0);  // Устанавливаем яркость подсветки
  lcd.clear();}  // Очищаемь экран и устанавливаем курсор в позицию 0, 0
void loop() { 
    if(a[1] == 0){
   // print_read = "Unstable";  // компилятор не пропускает print_read. Пожтому временно закомментил
    flag = 1;}   // Запоминаем событие
    else {//print_read = ""; // компилятор не пропускает print_read. Пожтому временно закомментил
  }
    if(flag == 1 && round(millis()/1000%5 != 0)){ //Здесь 5 секунд
      lcd.setBacklight(1);}
      else{lcd.setBacklight(0);
       flag = 0;}   // Забываем событие
    lcd.setCursor(2,0); lcd.print("                ");
   // lcd.setCursor(4,0); lcd.print(print_read);    // компилятор не пропускает print_read. Пожтому временно закомментил
    lcd.setCursor(0,1); lcd.print("TMP = ");
    lcd.setCursor(6,1); lcd.print("     ");
    lcd.setCursor(6,1); lcd.print("VES");
    delay(400);}
[/code]

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014
void setup(){
}

void loop(){
  static uint32_t timer;
  static bool backlightState=false;
  if(a[1]==1){ 
     timer=millis();
     if(!backlightState){
        lcd.setBacklight(1);
        backlightState=true;
     }
  } else if (backlightState && millis()-timer>5000){ // выключаем подсветку
     lcd.setBacklight(0); 
     backlightState=false;
  }
}

 

void setup(){
}

void loop(){
  static uint32_t timer;
  if(a[1]==1){ 
     timer=millis();
     lcd.setBacklight(1);
  } else if (millis()-timer>5000){
     lcd.setBacklight(0); 
  }
}

 

itehno
Offline
Зарегистрирован: 18.04.2015

Спасибо всем вам огромное. Обязательно проверю вариант каждого из Вас завтра на работе.

Вот, как я попробовал сделать, но работает или нет, также проверю только завтра. 

Ваши варианты, безусловно, менее громоздкие и гораздо удобнее, чем мой.

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27);
unsigned long a[5] = {-1,-1,-1,-1,-1};  // Переменная для хранения данных буфера функции Wire.read

class B_LCD {
public:
  B_LCD(int VKL);
  void On();
private:
  int t_VKL;
};

B_LCD::B_LCD(int VKL)
  : t_VKL(VKL) {
}

void B_LCD::On() {
  lcd.setBacklight(1);
  delay(t_VKL);
  lcd.setBacklight(0);
}
B_LCD LCD(5000);

void setup() {
  Wire.begin();
  lcd.begin(16, 2);
  lcd.setBacklight(0);
  lcd.clear();
}

void loop() {

    if(a[1] == 0){print_read = "Unstable";} else {print_read = "";}

    if(a[1] != 0){LCD.On();}
   
    lcd.setCursor(2,0); lcd.print("                ");
    lcd.setCursor(4,0); lcd.print(print_read);
    lcd.setCursor(0,1); lcd.print("TMP = ");
    lcd.setCursor(6,1); lcd.print("     ");
    lcd.setCursor(6,1); lcd.print(VES);


    delay(400);
}

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Вы считаете , что класс живет в другом потоке ? Это ошибочно.

itehno
Offline
Зарегистрирован: 18.04.2015

brokly пишет:

Вы считаете , что класс живет в другом потоке ? Это ошибочно.

Я еще пока только учусь. :) И я действительно думал, что это так.

itehno
Offline
Зарегистрирован: 18.04.2015

Спасибо уважаемым DIYMan, Муж_Долговой и brokly за помощь. Все получилось. Разобрал ваши примеры и пополнил свой багаж знаний. Хорошего вам дня.

 

Green
Offline
Зарегистрирован: 01.10.2015

Хех. Мне тут заказчик попросил написать СКЕТЧ что бы светодиод зажигался через 45 сек. после включения... Этто чтотто!)