Автоматизация теплицы, ошибка кода?

vit177
Offline
Зарегистрирован: 08.04.2017

Добрый день.

Люди, помогите разобраться, есть автоматизированная теплица, работала неделю. Для открывания дверей используются электростеклоподъемники подключенные через отдельный БП через релюшки и переполюсовка тоже через релюшки (на момент запуска были только релюшки и не было времени ждать драйвер двигателя) Вот  код:

#include "DHT.h"
#include <OLED_I2C.h>
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS3231);
/* для дисплея
OLED  myOLED(SDA, SCL);
extern uint8_t RusFont[]; // Русский шрифт
extern uint8_t MediumNumbers[];
extern uint8_t SmallFont[];
*/
int tempOpen = 30;
int tempClose = 20;
int t = 25; // задаю время специально между tempOpen и tempClose
int rele1_right = 38; // реле полива 1 правой грядки
int rele2_left = 44;   // реле полива 2 левой грядки
int rele3_street = 40;  // реле полива 3 уличной грядки
int rele4_valve = 42;  // магистральный клапан набора воды в бочке
const int pin_door1_open = 39; // концевик открытой ближней двери
const int pin_door1_close = 41; // концевик закрытой ближней двери
const int pin_door2_open = 45; // концевик открытой дальней двери
const int pin_door2_close = 43; // концевик закрытой дальней двери
int rele_220_f = 22; // реле подачи 220 на БП 12 В для дверей
int rele_220_null = 26; // реле подачи 220 на БП 12 В для дверей
int rele_open_door1 = 30; // реле переполюсовки ближней двери
int rele_close_door1 = 28; // реле переполюсовки ближней двери
int rele_open_door2 = 34; // реле переполюсовки дальней двери
int rele_close_door2 = 32; // реле переполюсовки дальней двери
//int pin_manual_open_door1 = A3 ; // кнопка ручного открытия основной двери
int pin_water_level_full = A7 ; // концевик в бочке на максимальный уровень воды
int pin_power_water_level = 46;
//int pin_manual_water_filling = A6 ; // кнопка ручного включения набора воды в бочке
int summa,water_level_full,now_time,currentMillis,Hour,Minut,Day;
int door1_open_state = 0;
int door1_close_state = 0;
int door2_open_state = 0;
int door2_close_state = 0;
int time_read_temp = 5000; // интервал опроса датчика темп (5с)
unsigned long next_time_read_temp; //время очередного чтения датчика темп

#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT22   
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  next_time_read_temp = millis()+ time_read_temp; // вычисляем время следующего чтения датчика темп
 
  pinMode(pin_door1_open, INPUT);
  pinMode(pin_door1_close, INPUT);
  pinMode(pin_door2_open, INPUT);
  pinMode(pin_door2_close, INPUT);
  pinMode(pin_power_water_level, OUTPUT);
  pinMode(rele1_right, OUTPUT);
  pinMode(rele2_left, OUTPUT);
  pinMode(rele3_street, OUTPUT);
  pinMode(rele4_valve, OUTPUT);
    pinMode(rele_220_f, OUTPUT);
    pinMode(rele_220_null, OUTPUT);
  pinMode(rele_open_door1, OUTPUT);
  pinMode(rele_close_door1, OUTPUT);
  pinMode(rele_open_door2, OUTPUT);
  pinMode(rele_close_door2, OUTPUT);
  
  digitalWrite(pin_power_water_level, HIGH);
  digitalWrite(rele1_right, HIGH);
  digitalWrite(rele2_left, HIGH);
  digitalWrite(rele3_street, HIGH);
  digitalWrite(rele4_valve, HIGH);
  digitalWrite(rele_220_f, HIGH);
  digitalWrite(rele_220_null, HIGH);
  digitalWrite(rele_open_door1, HIGH);
  digitalWrite(rele_close_door1, HIGH);
  digitalWrite(rele_open_door2, HIGH);
  digitalWrite(rele_close_door2, HIGH);
   dht.begin();
//  myOLED.begin();
  time.begin();
