Эксперименты с термостатом
- Войдите на сайт для отправки комментариев
Пт, 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, внутри которого размещаются все команды или процедуры вывода на дисплей:
u8g.firstPage(); do { xxxxxxxx; xxxxxxxx; xxxxxxxx; } while( u8g.nextPage() );В теле цикла вместо xxxxxxxx располагаются команды или процедуры вывода на дисплей.
Примеры работают, вывод есть, остается сборка. Но задумался из-за этой задержки: delay(500) которая присутствует в примерах, а у меня будет своя, большая задержка... подскажите пожалуйста, откуда ждать черенок граблей? На примере и двухсекундные задержки себя никак не проявляют.