Много условий а результат 0.
- Войдите на сайт для отправки комментариев
Втр, 26/11/2013 - 11:25
Вроде и блок схему нарисовал и цепочку всю построил, а программа работать не хочет.
Смысл какой:
Включили в ванной свет. Если свет горит больше 1 минуты, необходимо приготовиться.
Приготовились. Ждем когда свет выключится. Свет погас и включаем вытяжной вентилятор на интервал (задан заранее пользователем). Ждем интервал. Если время вышло и влажность ниже аварии (задается заранее пользователем) выключаем вентилятор.
А вот и код
void fan (){
int present_time = RTC.get(DS1307_HR,true)*3600+RTC.get(DS1307_MIN,false)*60+RTC.get(DS1307_SEC,false);
int time; //для фиксации времени начала периода
int time_light; //для подтверждения начала периода
if (light == true && stat == LOW && time_light != true ) { //если зажгли свет и вентилятор выключен
time = present_time; // запоминаем время включения света
time_light = true; // фиксируем факт включения света
Serial.println ("light ok ");
Serial.println (stat);
}
if (light == false) { // если свет выключили
Serial.println ("light off ");
Serial.println (stat);
if ((present_time-time) > 60 && time_light == true) { //если текущее время минус время включения света больше 60 сек. и свет действительно был включен минуту назад
stat = HIGH; // включаем вентилятор
time = present_time; //перезаписываем время, на время включения вентилятора
time_light = false; //обнуляем факт записи включения света
Serial.println ("fan - ON");
Serial.println (stat);
}
}
if (stat == HIGH && humidity < h) { //Если вентилятор работает и влажность в норме
if ( present_time-time > delay_fan) { //если текущее время минус время с начала включения вентилятора больше интервала задержки включения вентилятора
stat = LOW; //выключаем вентилятор
Serial.println ("fan - OFF");
Serial.println (stat);
}
}
}
По факту, свет включается и гаснет, интервалы проходят, а сигнала о вкл вентелятора нет.
Вы бы хоть весь скетч выложили что-ли.
Ну.... каГ-бЕ в общем случае:
"Значения локальных переменных не сохраняются после выхода из функции."
Поэтому значения переменных time и time_light могут приниматься от совершеннейшей балды.
Вы бы хоть весь скетч выложили что-ли.
смысл вас грузить ~500 строками, не относящимися к данной части кода, кроме, заданных ранее, глобальных переменных?
Ну.... каГ-бЕ в общем случае:
"Значения локальных переменных не сохраняются после выхода из функции."
Поэтому значения переменных time и time_light могут приниматься от совершеннейшей балды.
конструктивно. попробую зделать их глобальными.
зачем DS1307 для отсчета времени работы вентилятора и тп? еще время показывать?
зачем DS1307 для отсчета времени работы вентилятора и тп? еще время показывать?
да, просто вывод на LCD текущего времени, ну а раз DS1307 уже стоит, то почему бы его и не использовать для таймера?
Ну.... каГ-бЕ в общем случае:
"Значения локальных переменных не сохраняются после выхода из функции."
Поэтому значения переменных time и time_light могут приниматься от совершеннейшей балды.
действительно, это оказалось так.
Хм теперь не хочет выключаться, как пройдет интервал работы.Ну думаю тут уж сам разберуь.
Всем спасибо!
при входе в функцию "fan" значение переменной
time_light берется от фонаря. При переходе на глобальные переменные не забудьте сделать начальную инициализацию флагов.блок схему нарисовал
картинку в студию.
Я бы сделал конечный автомат. Типа
... void loop() { doFan(); } byte state; // состояние автомата unsigned long myTimer; unsigned long delayMs=60000; void doFan() { // включили свет if(state==0 && СветВключён()==true) { state = 1; myTimer = millis(); } // выключили свет когда минута ещё не прошла if(state==1 && СветВключён()==false && myTimer + delayMs > millis() ) { state = 0; } // минута прошла и свет всё ещё горит if(state==1 && СветВключён()==true && myTimer + delayMs < millis() ) { state = 2; // "приготовились" } // свет выключили if(state==2 && СветВключён()==false ) { state = 3; myTimer = millis(); ВентиляторВключить(); } if(state==3 && myTimer + delayMs < millis() ) { state = 0; if(ВлажностьНижеАварии()==true) ВентиляторВыключить(); } }жаль что я упустил из вида теорию автоматов. Очень удобно и прозрачно.
Сейчас сам пишу код для контроллера солнечного коллектора и уже ноги можно поломать в условиях, флагах.
блок схему нарисовал
картинку в студию.
Я бы сделал конечный автомат. Типа
... void loop() { doFan(); } byte state; // состояние автомата unsigned long myTimer; unsigned long delayMs=60000; void doFan() { // включили свет if(state==0 && СветВключён()==true) { state = 1; myTimer = millis(); } // выключили свет когда минута ещё не прошла if(state==1 && СветВключён()==false && myTimer + delayMs > millis() ) { state = 0; } // минута прошла и свет всё ещё горит if(state==1 && СветВключён()==true && myTimer + delayMs < millis() ) { state = 2; // "приготовились" } // свет выключили if(state==2 && СветВключён()==false ) { state = 3; myTimer = millis(); ВентиляторВключить(); } if(state==3 && myTimer + delayMs < millis() ) { state = 0; if(ВлажностьНижеАварии()==true) ВентиляторВыключить(); } }Как вариант. Надо запесать в примеры. Спасибо.
if(state==3 &&44myTimer + delayMs < millis() )45{46state = 0;47if(ВлажностьНижеАварии()==true)48ВентиляторВыключить();49}50}этот кусок кода несколько смущает. Получается что алгоритм ждет пока не упадет влажность. А пока падала влажность, могли уже включить свет, и новый отсчет таймера не начался... Как по мне логичнее было бы включать вентилятор по влажности вне зависимости от временных интервалов при выключенном свете.
При выключенном свете - т.к насколько я понял шум включенного вентилятора раздражает находящегося в ванной
RainMan, моя "реализация" не соответствует "тех.заданию"* товарища инженера Соловьёва? ;)
* я прочитал только текстовую часть первого сообщения. Код не осилил, сорри.
Не берите на свой счет. Это просто мысли в слух.
Доброго времени суток !
Я бы пробовал так:
typedef enum { off, onlight1l, onlight1h, offlight } StatType; StatType status = off; volatile unsigned long tim; void loop() { switch(status) { case off: do_off(); break; case onlight1l: do_light1l(); break; case onlight1h: do_light1h(); break; case offlight: do_offlight(); break; } } void do_off() { if (свет включен) { tim = millis(); status = onlight1l;} } void do_light1l() { unsigned long tim2; if (свет включен) { tim2 = millis(); tim2 -= tim; if (tim2 > 60000) status = onlight1h; } else status = off; } void do_light1h() { if (свет погас) { вентилятор_включить(); tim = millis(); status = offlight; } } void do_offlight() { unsigned long tim2; tim2 = millis(); tim2 -= tim; if (tim2 > интервал) { if (авария) tim = mills(); else {ветилятор_выключить();status = off;} } }