//    Serial.begin(9600);
 }

void loop() {
 /*  digitalWrite(rele_220_f, LOW); // включаем реле для подачи 220 на БП
  digitalWrite(rele_220_null, LOW); // включаем реле лдя подачи 220 на БП
  digitalWrite(rele_open_door2, LOW); // включаем реле переполюсовки для открывания двери


if (door2_open_state ==1){ // если дверь достигает концевик door1_open_state, значит она открыта
   digitalWrite(rele_open_door2, HIGH); //вЫключаем реле переполюсовки для выключения открывания двери
}
*/
   
// здесь будет код, который будет работать постоянно
  door1_open_state = digitalRead(pin_door1_open);  // читаем состояние концевика
  door1_close_state = digitalRead(pin_door1_close); // читаем состояние концевика
  door2_open_state = digitalRead(pin_door2_open); // читаем состояние концевика
  door2_close_state = digitalRead(pin_door2_close);  // читаем состояние концевика
 
  int now_time = millis(); // присваиваем текущее значение счетчика миллис
  
   if  ( now_time >= next_time_read_temp ){
  next_time_read_temp = now_time + time_read_temp;
  t = dht.readTemperature(); // читаем значение температуры и присваиваем значение переменной t
  float h = dht.readHumidity(); // читаем значение влажности и присваиваем значение переменной h
/*  Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
Serial.print(water_level_full);
  Serial.print("water_level_full ");
*/
}
time.gettime();
Hour = time.Hours;
Minut = time.minutes;
Day = time.weekday;

 // Проверяем датчик температуры 

// Мапируем кнопки
  water_level_full = map((analogRead(pin_water_level_full)), 0, 900, 0, 1); // читаем аналоговый вход и если > 900 присваиваем значение 1 иначе 0 (1- полная)
 //****************************************************************************************************************
// Первая дверь
// Если температура больше или равна порогу tempOpen, кнопка ручного открывания двери manual_open_door1 не нажата
// и концевик door1_open_state открытой двери не нажат, то открываем дверь
if (t >= tempOpen) {
 if (door1_open_state==0){
  digitalWrite(rele_220_f, LOW); // включаем реле для подачи 220 на БП
  digitalWrite(rele_220_null, LOW); // включаем реле лдя подачи 220 на БП
  digitalWrite(rele_open_door1, LOW); // включаем реле переполюсовки для открывания двери

}

if (door1_open_state ==1){ // если дверь достигает концевик door1_open_state, значит она открыта
   digitalWrite(rele_open_door1, HIGH); //вЫключаем реле переполюсовки для выключения открывания двери
}

// Вторая дверь
// Если температура больше или равна порогу tempOpen, первая дверь уже открыта и концевик door2_open_state открытой двери не нажат, концевик открытой первой door1_open_state двери уже нажат то открываем дверь

if ((door1_open_state==1)&&(door2_open_state==0)) {
 digitalWrite(rele_open_door2, LOW); // включаем реле переполюсовки для открывания двери
}
if (door2_open_state ==1){ // если дверь достигает концевик door2_open_state, значит она открыта
   digitalWrite(rele_open_door2, HIGH); // вЫключаем реле переполюсовки для открывания двери
   digitalWrite(rele_220_f, HIGH); // вЫключаем реле для подачи 220 на БП
   digitalWrite(rele_220_null, HIGH); // вЫключаем реле лдя подачи 220 на БП
  }
}


// Если температура меньше или равна порогу tempOpen, кнопка ручного открывания двери manual_open_door1 не нажата
// и концевик door1_open_state не нажат, то закрываем дверь

if (t <= tempClose) {
   if (door1_close_state==0){ 
  digitalWrite(rele_220_f, LOW); // включаем реле для подачи 220 на БП
  digitalWrite(rele_220_null, LOW); // включаем реле лдя подачи 220 на БП
  digitalWrite(rele_close_door1, LOW); // включаем реле переполюсовки для закрывания двери
    }
  if (door1_close_state ==1){ // если дверь достигает концевик door1_close_state, значит она закрыта
  digitalWrite(rele_close_door1, HIGH); // вЫключаем реле переполюсовки для выключения закрывания двери
  digitalWrite(rele_close_door2, LOW); // включаем реле переполюсовки для закрывания второй двери
    }
   if (door2_close_state ==1){ // если дверь достигает концевик door2_close_statе, значит она закрыта
   digitalWrite(rele_close_door2, HIGH); // вЫключаем реле переполюсовки для открывания двери
   digitalWrite(rele_220_f, HIGH); // вЫключаем реле для подачи 220 на БП
   digitalWrite(rele_220_null, HIGH); // вЫключаем реле лдя подачи 220 на БП
  }
}

/*
//*****************************************************************************************************************
// Ручное управление открыванием только первой двери по кнопке
// Проверяем не нажата ли кнопка и если нажата, то открываем первую дверь

if ((manual_open_door1==0)&&(door1_open==0)){ 
  digitalWrite(pin_power_off_m1, LOW); // Сниманием HIGH с ENABLE на drv8825 и тем самым включаем драйвер
  Stepper2.move(-5000); 
}
else {digitalWrite(pin_power_off_m1, HIGH);}

}

*/
//*****************************************************************************************************************
// Набор воды в бочке по расписанию в заданное время
if((Hour==1)&&(Minut==00)&&(water_level_full==0)){
digitalWrite(rele4_valve, LOW);
}

if((water_level_full==1)||(Hour==3)){
digitalWrite(rele4_valve, HIGH);
}

//*****************************************************************************************************************
// полив грядки на улице
if(((Hour==20)&&(Minut==00))&&((Day==1)||(Day==3)||(Day==5))){
digitalWrite(rele3_street, LOW);
digitalWrite(rele2_left, LOW);
}
// Полив обеих грядок в теплице
if(((Hour==20)&&(Minut==00))&&((Day==0)||(Day==2)||(Day==4)||(Day==6))){
digitalWrite(rele3_street, LOW);
digitalWrite(rele1_right, LOW);
}
// выключаем полив
if((Hour==22)&&(Minut==00)){
  digitalWrite(rele2_left, HIGH);
  digitalWrite(rele1_right, HIGH);
}
if((Hour==22)&&(Minut==01)){
digitalWrite(rele3_street, HIGH);
}
}

