СОДЕРЖАНИЕ ►
Этот проект позволяет управлять температурой электрического теплого пола в дневное и ночное время, включать и выключать обогрев, а также получать информацию с датчиков через приложение на смартфоне. Кроме того, приложение позволяет узнать сколько времени в течении суток был включен теплый пол, сколько киловатт было потрачено на обогрев пола в течении суток и в течении месяца.
Для этого проекта потребуется:
- Arduino Micro / Arduino Mega
- SSR твердотельное реле
- блютуз модуль HC-05 (HC-06)
- модуль часов RTC DS1307
- библиотеки EEPROM.h, iarduino_RTC.h и SoftwareSerial.h
- андроид приложение tepluy_pol.apk
Перед тем, как собирать схему, установите на модуле часов реального времени DS1307 или DS3231 время и дату. В приложении не будет возможности изменить или настроить время. О том как настроить RTC модуль часов реального времени читайте здесь — Часы реального времени Ардуино. И прошейте Bluetooth модуль HC-05/HC-05 при необходимости, как это сделать читайте здесь — Прошивка Bluetooth модуля Ардуино
Теплый пол на Arduino с Bluethoot управлением

| OLED i2c 0,96 | Arduino Micro | Arduino Mega |
| GND | GND | GND |
| VDD | 5V | 5V |
| SDA | 2 | 20 |
| SCL | 3 | 21 |
В проекте используется плата Arduino Micro, так как на Uno и Nano недостаточно памяти для скетча. Обратите внимание, что на плате Arduino Micro порты SDA и SCL расположены на цифровых пинах 2 и 3. А для подключения выводов TX и RX у Блютуз модуля с библиотекой SoftwareSerial.h следует использовать порты на плате Micro, поддерживающие внешние прерывания (цифровые пины 8, 9, 10 или 11).
Сохранение настроек и переменных в памяти EEPROM
После сборки схемы следует записать в память ЕЕПРОМ настройки работы электрического теплого пола по умолчанию (потом их можно будет изменить через приложение на смартфоне). Переменные необходимо сохранить в EEPROM Arduino, чтобы при перезагрузке микроконтроллера после отключения электричества, все настройки не сбились, а были прочитаны из энергонезависимой памяти.
#include "EEPROM.h" // === настройка температуры по умолчанию === // int t_day = 16; // температура пола днем int t_night = 12; // температура пола ночью int t_light = 17; // температура при включении света int air_day = 24; // температура воздуха днем int air_night = 20; // температура воздуха ночью // === настройка времени по умолчанию === // int h_day = 10; // время включения дневной температуры int h_night = 22; // время включения ночной температуры int delta = 2; // на сколько градусов увеличить температуру (0, 2 или 3) int mode = 1; // режим работы (0 - пол выключен, 1 - включен) void setup() { Serial.begin(9600); // полностью очищаем еепром for (int i = 0 ; i < EEPROM.length() ; i++) { EEPROM.write(i, 0); } // сохраняем данные в энергонезависимую память EEPROM.update(0, t_day); EEPROM.update(1, t_night); EEPROM.update(2, t_light); EEPROM.update(3, h_day); EEPROM.update(4, h_night); EEPROM.update(5, air_day); EEPROM.update(6, air_night); EEPROM.update(7, mode); EEPROM.update(8, delta); delay(1000); // выводим все данные на монитор порта Serial.println("t_day - " + String(EEPROM.read(0))); Serial.println("t_night - " + String(EEPROM.read(1))); Serial.println("t_light - " + String(EEPROM.read(2))); Serial.println("h_day - " + String(EEPROM.read(3))); Serial.println("h_night - " + String(EEPROM.read(4))); Serial.println("air_day - " + String(EEPROM.read(5))); Serial.println("air_night - " + String(EEPROM.read(6))); Serial.println("mode - " + String(EEPROM.read(7))); Serial.println("delta - " + String(EEPROM.read(8))); } void loop() { }
Пояснения к коду:
- температуру пола указывайте на 2 градуса меньше комфортной для вас температуры, так как потом к ней будет добавляться переменная delta. При оптимальном режиме работы пола переменная будет равна двум.
Скетч для управления теплым полом от Arduino с Bluetooth
#include "EEPROM.h" // подключаем модуль часов времени #include "iarduino_RTC.h" iarduino_RTC myRTC (RTC_DS1307); // подключаем блютуз модуль #include "SoftwareSerial.h" SoftwareSerial hcSerial(8, 9); // RX, TX // === основные настройки для работы программы === // #define LED 10 // пин подключения светодиода #define REL 13 // пин подключения реле #define LM35F A0 // пин подключения датчика lm35 #define LM35A A3 // пин подключения датчика lm35 #define LDR A5 // пин подключения фоторезистора int ldr = 800; // уровень освещенности при включении света float kvt = 0.50; // мощность теплого пола в Квт byte period = 10; // через сколько секунд опрашивать датчик // === далее, если нет опыта, ничего не меняем === // // переменные для счетчика энергии int SEC, MIN, HOUR, CET; // переменные для времени и даты int hours, minuts, days, monts; // переменные для режимов работы пола int delta, mode, h_day, h_night; // переменные для температуры работы пола int t_day, t_night, t_light, air_day, air_night; // переменные для опроса датчиков float temp_f, temp_floor, temp_a, temp_air; // переменные для работы программы String h, m, d, mo, str, message; int t_f, t_a; float k_day, k_mon; bool r, e; char val; unsigned long timer; void setup() { Serial.begin(9600); hcSerial.begin(9600); myRTC.begin(); // конфигурация пинов платы pinMode(LDR, INPUT); pinMode(LM35F, INPUT); pinMode(LM35A, INPUT); pinMode(REL, OUTPUT); pinMode(LED, OUTPUT); } void loop() { // выполняем цикл, если с блютуз модуля пришла информация while (hcSerial.available()) { val = hcSerial.read(); // переходим в функцию сохранения температуры if (val == '*') { temp(); break; } // переходим в функцию сохранения времени if (val == '^') { vremya(); break; } // включаем low режим, обновляем переменную delta if (val == '=') { delta = 0; EEPROM.update(8, delta); job(); break; } // включаем high режим, обновляем переменную delta if (val == '%') { delta = 3; EEPROM.update(8, delta); job(); break; } // включаем пол, обновляем переменные delta и mode if (val == '+') { delta = 2; mode = 1; EEPROM.update(7, mode); EEPROM.update(8, delta); job(); break; } // выключаем пол, обновляем переменные delta и mode if (val == '-') { delta = 2; mode = 0; EEPROM.update(7, mode); job(); break; } str = str + val; } // запускаем отсчет таймера if (millis() - timer > 1000) { timer = millis(); CET++; // если реле включено, то ведем подсчет секунд if (r == 1) { SEC = SEC + 1; if (SEC == 59) { SEC = 0; MIN = MIN + 1; } if (MIN == 59) { MIN = 0; HOUR = HOUR + 1; } } } // ежедневно обновляем и сохраняем киловатты в еепром if (hours == 23 and minuts == 58) { e = 1; } if (hours == 23 and minuts == 59) { SEC = 0; MIN = 0; HOUR = 0; if (e == 1) { k_mon = EEPROM_float_read(monts * 10); k_mon = k_mon + k_day; if (days == 1) { k_mon = 0.00; } EEPROM_float_write(monts * 10, k_mon); k_day = 0.00; } } // если прошло заданное количество секунд выполняем функцию job if (CET == period) { CET = 0; job(); } } // === функция сохранения времени в еепром === // void vremya() { message = str; message.remove(2, 2); h_day = message.toInt(); message = str; message.remove(0, 2); h_night = message.toInt(); EEPROM.update(3, h_day); EEPROM.update(4, h_night); job(); } // === функция сохранения температуры в еепром === // void temp() { message = str; message.remove(2, 8); t_day = message.toInt(); message = str; message.remove(0, 2); message.remove(2, 6); t_night = message.toInt(); message = str; message.remove(0, 4); message.remove(2, 4); t_light = message.toInt(); message = str; message.remove(0, 6); message.remove(2, 2); air_day = message.toInt(); message = str; message.remove(0, 8); air_night = message.toInt(); EEPROM.update(0, t_day); EEPROM.update(1, t_night); EEPROM.update(2, t_light); EEPROM.update(5, air_day); EEPROM.update(6, air_night); job(); } // === функция опроса датчиков и включения реле === // void job() { // несколько раз опрашиваем датчик температуры пола temp_floor = 0; for (byte i = 0; i <= 4; i++) { temp_f = ( analogRead(LM35F) / 1023.0 ) * 5.0 * 1000 / 10; temp_floor = temp_floor + temp_f; } t_f = temp_floor / 5; // несколько раз опрашиваем датчик температуры воздуха temp_air = 0; for (byte i = 0; i <= 4; i++) { temp_a = ( analogRead(LM35A) / 1023.0 ) * 5.0 * 1000 / 10; temp_air = temp_air + temp_a; } t_a = temp_air / 5; // получаем настройки из еепром и модуля часов t_day = EEPROM.read(0); t_night = EEPROM.read(1); t_light = EEPROM.read(2); h_day = EEPROM.read(3); h_night = EEPROM.read(4); air_day = EEPROM.read(5); air_night = EEPROM.read(6); mode = EEPROM.read(7); delta = EEPROM.read(8); h = myRTC.gettime("H"); m = myRTC.gettime("i"); d = myRTC.gettime("d"); mo = myRTC.gettime("m"); hours = h.toInt(); minuts = m.toInt(); days = d.toInt(); monts = mo.toInt(); k_day = (HOUR * 60 + MIN) / 60.00 * kvt; // отправляем всю информацию через блютуз модуль hcSerial.println("T-AIR: " + String(t_a) + "°C"); hcSerial.println("T-POL: " + String(t_f) + "°C"); hcSerial.println("LDR: " + String(analogRead(LDR))); hcSerial.println("t_day = " + String(t_day + delta)); hcSerial.println("t_night = " + String(t_night + delta)); hcSerial.println("t_light = " + String(t_light + delta)); hcSerial.println("h_day = " + String(h_day)); hcSerial.println("h_night = " + String(h_night)); hcSerial.println("air_day = " + String(air_day)); hcSerial.println("air_night = " + String(air_night)); hcSerial.println(myRTC.gettime("H:i:s")); hcSerial.println("time = " + String(HOUR) + "-" + String(MIN)); hcSerial.println("today = " + String(k_day) + " kv"); hcSerial.println("month = " + String(EEPROM_float_read(monts * 10)) + " kv"); hcSerial.println("m = " + String(mode)); hcSerial.println("d = " + String(delta)); // в зависимости от времени и температуры меняем переменную r if (hours >= h_day and hours < h_night) { if (t_f < t_day + delta) { r = 1; } if (t_f > t_day + delta or t_a > air_day + 1) { r = 0; } } if (hours < h_day or hours >= h_night) { if (t_f < t_night + delta) { r = 1; } if (t_f > t_night + delta or t_a > air_night + 1) { r = 0; } } // проверяем включен ли свет if (analogRead(LDR) > ldr and t_f < t_light + delta) { r = 1; } if (analogRead(LDR) < ldr and t_f > t_light + delta) { r = 0; } // проверяем, что пол не был выключен if (mode == 0) { r = 0; } // в зависимости от переменной r1 включаем или выключаем пол if (r == 0) { digitalWrite(REL, LOW); digitalWrite(LED, LOW); hcSerial.println("RELE: OFF"); } if (r == 1) { timer = millis(); digitalWrite(REL, HIGH); digitalWrite(LED, HIGH); hcSerial.println("RELE: ON"); } str = ""; } // === функция сохранения киловатт в еепром (переменная float) === // void EEPROM_float_write(int addr, float val) { byte *x = (byte *)&val; for (byte i = 0; i < 4; i++) EEPROM.write(i + addr, x[i]); e = 0; } // === функция чтения киловатт из еепром (переменная float) === // float EEPROM_float_read(int addr) { byte x[4]; for (byte i = 0; i < 4; i++) x[i] = EEPROM.read(i + addr); float *y = (float *)&x; return y[0]; }
Пояснения к коду:
- при необходимости в скетче следует изменить порты подключения датчиков и модулей к микроконтроллеру Ардуино Микро;
- также в скетче следует указать значение с аналогового входа A5 к которому подключен фоторезистор при включенном свете (переменная ldr), указать мощность электрического пола в Киловаттах (переменная kvt), а также период опроса датчиков в секундах (переменная period).
Приложение для управления теплым полом со смартфона
Проект позволяет узнать сколько был включен теплый пол в течении суток, Ардуино переводит время в Киловатты и отправляет информацию на смартфон. Ежедневно в 23:59 информация о потраченных Киловаттах суммируется с месячными расходами и сохраняется в EEPROM. Каждый месяц 1 числа месячный расход Киловатт обнуляется. При перезагрузке Ардуино суточный расход электроэнергии обнулится.

