Эксперименты с термостатом
- Войдите на сайт для отправки комментариев
Пт, 25/01/2013 - 09:45
Имея Uno, часики самопальные на DS1307, термодатчики DS18b20, LSD 128x64, модуль с четырьмя реле, задумалось слепить из сего: Часы (кажут крупно и чередуют показания с температурой в доме и снаружи). Попутно управляет тремя рожками газовой горелки. Пока мало понимая суть происходящего надергал кусков и заставил держать температуру. Прошу помощи "причесать код"
#include <Wire.h> #include <DS1307.h> #include <OneWire.h> OneWire ds(10); // on pin 10. Датчики DS18b20 в режиме нормального питания byte i; byte present = 0; byte data[12]; byte addr[2][8]; bool isSubZero; int Temp1,Temp; float celsius; int ust = 23; // температура день int time_eco_bg = 22; // время эконом режима начало int time_eco_end = 5; // время эконом режима конец int time_act; // действительное время по DS1307 void temper() { ds.reset(); ds.select(addr[0]); ds.write(0x44,1); present = ds.reset(); ds.select(addr[0]); ds.write(0xBE); for ( i = 0; i < 9; i++) { data[i] = ds.read(); } Temp=(data[1]<<8)+data[0]; isSubZero = false; if (Temp & 0x8000) { isSubZero = true; Temp = (Temp ^ 0xffff) + 1; } float temp = (6 * Temp) + Temp / 4; if(isSubZero) temp = 0 - temp; ds.reset(); ds.select(addr[1]); ds.write(0x44,1); present = ds.reset(); ds.select(addr[1]); ds.write(0xBE); for ( i = 0; i < 9; i++) { data[i] = ds.read(); } Temp1=(data[1]<<8)+data[0]; isSubZero = false; if (Temp1 & 0x8000) { isSubZero = true; Temp1 = (Temp1 ^ 0xffff) + 1; } float temp1 = (6 * Temp1) + Temp1 / 4; if(isSubZero) temp1 = 0 - temp1; Serial.print(" Outdoor "); // Для контроля Serial.print(temp1/100); // не нашел Serial.println(" C"); // правильного Serial.print(" Home "); // места Serial.print(temp/100); Serial.println(" C"); // return(temp1/100); // было так // return(temp/100); celsius = (temp/100); // то же time_act = RTC.get(DS1307_HR,true); // Serial.print(" ust = "); // Serial.print(ust); // вроде не Serial.print(" time_act = "); // Serial.println(time_act); // на месте... } void setup() { Serial.begin(9600); if ( !ds.search(addr[0])) { ds.reset_search(); } if ( !ds.search(addr[1])) { ds.reset_search(); } pinMode(2, OUTPUT); //управл. 1 реле pinMode(4, OUTPUT); //управл. 2 реле pinMode(7, OUTPUT); //управл. 3 реле } void loop() { temper(); if (time_act > time_eco_end && time_act < time_eco_bg) // с этим то же бы { ust = 23; } else { ust = 22; } if (celsius >= ust) { digitalWrite(2, HIGH); } else { digitalWrite(2, LOW); } if (celsius > (ust-1)) { digitalWrite(4, HIGH); } else { digitalWrite(4, LOW); } if (celsius > (ust-2)) { digitalWrite(7, HIGH); } else { digitalWrite(7, LOW); // вынести куда-то... } delay(90000); }
Спасибо участнику maxim за его ссылку: http://arduino.ru/forum/programmirovanie/ds1307-pokazyvayut-strannoe-vremya-kotoroe-stoit#comment-22002
Нет обработки аварийных ситуаций, например: включили нагрев, а температура продолжает падать, или наоборот - выключили, а температура ползет вверх... Т.е. в коде, при проверке условий, надо делать сохранение в промежуточные переменные текущего состояния управляющих элементов и датчиков температуры... Ну и проверять их периодически...
Да. Спасибо, Андрей! В коде, а это был только двухдатчиковый термометр есть функция или как оно правильно называется, void temper() и этот кусок выглядит логично и завершенно. В бесконечном цикле только указан вызов. Вот то, что там кроме прилепил, это можно вынести также в отдельную функцию? И где бы узнать про это? Ну или как оно правильно называется? И вот еще бы delay(90000) убрать бы, а ведь его рано или поздно убирать? Да... уж.
А что бы посоветовали Вы? Очень благодарен даже за скелет идею!
Вот то, что там кроме прилепил, это можно вынести также в отдельную функцию? И где бы узнать про это? Ну или как оно правильно называется?
Можно и в отдельную. Тут главное - не переусердствовать... В отдельную функцию имеет смысл выносить повторяющиеся операции. А перед этим еще почитать про видимость переменных в различных частях программы.
И вот еще бы delay(90000) убрать бы, а ведь его рано или поздно убирать?
Это надо почитать статьи на тему: "замена delay() на millis()"
Это надо почитать статьи на тему: "замена delay() на millis()"
Я подумал, что часы тоже счет ведут и нужно этим активно пользоваться.
Я подумал, что часы тоже счет ведут и нужно этим активно пользоваться.
Если в проекте требуется независимое время - можно и к часам привязаться. Просто аптайм ( millis() ) - гораздо быстрее отрабатывает, чем опрос платы часов по достаточно медленной шине с таймингами кратными сотне миллисекунд. Кроме того, циклы опроса лучше делать почаще: тогда у Вас появится возможность (и необходимость) усреднять полученные значения и выкидывать явно ошибочные. А уже по результатам усреднения - принимаем решение об управляющих воздействиях.
Имея LCD на ST7920 и графическую библиотеку U8glib хочу использовать его для вывода показаний температуры и времени.
Из-за особенностей функционирования дисплея и графической библиотеки вывод информации на дисплей осуществляется следующим образом: создается специальный цикл, называемый Picture Loop, внутри которого размещаются все команды или процедуры вывода на дисплей:
В теле цикла вместо xxxxxxxx располагаются команды или процедуры вывода на дисплей.
Примеры работают, вывод есть, остается сборка. Но задумался из-за этой задержки: delay(500) которая присутствует в примерах, а у меня будет своя, большая задержка... подскажите пожалуйста, откуда ждать черенок граблей? На примере и двухсекундные задержки себя никак не проявляют.