Ардуино контроллер. Управление твердотопливным котлом Arduino Nano

Статья о платформе для умного дома Arduino: пример реализации, настройки и програмирования умного дома.

Что такое Arduino?

Ардуино (Arduino) — специальный инструмент, позволяющий проектировать электронные устройства, имеющие более тесное взаимодействие с физической средой в сравнении с теми же ПК, фактически не выходящими за пределы виртуальной реальности.

В основе платформы лежит открытый код, а само устройство построено на печатной плате с «вшитым» в ней программным обеспечением.

Другими словами, Ардуино — небольшое устройство, обеспечивающее управление различными датчиками, системами освещения, принятия и передачи данных.

В состав Arduino входит микроконтроллер, представляющий собой собранный на одной схеме микропроцессор. Его особенность — способность выполнять простые задачи. В зависимости от модели устройство Ардуино может комплектоваться микроконтроллерами различных типов.

Существует несколько моделей плат, самые распространённые из них – UNO, Mega 2560 R3.

Не менее важная особенность печатной платы заключается в наличии 22 выводов, которые расположены по периметру изделия. Они бывают аналоговыми и цифровыми.

Особенность последних заключается в управлении с помощью только двух параметров — логической единицы или нуля. Что касается аналогового вывода, между 1 и 0 имеется много мелких участков.

Сегодня Arduino используется при создании электронных систем, способных принимать информацию с различных датчиков (цифровых и аналоговых).

Устройства на Ардуино могут работать в комплексе с ПО на компьютере или самостоятельно.

Что касается плат, их можно собрать своими руками или же приобрести готовое изделие. Программирование Arduino производится на языке Wiring.

ЧИТАЙТЕ ПО ТЕМЕ: Умный дом Xiaomi Smart Home, обзор, комплектация, подключение и настройка своими руками, сценарии.

Как работает такой умный дом?

Чтобы создать умный дом своими руками, потребуется навык Домовёнок Кузя. Через него можно не только контролировать умный дом, но и интегрировать виртуальные устройства напрямую в Яндекс.Алису. Это значит, что вам не придётся постоянно открывать навык, чтобы просто выключить лампочку. С микроконтроллером навык будет связываться через веб-хуки.

Для веб-хуков отлично подходит платформа Blynk — панель управления устройствами на Arduino и Raspberry Pi. Там вы сможете без труда создать графический интерфейс, через который можно будет управлять устройством по Wi-Fi (а ещё по Ethernet, USB, GSM и Bluetooth).

Предмет проекта домашней автоматики

Вашему вниманию представлен большой проект – автоматический щиток управления воздушной заслонкой твердотопливного домашнего котла (можно применять и для управления заслонкой уходящих газов).

В нем предусмотрено управление как аналоговой заслонкой, так и дискретной заслонкой системы отопления; предусмотрена защита от пропадания питающего напряжения сети 220 В.

Чем управляет Arduino?

Благодаря большому количеству выводов на печатной плате, к Ардуино удается подключить множество различных устройств, а именно:

Кроме того, к Ардуино подключается набор датчиков в зависимости от задач, поставленных перед системой. Как правило, устанавливаются датчики освещенности, дыма и состава воздуха, магнитного поля, влажности, температуры и прочие.

Благодаря этой особенности, Arduino становится универсальным устройством — «мозговым центром» системы «Умный дом» с возможностью конфигурации с учетом поставленных задач.

Преимущества системы Arduino

  1. Низкая стоимость по отношению к другим вариантам плат: готовые модули стоят 10 долларов.
  2. Межплатформенность ПО позволяет работать с операционными системами Windows, MacOSX, Linux.
  3. Интегрированная среда разработки IDE подходит для начинающих программистов, которые решили сделать Умный дом на Ардуино своими руками.
  4. Возможность создать небольшой проект за считаные минуты с помощью стандартных библиотек.
  5. Удобная в плане конструирования и соединения.

Какие устройства можно интегрировать в умный дом?

Через навык можно взаимодействовать с обширным количеством устройств: лампочки, розетки, шторы, замки, роботы-пылесосы, термостаты, очистители воздуха, кондиционеры и  чайники. Кроме этого, можно переключать каналы на телевизоре (через универсальный пульт) и менять цвета RGB-ламп.

Все устройства имеют базовую пару функций: включение и выключение (открытие и закрытие для штор и замков). Некоторые из устройств могут работать с диапазоном значений (яркость лампы, температура поддержки тепла для чайника).

Разработка проекта

На современном рынке представлено множество устройств Arduino, имеющих различную комплектацию. Но универсального решения «на все случаи жизни» не существует. В зависимости от поставленной задачи каждый комплект подбирается в индивидуальном порядке. Чтобы избежать ошибок, требуется разработка проекта.

Какие проекты можно создавать на Arduino?

