Продолжаю серию статей о компонентах умного дома. Сегодня поговорим о датчике протечки, какие электро краны купить и как этим управлять.

Для реализации проекта по защите от потопа в квартире я заказа у китайцев два электрических крана под резьбу 1/2 '' (DN15) схемой подключения DC3 и питанием 5 вольт.
Можно было заказать и на 12 вольт (они почему-то дешевле), но у меня не было подходящего блока питания. Для 5-и вольт подойдет любая зарядка от старого телефона.

Электрический кран
Кран имеет 3 провода:
- Красный - плюс 5 вольт
- Зеленый - минус
- Желтый - управляющий (плюс - закрыт, разрыв - открыт)

Электрическая схема
Управлять этими кранами будет ESP8266-01. Это очень удобное и дешевое решение, но требующее подключения стабилизатора на 3.3 вольта. Управление мы будем осуществлять по протоколу MQTT с мобильного телефона на android.
Подробно о том как подготовить ESP к прошивке скетчем из Arduino IDE и настройке брокер-сервера cloudmqtt.com для обмена данными между устройствами я описывал в статье "ESP + MQTT как основа умного дома" и по тому повторяться не буду.
Управлять нашими электрическими кранами будет микроконтроллер ESP8266. Порт RxD будет управлять открытием/закрытием крана. Порт GPIO0 будет измерять сопротивление между ним и землей - датчик воды. Краны подключены не напрямую, а через транзистор КТ316. Ток для этих кранов не большой и этого маломощного транзистора хватает. Принципиальная схема устройства:

Датчик воды представляет собой кусок текстолита с двумя контактами. Он двухсторонним скотчем приклеен в укромном низком месте где может появиться вода.
Принцип работы
При включении устройства оно проверяет сопротивление на датчике. Если оно мало - включает тревогу и отключает подачу воды, если в норме - работает в следящем режиме.
Параллельно с этим устройство соединяется к домашнему роутеру и через интернет находит подключение к брокер серверу. Подписывается на топики "valve/1", "valve/alarm". Если на брокер сервер с мобильного клиента приходит топик "valve/alarm" = true - кран открывается, false - закрывается. Топик "valve/alarm" = true искусственно вызывает срабатывание тревоги и краны закрываются. "valve/alarm" = false отключает тревогу, если датчик не касается воды.
Скетч программы для Arduino IDE
#include <ESP8266WiFi.h> #include <PubSubClient.h> const char *ssid = "xxxxxx"; // Имя роутера const char *pass = "xxxxxx"; // Пароль роутера const char *mqtt_server = "m13.cloudmqtt.com"; // Имя сервера MQTT const int mqtt_port = 14483; // Порт для подключения к серверу MQTT const char *mqtt_user = "xxxxxx"; // Логи для подключения к серверу MQTT const char *mqtt_pass = "xxxxxx"; // Пароль для подключения к серверу MQTT const int sensor = 0; // датчик воды const int drive1 = 3; // кран const int led = 5; // диод на плате #define BUFFER_SIZE 100 int tm = 300; float temp = 0; bool sensor_is_alarm = false; bool drive1_is_close = false; WiFiClient wclient; PubSubClient client(wclient); // Функция получения данных от сервера void callback(char* topic, byte* bpayload, unsigned int length) { // конвертируем byte в sting String payload = ""; for (int i = 0; i < length; i++) { payload = payload + (char)bpayload[i]; } Serial.print(topic); // выводим в сериал порт название топика Serial.print(" => "); Serial.println(payload); // выводим в сериал порт значение полученных данных // проверяем из нужного ли нам топика пришли данные if(topic == "valve/1" && sensor_is_alarm == false) { int value = payload.toInt(); if (value == 0) drive1_is_close = true; else drive1_is_close = false; } if(topic == "valve/alarm") { int value = payload.toInt(); if (value == 0) { sensor_is_alarm = false; } else { sensor_is_alarm = true; drive1_is_close = true; } } } void setup() { Serial.begin(115200); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); delay(10); Serial.println(); Serial.println(); pinMode(led, OUTPUT); pinMode(sensor, INPUT_PULLUP); pinMode(drive1, OUTPUT); digitalWrite(drive1, LOW); } // Функция проверка датчика воды void readSensor() { int sensorValue = analogRead(sensor); if (sensorValue < 1023 && sensor_is_alarm == false) { // сработал датчик потопа sensor_is_alarm = true; drive1_is_close = true; Serial.println("Alarm on"); } if (drive1_is_close == true) digitalWrite(drive1, HIGH); else digitalWrite(drive1, LOW); digitalWrite(led, sensor_is_alarm); } // Функция отправки показаний void sendCurrentValue() { if (tm == 0) { // отсылаем текущий статус //client.publish("valve/alarm", String(sensor_is_alarm)); //client.publish("valve/1", String(!drive1_is_close)); tm = 3000; // пауза меду отправками 3 секунды } tm--; } void loop() { // подключаемся к wi-fi if (WiFi.status() != WL_CONNECTED) { Serial.print("Connecting to "); Serial.print(ssid); Serial.println("..."); WiFi.begin(ssid, pass); if (WiFi.waitForConnectResult() != WL_CONNECTED) return; Serial.println("WiFi connected"); } // подключаемся к MQTT серверу if (WiFi.status() == WL_CONNECTED) { if (!client.connected()) { Serial.print("Connecting to MQTT server "); Serial.print(mqtt_server); Serial.println("..."); if (client.connect("arduinoClient", mqtt_user, mqtt_pass)) { Serial.println("Connected to MQTT server"); // подписываемся по топики client.subscribe("valve/1"); client.subscribe("valve/alarm"); } else { Serial.println("Could not connect to MQTT server"); } } readSensor(); if (client.connected()){ client.loop(); sendCurrentValue(); delay(1); } } }
Управление на телефона
Скачал на свой Android программу - IoT MQTT Dashboard. В ней настроил отображение значения топиков "valve/1", "valve/alarm", которые присылаются раз в 3 секунды. Для управления кранами создал два переключателя "valve/1" и "valve/alarm", которые отсылают строки "true" и "false" при переключении.
Теперь остается спаять схемку и подключить. Тратить время на печатную плату было лень и сделал все по простому.

