Как сделать несколько действий на определённое время в if

Lexan
Offline
Зарегистрирован: 12.02.2016

Всем доброго времени суток!

Нужна помощ. Решил собрать вентиляцию для гаража . Чтобы включались два вентилятора через 2 РЕЛЕ при превышении загазованасти воздуха выше 150, на 3 минуты. И при этом срабатывал звукавой зумер и мигал светодиод .Светодиод и зумер должен включатся при условии что показания выше 150 и выключатся ниже 150. Ну с эттим я справился. 

Но как обяснить двум реле (RELE1, RELE2) включатся при показании выше 150 на 3 минуты ???

 

#define AIn A0 //Вход датчика газа
#define alarm 4 //Зумер
#define RELE1 2 // Реле1
#define RELE2 3 // Реле2
#define LED 5 //светодиод

void setup() {
  
 pinMode(AIn, INPUT); //аналоговый А0 он же AIn будет работать как вход 
 Serial.begin(9600); //Серийный порт скорость 9600
 pinMode(alarm, OUTPUT);
 pinMode(RELE1, OUTPUT);
 pinMode(RELE2, OUTPUT);
 pinMode(LED, OUTPUT);
}

void loop() {
  
   Serial.println(analogRead(AIn));
  int SensorData = analogRead(AIn);
  if (SensorData > 150 and SensorData < 1023) // Показания газа
  {
    digitalWrite(alarm, HIGH); // включили зумер
    digitalWrite(LED, HIGH); // Включили светодиод  диод
   delay (100);              //Задержка 100 мсек
    digitalWrite(alarm, LOW);//Выключим зумер
    digitalWrite(LED, LOW);   // Включили светодиод
  }
 
}

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015
Lexan
Offline
Зарегистрирован: 12.02.2016