Ардуино позволяет создавать множество уникальных проектов. Вот лишь некоторые из них:

  • Сборка кубика Рубика (система справляется за 0,887 с);
  • Контроль влажности в подвальном помещении;
  • Создание уникальных картин;
  • Отправка сообщений;
  • Балансирующий робот на двух колесах;
  • Анализатор спектра звука;
  • Лампа оригами с емкостным сенсором;
  • Рука-робот, управляемая с помощью Ардуино;
  • Написание букв в воздухе;
  • Управление фотовспышкой и многое другое.

Читайте также:
main.jpg

Составление проекта для умного дома

Рассмотрим ситуацию, когда необходимо сделать автоматику для дома с одной комнатой.

Такое здание состоит из пяти основных зон — прихожей, крыльца, кухни, санузла, а также комнаты для проживания.

При составлении проекта стоит учесть следующее:

  • КРЫЛЬЦО. Включение света производится в двух случая — приближение хозяина к дому в темное время суток и открытие дверей (когда человек выходит из здания).
  • САНУЗЕЛ. В бойлере предусмотрен выключатель питания, который при достижении определенной температуры выключается. Управление бойлером производится в зависимости от наличия соответствующей автоматики. При входе в помещение должна срабатывать вытяжка, и загорается свет.
  • ПРИХОЖАЯ. Здесь требуется включение света при наступлении темноты (автоматическое), а также система обнаружения движения. Ночью включается лампочка небольшой мощности, что исключает дискомфорт для других жильцов дома.
  • КОМНАТА. Включение света производится вручную, но при необходимости и наличии датчика движения эта манипуляция может происходить автоматически.
  • КУХНЯ. Включение и отключение света на кухне осуществляется в ручном режиме. Допускается автоматическое отключение в случае продолжительного отсутствия перемещений по комнате. Если человек начинает готовить пищу, активируется вытяжка.

Отопительные устройства выполняют задачу поддержания необходимой температуры в помещении. Если в доме отсутствуют люди, нижний предел температуры падает до определенного уровня.

После появления людей в здании этот параметр поднимается до прежнего значения. Рекуперация воздуха осуществляется в случае, когда система обнаружила присутствие владельца. Продолжительность процесса — не более 10 минут в час.

Стоит обратить внимание, что если в доме планируется установка умных розеток, то для управления ими лучше использовать приложения на мобильных устройствах, WIFI или через SMS сообщения.

Визуальное программирование для Arduino можно осуществлять с помощью специального приложения FLProg, которое можно скачать с официального сайта https://flprog.ru/.

Какие решения предлагает Arduino

Датчики и устройства, совместимые с Ардуино, выпускают многие производители, поэтому ассортимент комплектующих для системы Умный дом на Arduino внушительный:

  • Сенсоры для отслеживания температуры, освещенности в разное время суток, влажности, осадков и атмосферного давления.
  • Сенсоры реагирования на движение.
  • Аварийные датчики.
  • Другие устройства и пульты.

В набор Arduino Start (у большинства производителей – StarterKit) включена часть индикаторов и датчиков.

Для исполнения команд, направляемых системой Умный дом на базе Arduino, требуются:

  • реле и переключатели;
  • вентили;
  • электромоторы;
  • 3-ходовые клапаны с сервоприводом;
  • диммеры.

Примечание: для освещения в системе Умный дом своими руками на базе Arduino используются светодиоды, так как лампы накаливания при подключении через реле сразу горят.

Начало работы

Как только необходимое оборудование подготовлено, а проект разработан, можно приступать к выполнению поставленной задачи.

Этапы

При организации системы «Умный дом» на базе Ардуино, стоит действовать по следующему алгоритму:

  • Инсталляция программного кода;
  • Конфигурация приложения под применяемое устройство;
  • Переадресация портов (для роутера);
  • Проведение тестов;
  • Внесение правок и так далее.

В Сети имеется весь необходимый софт на применяемое оборудование — его достаточно скачать с официального сайта и установить (ссылку смотрите выше).

Приложение позволяет увидеть информацию о датчиках. Если это требуется, настройки IP-адрес могут быть изменены.

Последовательность действий при подключении к компьютеру

Чтобы начать работать с Ардуино в Windows, сделайте следующие шаги:

Работа с роутером

Для полноценной работы «Умного дома» важно правильно обращаться с роутером. Здесь требуется выполнить следующие действия — открыть конфигурацию, указать адрес Arduino IP, к примеру, 192.168.10.101 и открыть 80-й порт.

После требуется присвоить адресу доменное имя и перейти к процессу тестирования проекта. Учтите, что для такой системы запрещено применение открытого IP-адреса, ведь в этом случае высок риск взлома через Сеть.

Читайте также:
main.jpg

Обучение азов Arduino

С помощью приложения «Справочник по Arduino 2» можно в течении двух недель освоить материал. Приложение полностью автономно и не требует подключение к интернету. В нем описана такая информация: функции, данные, операторы, библиотеки Arduino.

