/
// Подключаем все нужные библиотеки для работы с датчиком и дисплеем
#include <EEPROM.h> // Библиотека энергонезависимой памяти
#include <GyverWDT.h> // Библиотека для отслеживания зависаний МК
#include <microDS18B20.h> // Библиотека для цифрового датчика ds18b20
#include <GyverNTC.h> // Библиотека для аналового NTC термистора
#include <iarduino_RTC.h> // Библиотека для модуля реального времени
#define magnetic 2 // Пин подключения реле управления пускателем
#define ds_temp 3 // Пин подключения ds18b20
#define led_error 12 // Пин подключения сигнализирующего светодиода об аварии
#define ntc_boiler_temp A0 // Пин подключенияn NTC термистора
#define ntc_street_temp A1 // Пин подключенияn NTC термистора
#define R1 12950 // Сопратевление делительного резитора
#define R2 12950 // Сопратевление делительного резитора
#define K 3950 // B-постоянная, K
#define K2 3380 // B-постоянная, K
#define normal_temp 25 // Заданная температура
#define normal_R 10000 // Сопративление термистора при заданной температуре
#define HYSTERESIS 2 // Задаём Гистерезис
MicroDS18B20<ds_temp> ds; // Прописываем датчик ds18b20
iarduino_RTC watch(RTC_DS1307); // Прописываем модуль RTC
GyverNTC ntc_boiler(ntc_boiler_temp, R1, K, normal_temp, normal_R); // Прописываем NTC датчик
GyverNTC ntc_street(ntc_street_temp, R2, K2, normal_temp, normal_R); // Прописываем NTC датчик
int temp_boiler; // Переменная температуры в котле
int temp_room; // Переменная температуры в помещении
int temp_room_set; // Переменная для установки комнатной температуры
int temp_street; // Переменная температуры на улице
int temp_set; // Переменная для установки температуры котла
uint8_t time_h; // Переменная хранящая в себе данные о текущем часе
uint8_t reload; // Переменная хранящая в себе количество перезагрузок МК при зависании
bool mag_on; // Флаг включения дневного цикла нагрева
bool mag_on_night; // Флаг включения ночного цикла нагрева
bool night_mode; // Флаг включения ночного режима
bool temp_room_test; // Флаг тестирования комнатной температуры
void setup() {
Watchdog.enable(INTERRUPT_RESET_MODE, WDT_PRESCALER_128); // Задаём режим и время для WDT
pinMode(magnetic, OUTPUT); // Прописываем пин magnetic как выход
pinMode(led_error, OUTPUT); // Прописываем пин led_error как выход
watch.begin(); // Инициализируем модуль RTC
watch.period(1); // Задаём опрос данных с RTC модуля раз в минуту
Serial.begin(9600); // Открываем порт отладки
}
void loop() {
if (EEPROM.put(0, reload) >= 5) digitalWrite(led_error, HIGH); // Если перезагрузок будет больше 5, то включаем сигнализирующий светодиод ошибки
yield(); // Опрашиваем все датчики и модуль RTC
if (temp_room < temp_room_set - HYSTERESIS) temp_room_test = false; // Если температура в комнате ниже заданной, то опускаем флаг тестирования комнатной температуры
if ((time_h >= 19 or time_h <= 6) and temp_room_test == false) { // Если время с 19 вечера по 6 утра и флаг тестирования температуры опущен, то задаём параметры для ночного режима
//Serial.println("night_mode");
temp_room_set = 15; // Температура в помещении
temp_set = 35; // Температура котла
night_mode = true; // Поднимаем флаг ночного режима
mag_on_night = true; // Поднимаем флаг для ночного цикла нагрева
magnetic_on(); // Переходим в функцию нагрева
}
if ((time_h >= 7 or time_h <= 18) and temp_room_test == false) { // Если время с 7 утра по 18 вечера и флаг тестирования температуры опущен, то выключаем ночной режим и задаём параметры
//Serial.println("day_mode");
night_mode = false;
if ((temp_street == 8 or temp_street > 0) and night_mode == false) {
temp_room_set = 22;
temp_set = 35;
mag_on = true;
magnetic_on();
}
if ((temp_street == 0 or temp_street > -8) and night_mode == false) {
temp_room_set = 22;
temp_set = 40;
mag_on = true;
magnetic_on();
}
if ((temp_street == -8 or temp_street > -18) and night_mode == false) {
temp_room_set = 20;
temp_set = 55;
mag_on = true;
magnetic_on();
}
if ((temp_street == -18 or temp_street > -25) and night_mode == false) {
temp_room_set = 20;
temp_set = 60;
mag_on = true;
magnetic_on();
}
if ((temp_street == -25 or temp_street < -30) and night_mode == false) {
temp_room_set = 22;
temp_set = 68;
mag_on = true;
magnetic_on();
}
}
Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло
}
void magnetic_on() {
while(mag_on) {
yield(); // Опрашиваем датчики
if (temp_boiler <= temp_set - HYSTERESIS) { // Если температура котла меньше заданной
if (temp_room <= temp_room_set - HYSTERESIS) { // И если температура в помещении меньше заданной
digitalWrite(magnetic, LOW); // Включаем тен
Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло
}
}
if (temp_boiler >= temp_set + HYSTERESIS) { // Если температура котла набралась до заданной
digitalWrite(magnetic, HIGH); // Выключаем тен
Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло
}
if (temp_room >= temp_room_set + HYSTERESIS) { // Если температура в помещении набралась до заданной
digitalWrite(magnetic, HIGH); // Выключаем тен
mag_on = false; // Опускаем флаг цикла нагрева
temp_room_test = true; // Поднимаем флаг тестирования температуры в комнате
}
}
while(mag_on_night) {
yield(); // Опрашиваем датчики
if ((temp_boiler <= temp_set - HYSTERESIS) and night_mode == true) { // Если температура котла меньше заданной
if (temp_room <= temp_room_set - HYSTERESIS) { // И если температура в помещении меньше заданной
digitalWrite(magnetic, LOW); // Включаем тен
Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло
}
}
if ((temp_boiler >= temp_set + HYSTERESIS) and night_mode == true) { // Если температура котла набралась до заданной
digitalWrite(magnetic, HIGH); // Выключаем тен
Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло
}
if ((temp_room >= temp_room_set + HYSTERESIS) and night_mode == true) { // Если температура в помещении набралась до заданной
digitalWrite(magnetic, HIGH); // Выключаем тен
mag_on = false; // Опускаем флаг цикла нагрева
temp_room_test = true; // Поднимаем флаг тестирования температуры в комнате
}
}
}
void yield() {
static uint32_t timer_ds = millis(); // Переменная для таймера на millis() на 1 секунду
if (millis() - timer_ds >= 1000) {
timer_ds = millis();
if (ds.readTemp()) {
temp_room = ds.getTemp(); // Записываем данные с датчика в переменную
temp_street = ntc_street.getTempAverage(); // Записываем данные с датчика в переменную
temp_boiler = ntc_boiler.getTempAverage(); // Записываем данные с датчика в переменную
//Serial.println(temp_room);
//Serial.println(temp_boiler);
//Serial.println(temp_street);
}
ds.requestTemp();
}
static uint32_t timer_watch = millis(); // Переменная для таймера на millis() на 1 минуту
if (millis() - timer_watch >= 60000) {
timer_watch = millis();
watch.gettime(); // Опрашиваем модуль RTC
time_h = watch.Hours; // Записываем данные с датчика в переменную
}
}
ISR(WATCHDOG) {
reload++;
EEPROM.get(0, reload); // Дабовляем +1 к перезагрузке
}
}