//*****************************************************************************************************************

Сегодня первая дверь открылась не до конца , т.е. не достигла концевика door1_open_state  и исходя из кода соответственно и вторая не открылась. При  осмотре, были в состоянии LOW реле rele_220f, rele_220null, rele_open door1 и rele_close_door1. Как так получилось то? Я пока грешу только на сами концевики, видимо показания прыгают , хотя я через стягивающий резисторы все подключил.

vit177
Offline
Зарегистрирован: 08.04.2017

Сейчас хочу дописать чтобы самотестировплась при старте или каждый час при t>tempOpen пытались открыться, а при t<tempClose пытались закрыться. Но это не исправит саму проблему, а только выход из ситуации. 

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

Крепись! Я три года допиливаю свой проект автоматизации теплицы, ты ещё в самом начале пути ;) А лучше - брось это дело, муторное оно и долгое.

vit177
Offline
Зарегистрирован: 08.04.2017

Не не, у меня тоже третий год , но правда ранее работал только полив. В этом году и двери прикрутил, я не сдамся, отношусь к этому как к хобби, мне даже больше не сам урожай уже интересен, а весь этот проект ))) но урожай это приятный бонус. 

vit177
Offline
Зарегистрирован: 08.04.2017

У меня наоборот в планах ещё докрутить экранчик, кнопки для ручного управления, ethernet для удаленного анализа и управления. 

asam
Offline
Зарегистрирован: 12.12.2018

vit177 пишет:

 При  осмотре, были в состоянии LOW реле rele_220f, rele_220null, rele_open door1 и rele_close_door1. Как так получилось то? Я пока грешу только на сами концевики, видимо показания прыгают , хотя я через стягивающий резисторы все подключил.

