☰ Оглавление

Управление умным домом на расстоянии (продолжение)

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

В этот раз попробуем модернизировать наш прошлый пульт управления, чтобы вы могли убедится в том, что умный дом можно создать и самому, без сложных устройств и большого опыта.

Комплектующие

Я возьму за основу 3 пункт из прошлой статьи (соединение двух плат через два Bluethooth модуля).

Нам понадобится:

  • LCD дисплей (16×2)
  • Кнопка
  • Реостат
  • Зуммер
  • Две платы Arduino UNO
  • Два Bluetooth модуля HC-05
  • Реле с лампой (постоянные гости нашей рубрики, смотрите 1-ую статью)
  • Сервопривод
  • Дальномер (HC-SR04)
  • Термистор (B57164-K 103-J )

Система, назову ее "Master", будет отправлять команды на систему "Slave", затем "Slave" отправит информацию "Master" об исполнении команды или данные с датчиков. Разберемся с системами поподробнее.

Система Master

Master. Она будет состоять из:

  • Зуммера
  • Реостата
  • Кнопки
  • LCD дисплея
  • Bluetooth модуля
  • Arduino UNO

За основу берем прошлый опыт, а значит информация будет отправляется по нажатию кнопки, но на пульте будет теперь три вида услуг (температура; включение и выключение лампы; нахожусь ли я на рабочем месте) информация будет разной в зависимости от выбранной услуги (0;1 - включение\выключение реле) (2;3 - показание температуры) (4;5 - движение сервопривода).

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

Так как у нас свободно движется ручка потенциометра, то говорить нам, о смене вида услуг, будет зуммер.

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

Проблема будет все это подключить, но пинов будет достаточно, чтобы подключить и не только то, что я перечислил выше. LCD дисплей имеет 16 штырьков, но для работы с ним хватит всего 6 пинов для ардуино.

Также подключаем Bluethooth модуль, как и в прошлом опыте, главное, чтобы вы сразу настроили их на работу одно как Slave устройство, а второе как Master. Об этом мы подробно говорили в прошлой статье.

  • Реостат подключаем к пину A0
  • Кнопку к цифровому пину 8
  • Зуммер к цифровому пину 7

Теперь перейдем к коду Мастера:

int data = 0; // присылаемые данные
int reading = 8; // пин, который считывает значение с кнопки `  
int zum = 0;    //
int val = 0; // значение с реостата
boolean buttem = 0; // значение кнопки до нажатия
boolean butlig = 0; // значение кнопки до нажатия
boolean butwok = 0;// значение кнопки до нажатия
boolean currentButtontem = 0; // значение кнопки после нажатия
boolean currentButtonlig = 0; // значение кнопки после нажатия
boolean currentButtonwok = 0;// значение кнопки после нажатия
boolean sendt = 0; // отсылаемые данные для режима "Термистр"
boolean sendl = 0; // отсылаемые данные для режима "Lamp"
boolean sendw = 0;// отсылаемые данные для режима "Work place"
#define BUZZER_PIN     7 // пин для зуммера
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
   lcd.begin(16, 2); 
  Serial.begin(38400);
  Serial.setTimeout(40); // При вызове parseInt() задержка ожидания последующего символа по умолчанию 1 секунда.
  // Функцией setTimeout() можно уменьшить эту задержку. Например на 40 миллисекунд, setTimeout(40);.
  pinMode(reading,INPUT); //  
}
void signaling() // функция для звучания зуммера
{
  tone(BUZZER_PIN, 300, 300);
  delay(300);
}
boolean Button( boolean got ) // функция, которая принимает предыдущее значение нажатия кнопки и отправляет текущие значение
{
  boolean current = digitalRead(reading);
  if( !got == current)
    {
      delay(10);
      current = digitalRead(reading);
    }
    return(current);
 }
void loop() 
{   val = analogRead(A0); //  читаем значение реостата и выбираем режим в зависимости от положения ручки
    if ( val>=0 && val<=270) 
    { 
    zum = 0; // это переменная нужна, чтобы зуммер мог прозвучать один раз, каждый раз при смене режима 
    lcd.setCursor(0, 0);
    lcd.print("Temperature");
    while ( val>=0 && val<=270) // делаем цикл, по которому отправляется команды и принимаются в зависимости от режима
    {
  currentButtontem = Button(buttem); 
  if (currentButtontem == 1 && buttem ==0) // если кнопка была нажата и отжата
  {
  sendt = !sendt; // 
  Serial.print(sendt+1); // отправляем показание кнопки
  }
 buttem = currentButtontem;
 
 if (Serial.available()> 0)  // если в Serial пришли данные
  {
    data =Serial.parseInt();  // записываем данные в data
    lcd.setCursor(0, 1);
    lcd.print("C =");
    lcd.print(data);
    }
    if (zum<=0)
    {
      signaling();
      zum=zum+1;
    }
    val = analogRead(A0);
    }
    lcd.clear();
    }
    if ( val>=271 && val<=700)
    { 
    zum = 0;
    lcd.setCursor(5, 0);
    lcd.print("light");
    while ( val>=271 && val<=700)
    {
  currentButtonlig = Button(butlig); 
  if (currentButtonlig == 1 && butlig ==0) 
  {
  sendl = !sendl;  
  Serial.println(sendl+3); 
  }
 butlig = currentButtonlig;
 
 if (Serial.available()> 0)  
  {
    data=Serial.parseInt(); 
    if (data==1) 
         {
         lcd.setCursor(5, 1);
         lcd.print("OFF");
         }
      if (data==2) 
         {
         lcd.setCursor(5, 1);
         lcd.print("ON ");
         }
    }
    if (zum<=0)
    {
      signaling();
      zum=zum+1;
    }
    val = analogRead(A0);
    }
    lcd.clear();
    }
    if ( val>=701 && val<=1023)
    { 
    zum = 0;
    lcd.setCursor(0, 0);
    lcd.print("Work Place");
    while ( val>=701 && val<=1023)
    {
  currentButtonwok = Button(butwok); 
  if (currentButtonwok == 1 && butwok ==0) 
  {
  sendw = !sendw; // 
  Serial.println(sendw+5); 
  }
 butwok= currentButtonwok;
 
 if (Serial.available()> 0)  
  {
    data=Serial.parseInt();  
    if (data==2) 
         {
         lcd.setCursor(0, 1);
         lcd.print(" Good work! ");
         }
      if (data==1) 
         {
           lcd.setCursor(0, 1);
           lcd.print(" Go to work!");
          
         }
    }
    if (zum<=0)
    {
      signaling();
      zum=zum+1;
    }
    val = analogRead(A0);
    }
    lcd.clear();
    }
}