Кроме информации с датчиков в режиме реального времени и возможности настройки работы электрического теплого пола по времени суток. Приложение позволяет дистанционно включить или выключить электрический пол (в приложении переменная m, в скетче — mode), а также перевести нагрев в экономный (LOW) режим или усиленный (HIGH) за счет изменения переменной d (в скетче это переменная delta).
Заключение. Обязательно убедитесь, что твердотельное реле сможет выдержать нагрузку от нагревательных матов. Также в программе предусмотрено дополнительное включение светодиода на 10 пине при включении реле (на схеме светодиод не изображен). Это может понадобиться для индикации работы электрического пола. Все вопросы по проекту можно оставлять в комментариях к этой записи.










Перед прошивкой б.т модуль надо отключить.потомучто о передаёт данные через Tx RX
Не надо его отключать, так как используется программный последовательный порт
впервые работаю с ардуино, работаю с платой мега подскажите как собрать с ней ту схему, которая изображена с платой микро
на мега и микро пины не совсем схожи
подскажите какие пины использовать для подключения к плате ( у меня ардуино мега) пины микро и мега немного отличаются
На Ардуино Мега не получится использовать программный порт с библиотекой SoftwareSerial.h, лучше возьмите плату Уно или Нано. Тогда не придется переписывать программу
Но Вы сами говорите что на унке и на нанке мало памяти?
Тогда да, только Микро подойдет в вашем случае
добрый день, не могу подключиться приложением к данному проекту , когда в приложении нажимаю подключить Bluetooth появляется тр в левом верхнем углу и темный экран
До этого подключали Блютуз к Ардуино? Ищите ошибку в подключении Блютуз модуля.
может ли быть причиной версия Блютуз? НС-05 v3.0, а телефон v4.0 и выше.
Если использовать модуль НС-08 или НМ10, приложение на телефоне будет работать?
Запустил проект, блютуз работает,с телефоном сопрежен, а в приложение нажимаю подключить влютуз и там открывается окно и тёмный экран
Подключите Блютуз по этому уроку — Блютуз и Ардуино
Если не получается, то ничем не могу помочь
Добрый вечер , все элементы подключил правильно загружаю 2-ой код и ничего не работает в приложении не показывается температура, и в целом всё устройство не работает , даже реле не отрабатывает по команде с телефона , делаю на ардуино уно
Модуль часов и Блютуз к каким пинам Ардуино подключили?
D2 D3 модуль часов и блютуз D8 D9
На Arduino Micro порты SDA и SCL расположены на пинах 2 и 3, на Arduino Uno порты SDA и SCL расположены на пинах A4 и A5. Если все правильно подключите, может и заработает тогда. Еще попробуйте порты D8 и D9 поменять местами
буквально пару дней назад начал просматривать скечи, пытаясь разобраться как «это все» работает.
приятно удивлен, что довольно быстро получилось найти «живой» сайт с полезной информацией.
Спасибо всем причастным.
заинтересован материалами для изучения, все что может быть полезно.
Понимаю, что ИИ сейчас справляется с львиной долей задач по написанию, это приятная, но недостаточная возможность. Хочу уметь корректировать под свои задачи готовые шаблоны, а также анализировать, что же выбирает ИИ, какие есть плюсы и минусы разных вариантов решения.
в общем хочу углубиться конкретно. Благо с запросом все в порядке ))) конкретные проекты есть.
Посоветуйте литературу.
еще раз благодарю всех кто развивается сам и делится опытом!
Здравствуйте. Почему Вы говорите, что Нано не подойдёт из-за памяти? Флэшки там одинаково с Микро, а оперативка различается совсем на чуть-чуть.