Могу только посоветовать анализ логов. Надо добавить Serial.print на срабатывания каждого датчика (желательно с TimeStamp от RTC). И подключить к компу с какой-нибудь терминальной программой умеющей записывать логи (TeraTerm, PuTTy итд)

sadman41
Offline
Зарегистрирован: 19.10.2016

millis() в int читается, интервалы через сложение вычисляются... Откуда-то, как черт из табакерки, выскакивает Stepper2.

Наврядли этот код стоит анализировать.

vit177
Offline
Зарегистрирован: 08.04.2017

Сорри, вставился код код криво, stepper это действительно черт из табакерки, я ранее хотел сделать открывание на шаговых двигателях. Тот кусок кода закомментиован, вот :

#include "DHT.h"
#include <OLED_I2C.h>
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS3231);
/* для дисплея
OLED  myOLED(SDA, SCL);
extern uint8_t RusFont[]; // Русский шрифт
extern uint8_t MediumNumbers[];
extern uint8_t SmallFont[];
*/
int tempOpen = 30;
int tempClose = 20;
int t = 25; // задаю время специально между tempOpen и tempClose
int rele1_right = 38; // реле полива 1 правой грядки
int rele2_left = 44;   // реле полива 2 левой грядки
int rele3_street = 40;  // реле полива 3 уличной грядки
int rele4_valve = 42;  // магистральный клапан набора воды в бочке
const int pin_door1_open = 39; // концевик открытой ближней двери
const int pin_door1_close = 41; // концевик закрытой ближней двери
const int pin_door2_open = 45; // концевик открытой дальней двери
const int pin_door2_close = 43; // концевик закрытой дальней двери
int rele_220_f = 22; // реле подачи 220 на БП 12 В для дверей
int rele_220_null = 26; // реле подачи 220 на БП 12 В для дверей
int rele_open_door1 = 30; // реле переполюсовки ближней двери
int rele_close_door1 = 28; // реле переполюсовки ближней двери
int rele_open_door2 = 34; // реле переполюсовки дальней двери
int rele_close_door2 = 32; // реле переполюсовки дальней двери
//int pin_manual_open_door1 = A3 ; // кнопка ручного открытия основной двери
int pin_water_level_full = A7 ; // концевик в бочке на максимальный уровень воды
int pin_power_water_level = 46;
//int pin_manual_water_filling = A6 ; // кнопка ручного включения набора воды в бочке
int summa,water_level_full,now_time,currentMillis,Hour,Minut,Day;
int door1_open_state = 0;
int door1_close_state = 0;
int door2_open_state = 0;
int door2_close_state = 0;
int time_read_temp = 5000; // интервал опроса датчика темп (5с)
unsigned long next_time_read_temp; //время очередного чтения датчика темп

#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT22   
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  next_time_read_temp = millis()+ time_read_temp; // вычисляем время следующего чтения датчика темп
 
  pinMode(pin_door1_open, INPUT);
  pinMode(pin_door1_close, INPUT);
  pinMode(pin_door2_open, INPUT);
  pinMode(pin_door2_close, INPUT);
  pinMode(pin_power_water_level, OUTPUT);
  pinMode(rele1_right, OUTPUT);
  pinMode(rele2_left, OUTPUT);
  pinMode(rele3_street, OUTPUT);
  pinMode(rele4_valve, OUTPUT);
    pinMode(rele_220_f, OUTPUT);
    pinMode(rele_220_null, OUTPUT);
  pinMode(rele_open_door1, OUTPUT);
  pinMode(rele_close_door1, OUTPUT);
  pinMode(rele_open_door2, OUTPUT);
  pinMode(rele_close_door2, OUTPUT);
  
  digitalWrite(pin_power_water_level, HIGH);
  digitalWrite(rele1_right, HIGH);
  digitalWrite(rele2_left, HIGH);
  digitalWrite(rele3_street, HIGH);
  digitalWrite(rele4_valve, HIGH);
  digitalWrite(rele_220_f, HIGH);
  digitalWrite(rele_220_null, HIGH);
  digitalWrite(rele_open_door1, HIGH);
  digitalWrite(rele_close_door1, HIGH);
  digitalWrite(rele_open_door2, HIGH);
  digitalWrite(rele_close_door2, HIGH);
   dht.begin();