После освоения азов, можно посетить ресурс Habrahabr, на котором собраны 100 уроков по программированию на Arduino.

Тем, кто привык черпать знания из книг, станет замечательным пособием для теории и практики «Джереми Блум: изучаем Arduino».

Самый популярный учебник по Arduino

В книге приведены основные сведения об аппаратном и программном обеспечении Ардуино. Рассказаны принципы программирования в среде Arduino IDE. Автор книги учит анализу электрических схем и чтению технических заданий. Информация из книги поможет в дальнейшем определится с выбором подходящих деталей для создания умного дома.

Автор приводит примеры работы электродвигателей, датчиков, индикаторов, сервоприводов, всевозможных интерфейсов передачи данных. Книга содержит иллюстрированные комплектующие, монтажные схемы и листинги программ. Самое главное, комплектующие для практики, с которыми работает автор – не дорогой, не сложный и популярный материал для экспериментальных сборок в домашних условиях.

Расширение возможности на Ардуино

Одной из возможностей умного дома является визуализация состояния автоматики и проходящих в системе процессов. Для этого рекомендуется применять отдельный сервер, обеспечивающий обработку состояний (может применяться программа Node.js).

Упомянутая программная технология применяется для решения интернет-задач, поэтому для визуализации «Умного дома» используется язык Java Script (именно с его помощью создается обработчик и сервер). Результаты можно увидеть на экране компьютера или ПК.

Для реализации задуманного подойдет ноутбук, обычный ПК или Raspberry Pi. Применение такой системы позволяет увеличить ее возможности. Так, если на плате Ардуино имеется небольшой объем памяти, на сервере такие ограничения отсутствуют. Программа пишется таким образом, чтобы обеспечить полное управление платформой.

При желании можно задать алгоритм, который будет фиксировать факт нахождения человека в доме, и собирать эту информацию. Если владелец ежедневно возвращается где-то к 17.30, за час может быть включен бойлер или отопительные устройства. По приходу домой человек попадает в теплое здание с горячей водой.

Программа может запомнить время, когда владелец ложится отдыхать и отключать нагрев воды. Таких нюансов, которые при необходимости вносятся в программу, множество. Именно наличие внешнего ПК дает большие возможности контроллеру на Ардуино.

Программа для контроллера Arduino Nano

