Друг построил на дачном участке баню из бруса. Возникла необходимость отапливать ее зимой и как-то управлять этим процессом. Без узла автоматики приходилось приезжать в субботу рано утром включать котел и в лучшем случае в субботу вечером собираться компанией. После установки автоматики стало возможным поддерживать в помешивании температуру +8 градусов экономить на электроэнергии и по мире необходимости прогревать помещение за ранее. Стало возможным не собираться в субботу вечером, а к примеру, в ночь с четверга на пятницу прогреть помещение по ночному тарифу, в течении дня пятницы поддерживать в помещении температуру +22, а в пятницу сразу после работы ехать закупаться пивом рыбой и всей компанией собираться в бане. На участке из коммуникаций только свет, газа нет, центрального отопления тоже нет, вода из скважины, был установлен водяной электро-котел, смонтирован коллектор и сделан водяной теплый пол в стяжке.
Сам котел на фото:
Так как электроникой я увлекаюсь давно, делать автоматику для электро-котла было решено из того что уже есть в тумбочке и давно лежит без дела, а это были:
- плата Arduino Nano
- модуль GSM Neoway M590
- датчик температуры на DS18B20
- твердотельное реле SSR-40DA
- блок питания 220В -> 5В 2А я воткнул что было, а вы можете поставить минвел
Основная задача — необходимо собрать и запрограммировать блок управления твердотельным реле, к которому будет подключаться нагрузка посредством SMS и отслеживание температуры.
Условия: прием модулем SMS только от одного абонента (чтобы ограничиться от спама и ложных команд), получение SMS о текущем состоянии реле и температуры, установка значения поддержания температуры в помещении (+гистерезис), переключение работы с блока управления на термостат.
Схема:
Фото в собранном виде.
Основные команды SMS:
- T=** (** — установка температуры, по умолчанию установлено +3 градуса)
- Stat — получение состояние реле, текущей температуры и уставки.
- On — включение модуля управления
- Off — отключение модуля управления (модуль по умолчанию выключен)
На данный момент устройство успешно проработало один зимний сезон и с наступлением теплого времени года планируется его апгрейд. В будущем в программе будет реализована возможность подключения двух дополнительных реле, а так же отображения их состояния в SMS по запросу Stat.
Исходный код для ArduinoIDE:
#include <SoftwareSerial.h>
#include <microDS18B20.h>
#include "GyverRelay.h"
//#define SETPOINT 30.0 // установка (ставим на 25 градусов)
#define HYSTER 3 // ширина гистерезиса
GyverRelay regulator(REVERSE); // установка, гистерезис, направление регулирования
MicroDS18B20<2> sensor1; //датчик на D2
SoftwareSerial mySerial(10, 11); //RX, TX пины
byte R1 = 9; //пин D9 реле 1
byte R2 = 8; //пин D8 реле 2
int val1 = 0; //переменная для хранения значения R1
int val2 = 0; //переменная для хранения значения R2
String tel = "+7**********"; //номер телефона куда будут отправляться данные
String availablePhone = "+7**********"; //номер телефона только с которого будут приниматься сообщения
int setTemperature = 3; //уставка температуры по умолчанию
bool state = false; //состояние включено/выключено
void setup() {
delay(2000); //задержка
regulator.setpoint = setTemperature;
regulator.hysteresis = HYSTER;
regulator.k = 0.5; // коэффициент обратной связи (подбирается по факту)
pinMode(R1, OUTPUT); //устанавливаем режим работы пина 8 как Выход
digitalWrite(R1, LOW); //устанавливаем низкое значение пина 1
pinMode(R2, OUTPUT); //устанавливаем режим работы пина 9 как Выход
digitalWrite(R2, LOW); //устанавливаем низкое значение пина 2
Serial.begin(9600); //инициируем последовательное соединение и задаем скорость передачи данных в бит/c
mySerial.begin(9600);
Serial.println("GSM NEOWAY M590");
Serial.println();
Serial.println("Turn on AOH:");
mySerial.println("AT+CLIP=1"); //включить АОН
delay(300);
Serial.println("Text format sms:");
mySerial.println("AT+CMGF=1"); // текстовый формат SMS
delay(300);
Serial.println("Mode GSM:");
mySerial.println("AT+CSCS=\"GSM\""); // кодировка текста - GSM
delay(300);
Serial.println("SMS to terminal:");
mySerial.println("AT+CNMI=2,2,0,0,0"); // вывод смс в консоль
delay(10000);
sms(String("GSM NEOWAY M590 ON"), String(tel)); // отправка смс о включении модема
}
void loop()
{
if(mySerial.available()) //если модуль что-то послал
{ //проверка всех условий
char ch = ' ';
String val = "";
while(mySerial.available()) //получение символов для чтения из последовательного порта
{
ch = mySerial.read();
val += char(ch); //собираем принятые символы в строку
delay(3);
}
Serial.print("Neoway send> ");
Serial.println(val);
if(val.indexOf("+CMT") > -1) //если есть входящее sms
{
String phoneSend = val.substring(val.indexOf("+7"), val.indexOf("+7") + 12);
Serial.println("PhoneSend: " + phoneSend);
if (phoneSend == availablePhone){
if(val.indexOf("On") > -1 || val.indexOf("on") > -1 || val.indexOf("ON") > -1) //если есть входящее sms
{
state = true;
Serial.println("State ON");
}
if(val.indexOf("Off") > -1 || val.indexOf("off") > -1 || val.indexOf("OFF") > -1) //если есть входящее sms
{
state = false;
Serial.println("State OFF");
}
if(val.indexOf("T=") > -1) // смотрим, что за команда
{
setTemperature = val.substring(val.indexOf("T=")+2).toInt();
regulator.setpoint = setTemperature;
Serial.println("Set TEMP: " + setTemperature);
}
if(val.indexOf("Stat") > -1) // смотрим, что за команда
{
Serial.println("Stat1");
val1 = digitalRead(R1); //чтение значения пина на реле R1
val2 = digitalRead(R2); //чтение значения пина на реле R2
Serial.println("Stat2");
sensor1.requestTemp(); // запрос температуры
Serial.println("Stat3");
String val1Str, val2Str;
if (val1 == 0){
val1Str = "Off";
}
else{
val1Str = "On";
}
if (val2 == 0){
val2Str = "Off";
}
else{
val2Str = "On";
}
Serial.println("Stat4");
String result = "R1:" + String (val1Str) + " " + "R2:" + String (val2Str) + " " + "Temp:" + String (sensor1.getTemp()) + " SetTemp: " + String(setTemperature);
Serial.println("Stat5");
sms(result, String(tel));
}
}
}
}
regul();
debug();
}
void sms(String text, String phone) // отправка СМС
{
Serial.println("Start SMS send");
mySerial.println("AT+CMGS=\"" + phone + "\"");
delay(500);
mySerial.print(text);
delay(500);
mySerial.print((char)26);
delay(500);
Serial.println("SMS send OK");
delay(2000);
}
void regul() {
static uint32_t tmr;
if (millis() - tmr > 500) {
if (state){
Serial.println(sensor1.getTemp());
Serial.println(regulator.getResult());
tmr = millis();
sensor1.requestTemp(); // запрос температуры
regulator.input = sensor1.getTemp(); // сообщаем регулятору текущую температуру
digitalWrite(R1, regulator.getResult()); // отправляем на реле (ОС работает по своему таймеру)
}
else{
digitalWrite(R1, LOW);
}
}
}
void debug() {
static uint32_t tmr;
if (millis() - tmr > 50) {
tmr = millis();
/*Serial.print(regulator.input); // фактическая
Serial.print(',');
Serial.print(setTemperature); // гистерезис
Serial.print(',');
Serial.print(setTemperature + HYSTER); // гистерезис
Serial.print(',');
Serial.print(setTemperature - HYSTER); // гистерезис
Serial.print(',');
Serial.println(regulator.output * 2 + 30); // сост. реле*/
}
}
Автор: mefi73