Управление электрокотлом с тремя тэнами
- Войдите на сайт для отправки комментариев
Прошу помощи новичку. Я переделал скетч с этого форума (http://arduino.ru/forum/proekty/upravlenie-obogrevom-komnaty-pri-pomoshchi-arduino-i-dallas18b20) под нагревательный котел с 3 мя тэнами. При включений с интервалом в полсекунды включаюся 3 группы тэнов . При наборе заданной температуры выключаются. Как температура падает на 1 градус 1 тэн включается ,на 2-2 тэна ,на 3-3 тэна.И еще подцепил второй датчик для информаций улицы например. Как ограничить возможную уставку температуры например от 15 до 75 и сделать шаг уставки 5. Как подцепить аналоговый вход чтоб при размыканий или замыканий выводил сообщение и отключал выходы. И еще можно как то убрать десятичные градусов в отображений?
// Подключаем библиотеку для работы с шиной OneWire
// Термометр будет подключен на Pin2
#include <OneWire.h>
OneWire oneWire(2);
//Подключаем библиотеку для работы с термометром
#include <DallasTemperature.h>
//Создаем объект sensors, подключенный по OneWire
DallasTemperature sensors(&oneWire);
//Создаем переменные для работы с термометром
DeviceAddress temp1DeviceAddress;//переменная для хранения адреса датчика
DeviceAddress temp2DeviceAddress; //второй информационный датчик
float temp1=0; //переменная для текущего значения температуры 1
float temp2=0; //переменная для текущего значения температуры 2
int setTmp=0; // переменная для заданного значения температуры
//Подключаем LCD-дисплей
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//Подсветка управляется через пин D10
#define BACKLIGHT_PIN 10
//Создаем переменную для хранения состояния подсветки
boolean backlightStatus = 1;
// Подключаем библиотеку для работы с ARDUINO EEPROM
//Заданная температура будет храниться по адресу 0
#include <EEPROM2.h>
//Реле подключено к пину D11
#define RELAY1 11
#define RELAY2 12
#define RELAY3 13
//Объявим переменную для хранения состояния реле
boolean relayStatus1=LOW;
boolean relayStatus2=LOW;
boolean relayStatus3=LOW;
//Объявим переменные для задания задержки
long previousMillis1 = 0;
long interval1 = 2000; // интервал опроса датчиков температуры
//Аналоговая клавиатура подключена к пину A0
#define KEYPAD_PIN A0
//Определим значения на аналоговом входе для клавиатуры
#define ButtonUp_LOW 140
#define ButtonUp_HIGH 145
#define ButtonDown_LOW 324
#define ButtonDown_HIGH 330
#define ButtonLeft_LOW 503
#define ButtonLeft_HIGH 509
#define ButtonRight_LOW 0
#define ButtonRight_HIGH 5
#define ButtonSelect_LOW 740
#define ButtonSelect_HIGH 745
void setup() {
//Настроим пин для управления реле
pinMode(RELAY1,OUTPUT);
pinMode(RELAY2,OUTPUT);
pinMode(RELAY3,OUTPUT);
digitalWrite(RELAY1,LOW);
digitalWrite(RELAY2,LOW);
digitalWrite(RELAY3,LOW);
//Считаем из постоянной памяти заданную температуру
setTmp=EEPROM_read_byte(0);
//Инициализируем термодатчик и установим разрешающую способность 12 бит
//(обычно она установлена по умолчанию, так что последнюю строчку
//можно опустить)
sensors.begin();
sensors.getAddress(temp1DeviceAddress, 0);
temp1=sensors.getTempC(temp1DeviceAddress);
sensors.getAddress(temp2DeviceAddress, 1);
temp2=sensors.getTempC(temp2DeviceAddress);
// sensors.setResolution(12);
//Настроим подсветку дисплея
pinMode(BACKLIGHT_PIN, OUTPUT);
digitalWrite(BACKLIGHT_PIN, backlightStatus);
//Выведем на дисплей стартовое сообщение на 2 секунды
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Temp. Controller");
lcd.setCursor(0, 1);
lcd.print(" v1.1 ");
delay(1500);
// выведем на дисплей заданное значение температуры на 2 секунды
lcd.setCursor(0, 1);
lcd.print(" Set temp: ");
lcd.setCursor(12,1);
lcd.print(setTmp);
delay(1500);
//Очистим дисплей
lcd.begin(16, 2);
}
//Определим функцию для опроса аналоговой клавиатуры
//Функция опроса клавиатуры, принимает адрес пина, к которому
//подключена клавиатура, и возвращает код клавиши:
// 1 - UP
// 2 - DOWN
// 3 - LEFT
// 4 - RIGHT
// 5 - SELECT
int ReadKey(int keyPin)
{
int KeyNum=0;
int KeyValue1=0;
int KeyValue2=0;
//Читаем в цикле аналоговый вход, для подавления дребезга
//и нестабильности читаем по два раза подряд, пока значения
//не будут равны.
//Если значения равны 1023 – значит не была нажата ни одна клавиша.
do {
KeyValue1=analogRead(keyPin);
KeyValue2=analogRead(keyPin);
} while (KeyValue1==KeyValue2&&KeyValue2!=1023);
//Интерпретируем полученное значение и определяем код нажатой клавиши
if (KeyValue2<ButtonUp_HIGH&&KeyValue2>ButtonUp_LOW) {KeyNum=1;}//Up
if (KeyValue2<ButtonDown_HIGH&&KeyValue2>ButtonDown_LOW) {KeyNum=2;}//Down
if (KeyValue2<ButtonLeft_HIGH&&KeyValue2>ButtonLeft_LOW) {KeyNum=3;}//Left
if (KeyValue2<ButtonRight_HIGH&&KeyValue2>ButtonRight_LOW) {KeyNum=4;}//Right
if (KeyValue2<ButtonSelect_HIGH&&KeyValue2>ButtonSelect_LOW) {KeyNum=5;}//Select
//Возвращаем код нажатой клавиши
return KeyNum;
}
//Определим процедуру редактирования заданной температуры
//Вызывается по нажатию клавиши Select, отображает на дисплее
//заданную температуру и позволяет изменять ее клавишами Up и Down
void setTemperature()
{
lcd.begin(16,2);
int keyCode=0;
//выводим на дисплей заданное значение температуры
lcd.setCursor(0, 0);
lcd.print(" Setting temp ");
lcd.setCursor(7, 1);
lcd.print(setTmp);
//Опрашиваем клавиатуру, если нажата клавиша Up увеличиваем
//значение на 1, если Down – уменьшаем на 1
//Если нажаты клавиши Select или Right – цикл опроса прерывается
//Задержки введены для борьбы с дребезгом, если клавиши срабатывают
//четко – можно уменьшить время задержек или вообще их убрать
do
{
keyCode=ReadKey(KEYPAD_PIN);
if (keyCode==1){setTmp++;delay(150);lcd.setCursor(7, 1);lcd.print(setTmp);}
if (keyCode==2){setTmp--;delay(150);lcd.setCursor(7, 1);lcd.print(setTmp);}
//lcd.begin(16,2);
}
while (keyCode!=5 && keyCode!=4);
delay(200);
//lcd.begin(16, 2);
//По клавише Select – созраняем в EEPROM измененное значение
//По клавише Right – восстанавливаем старое значение
if (keyCode==5) {EEPROM_write_byte(0, setTmp);}
if (keyCode==4) {setTmp = EEPROM_read_byte(0);}
}
void loop() {
//Модуль опроса датчиков и получения сведений о температуре
//Вызывается 1 раз в секунду
unsigned long currentMillis1 = millis();
if(currentMillis1 - previousMillis1 > interval1) {
previousMillis1 = currentMillis1;
//Запуск процедуры измерения температуры
// sensors.setWaitForConversion(false);
sensors.requestTemperatures();
//sensors.setWaitForConversion(true);
//Delay(250) // задержка для обработки информации внутри термометра,
//в данном случае можно не задавать
//Считывание значения температуры
sensors.getAddress(temp1DeviceAddress, 0);
temp1=sensors.getTempC(temp1DeviceAddress);
sensors.getAddress(temp2DeviceAddress, 1);
temp2=sensors.getTempC(temp2DeviceAddress);
// Вывод текущего значения температуры на дисплей
lcd.setCursor(0, 0);
lcd.print("Current");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.print(temp1);
lcd.print("C");
lcd.setCursor(9, 1);
lcd.print("Ty");
lcd.print(temp2);
}
//Проверка условия включения/выключения нагревателя
if (temp1<setTmp&&relayStatus1==LOW)
{relayStatus1=HIGH; digitalWrite(RELAY1,HIGH);
lcd.setCursor(10, 0);
lcd.print("P= 35%");}
if (temp1>setTmp&&relayStatus1==HIGH)
{relayStatus1=LOW; digitalWrite(RELAY1,LOW);
lcd.setCursor(10, 0);
lcd.print("P= 0%");
}
delay(500);
if (temp1+1<setTmp&&relayStatus2==LOW)
{relayStatus2=HIGH; digitalWrite(RELAY2,HIGH);
lcd.setCursor(10, 0);
lcd.print("P= 70%");}
if (temp1>setTmp&&relayStatus2==HIGH)
{relayStatus2=LOW; digitalWrite(RELAY2,LOW);
//lcd.begin(10, 2);
}
delay(500);
if (temp1+2<setTmp&&relayStatus3==LOW)
{relayStatus3=HIGH; digitalWrite(RELAY3,HIGH);
lcd.setCursor(10, 0);
lcd.print("P=100%");}
if (temp1>setTmp&&relayStatus3==HIGH)
{relayStatus3=LOW; digitalWrite(RELAY3,LOW);
//lcd.begin(16, 2);
}
delay(200);
// Опрос клавиатуры
int Feature = ReadKey(KEYPAD_PIN);
//Включение подсветки
if (Feature==1 )
{backlightStatus=1;digitalWrite(BACKLIGHT_PIN, backlightStatus);}
//Отключение подсветки
if (Feature==2 )
{backlightStatus=0;digitalWrite(BACKLIGHT_PIN, backlightStatus);}
//Переход к редактированию заданной температуры
if (Feature==5 )
{delay(200);setTemperature();
}
}
И ещё можно ли сделать чтоб тэны в случайном порядке включались. (типа по моточасам) А не молотил всегда первый иногда второй а третий почти не включался.
Сделать можно все, надо только уметь и хотеть.
По уставке надо найти место, где , под if код нажатой кнопки меняет переменную. Скажем после 160 строки. Там надо вместо ++ ставить = переменная +5. Для декремента -5. Для ограничений - в эти же ифы доп условие по &&.
по выводу смотрите в районе 204 строки. Надо добавить после temp, признак соответствующего форматирования вывода.
случайный порядок тэнов- заменить в начале дефайны реле на назначенные переменные. Добавить их переназначение в основном цикле по таймеру от миллис.
по аналоговому входу и размыканий/замыканий непонятно, что Вам нужно.
Довели до ума?
Вопрос: И еще можно как то убрать десятичные градусов в отображений?
Ответ : Использовать операцию приведение типов. Банально привести к целому числу. (int)
// Вывод текущего значения температуры на дисплей lcd.setCursor(0, 0); lcd.print("Current"); lcd.setCursor(0, 1); lcd.print("T="); lcd.print((int)temp1); lcd.print("C"); lcd.setCursor(9, 1); lcd.print("Ty"); lcd.print((int)temp2);Вопрос:И ещё можно ли сделать чтоб тэны в случайном порядке включались. (типа по моточасам) А не молотил всегда первый иногда второй а третий почти не включался.
Можно: используй millis() http://arduino.ru/Reference/Millis Тоже в некотором смысле генератор псевдослучайных чисел.
Можно: используй millis() http://arduino.ru/Reference/Millis Тоже в некотором смысле генератор псевдослучайных чисел.
О_о - не перестаю открывать для себя новое и интересное! С каких это пор функция с линейным возвращаемым значением у нас стала "в некотором смысле генератор псевдослучайных чисел"? Да там в любом смысле, как эти смыслы не крути - не проходит.
Мда. DIYMan. А вы точно учились программировать? Это же классика. Любой счетчик это генератор псевдослучайных чисел. Ключевое слова ПСЕВДО. Проблема счетчиков случайных чисел в том что бы вероятность выпадания каждого числа была равновероятна. А если они выподают последовательно, то вероятность выпадания каждой одинакова. Разумеется если взять 1000 случаев. Теория вероятности вам поможет. Теперь если всеже хочется более менее случайное число выбрать. То откиньте старшие с помощью % и младшие / ,округлите до целого. И вуаля. В данном случае топик стартеру не надо совсем уж случайные числа. Есть еще проще. Первые тысячу обращений к температуре работают тены 1,2, 3 . Вторая тысяча 2,3,1. Третья тысяча 3,1,2. И дальше по кругу. Износ тенов равномерен.
Мда. DIYMan. А вы точно учились программировать? Это же классика. Любой счетчик это генератор псевдослучайных чисел. Ключевое слова ПСЕВДО. Проблема счетчиков случайных чисел в том что бы вероятность выпадания каждого числа была равновероятна. А если они выподают последовательно, то вероятность выпадания каждой одинакова. Разумеется если взять 1000 случаев. Теория вероятности вам поможет. Теперь если всеже хочется более менее случайное число выбрать. То откиньте старшие с помощью % и младшие / ,округлите до целого. И вуаля. В данном случае топик стартеру не надо совсем уж случайные числа. Есть еще проще. Первые тысячу обращений к температуре работают тены 1,2, 3 . Вторая тысяча 2,3,1. Третья тысяча 3,1,2. И дальше по кругу. Износ тенов равномерен.
Ещё один, понятно. Отошлю-ка я вас в википедию, пожалуй: https://ru.wikipedia.org/wiki/%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%D0%BF%D1%81%D0%B5%D0%B2%D0%B4%D0%BE%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D1%8B%D1%85_%D1%87%D0%B8%D1%81%D0%B5%D0%BB
И плз - больше никому не говорите, что линейная последовательность чисел - это генератор ПСЕВДОслучайных чисел. Я вам даже выделил ваше псевдо-, хотя оно тут и ни к чему было.
Отвечу. МНОГА БУКВ. МАЛО ТОЛКА. В те времена, когда начинали учится только по Бейсику, так и выкручивались.
Отвечу. МНОГА БУКВ. МАЛО ТОЛКА. В те времена, когда начинали учится только по Бейсику, так и выкручивались.
Это вы про что сейчас? Я привёл ссылку на совершенно точное определение генератора псевдослучайных чисел, millis() под это определение не попадает никак, о чём я вам и написал. Имейте смелость признавать свои ошибки. Если я где впарываю - я признаю, поверьте. И не упорствую в невежестве.
кончай тупить, DIYMan
Разумеется для шифрования даных в среде Интернета millis() не годится. Но как генератор случайных чисел в простых, даже не сетевых игр , может справлятся вполне. Или в данном случае(ПОДЧЕРКИВАЮ) вполне обойтись дешевым аналогом. В крайнем случает то на то выйдет. Только разве объем программы возрастет.
ПС: Напоминаю , сейчас мы беседуем на Форуме посвященым Ардуино и ее среды.
Разумеется для шифрования даных в среде Интернета millis() не годится. Но как генератор случайных чисел
Ещё раз: давайте не называть millis() генератором случайных чисел, ок? Это как назвать белое чёрным. Я согласен с вами, что для каких-то применений оно сгодится, но это, при всём желании - не генератор ни случайных, ни псевдослучайных чисел.
С этим вы согласны?
кончай тупить, DIYMan
Тупишь тут только ты.
Может проще задать когда нужен 1 тен работает 1. если нужно 2 -работает 2-3. 1 отдыхает. Раз в год, два всеравно ревизию надо делать 1 с 2-3 меняем местами. хотя и так износ довольно равномерный должен получиться.
qwone о сути дела написал справедливо и из-за особо прикапывающихся ко всяким синтаксисам, без понимания сути, нет смысла отказываться от работающего алгоритма.
Извените что вмешиваюсь, а кто схему подключения может нарисовать? и правильный, поправленный скеч? Тоже хочеться управлять дома электрокотлом. Эта версия помоемому самая подходящая, и я правильно понимаю что тут используется Шильд LCD+Keypad от DFRobot?
Нарисовать я программу и схему могу. Но код будет кривоват, да надо будет ловить ошибки , что в схеме, что в программе. Шилд у меня есть, а вот датчиков, электрокотла у меня нет. Так что код и схема будет на страх самого собравшего и запустившего.
Добрый день!
Шилд, датчики все это есть, давайте попробую.
Доброго времени суток!
Тема заглохла? А очень востребованна.
Доброго времени суток!
Тема заглохла? А очень востребованна.
Да мне бы хотябы рабочую версию. Попробовать хочеться.
Идея то очень замечательная.
Идея то очень замечательная.
Тут есть простенькая схема http://vrtp.ru/index.php?showtopic=25364. В общемто управлять больше насосом нужно регулировать скорость циркуляцию теплоносителя. ставить 3 ходовой клапан который будет определять обратка пришла достаточно теплая чтобы пустить ее на второй круг циркуляции или к ней нужно подмешать теплой воды, а обратку пустить в котел. Идея не дает нужного эфекта не экономит электроинергию, не дает поддерживать стабильную температуру в комнате. точнее дает но очень неэффиктивно.
Может кто то подсказать,у меня по чему то при копировании текста и переносе в IDE вылазит одна и таже ошибка , связанная c EEprom
EEprom ('EEPROM_read_byte' was not declared in this scope).
Или в другой версии скетча вылезает ошибка
if(keyCode==4) {setTmp = EEPROM_read_byte(0);}{setTmp = EEPROM_read_byte(0);} was not declared in this scope
Копировал текст программы с разных источников , итог один.
потому что 'EEPROM_read_byte' was not declared in this scope