#include <Wire.h> #include <LiquidCrystal_I2C.h>#include <EEPROM.h>#include <OneWire.h>#include <max6675.h>#include <Servo.h>//datchiki DS18B20OneWire temp1(0);OneWire temp2(1);byte addr1[8];byte addr2[8];float celsius[3];int dsreset[2] = {0, 0};int servodelay;unsigned long prevMillis_ds[3] = {0, 0, 0};//datchiki DS18B20byte degree[8] = {B00110, B01001, B01001, B00110, B00000, B00000, B00000};//символ градуса для записи в память индикатораServo myservo;unsigned int K1 = 0.0;float PIDOUT = 0;float error, errSum, output, derror;float Kp, Ki, T1sp, T3sp, dT3sp, T2rozpaleno, T1potyhlo, T2max, dT2max;unsigned int t2rozpaleno, t1potyhlo, powerout;unsigned long rozpalenoMillis = 0;unsigned long potyhloMillis = 0;unsigned long poweroutMillis = 0;int OUTMIN, OUTMAX, MANOUT;bool KZ1MAN, KZ1AUTO;LiquidCrystal_I2C lcd(0x27, 16, 2);int thermoDO = 10;int thermoCS = 12;int thermoCLK = 11;MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);const int ButRUN = 6;const int ButSTOP = 7;const int LampRUN = 8;const int LampSTOP = 9;int powerPin = A7;bool power;const int KZ1pin = 2;bool KZ1;boolean L1, L2, L3;int L1_count = 0;int L2_count = 0;int L3_count = 0;const int button = 14;int button_old = 1;int p = 4; int piskpower = 3; //номер пина, к которому подключен пьезоэлементunsigned long piskMillis = 0;unsigned long piskwaitMillis = 0;unsigned long piskwait, piskset;bool pisk_once = 0;bool pisk1 = 0;bool highT2old = 0;int piskstep;int astep;int menu = 0;int menu_ = 0;int avto = 0; //rezhim avtoboolean Heat[4] = {0, 0, 0, 0};int pinA = 16; // номер вывода, подключенный к CLK енкодераint pinB = 15; // номер вывода контроллера, подключенный к DT енкодера int encoderPosCount = 0; int pinALast; int aVal; boolean bCW;unsigned long prev_Servo_delay = 0;unsigned long previousMillis = 0;unsigned long currentMillis;const long interval = 500;unsigned long prevMS[4];unsigned long curMS[4];void setup(){ EEPROM.get(50, Kp); EEPROM.get(55, T1sp); EEPROM.get(70, T3sp); EEPROM.get(75, dT3sp); EEPROM.get(40, T2rozpaleno); EEPROM.get(45, T1potyhlo); EEPROM.get(21, Ki); EEPROM.get(31, OUTMIN); EEPROM.get(25, OUTMAX); EEPROM.get(27, t2rozpaleno); EEPROM.get(29, t1potyhlo); EEPROM.get(33, powerout); EEPROM.get(60, T2max); EEPROM.get(65, dT2max); EEPROM.get(70, derror); myservo.attach(5); MANOUT = OUTMIN; servodelay = OUTMIN; myservo.write(MANOUT); pinMode(button, INPUT_PULLUP); pinMode (pinA,INPUT); pinMode (pinB,INPUT); pinMode(ButRUN, INPUT_PULLUP); pinMode(ButSTOP, INPUT_PULLUP); pinMode(piskpower, OUTPUT); pinMode(LampRUN, OUTPUT); pinMode(LampSTOP, OUTPUT); pinMode(KZ1pin, OUTPUT); pinMode(p, OUTPUT); //пищалка lcd.begin(); lcd.createChar(1, degree); lcd.backlight(); lcd.setCursor(0, 0); lcd.print(“Privit,”); lcd.setCursor(7, 1); lcd.print(“gospodar!”); temp1.search(addr1); temp2.search(addr2); delay(2000); pinALast = digitalRead(pinA); currentMillis = millis(); previousMillis = currentMillis; piskMillis = currentMillis; piskwaitMillis = currentMillis;}void loop(){ power = analogRead(powerPin)>500; currentMillis = millis(); if (!digitalRead(ButRUN)) {avto=1; astep = 100; rozpalenoMillis = currentMillis; potyhloMillis = currentMillis; pisk_once = 0;} if ((!digitalRead(ButSTOP))||(celsius[0]>999.0)||(String(celsius[2],0)==”NAN”)) {avto=0; astep = 0; MANOUT = OUTMIN; menu=0; encoderPosCount=0; pisk_once = 0;} currentMillis = millis(); if (avto==0) {errSum = 0.0; PIDOUT = OUTMIN;} //datchiki DS18B20 func_dallas(temp1, addr1, 0); func_dallas(temp2, addr2, 1); //datchiki DS18B20 currentMillis = millis(); if (currentMillis – prevMillis_ds[2] >= 1000) { prevMillis_ds[2] = currentMillis; celsius[2] = thermocouple.readCelsius(); if (avto==1) func_auto(); func_outs(); } func_encoder(); func_menu(); func_button(); currentMillis = millis(); if (currentMillis – prev_Servo_delay >= 150) { prev_Servo_delay = currentMillis; if (avto==1) K1 = PIDOUT; else K1 = MANOUT; if (servodelay < K1) servodelay=servodelay+1; if (servodelay > K1) servodelay=servodelay-1; myservo.write(servodelay); } func_pisk(); func_ac();}
void func_ac(){ if ((avto==1)&&(power)){ currentMillis = millis(); if (currentMillis – poweroutMillis > powerout*1000) { avto=0; MANOUT = OUTMIN; KZ1MAN = 0; astep=0; } } else poweroutMillis = currentMillis;}
void func_dallas(OneWire ds, byte addr[8], int num){ byte present = 0; int temp; unsigned long curMillis_ds; if (dsreset[num]==0){ ds.reset(); ds.select(addr); ds.write(0x44); dsreset[num] = 1; } curMillis_ds = millis(); if (curMillis_ds – prevMillis_ds[num] >= 1000) { prevMillis_ds[num] = curMillis_ds; dsreset[num] = 0; present = ds.reset(); ds.select(addr); ds.write(0xBE); temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры if (present==1) celsius[num] = (float)temp / 16.0; else celsius[num] = 1000.00; }} void func_outs(){ //button_old = digitalRead(button); digitalWrite(LampRUN, avto); digitalWrite(LampSTOP, !avto); if (avto==1) {KZ1 = KZ1AUTO; KZ1MAN = KZ1AUTO;} else KZ1 = KZ1MAN; digitalWrite(KZ1pin, KZ1); }
void func_pid(){ if (Kp>=0.0) error = T1sp – celsius[2]; else error = celsius[2] – T1sp; errSum += error; //if (Ki *errSum/100.0>OUTMAX) errSum=OUTMAX*100.0/Ki; //if (Ki *errSum/100.0<-OUTMAX) errSum=-OUTMAX*100.0/Ki; output = abs(Kp) * error + Ki * errSum/100.0; if ((output > OUTMAX)||(output < OUTMIN)) errSum = ((K1 – (abs(Kp) * error))/Ki) * 100.0;; PIDOUT = output; if (PIDOUT>OUTMAX) PIDOUT=OUTMAX; if (PIDOUT<OUTMIN) PIDOUT=OUTMIN;}void func_auto(){ if (celsius[1]<1000.0){ if (celsius[1] > T3sp) KZ1AUTO = 0; if (celsius[1] < T3sp – dT3sp) KZ1AUTO = 1; }else{ KZ1AUTO = 1; } if (celsius[0] > T2max+10.0) { pisk_once = 1; piskset = 3000; }else pisk_once = 0; if (astep==100){ //bezydarnost if (Kp>=0.0) error = T1sp – celsius[2]; else error = celsius[2] – T1sp; errSum = ((K1 – (abs(Kp) * error))/Ki) * 100.0; //bezydarnost PIDOUT = OUTMIN; if (celsius[0] > T2rozpaleno){ currentMillis = millis(); if (currentMillis – rozpalenoMillis > t2rozpaleno*1000) { astep = 200; potyhloMillis = currentMillis; } }else rozpalenoMillis = currentMillis; } if (astep==200){ if ((abs(T1sp – celsius[2]))>derror) func_pid(); if (celsius[2] < T1potyhlo){ currentMillis = millis(); if (currentMillis – potyhloMillis > t1potyhlo*1000) { astep = 300; piskwait = 1000; piskset = 15000; piskwaitMillis = currentMillis; } }else potyhloMillis = currentMillis; if (celsius[0] > T2max) astep=400; } if (astep==300){ avto=0; MANOUT = OUTMIN; KZ1MAN = 0; } if (astep==400){ PIDOUT = OUTMIN; if (celsius[0] < T2max – dT2max) { astep = 100; rozpalenoMillis = currentMillis; } } }void func_button(){ if ((digitalRead(button)==LOW)&&(button_old==1)) { if ((menu == 1)and(button_old==1)) { switch (menu_) { case 0: menu = 100; encoderPosCount=MANOUT; break; case 1: menu = 200; encoderPosCount=0; break; case 2: menu = 300; encoderPosCount=0; break; case 3: menu = 400; encoderPosCount=0; break; case 4: menu = 0; encoderPosCount=0; break; } button_old=0; } if ((menu == 100)and(button_old==1)) { menu = 1; encoderPosCount = 0; button_old=0; } if ((menu == 200)and(button_old==1)) { switch (menu_) { case 0: KZ1MAN = !KZ1MAN; break; case 1: menu = 1; encoderPosCount=1; break; } button_old=0; } if ((menu == 300)and(button_old==1)) { switch (menu_) { case 0: menu = 301; encoderPosCount = T1sp; break; case 1: menu = 302; encoderPosCount = T2rozpaleno; break; case 2: menu = 303; encoderPosCount = T1potyhlo; break; case 3: menu = 304; encoderPosCount = t2rozpaleno; break; case 4: menu = 305; encoderPosCount = t1potyhlo; break; case 5: menu = 306; encoderPosCount = T3sp; break; case 6: menu = 307; encoderPosCount = dT3sp; break; case 7: menu = 308; encoderPosCount = powerout; break; case 8: menu = 309; encoderPosCount = T2max; break; case 9: menu = 310; encoderPosCount = dT2max; break; case 10: menu = 1; encoderPosCount=2; break; } button_old=0; } if ((menu == 301)and(button_old==1)) { menu = 300; T1sp = encoderPosCount; EEPROM.put(55, T1sp); encoderPosCount = 0; button_old=0; } if ((menu == 302)and(button_old==1)) { menu = 300; T2rozpaleno = encoderPosCount; EEPROM.put(40, T2rozpaleno); encoderPosCount = 1; button_old=0; } if ((menu == 303)and(button_old==1)) { menu = 300; T1potyhlo = encoderPosCount; EEPROM.put(45, T1potyhlo); encoderPosCount = 2; button_old=0; } if ((menu == 304)and(button_old==1)) { menu = 300; t2rozpaleno = encoderPosCount; EEPROM.put(27, t2rozpaleno); encoderPosCount = 3; button_old=0; } if ((menu == 305)and(button_old==1)) { menu = 300; t1potyhlo = encoderPosCount; EEPROM.put(29, t1potyhlo); encoderPosCount = 4; button_old=0; } if ((menu == 306)and(button_old==1)) { menu = 300; T3sp = encoderPosCount; EEPROM.put(70, T3sp); encoderPosCount = 5; button_old=0; } if ((menu == 307)and(button_old==1)) { menu = 300; dT3sp = encoderPosCount; EEPROM.put(75, dT3sp); encoderPosCount = 6; button_old=0; } if ((menu == 308)and(button_old==1)) { menu = 300; powerout = encoderPosCount; EEPROM.put(33, powerout); encoderPosCount = 7; button_old=0; } if ((menu == 309)and(button_old==1)) { menu = 300; T2max = encoderPosCount; EEPROM.put(60, T2max); encoderPosCount = 8; button_old=0; } if ((menu == 310)and(button_old==1)) { menu = 300; dT2max = encoderPosCount; EEPROM.put(65, dT2max); encoderPosCount = 9; button_old=0; } if ((menu == 400)and(button_old==1)) { switch (menu_) { case 0: menu = 401; encoderPosCount = Kp*10; break; case 1: menu = 402; encoderPosCount = Ki; break; case 2: menu = 403; encoderPosCount = OUTMIN; break; case 3: menu = 404; encoderPosCount = OUTMAX; break; case 4: menu = 405; encoderPosCount = derror; break; case 5: menu = 1; encoderPosCount=3; break; } button_old=0; } if ((menu == 401)and(button_old==1)) { menu = 400; Kp = encoderPosCount*0.1; EEPROM.put(50, Kp); encoderPosCount = 0; button_old=0; } if ((menu == 402)and(button_old==1)) { menu = 400; Ki = encoderPosCount; EEPROM.put(21, Ki); encoderPosCount = 1; button_old=0; } if ((menu == 403)and(button_old==1)) { menu = 400; OUTMIN = encoderPosCount; EEPROM.put(31, OUTMIN); encoderPosCount = 2; button_old=0; } if ((menu == 404)and(button_old==1)) { menu = 400; OUTMAX = encoderPosCount; EEPROM.put(25, OUTMAX); encoderPosCount = 3; button_old=0; } if ((menu == 405)and(button_old==1)) { menu = 400; derror = encoderPosCount; EEPROM.put(70, derror); encoderPosCount = 4; button_old=0; } if ((menu == 0)and(button_old==1)) { menu = 1; menu_ = 0; button_old=0; encoderPosCount=0; } menu_ = 0; } button_old = digitalRead(button); }void func_encoder(){ //encoder aVal = digitalRead(pinA); if (aVal != pinALast){ // проверка на изменение значения на выводе А по сравнению с предыдущим запомненным, что означает, что вал повернулся // а чтобы определить направление вращения, нам понадобится вывод В. if (digitalRead(pinB) != aVal) { // Если вывод A изменился первым – вращение по часовой стрелке encoderPosCount ++; bCW = true; } else {// иначе B изменил свое состояние первым – вращение против часовой стрелки bCW = false; encoderPosCount–; } } pinALast = aVal; //encoder}void func_menu(){ int celsius2; if (currentMillis – previousMillis >= interval) { previousMillis = currentMillis; if (menu == 1){ if (encoderPosCount>4) encoderPosCount = 0; if (encoderPosCount<0) encoderPosCount = 4; menu_ = encoderPosCount; lcd.setCursor(0, 0); lcd.print(“>”); switch (menu_) { case 0: lcd.print(“K1 “); break; case 1: lcd.print(“KZ1 “); break; case 2: lcd.print(“Parametri “); break; case 3: lcd.print(“PID reguliator “); break; case 4: lcd.print(“EXIT “); break; } lcd.setCursor(0, 1); switch (menu_) { case 4: lcd.print(“K1 “); break; case 0: lcd.print(“KZ1 “); break; case 1: lcd.print(“Parametri “); break; case 2: lcd.print(“PID reguliator “); break; case 3: lcd.print(“EXIT “); break; } } if (menu == 0){ lcd.setCursor(0, 0); celsius2 = celsius[2]; if (String(celsius[2],0)==”NAN”){lcd.print(” ERR “);} else {lcd.print(celsius2);} lcd.print(“1C “); lcd.setCursor(6, 0); if (!power) lcd.print(“AV “); else lcd.print(“av “); if (KZ1) lcd.print(“KZ”); else lcd.print(“kz”); lcd.print(” “); lcd.print(K1); lcd.print(“1 “); lcd.setCursor(0, 1); //lcd.print(“er”); lcd.print(error); lcd.print(“ers”); lcd.print(errSum);lcd.print(” “); celsius2 = celsius[0]; if (celsius[0]<1000.0) {lcd.print(celsius2);lcd.print(“1C “);} else {lcd.print(“ERROR “);} switch (astep) { case 100: lcd.print(“#”); break; case 200: lcd.write(byte(178)); break; case 400: lcd.write(byte(64)); break; default: lcd.print(“_”); break; } lcd.print(” “); celsius2 = celsius[1]; if (celsius[1]<1000.0) {lcd.print(celsius2);lcd.print(“1C”);} else lcd.print(“ERROR”); lcd.print(” “); } if (menu == 100){ if (encoderPosCount>180) encoderPosCount = 180; if (encoderPosCount<0) encoderPosCount = 0; MANOUT = encoderPosCount; lcd.setCursor(0, 0); lcd.print(“Otkritie K1 “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” grad “); } if (menu == 200){ if (encoderPosCount>1) encoderPosCount = 0; if (encoderPosCount<0) encoderPosCount = 1; menu_ = encoderPosCount; lcd.setCursor(0, 0); lcd.print(“>”); switch (menu_) { case 0: if (KZ1) lcd.print(“KZ1 OTKRITO “); else lcd.print(“KZ1 ZAKRITO “); break; case 1: lcd.print(“EXIT “); break; } lcd.setCursor(0, 1); switch (menu_) { case 1: if (KZ1) lcd.print(“KZ1 OTKRITO “); else lcd.print(“KZ1 ZAKRITO “); break; case 0: lcd.print(“EXIT “); break; } } if (menu == 300){ if (encoderPosCount>10) encoderPosCount = 0; if (encoderPosCount<0) encoderPosCount = 10; menu_ = encoderPosCount; lcd.setCursor(0, 0); lcd.print(“>”); switch (menu_) { case 0: lcd.print(“T1sp DG “); break; case 1: lcd.print(“T2rozpaleno SO “); break; case 2: lcd.print(“T1potyhlo DG “); break; case 3: lcd.print(“t2rozpaleno “); break; case 4: lcd.print(“t1potyhlo “); break; case 5: lcd.print(“T3sp GVS “); break; case 6: lcd.print(“dT3sp GVS “); break; case 7: lcd.print(“t3 nema 220V “); break; case 8: lcd.print(“T2max SO “); break; case 9: lcd.print(“dT2max SO “); break; case 10:lcd.print(“EXIT “); break; } lcd.setCursor(0, 1); switch (menu_) { case 10:lcd.print(“T1sp DG “); break; case 0: lcd.print(“T2rozpaleno SO “); break; case 1: lcd.print(“T1potyhlo DG “); break; case 2: lcd.print(“t2rozpaleno “); break; case 3: lcd.print(“t1potyhlo “); break; case 4: lcd.print(“T3sp GVS “); break; case 5: lcd.print(“dT3sp GVS “); break; case 6: lcd.print(“t3 nema 220V “); break; case 7: lcd.print(“T2max SO “); break; case 8: lcd.print(“dT2max SO “); break; case 9: lcd.print(“EXIT “); break; } } if (menu == 301){ if (encoderPosCount>600) encoderPosCount = 600; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“Zadana T1sp DG “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 302){ if (encoderPosCount>100) encoderPosCount = 100; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“T2 SO rozpalen “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 303){ if (encoderPosCount>600) encoderPosCount = 600; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“T1 DG potyhlo “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 304){ if (encoderPosCount>60000) encoderPosCount = 60000; if (encoderPosCount<1) encoderPosCount = 1; lcd.setCursor(0, 0); lcd.print(“Chas rozpaleno “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” cek “); } if (menu == 305){ if (encoderPosCount>60000) encoderPosCount = 60000; if (encoderPosCount<1) encoderPosCount = 1; lcd.setCursor(0, 0); lcd.print(“Chas potyhlo “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” cek “); } if (menu == 306){ if (encoderPosCount>100) encoderPosCount = 100; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“Zadana T3sp GVS “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 307){ if (encoderPosCount>30) encoderPosCount = 30; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“Delta dT3sp GVS “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 308){ if (encoderPosCount>60000) encoderPosCount = 60000; if (encoderPosCount<1) encoderPosCount = 1; lcd.setCursor(0, 0); lcd.print(“Chas koly ‘ac'”); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” cek “); } if (menu == 309){ if (encoderPosCount>100) encoderPosCount = 100; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“Zadana T2max SO “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 310){ if (encoderPosCount>100) encoderPosCount = 100; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“Delta dT2max SO “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } if (menu == 400){ if (encoderPosCount>5) encoderPosCount = 0; if (encoderPosCount<0) encoderPosCount = 5; menu_ = encoderPosCount; lcd.setCursor(0, 0); lcd.print(“>”); switch (menu_) { case 0: lcd.print(“Kp “); break; case 1: lcd.print(“Ki “); break; case 2: lcd.print(“OUTMIN “); break; case 3: lcd.print(“OUTMAX “); break; case 4: lcd.print(“dBAND “); break; case 5: lcd.print(“EXIT “); break; } lcd.setCursor(0, 1); switch (menu_) { case 5: lcd.print(“Kp “); break; case 0: lcd.print(“Ki “); break; case 1: lcd.print(“OUTMIN “); break; case 2: lcd.print(“OUTMAX “); break; case 3: lcd.print(“dBAND “); break; case 4: lcd.print(“EXIT “); break; } } if (menu == 401){ if (encoderPosCount>1000) encoderPosCount = 1000; if (encoderPosCount<-1000) encoderPosCount = -1000; lcd.setCursor(0, 0); lcd.print(“Kp -100…100 “); lcd.setCursor(0, 1); lcd.print(encoderPosCount*0.1); lcd.print(” “); } if (menu == 402){ if (encoderPosCount>10000) encoderPosCount = 10000; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“Ki 0…10000 “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” “); } if (menu == 403){ if (encoderPosCount>180) encoderPosCount = 180; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“OUTMIN 0…180 “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” grad “); } if (menu == 404){ if (encoderPosCount>180) encoderPosCount = 180; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“OUTMAX 0…180 “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” grad “); } if (menu == 405){ if (encoderPosCount>200) encoderPosCount = 200; if (encoderPosCount<0) encoderPosCount = 0; lcd.setCursor(0, 0); lcd.print(“dBAND 0…200 “); lcd.setCursor(0, 1); lcd.print(encoderPosCount); lcd.print(” 1C “); } }}void func_pisk(){ if ((pisk_once)||(astep==300)){ currentMillis = millis(); if (currentMillis – piskwaitMillis > piskwait) { piskwaitMillis = currentMillis; if (!pisk1){ pisk1 = 1; digitalWrite(piskpower, HIGH); tone (p, 1000); //пищим на частоте 1000 Гц} piskwait = 1000; }else{ pisk1 = 0; noTone(p); //выключаем звук digitalWrite(piskpower, LOW); piskwait = piskset; } } currentMillis = millis(); if (currentMillis – piskMillis > 3600000) { pisk_once = 0; if (astep==300) astep = 0; noTone(p); //выключаем звук digitalWrite(piskpower, LOW);} }else {piskMillis = currentMillis; piskwait = 1000; piskwaitMillis = currentMillis; noTone(p);}}

Общение с Arduino

Чтобы узнать, какие действия осуществлять, процессор должен получить соответствующую команду. Общение производится с помощью специального языка, который адаптирован под работу с Ардуино и достаточно прост. При желании в нем легко работаться даже при отсутствии навыков программирования.

Оформление и отправка сообщения контроллеру называется программированием. Чтобы упростить процесс, разработана среда Arduino IDE, в состав которой входит множество программ. Их изучение позволяет получить массу полезной информации о работе с Ардуино.

Прототип скетча

Здесь не полная версия программы Ардуино, но предоставленная часть рабочая и требует минимального доведения руками. Конкретно понадобиться выставить пороги срабатывания в зависимости полученных данных (помечено «обратить внимание») от термистора и оптического датчика. Все остальное, включая интерфейсную часть — сделано.

Ссылка для скачивания скетча: https://cloud.mail.ru/public/eSuY/tefqzrxXS

Готовые комплекты и решения

Получение функциональности умного дома доступно не только самодельным методом. Продаются готовые комплекты и наборы оборудования, которые можно объединять в единую систему. Сюда входят:

  • блок микроконтроллера;
  • беспроводные выключатели;
  • датчики дыма, движения, температуры, открытия;
  • управляемые розетки с контролем состояния;
  • пульт дистанционного управления или иное средство коммуникации с пользователем;
  • сигнализаторы;
  • модемы или роутеры, позволяющие вывести информацию из системы в сеть;
  • камеры видеонаблюдения;
  • блоки бесперебойного питания.

Возможности контроля таких систем достаточно широки и могут выражаться не только в реакции на нажатие физического выключателя или кнопки на пульте. Доступно начальное программирование функций (времени включения, расписания) и проверка происходящего через сеть.

Пример интерфейса «умного дома»

Объем сервисных возможностей, предоставляемых комплексами такого класса, непосредственно зависит от их стоимости и бренда. Доступно расширение начальной комплектации дополнительными устройствами от производителя, ориентированными на интеграцию в конкретную систему.

Распространенные комплексы выполняют контроль оборудования по нескольким физическим интерфейсам, каждый из которых имеет определенные плюсы и минусы в установке с использованием. Речь идет о проводных и беспроводных коммуникациях. Кроме того, управление может осуществляться на уровне одного микроконтроллера или быть распределенным по различным «умным» элементам. В последнем случае система не сильно зависит от центра, который осуществляет только объединяющую функцию.

Модели умных домов, представленные на рынке

Бренд/название Комплектация Коммуникации Удаленное управление/контроль Расширение уст-ми производителя Пульт *Универсальность Цена (руб)
Xiomi Smart Home Suite Контроллер, замаскированный под настольную лампу, датчики открытия и движения, умная розетка и беспроводная кнопка включения Проводные Приложение Mi Home Есть Нет Нет 5000
Redmond Smart Home Продается раздельно, собирается во едино с основой в виде модуля skycenter Bluetooth Приложение Ready for Sky Есть Есть Нет
Vstarcam E27AR-TZ1V Умная камера (по совместительству контроллер), датчики движения и открывания дверей, светильник и управляемая розетка ИК Приложение на мобильный телефон, электронная почта Есть Есть Нет 12000
NooLite mini kit Приложение на мобильный телефон Есть Есть Есть 14000
Fibaro starter kit Контроллер, БП, Датчики в комплекте: освещенности, движения, температуры, протечки, открытия Веб-интерфейс, приложение смартфона Есть Есть Есть 50000
Wulian Smart Home Дизайнерский контроллер Радио Приложение Есть Нет Есть

* Универсальность — подразумевает подключение внешних устройств не только через розетку, но и иные контроллеры. К примеру, внешние реле времени или силовые повторители.

Рейтинг
( 1 оценка, среднее 5 из 5 )
Загрузка ...