Устройство закрепил в техническом шкафу санузла. Подвел питание 5 вольт от блока питания, что бы лишний раз не светить фазой возле водяных труб.

Модернизация
В планах на доработку системы - отказ от проводных датчиков и использовать радио модули 433 МГц датчиков охраны двери с герконом. Геркон выпаивается и подпаивается самопальный сенсор воды (Контакты на плате уже есть. Такой же датчик для воды стоит вдвое дороже но практически ничем не отличается.)

На плату нужно будет добавить приемник 433 МГц и доработать код.

Библиотека pubsubclient.h в приложении. Она используются в скетче. Если выйдет более свежая версия библиотеки - может потеряться обратная совместимость с кодом и тогда можно использовать pubsubclient.h из архива.
Он же вроде способен только быть либо 0 либо 1.
2) true/false и LOW/HIGH на логических выводах работает одинаково.
1)const int sensor = 0; // датчик воды
а на схеме указано что датчик подключен к выводу 5!?
2)разве можно там где LOW/HIGH присваивать true/false?
Если да, то почему так:
digitalWrite(drive1, drive1_is_close );
не сделать тут:
if (drive1_is_close == true) digitalWrite(drive1, HIGH);
else digitalWrite(drive1, LOW);
если нельзя то почему тут сделано так:
digitalWrite(led, sensor_is_alarm);
Вы правы. Внес исправление в код. Если есть какие-то другие замечания - с удовольствием выслушаю.
В вашей Скетч программе есть одна не точность. Если соединение не установлено то и проверка датчика на протекание не происходит и кран не закроется.