да уж для новичка это сложновато :(

а какогото решения по проще я так понял несуществует, да?

А где взять библеотеку? я создал папку class_noDELAY

 потом создал текстовый фаил с названием class_noDELAY.h

но что в него записать нужно???

Вот это

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для delay без delay().
// динамически управляемая генерация событий с динамически изменяемым интервалом времени между событиями.

class noDELAY {

public:
unsigned long previous;
unsigned long interval;
boolean s;
boolean push;
boolean push_tick;

noDELAY() {
previous  = millis();
s         =        0;
push      =        0;
push_tick =        0;
}

void start()                        {s = 1;}
void  stop()                        {s = 0;}
void  read(unsigned long _interval) {
              interval = _interval;
unsigned long current  =  millis();
push_tick =     0;
if (s                  ==        0) {previous = current;}
if (current - previous >  interval) {previous = current;
push_tick =     1;
push      = !push;
}
}

};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

vde69
Offline
Зарегистрирован: 10.01.2016
#define AIn A0 //Вход датчика газа
#define alarm 4 //Зумер
#define RELE1 2 // Реле1
#define RELE2 3 // Реле2
#define LED 5 //светодиод

const unsigned long TIME_STEP = 180000; // время шага 
unsigned long time_last_step = 0;


void setup() {
  
 pinMode(AIn, INPUT); //аналоговый А0 он же AIn будет работать как вход 
 Serial.begin(9600); //Серийный порт скорость 9600
 pinMode(alarm, OUTPUT);
 pinMode(RELE1, OUTPUT);
 pinMode(RELE2, OUTPUT);
 pinMode(LED, OUTPUT);
}

void loop() {
  unsigned long time_loop_new;  
  unsigned long time_pause;     
  time_loop_new = millis();     // получим время начала цикла

  time_pause = getDelayTime(time_last_step, time_loop_new);
  if (time_pause > TIME_STEP) { 
    time_last_step = time_loop_new;
    // тут делаем счастье ..........................
  }

}


//*************************************************************************************************
// процедура сравнивает два времени и возвращает разницу в виде числа, учитывает переход времени через 0
//   start_time - начальное время
//   end_time - конечное время
//
// !!!! процедура чуствительна к разрядности исполняемого кода !!!!
// !!!! процедура может работать неправильно при двойном переходе времени через 0 !!!!
//*************************************************************************************************
unsigned long getDelayTime(unsigned long start_time, unsigned long end_time)
{
  unsigned long result;
  if (start_time <= end_time) {
    result = end_time - start_time;
  }
  else {
    result = 4294967295 - end_time + start_time;
  }
  return result;
}


 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

vde69, не вводи людей в заблуждение, должно быть так:

//*************************************************************************************************
// процедура сравнивает два времени и возвращает разницу в виде числа, учитывает переход времени через 0
//   start_time - начальное время
//   end_time - конечное время
//
// процедура НЕ чувствительна к разрядности исполняемого кода !!!!
//*************************************************************************************************
unsigned long getDelayTime(unsigned long start_time, unsigned long end_time)
{
  return end_time - start_time;
}

 

Lexan
Offline
Зарегистрирован: 12.02.2016

Ребят я теперь совсем запутался. Как мне теперь туда превязать 2 реле со светодиодом и зумером, ведь они все  должны срабатывать только при условии что с датчика приходит значение от 150 до 1023.

Куда вписать условия включения всего механизма?

if (SensorData > 150 and SensorData < 1023) /*после этого должны включатся RELE1, RELE2 на 3 минуты и мигать светодиод и зумер с интервалом 100 мсек тоже на 3 минуты*/

И теперь я так понял delay использовать нельзя? Но как в таком случае светодиод и зумер будут мигать и звинеть? Как их прерывать на 100 мсек не мешая двум реле??

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

взять пример BlinkWithoutDelay и на его основе сделать конечные автоматы:


#define SENSOR_PIN     A1    // пин для подключения сенсора
#define SENSOR_MIN     150   // пороговые значения сенсора для срабатывания
#define SENSOR_MAX     1023
#define LED2_PIN       8     // пин для подключения светодиода №2
#define RELAY2_PIN     10    // пин для подключения реле №2
#define BUZZER_PIN     9     // пин для подключения зуммера
#define BEEP_INTERVAL  200   // частота включения зуммера, мсек
#define FLASH_INTERVAL 250   // частота включения светодиода, мсек
#define BUZZER_TIMEOUT 300   // длительность звучания зуммера, сек
#define LED2_TIMEOUT   600   // длительность мигания светодиода №2, сек
#define RELAY2_TIMEOUT 300   // длительность включения реле №2, сек
#define ON             HIGH  // синонимы для реле (если реле инверсное - поставить LOW)
#define OFF            LOW   // синонимы для реле (если реле инверсное - поставить HIGH)

boolean relay2Enable = false;// флаг состояния реле 2
boolean buzzerEnable = false;// флаг состояния зуммера
boolean led2Enable = false;  // флаг состояния светодиода 2


void setup() 
{
  pinMode(RELAY2_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
}


void loop() 
{
  unsigned int sensorData;               // текущее значение с сенсора
  static unsigned long relay2StartTime;  // внутренние счетчики времени
  static unsigned long led2StartTime;
  static unsigned long buzzerStartTime;

  sensorData = analogRead(SENSOR_PIN);

  if(sensorData > SENSOR_MIN && sensorData < SENSOR_MAX) // проверка пороговых значений
  {
    if(relay2Enable == false)     // если до этого реле №2 было выключено
    {
      relay2Enable = true;        // разрешаем включение реле №2
      relay2StartTime = millis(); // запускаем счетчик времени
    }

    if(led2Enable == false)
    {
      led2Enable = true;          // разрешаем включение светодиода №2
      led2StartTime = millis();
    }

    if(buzzerEnable == false)
    {
      buzzerEnable = true;        // разрешаем включение зуммера
      buzzerStartTime = millis();
    }
  }
  else // используется, если нужно моментальное отключение 
  {    // при выходе за пороговые значения, а не по истечении времени
    // relay2Enable = false;     // запрещаем включение реле №2
    // led2Enable = false;       // запрещаем включение светодиода №2
    // buzzerEnable = false;     // запрещаем включение зуммера
  }

  // проверка на время отключения
  if(relay2Enable && millis()-relay2StartTime > RELAY2_TIMEOUT*1000) relay2Enable = false;
  if(led2Enable   && millis()-led2StartTime   > LED2_TIMEOUT*1000)   led2Enable = false;
  if(buzzerEnable && millis()-buzzerStartTime > BUZZER_TIMEOUT*1000) buzzerEnable = false;

  // взаимодействие с периферией
  digitalWrite(RELAY2_PIN, relay2Enable); // управляем реле №2
  if(led2Enable)   flash(LED2_PIN);       // если надо - моргаем светодиодом №2
  if(buzzerEnable) siren();               // если надо - пищим
}


void siren() // кричим
{
  static unsigned long beepTime;
  if(millis() - beepTime > BEEP_INTERVAL)
  {
    digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
    beepTime = millis();
  }
}


void flash(byte pin) // мигаем указанным светиком
{
  static unsigned long flashTime;
  if(millis() - flashTime > FLASH_INTERVAL)
  {
    digitalWrite(pin, !digitalRead(pin));
    flashTime = millis();
  }
}

Хотя у меня есть такое подозрение, что если взять Велосипед от Клапауция и вникнуть в те абстракции, задачу можно реализовать более изящно.

Lexan
Offline
Зарегистрирован: 12.02.2016

Спасибо друг, буду пробовать...

Lexan
Offline
Зарегистрирован: 12.02.2016

Попробовал внести свои параметры пока не стал добавлять вторую реле.

Но при кампиляцыи выходит ошибка в трёх строчках (68,69,70)

Это видимо данные об ошибке: 69:62: warning: integer overflow in expression [-Woverflow]

не пойму что конкретно там не так?

#define SENSOR_PIN     A1    // пин для подключения сенсора
#define SENSOR_MIN     150   // пороговые значения сенсора для срабатывания
#define SENSOR_MAX     1023  // макс значение сенсора
#define LED2_PIN       5     // пин для подключения светодиода №2
#define RELAY2_PIN     3    // пин для подключения реле №2
#define BUZZER_PIN     4     // пин для подключения зуммера
#define BEEP_INTERVAL  100   // частота включения зуммера, мсек
#define FLASH_INTERVAL 100   // частота включения светодиода, мсек
#define BUZZER_TIMEOUT 180   // длительность звучания зуммера, сек
#define LED2_TIMEOUT   180   // длительность мигания светодиода №2, сек
#define RELAY2_TIMEOUT 180   // длительность включения реле №2, сек
#define ON             HIGH  // синонимы для реле (если реле инверсное - поставить LOW)
#define OFF            LOW   // синонимы для реле (если реле инверсное - поставить HIGH)

boolean relay2Enable = false;// флаг состояния реле 2
boolean buzzerEnable = false;// флаг состояния зуммера
boolean led2Enable = false;  // флаг состояния светодиода 2


void setup() 
{
  Serial.begin(9600); //Серийный порт скорость 9600
  pinMode(RELAY2_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
}


void loop() 
{
  unsigned int sensorData;               // текущее значение с сенсора
  static unsigned long relay2StartTime;  // внутренние счетчики времени
  static unsigned long led2StartTime;
  static unsigned long buzzerStartTime;
   
   Serial.println(analogRead(SENSOR_PIN));
  sensorData = analogRead(SENSOR_PIN);

  if(sensorData > SENSOR_MIN && sensorData < SENSOR_MAX) // проверка пороговых значений
  {
    if(relay2Enable == false)     // если до этого реле №2 было выключено
    {
      relay2Enable = true;        // разрешаем включение реле №2
      relay2StartTime = millis(); // запускаем счетчик времени
    }

    if(led2Enable == false)      //если светодиод был выключен
    {
      led2Enable = true;          // разрешаем включение светодиода №2
      led2StartTime = millis();   // запуск счетчика
    }

    if(buzzerEnable == false)     //еслее бузер был выключен
    {
      buzzerEnable = true;        // разрешаем включение зуммера
      buzzerStartTime = millis(); // запуск счетчика
    }
  }
  else // используется, если нужно моментальное отключение 
  {    // при выходе за пороговые значения, а не по истечении времени
    // relay2Enable = false;     // запрещаем включение реле №2
    // led2Enable = false;       // запрещаем включение светодиода №2
    // buzzerEnable = false;     // запрещаем включение зуммера
  }

  // проверка на время отключения
  if(relay2Enable && millis()-relay2StartTime > RELAY2_TIMEOUT*1000) relay2Enable = false;
  if(led2Enable   && millis()-led2StartTime   > LED2_TIMEOUT*1000)   led2Enable = false;
  if(buzzerEnable && millis()-buzzerStartTime > BUZZER_TIMEOUT*1000) buzzerEnable = false;

  // взаимодействие с периферией
  digitalWrite(RELAY2_PIN, relay2Enable); // управляем реле №2
  if(led2Enable)   flash(LED2_PIN);       // если надо - моргаем светодиодом №2
  if(buzzerEnable) siren();               // если надо - пищим
}


void siren() // кричим
{
  static unsigned long beepTime;
  if(millis() - beepTime > BEEP_INTERVAL)
  {
    digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
    beepTime = millis();
  }
}


void flash(byte pin) // мигаем указанным светиком
{
  static unsigned long flashTime;
  if(millis() - flashTime > FLASH_INTERVAL)
  {
    digitalWrite(pin, !digitalRead(pin));
    flashTime = millis();
  }
}

 

KOMAPbI4
KOMAPbI4 аватар
Offline
Зарегистрирован: 22.03.2016

Попрбовал ваш код - скомпелировался и залился без каких либо ошибок (Ардуино 1.6.8)

Lexan
Offline
Зарегистрирован: 12.02.2016

А у меня вот что пишет красным после компелирования (1.6.8):

C:\Users\.........................................ino:68:64: warning: integer overflow in expression [-Woverflow]
 
   if(relay2Enable && millis()-relay2StartTime > RELAY2_TIMEOUT*1000) relay2Enable = false;
 
                                                                ^
 
C:\Users\..............................................ino:69:62: warning: integer overflow in expression [-Woverflow]
 
   if(led2Enable   && millis()-led2StartTime   > LED2_TIMEOUT*1000)   led2Enable = false;
 
                                                              ^
 
C:\Users\.............................ino:70:64: warning: integer overflow in expression [-Woverflow]
 
   if(buzzerEnable && millis()-buzzerStartTime > BUZZER_TIMEOUT*1000) buzzerEnable = false;
Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

В строках 9-11 добавь UL к 180:   180UL

Lexan
Offline
Зарегистрирован: 12.02.2016

Спасибо всё получилось. Буду проверять скеч на деле ;)

А что означает это UL после 180 секунд?

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Литерал UL == unsigned long

http://mycpp.ru/cpp/book/c03_1.html

Lexan
Offline
Зарегистрирован: 12.02.2016

Эхх только обрадовался но появилась новая проблема ((

Теперь после запуска значение датчика резко подпрыгивает гдето от 149-150 до 230-240.

Думал датчик накрылся, но когда заливаю обычный скеч без реле и временных настроек, то паказывает нормально значение около 50.

Вот старый скеч на котором данные датчика правельные(просто для примера):

#define AIn A0
#define alarm 4
#define LED 5

void setup() {
  
 pinMode(AIn, INPUT); //аналоговый А0 онже AIn будет работать как вход
 Serial.begin(9600); //Серийный порт скорость 9600
 pinMode(alarm, OUTPUT);
 pinMode(RELE1, OUTPUT);
 pinMode(RELE2, OUTPUT);
 pinMode(LED, OUTPUT);
}

void loop() {
  
   Serial.println(analogRead(AIn));
  int SensorData = analogRead(AIn);
  if (SensorData > 150 and SensorData < 1023) // Паказания газа
  {
    digitalWrite(alarm, HIGH); // включили пищалку
    digitalWrite(LED, HIGH); // Включили зеленый диод
   delay (100);              //Задержка 100мсек
    digitalWrite(alarm, LOW);//Выключим пищалку
    digitalWrite(LED, LOW);   // Включили светодиод
  }

А вот нужный скеч на котором датчик врет. И почемуто раз уж значение сразу выше 150 получаются то должно по задумке включится реле. А оно щелкнит один раз и зумер также, и всё на этом. А значения датчика так и висит 230-240...

#define SENSOR_PIN     A1    // пин для подключения сенсора
#define SENSOR_MIN     150   // пороговые значения сенсора для срабатывания
#define SENSOR_MAX     1023  // макс значение сенсора
#define LED2_PIN       5     // пин для подключения светодиода №2
#define RELAY2_PIN     3    // пин для подключения реле №2
#define BUZZER_PIN     4     // пин для подключения зуммера
#define BEEP_INTERVAL  100   // частота включения зуммера, мсек
#define FLASH_INTERVAL 100   // частота включения светодиода, мсек
#define BUZZER_TIMEOUT 180UL   // длительность звучания зуммера, сек
#define LED2_TIMEOUT   180UL   // длительность мигания светодиода №2, сек
#define RELAY2_TIMEOUT 180UL   // длительность включения реле №2, сек
#define ON             LOW  // синонимы для реле (если реле инверсное - поставить LOW)
#define OFF            HIGH   // синонимы для реле (если реле инверсное - поставить HIGH)

boolean relay2Enable = false;// флаг состояния реле 2
boolean buzzerEnable = false;// флаг состояния зуммера
boolean led2Enable = false;  // флаг состояния светодиода 2


void setup() 
{
  Serial.begin(9600); //Серийный порт скорость 9600
  pinMode(RELAY2_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
}


void loop() 
{
  unsigned int sensorData;               // текущее значение с сенсора
  static unsigned long relay2StartTime;  // внутренние счетчики времени
  static unsigned long led2StartTime;
  static unsigned long buzzerStartTime;
   
   Serial.println(analogRead(SENSOR_PIN));
  sensorData = analogRead(SENSOR_PIN);

  if(sensorData > SENSOR_MIN && sensorData < SENSOR_MAX) // проверка пороговых значений
  {
    if(relay2Enable == false)     // если до этого реле №2 было выключено
    {
      relay2Enable = true;        // разрешаем включение реле №2
      relay2StartTime = millis(); // запускаем счетчик времени
    }

    if(led2Enable == false)      //если светодиод был выключен
    {
      led2Enable = true;          // разрешаем включение светодиода №2
      led2StartTime = millis();   // запуск счетчика
    }

    if(buzzerEnable == false)     //еслее бузер был выключен
    {
      buzzerEnable = true;        // разрешаем включение зуммера
      buzzerStartTime = millis(); // запуск счетчика
    }
  }
  else // используется, если нужно моментальное отключение 
  {    // при выходе за пороговые значения, а не по истечении времени
    // relay2Enable = false;     // запрещаем включение реле №2
    // led2Enable = false;       // запрещаем включение светодиода №2
    // buzzerEnable = false;     // запрещаем включение зуммера
  }

  // проверка на время отключения
  if(relay2Enable && millis()-relay2StartTime > RELAY2_TIMEOUT*1000) relay2Enable = false;
  if(led2Enable   && millis()-led2StartTime   > LED2_TIMEOUT*1000)   led2Enable = false;
  if(buzzerEnable && millis()-buzzerStartTime > BUZZER_TIMEOUT*1000) buzzerEnable = false;

  // взаимодействие с периферией
  digitalWrite(RELAY2_PIN, relay2Enable); // управляем реле №2
  if(led2Enable)   flash(LED2_PIN);       // если надо - моргаем светодиодом №2
  if(buzzerEnable) siren();               // если надо - пищим
}


void siren() // кричим
{
  static unsigned long beepTime;
  if(millis() - beepTime > BEEP_INTERVAL)
  {
    digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
    beepTime = millis();
  }
}


void flash(byte pin) // мигаем указанным светиком
{
  static unsigned long flashTime;
  if(millis() - flashTime > FLASH_INTERVAL)
  {
    digitalWrite(pin, !digitalRead(pin));
    flashTime = millis();
  }
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Цитата:
Теперь после запуска значение датчика резко подпрыгивает гдето от 149-150 до 230-240.

Думал датчик накрылся, но когда заливаю обычный скеч без реле и временных настроек, то паказывает нормально значение около 50.

Видимо разница в этом:

#define AIn A0 - в первом

#define SENSOR_PIN A1 - во втором

Lexan
Offline
Зарегистрирован: 12.02.2016

Да действительно, так глупо прозивал )).  Заменил A1 на A0 и датчик стал показывать нормально.

Но почемуто всё наоборот. При запуске реле сразуже включается хоть значения датчика и около 50. А после того как значения подымаются выше 150 оно выключается. Ну и по прошествию 3 минут оно пытается включится, но вместо этого немного моргнёт и зависает монитор порта и вместе с ним я так понимаю сама ардуина. 

Я уже подумал что нужно поменять местами (HIGH и LOW) в 12-ой и 13-ой строчке. Но это не помагло, работало точно также...

 

Нписал простенький скеч для проверки реле работает (выше 150 ВКЛ; а ниже 150 ВЫКЛ).

#define AIn A0
#define RELAY 3

void setup() {
  
 pinMode(AIn, INPUT); //аналоговый А0 онже AIn будет работать как вход
 Serial.begin(9600); //Серийный порт скорость 9600
 pinMode(RELAY, OUTPUT);
}

void loop() {
  
   Serial.println(analogRead(AIn));
  int SensorData = analogRead(AIn);
  if (SensorData > 150 and SensorData < 1023) // Паказания газа
  {
      digitalWrite(RELAY, LOW); // Включили реле
   
  }
  else
  {
    digitalWrite(RELAY, HIGH);   // Выключили реле
  }
}

 

 

 

 

Что тогда заставляет её сразуже включится при нормальных показаниях не превышающих условие ???

#define SENSOR_PIN     A0    // пин для подключения сенсора
#define SENSOR_MIN     150   // пороговые значения сенсора для срабатывания
#define SENSOR_MAX     1023  // макс значение сенсора
#define LED_PIN       5     // пин для подключения светодиода
#define RELAY_PIN     3    // пин для подключения реле
#define BUZZER_PIN     4     // пин для подключения зуммера
#define BEEP_INTERVAL  100   // частота включения зуммера, мсек
#define FLASH_INTERVAL 100   // частота включения светодиода, мсек
#define BUZZER_TIMEOUT 180UL   // длительность звучания зуммера, сек
#define LED_TIMEOUT   180UL   // длительность мигания светодиода, сек
#define RELAY_TIMEOUT 180UL   // длительность включения реле, сек
#define ON             LOW  // синонимы для реле (если реле инверсное - поставить LOW)
#define OFF            HIGH   // синонимы для реле (если реле инверсное - поставить HIGH)

boolean relayEnable = false;// флаг состояния реле
boolean buzzerEnable = false;// флаг состояния зуммера
boolean ledEnable = false;  // флаг состояния светодиода


void setup() 
{
  Serial.begin(9600); //Серийный порт скорость 9600
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
}


void loop() 
{

  unsigned int sensorData;               // текущее значение с сенсора
  static unsigned long relayStartTime;  // внутренние счетчики времени
  static unsigned long ledStartTime;
  static unsigned long buzzerStartTime;

   Serial.println(analogRead(SENSOR_PIN));
     sensorData = analogRead(SENSOR_PIN);

  if(sensorData > SENSOR_MIN && sensorData < SENSOR_MAX) // проверка пороговых значений
  {
    if(relayEnable == false)     // если до этого реле было выключено
    {
      relayEnable = true;        // разрешаем включение реле
      relayStartTime = millis(); // запускаем счетчик времени
    }

    if(ledEnable == false)      //если светодиод был выключен
    {
      ledEnable = true;          // разрешаем включение светодиода
      ledStartTime = millis();   // запуск счетчика
    }

    if(buzzerEnable == false)     //еслее бузер был выключен
    {
      buzzerEnable = true;        // разрешаем включение зуммера
      buzzerStartTime = millis(); // запуск счетчика
    }
  }
  else // используется, если нужно моментальное отключение 
  {    // при выходе за пороговые значения, а не по истечении времени
    // relayEnable = false;     // запрещаем включение реле
    // ledEnable = false;       // запрещаем включение светодиода
    // buzzerEnable = false;     // запрещаем включение зуммера
  }

  // проверка на время отключения
  if(relayEnable && millis()-relayStartTime > RELAY_TIMEOUT*1000) relayEnable = false;
  if(ledEnable   && millis()-ledStartTime   > LED_TIMEOUT*1000)   ledEnable = false;
  if(buzzerEnable && millis()-buzzerStartTime > BUZZER_TIMEOUT*1000) buzzerEnable = false;

  // взаимодействие с периферией
  digitalWrite(RELAY_PIN, relayEnable); // управляем реле
  if(ledEnable)   flash(LED_PIN);       // если надо - моргаем светодиодом
  if(buzzerEnable) siren();               // если надо - пищим
}


void siren() // кричим
{
  static unsigned long beepTime;
  if(millis() - beepTime > BEEP_INTERVAL)
  {
    digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
    beepTime = millis();
  }
}


void flash(byte pin) // мигаем указанным светиком
{
  static unsigned long flashTime;
  if(millis() - flashTime > FLASH_INTERVAL)
  {
    digitalWrite(pin, !digitalRead(pin));
    flashTime = millis();
  }
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

замени строку 73 на

digitalWrite(RELAY2_PIN, !relay2Enable); // управляем реле №2

У тебя инверсные реле, включаются по уровню LOW.

P.S. строки 12-13 можно выкинуть, они не используются.

Lexan
Offline
Зарегистрирован: 12.02.2016

Спасибо, оно теперь хоть включатся при старте перестало.  :)

При достижении значения сенсора 150 реле включается но на одну секунду, затем выключается, монитор порта зависает и ардуина. ((

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Lexan пишет:

А где взять библеотеку? я создал папку class_noDELAY

 потом создал текстовый фаил с названием class_noDELAY.h

#23

Lexan
Offline
Зарегистрирован: 12.02.2016

Извиняюсь я не понял, так в моём случае был нужен class BUTTON.h или class_noDELAY.h ??

там же вроде разные библиотеки или это одно и то же?

 

И ещё вопрос по решению которое предложил ув.Tomasina

Как доработать этот вариант, так как он для моего  "огромного" опыта :) немного понятнее ? А то я чтото в тупике. Вроде  понял как работает эта система с тремя счетчиками. Но немагу найти почему она не срабатывает как надо  (через сикунду после включения реле оно выключается и ардуино зависает, светодиод не мигает и бузер молчит).

Какой раз перечитываю скеч, ну всё вроде сходится. Но ведь такого же небывает. Или у меня опыта маловато и я чтото пропускаю мимо глаз.

У меня уже даже газ в зажигалке для опытов кончился. )))

 

#define SENSOR_PIN     A0    // пин для подключения сенсора
#define SENSOR_MIN     150   // пороговые значения сенсора для срабатывания
#define SENSOR_MAX     1023  // макс значение сенсора
#define LED_PIN       9     // пин для подключения светодиода
#define RELAY_PIN     3    // пин для подключения реле
#define BUZZER_PIN     4     // пин для подключения зуммера
#define BEEP_INTERVAL  100   // частота включения зуммера, мсек
#define FLASH_INTERVAL 100   // частота включения светодиода, мсек
#define BUZZER_TIMEOUT 180UL   // длительность звучания зуммера, сек
#define LED_TIMEOUT   180UL   // длительность мигания светодиода, сек
#define RELAY_TIMEOUT 180UL   // длительность включения реле, сек

boolean relayEnable = false;// флаг состояния реле
boolean buzzerEnable = false;// флаг состояния зуммера
boolean ledEnable = false;  // флаг состояния светодиода


void setup() 
{
  Serial.begin(9600); //Серийный порт скорость 9600
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
}


void loop() 
{

  unsigned int sensorData;               // текущее значение с сенсора
  static unsigned long relayStartTime;  // внутренние счетчики времени
  static unsigned long ledStartTime;
  static unsigned long buzzerStartTime;

   Serial.println(analogRead(SENSOR_PIN));
     sensorData = analogRead(SENSOR_PIN);

  if(sensorData > SENSOR_MIN && sensorData < SENSOR_MAX) // проверка пороговых значений
  {
    if(relayEnable == false)     // если до этого реле было выключено
    {
      relayEnable = true;        // разрешаем включение реле
      relayStartTime = millis(); // запускаем счетчик времени
    }

    if(ledEnable == false)      //если светодиод был выключен
    {
      ledEnable = true;          // разрешаем включение светодиода
      ledStartTime = millis();   // запуск счетчика
    }

    if(buzzerEnable == false)     //еслее бузер был выключен
    {
      buzzerEnable = true;        // разрешаем включение зуммера
      buzzerStartTime = millis(); // запуск счетчика
    }
  }
  else // используется, если нужно моментальное отключение 
  {    // при выходе за пороговые значения, а не по истечении времени
    // relayEnable = false;     // запрещаем включение реле
    // ledEnable = false;       // запрещаем включение светодиода
    // buzzerEnable = false;     // запрещаем включение зуммера
  }

  // проверка на время отключения
  if(relayEnable && millis()-relayStartTime > RELAY_TIMEOUT*1000) relayEnable = false;
  if(ledEnable   && millis()-ledStartTime   > LED_TIMEOUT*1000)   ledEnable = false;
  if(buzzerEnable && millis()-buzzerStartTime > BUZZER_TIMEOUT*1000) buzzerEnable = false;

  // взаимодействие с периферией
  digitalWrite(RELAY_PIN, !relayEnable); // управляем реле
  if(ledEnable)   flash(LED_PIN);       // если надо - моргаем светодиодом
  if(buzzerEnable) siren();               // если надо - пищим
}


void siren() // кричим
{
  static unsigned long beepTime;
  if(millis() - beepTime > BEEP_INTERVAL)
  {
    digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
    beepTime = millis();
  }
}


void flash(byte pin) // мигаем указанным светиком
{
  static unsigned long flashTime;
  if(millis() - flashTime > FLASH_INTERVAL)
  {
    digitalWrite(pin, !digitalRead(pin));
    flashTime = millis();
  }
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Только что проверено на макетке, все работает корректно, при превышении порога начинает истерично моргать LED на плате (остальное не подключено), через 10 секунд моргать перестает (если значение ниже 150). В порт сообщения выводятся постоянно, т.е. ничего не висит.

Попробуй физически отключить реле (может от него идет помеха) и проверить этот код:

#define SENSOR_PIN     A0    // пин для подключения сенсора
#define SENSOR_MIN     150   // пороговые значения сенсора для срабатывания
#define SENSOR_MAX     1023  // макс значение сенсора
#define LED_PIN       13     // пин для подключения светодиода //временно, для тестов ###################
#define RELAY_PIN     3    // пин для подключения реле
#define BUZZER_PIN     4     // пин для подключения зуммера
#define BEEP_INTERVAL  100   // частота включения зуммера, мсек
#define FLASH_INTERVAL 100   // частота включения светодиода, мсек
#define BUZZER_TIMEOUT 10UL   // длительность звучания зуммера, сек
#define LED_TIMEOUT   10UL   // длительность мигания светодиода, сек //временно, для тестов ###################
#define RELAY_TIMEOUT 10UL   // длительность включения реле, сек

boolean relayEnable = false;// флаг состояния реле
boolean buzzerEnable = false;// флаг состояния зуммера
boolean ledEnable = false;  // флаг состояния светодиода


void setup()
{
  Serial.begin(9600); //Серийный порт скорость 9600
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
}


void loop()
{
  unsigned int sensorData;               // текущее значение с сенсора
  static unsigned long relayStartTime;  // внутренние счетчики времени
  static unsigned long ledStartTime;
  static unsigned long buzzerStartTime;

  sensorData = analogRead(SENSOR_PIN);
  Serial.println(sensorData);

  if (sensorData > SENSOR_MIN && sensorData < SENSOR_MAX) // проверка пороговых значений
  {
    if (relayEnable == false)    // если до этого реле было выключено
    {
      Serial.println("Relay ON");
      relayEnable = true;        // разрешаем включение реле
      relayStartTime = millis(); // запускаем счетчик времени
    }

    if (ledEnable == false)     //если светодиод был выключен
    {
      Serial.println("LED ON");
      ledEnable = true;          // разрешаем включение светодиода
      ledStartTime = millis();   // запуск счетчика
    }

    if (buzzerEnable == false)    //еслее бузер был выключен
    {
      Serial.println("Buzzer ON");
      buzzerEnable = true;        // разрешаем включение зуммера
      buzzerStartTime = millis(); // запуск счетчика
    }
  }
  else // используется, если нужно моментальное отключение
  { // при выходе за пороговые значения, а не по истечении времени
    // relayEnable = false;     // запрещаем включение реле
    // ledEnable = false;       // запрещаем включение светодиода
    // buzzerEnable = false;     // запрещаем включение зуммера
  }

  // проверка на время отключения
  if (relayEnable && millis() - relayStartTime > RELAY_TIMEOUT * 1000)
  {
    relayEnable = false;
    Serial.println("Relay OFF");
  }

  if (ledEnable   && millis() - ledStartTime   > LED_TIMEOUT * 1000)
  {
    ledEnable = false;
    Serial.println("LED OFF");
  }

  if (buzzerEnable && millis() - buzzerStartTime > BUZZER_TIMEOUT * 1000)
  {
    buzzerEnable = false;
    Serial.println("Buzzer OFF");
  }

  // взаимодействие с периферией
  digitalWrite(RELAY_PIN, !relayEnable); // управляем реле
  Serial.print("Relay state: ");
  Serial.println(digitalRead(RELAY_PIN) ? "OFF" : "ON");
  if (ledEnable)   flash(LED_PIN);      // если надо - моргаем светодиодом
  if (buzzerEnable) siren();              // если надо - пищим
}


void siren() // кричим
{
  static unsigned long beepTime;
  if (millis() - beepTime > BEEP_INTERVAL)
  {
    digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
    beepTime = millis();
  }
}


void flash(byte pin) // мигаем указанным светиком
{
  static unsigned long flashTime;
  if (millis() - flashTime > FLASH_INTERVAL)
  {
    digitalWrite(pin, !digitalRead(pin));
    flashTime = millis();
  }
}

 

Lexan
Offline
Зарегистрирован: 12.02.2016

убрал 36 строчку вывод на серийный порт. Ардуино перестал зависать. Но реле включается и выключается каждую секунду, до тех пор пока значение не упадёт ниже 150( это я уже в слепую определил). Хотя указано что должно быть включенным 180 секунд. И светодиод с бузером по прежнему молчат...

Lexan
Offline
Зарегистрирован: 12.02.2016

Спасибо!! Ну ты ЧЕЛОВЕЧИЩЕ! Какой раз выручаеш! Вот такой должен быть настоящий друг! Я твой должник. Без тебя бы еще месяц этот скеч перечитывал. )) Если что может и я тебе прегожусь. Нуууууу... конечно програмист из меня пока некудышный ))) ну может что по железу подсказать нужно будет или дампом каким поделится. В общем считай что у тебя на одного друга больше ... :)

