Управление электрокотлом с тремя тэнами
- Войдите на сайт для отправки комментариев
Прошу помощи новичку. Я переделал скетч с этого форума (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)
Вопрос:И ещё можно ли сделать чтоб тэны в случайном порядке включались. (типа по моточасам) А не молотил всегда первый иногда второй а третий почти не включался.
Можно: используй 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