//  myOLED.begin();
  time.begin();
//    Serial.begin(9600);
 }

void loop() {
 /*  digitalWrite(rele_220_f, LOW); // включаем реле для подачи 220 на БП
  digitalWrite(rele_220_null, LOW); // включаем реле лдя подачи 220 на БП
  digitalWrite(rele_open_door2, LOW); // включаем реле переполюсовки для открывания двери


if (door2_open_state ==1){ // если дверь достигает концевик door1_open_state, значит она открыта
   digitalWrite(rele_open_door2, HIGH); //вЫключаем реле переполюсовки для выключения открывания двери
}
*/
   
// здесь будет код, который будет работать постоянно
  door1_open_state = digitalRead(pin_door1_open);  // читаем состояние концевика
  door1_close_state = digitalRead(pin_door1_close); // читаем состояние концевика
  door2_open_state = digitalRead(pin_door2_open); // читаем состояние концевика
  door2_close_state = digitalRead(pin_door2_close);  // читаем состояние концевика
 
  int now_time = millis(); // присваиваем текущее значение счетчика миллис
  
   if  ( now_time >= next_time_read_temp ){
  next_time_read_temp = now_time + time_read_temp;
  t = dht.readTemperature(); // читаем значение температуры и присваиваем значение переменной t
  float h = dht.readHumidity(); // читаем значение влажности и присваиваем значение переменной h
/*  Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
Serial.print(water_level_full);
  Serial.print("water_level_full ");
*/
}
time.gettime();
Hour = time.Hours;
Minut = time.minutes;
Day = time.weekday;

 // Проверяем датчик температуры 

// Мапируем кнопки
  water_level_full = map((analogRead(pin_water_level_full)), 0, 900, 0, 1); // читаем аналоговый вход и если > 900 присваиваем значение 1 иначе 0 (1- полная)
 //****************************************************************************************************************
// Первая дверь
// Если температура больше или равна порогу tempOpen, кнопка ручного открывания двери manual_open_door1 не нажата
// и концевик door1_open_state открытой двери не нажат, то открываем дверь
if (t >= tempOpen) {
 if (door1_open_state==0){
  digitalWrite(rele_220_f, LOW); // включаем реле для подачи 220 на БП
  digitalWrite(rele_220_null, LOW); // включаем реле лдя подачи 220 на БП
  digitalWrite(rele_open_door1, LOW); // включаем реле переполюсовки для открывания двери

}

if (door1_open_state ==1){ // если дверь достигает концевик door1_open_state, значит она открыта
   digitalWrite(rele_open_door1, HIGH); //вЫключаем реле переполюсовки для выключения открывания двери
}

// Вторая дверь
// Если температура больше или равна порогу tempOpen, первая дверь уже открыта и концевик door2_open_state открытой двери не нажат, концевик открытой первой door1_open_state двери уже нажат то открываем дверь

if ((door1_open_state==1)&&(door2_open_state==0)) {
 digitalWrite(rele_open_door2, LOW); // включаем реле переполюсовки для открывания двери
}
if (door2_open_state ==1){ // если дверь достигает концевик door2_open_state, значит она открыта
   digitalWrite(rele_open_door2, HIGH); // вЫключаем реле переполюсовки для открывания двери
   digitalWrite(rele_220_f, HIGH); // вЫключаем реле для подачи 220 на БП
   digitalWrite(rele_220_null, HIGH); // вЫключаем реле лдя подачи 220 на БП
  }
}


// Если температура меньше или равна порогу tempOpen, кнопка ручного открывания двери manual_open_door1 не нажата
// и концевик door1_open_state не нажат, то закрываем дверь

if (t <= tempClose) {
   if (door1_close_state==0){ 
  digitalWrite(rele_220_f, LOW); // включаем реле для подачи 220 на БП
  digitalWrite(rele_220_null, LOW); // включаем реле лдя подачи 220 на БП
  digitalWrite(rele_close_door1, LOW); // включаем реле переполюсовки для закрывания двери
    }
  if (door1_close_state ==1){ // если дверь достигает концевик door1_close_state, значит она закрыта
  digitalWrite(rele_close_door1, HIGH); // вЫключаем реле переполюсовки для выключения закрывания двери
  digitalWrite(rele_close_door2, LOW); // включаем реле переполюсовки для закрывания второй двери
    }
   if (door2_close_state ==1){ // если дверь достигает концевик door2_close_statе, значит она закрыта
   digitalWrite(rele_close_door2, HIGH); // вЫключаем реле переполюсовки для открывания двери
   digitalWrite(rele_220_f, HIGH); // вЫключаем реле для подачи 220 на БП
   digitalWrite(rele_220_null, HIGH); // вЫключаем реле лдя подачи 220 на БП
  }
}

//*****************************************************************************************************************
// Набор воды в бочке по расписанию в заданное время
if((Hour==1)&&(Minut==00)&&(water_level_full==0)){
digitalWrite(rele4_valve, LOW);
}

if((water_level_full==1)||(Hour==3)){
digitalWrite(rele4_valve, HIGH);
}

//*****************************************************************************************************************
// полив грядки на улице
if(((Hour==20)&&(Minut==00))&&((Day==1)||(Day==3)||(Day==5))){
digitalWrite(rele3_street, LOW);
digitalWrite(rele2_left, LOW);
}
// Полив обеих грядок в теплице
if(((Hour==20)&&(Minut==00))&&((Day==0)||(Day==2)||(Day==4)||(Day==6))){
digitalWrite(rele3_street, LOW);
digitalWrite(rele1_right, LOW);
}
// выключаем полив
if((Hour==22)&&(Minut==00)){
  digitalWrite(rele2_left, HIGH);
  digitalWrite(rele1_right, HIGH);
}
if((Hour==22)&&(Minut==01)){
digitalWrite(rele3_street, HIGH);
}
}