Система Slave

Slave состоит из:

  • Дальномер
  • Сервопривод
  • Реле
  • Термистр
  • Bluetooth модуля
  • Arduino UNO

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

  • Дальномер подключаем к пинам (9;8) (trig;echo)
  • Сервопривод к пину 5
  • Термистр к аналоговому пину 0
  • Реле к 13 пину

Соединяем дальномер с сервоприводом, и скрепляем этот механизм рядом с вашим рабочим столом. Когда приходит команда (5 – 6) то сервопривод делает поворот, чтобы дальномер мог просканировать место, где вы работаете. Можно изменить смысл данного механизма и создать небольшую систему безопасности вашего дома.

Термистр можно поставить за окном и тогда вы сможете узнавать температуру на улице.

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

Код Slave:

int led = 13; // пин для реле
int data; // получаемая информация
int object = 0; // данные об объектах, которые находятся рядом 
#define TEMP_PIN A0 // пин температуры
#define trigPin 9
#define echoPin 8 // пины для дальномера
#include <math.h> 
#include <Servo.h>
Servo myServo;
void setup() 
{
  Serial.begin(38400);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  // При вызове parseInt() задержка ожидания последующего символа по умолчанию 1 секунда.
  // Функцией setTimeout() можно уменьшить эту задержку. Например на 40 миллисекунд, setTimeout(40);.
  // Чем выше скорость Serial.begin, тем меньше потребуется значение setTimeout.
  Serial.setTimeout(40);
    myServo.attach(5);
  pinMode(led, OUTPUT);
}
int distans() // функция для определния дистанции до объекта 
{
long duration, distance; 
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
return (distance);
}
void loop() 
{
  if (Serial.available()>0 )  // если в Serial пришли данные, через Bluetooth модуль HC-05.
  {
    // Вместо "Serial.read"  будем использовать "Serial.parseInt" чтоб можно было работать с числами больше 9.
    data=Serial.parseInt();   
    if (data==1||data==2) // если пришла 1 или 2
      {
      float v_temp =  analogRead (TEMP_PIN) *5.0 / 1023.0 ; // определяем температуру
      int temp = 1.0/(log(v_temp/2.5)/4300.0 + 1.0/298.0) -273.0;
      Serial.print(temp); 
      }
      
      if (data==3) // если пришла 3
         {
          digitalWrite(led,LOW); // включаем или выключаем лампу
          Serial.print(1);
         }
         if (data==4) // если пришла 4
         {
          digitalWrite(led,HIGH); // включаем или выключаем лампу
          Serial.print(2);
         }
         if (data==5||data==6) // 5 или 6
         {
          object = 0;
          for(int i=80;i<=130;++i) // проводим цикл в 50 кругов
          {
           myServo.write(i); // двигаем сервопривод от 80 градусов до 130
           int did = distans(); // переменная дистанции
           if(did>=10 && did<=40) // если дальномер находит рядом объект
           {
            object=object+1; // записываем это в переменную
           }
            delay(15); // ждем немного
          }
          for( int i=130;i>=80;--i) // проводим цикл в 50 кругов
          { 
           myServo.write(i); // двигаем сервопривод от 130 градусов до 80
           long did = distans(); // переменная дистанции
           if(did>=10 && did<=40) // если дальномер находит рядом объект
           // этот параметр вы можете спокойно изменить
           {
            object=object+1; // записываем это в переменную
           }
          delay(15); // ждем немного
          }
          if(object>=5) // этот параметр вы можете спокойно изменить
          {
          Serial.print(2); // допускаем ошибку(>5) если есть объект рядом, то отправляем два
          }
          else
          {
          Serial.print(1); // отправляем 1, если нет объекта рядом
          }
         }
         
      }    
   }

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

И теперь закончим на Blueteth и перейдем к самой интересной теме, которая должна быть в каждом умном доме - интернет.

Попробуем через модуль esp8266 управлять через компьютер и смартфон вашим умным домом. Я попробую рассказать вам все подробно и использовать комбинированные системы с платой Rasbery pie. Обсудим управление через социальные сети. Данная тема очень обширна, и я попробую рассказать обо всем. Увидимся в следующий раз!

Автор - Артем Лужецкий

Ардуино+