Светодиод заработал, Реле работает как написано на 10 секунд. Им просто на двоих питания не хвотало вот реле и отключалось (потамучто слишком много жрет :))) ) питание проседало и дуино зависало. Кинул внешнее питание на реле и проблема исчезла! Осталась тока проблема с бузером. Молчит саббака. Может его заменить попробовать?? Вроде был рабочий...

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

зуммер на какое напряжение? Они разные бывают.

http://www.pighixxx.com/test/portfolio-items/connect-a-buzzer-with-trans...

Плюс они есть с внутренним генератором (сам пищит при подаче напряжения) или без (надо программно формировать ШИМ).

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Lexan пишет:

Извиняюсь я не понял, так в моём случае был нужен class BUTTON.h или class_noDELAY.h ??

там же вроде разные библиотеки или это одно и то же?

а сам ты как думаешь, что тебе нужно подключить - класс для кнопки или для генерации событий?

Lexan
Offline
Зарегистрирован: 12.02.2016

Клапауций 322

 Ну я собственно так и подумал ;)

Lexan
Offline
Зарегистрирован: 12.02.2016

 Tomasina

Да обычный с материнки напряжение щас не скажу... Но он  у меня работал в другом скече ему хватало, но не пещал а просто щелкал с интервалом 100мсек наверное вольт на 5, а щас не хочет. Так что думаю без встроенного генератора )... Да и програмно формировать шим наверно много заморочек?

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Lexan пишет:

Клапауций 322

 Ну я собственно так и подумал ;)

ок. ещё раз прочитай и подумай:

подключение кода класса как библиотеки #186

Lexan
Offline
Зарегистрирован: 12.02.2016

Клапауций 322

Спасибо, я ещё  вернусь к этой теме в будущем и обязательно её изучу.

Обещаю :)

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Lexan пишет:
 Но он  у меня работал в другом скече ему хватало, но не пещал а просто щелкал с интервалом 100мсек наверное вольт на 5, а щас не хочет. Так что думаю без встроенного генератора )... Да и програмно формировать шим наверно много заморочек?

Значит без генератора.
Формировать сигнал - пара строчек:  http://arduino.ru/Reference/Tone