//*****************************************************************************************************************

 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

sadman41 пишет:

millis() в int читается, интервалы через сложение вычисляются... 

Гивер?

vit177
Offline
Зарегистрирован: 08.04.2017

 

[/quote]

Могу только посоветовать анализ логов. Надо добавить Serial.print на срабатывания каждого датчика (желательно с TimeStamp от RTC). И подключить к компу с какой-нибудь терминальной программой умеющей записывать логи (TeraTerm, PuTTy итд)

[/quote]

Ок, спасибо, наверное так и сделаю. 

b707
Offline
Зарегистрирован: 26.05.2017

vit177 пишет:

 

Ок, спасибо, наверное так и сделаю. 

вы бы для начала явные ошибки поправили, на которые вам уже указали

цитата:

millis() в int читается, интервалы через сложение вычисляются...

vit177
Offline
Зарегистрирован: 08.04.2017

Добрый день.

now_time = millis(); // присваиваем текущее значение счетчика миллис
  if (now_time - next_time_read_temp > time_read_temp){
  next_time_read_temp = now_time;
}

Поправил millis, так правильно? Сам проверить пока не могу, теплица с контроллером ооочень далеко :-)

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

vit177 пишет:
так правильно?
Не видно, как именно описаны переменные, потому ничего сказать нельзя.

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

now_time по прежнему как int объявлена? Если да - то неправильно, посмотри, что возвращает millis()

Pyotr
Offline
Зарегистрирован: 12.03.2014

ТС, при повышении/снижении Т относительно заданной не открывай/закрывай двери на всю. Делай это мелкими шагами каждые 2-5 мин. 

Например, если дверь открывается за 10 сек, то шаги делай по 1 сек. Вдруг холодная погода и выглянуло яркое солнце, Т повысилась, дверь приоткрылась на пару-тройку шагов, Т уравнялась и все телодвижения остановились.

А лучше поставить датчик положения на привод.

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

vit177
Offline
Зарегистрирован: 08.04.2017

А если двери открыл на всю, не так уж и быстро там все замёрзнет. Если внутри темп снова будет меньше указанной темп, то ничего не мешает дверям снова закрыться.  Я вот не пойму как написать код так, чтобы при t> tempOpen ещё и засеклось время и уж если не отработало все должным образом, например за минуту, то меняю какую-нибудь переменную типа work_mode например на 2 и далее уже запущу сброс или аварийный режим открывания дверей. 

vit177
Offline
Зарегистрирован: 08.04.2017
Если вот так прописать, то ведь не будет работать, т.к. time_open_door и now_time1 будут переприсваиваться постоянно?
 
time_open_door = millis() + period_open_door; // переменная для интервала тестирования дверей при старте        
now_time1 = millis(); // присваиваем текущее значение счетчика миллис
  	if (time_open_door - now_time1 > period_open_door){
  	work_mode=1
        }

Если только какие-нибудь переменные новые добавить в условия, типа step. Опишу пока просто словами идею: если t>tempOpen и  step==0, выполняем time_open_door = millis() + period_open_door; и присваиваем новое значение step=1 и now_time1 = millis();. Далее, если (step==1 )&& (time_open_door - now_time1 > period_open_door), то уже тогда присваиваем новое значение переменной step=2; которое верну в 0 после ресета.  Но это все похоже на какой-то костыль, есть идеи как поменять  значение переменной через определенное время после срабатывания одног условия?

 

 

 
Pyotr
Offline
Зарегистрирован: 12.03.2014

vit177 пишет:

А если двери открыл на всю, не так уж и быстро там все замёрзнет. Если внутри темп снова будет меньше указанной темп, то ничего не мешает дверям снова закрыться.  Я вот не пойму как написать код так, чтобы при t> tempOpen ещё и засеклось время и уж если не отработало все должным образом, например за минуту, то меняю какую-нибудь переменную типа work_mode например на 2 и далее уже запущу сброс или аварийный режим открывания дверей. 

Для начала нужно правильно выстроить loop(). У тебя всё свалено в кучу-выполняется каждый проход loop().
Надо весь код равномерно "размазать" по времени, чтоб цикл не зависал надолго. Каждый цикл делаем что-то одно, ну или несколько коротких действия.

Пример. (конечно не компилируется)

 

word carrMillis, prevMillis, intervalMs = 20;
byte second;//секунды с RTC
void setup() {
  readTemp();
}

void loop(){
  carrMillis = (word)millis();//интервалы до 1 мин (у нас есть RTC)
  if(carrMillis - prevMillis >= intervalMs){//20ms
    prevMillis += intervalMs;    
    readKey();//читаем кнопки каждые 20 мс
    //что-то еще каждые 20 мс
    switch (countCycle){
      case 0:
        printLCD();   
        break;//раз в сек    
      case 5:  
        if((second % 5) == 0)  readTemp();//читаем датчик через 5 сек
        break;
      case 6:  
        //делаем что-то раз в сек
        break;  
      case 6: 
         //делаем что-то раз в сек
        break;
      case 40: 
        getTime();// получить время от модуля
        break;      
    }    
    if(++countCycle >= 50){//прошла  1 сек
      countCycle = 0;    
    }
  }
}//END loop()

Каждые 20 мс делается одно действие. Неважно за 1 мс или 50 мс. При длительной процедуре (более 20 мс) цикл "забуксует", а затем наверстает ускоренной прокруткой. Главное чтоб суммарная длительность всех шагов была менее 1 сек.

Переделаешь, тогда можно дальше двигаться.

Pyotr
Offline
Зарегистрирован: 12.03.2014

Да, ужас в строке 122 всёж лучше заменить на

if(analogRead(pin_water_level_full) > 900)  water_level_full = 1;
else                                        water_level_full = 0;

 

vit177
Offline
Зарегистрирован: 08.04.2017

Ок, заменю. Спасибо, попробую переписать код