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

В этой системе лампа накаливания эмулирует СКК в режиме обогрева, а вентилятор в режиме охлаждения. Лампа включается на обогрев, и нагревает температурный сенсор. Когда значение температуры достигает максимального порога, команда из облака выключает лампу и включает вентилятор до тех пор, пока температура не снизится ниже минимального порога.
Управляющая часть находится в облаке, поэтому изменения значений порогов могут быть выполнены удаленно. Также вентилятор можно включать и выключать кнопкой вручную. Программа написана на JavaScript с использованием Intel XDK IoT Edition. Загрузить Intel XDK IoT можно с сайта https://software.intel.com/ru-ru/iot/software/ide.

Использованные компоненты:
  • Плата Intel Edison с блоком питания.
  • Внешняя Wi-Fi антенная (при необходимости).
  • Из набора Grove Starter Kit:
    • Базовый шилд Seeed Studio.
    • Температурный сенсор.
    • Реле.
    • Кнопка.
    • Светодиод.
    • ЖК экран.
  • Лампа накаливания с блоком питания.
  • Вентилятор на 5 В.




Большинство сенсоров из набора Grove Starter Kit спроектированы так, чтобы их было просто подключить. Для этого достаточно присоединить кабель одной стороной к датчику, а другой к слоту, расположенному сверху на базовом шилде. Конечно, всегда проверяйте, что плата обесточена, когда вы подключаете провода и датчики. Также установите на шилде напряжение 5 В, которое требуется сенсорам из данного проекта.

Подробнее про базовый набор можно прочитать в статье Ингредиенты IoT деликатесов быстрого приготовления: Intel Edison + Intel XDK + JavaScript + Grove Kit.

Схема подключения всех датчиков


Все ниже описанные датчики подключаются к следующим разъемам на плате:


Датчик температуры


Самая главная часть устройства, датчик температуры, должен быть подключен к аналоговому входу A0. Значение температуры будет сохраняться в градусах Цельсия. Убедитесь, что датчик расположен рядом с нагревающей лампой, чтобы он быстрее реагировал на изменение её температуры.

Кнопка




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

Светодиод


Светодиод — это индикатор вентилятора. Если он светится, значит, вентилятор работает. Светодиод подключён к D2.

Вентилятор





Вентилятор не входит в набор Grove Starter Kit, поэтому его подключение будет немного сложнее. Напряжение 5 В для вентилятора надо получить с цифрового контакта D3, обозначенного на плате «~3». Общий провод возьмите с разъема «Power GND» расположенного на другом краю платы. Убедитесь, что вы не ничего не перепутали, так как ошибка может вызвать короткое замыкание и сжечь устройство. Направьте вентилятор на нагревательную лампу, чтобы он охлаждал её, когда работает.
Важно обратить внимание на следующее. Так как вентилятор подключен непосредственно к цифровому пину, у которого нагрузочная способность около 30 мА, то надо выбирать мотор с меньшим током потребления или делать подключение аналогично лампе накаливания через реле или, что немного сложнее, но правильнее, используя драйвер мотора.

Реле и лампа-обогреватель


Реле подключено к разъему D4 и управляет лампой-обогревателем. Лампе нужен свой собственный источник питания, так как ей требуется больше чем 5 В, которые есть на плате Intel Edison. Таким образом, реле будет работать как электронный выключатель между платой и лампой. Чтобы подключить лампу к реле, подсоедините контакт NO (он слева) к положительному контакту лампы и контакт CO (справа) к положительному контакту, который подходит к блоку питания. Общий провод лампы соедините с общим проводом блока питания напрямую или, проще говоря, включите реле в разрыв цепи питания лампы.

ЖК экран


Экран можно подключить к любому из четырех разъемов I2C. На нем отображается значение температуры, а цвет его задней подсветки может быть зелёным, оранжевым или красным в зависимости от заданных порогов (ниже 30 – зеленый, между 30 и 40 – оранжевый, выше 40 – красный).

Блоки питания





Сейчас можно подключить напряжение к плате и лампе. Подключите преобразователь 220 В -> 11.5 В к лампе, она не заработает до тех пор, пока плата Intel Edison не включит реле. Затем подключите разъем от блока питания к плате и сам блок питания вставьте в розетку. Должен загореться зеленый индикатор.

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


Сейчас вам надо сконфигурировать Intel Edison для подключения к локальной Wi-Fi сети. Убедитесь, что микропереключатель (1) на плате установлен по направлению к микро USB разъемам. Подключите микро USB кабель одним концом к крайнему разъему на плате (2), а другим к компьютеру (3). Это обеспечит подключение через терминал (программа PuTTY). Не обязательно использовать второй микро USB слот, так как он используется для подачи питающего напряжения, если нет блока питания, Ethernet, заливки Arduino скетчей и подключения внешних устройств хранения.



Инструкции для пользователей Windows


a. Когда вы подключите USB кабель, плата Edison появится в Диспетчере устройств в секции «Порты (COM и LPT)» как «USB Serial Port». Запомните его номер, он понадобится нам позднее.



b. Загрузите программу PuTTY на компьютер, для создания последовательного соединения с платой.
с. Откройте PuTTY, выберите тип соединения Serial, введите номер COM порта, полученного из первого шага. В нашем случае это COM7. Скорость 115200. Нажмите Open.



Инструкции для пользователей Mac


a. Откройте окно терминала (чтобы его найти используйте Spotlight со строкой ‘terminal’). Введите команду:
ls /dev/tty.*



В списке подключенных устройств найдите устройство, которое содержит cu.usbserial или tty.usbserial. На картинке сверху это устройство имеет имя /dev/tty.usbserial-A502YSYU

b. Скачайте goSerial, чтобы создать последовательное соединение компьютера и платы.
c. Откройте goSerial, выберите «Serial Port» — «usbserial», установите скорость 115200 и нажмите «OK».



Настройка



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



Установите пароль, используя команду
configure_edison --setup

чтобы задать пароль пользователя root. Это надо сделать обязательно, иначе не будет работать подключение к плате через Intel XDK.

Подключение к сети Wi-Fi


Введите:
configure_edison --wifi

после окончания сканирования, вы увидите список доступных Wi-Fi сетей.
Если вашей сети нет в списке, возможно, она у вас скрытая. Если Wi-Fi сигнал слабый, можете использовать внешнюю антенну, подключив ее к соответствующему разъему на плате Intel Edison.



Выберите вашу сеть или скрытую сеть — hidden. Вам будет задан вопрос, правильно ли вы указали сеть. Нажмите Enter. Если вы выбрали скрытую сеть, введите её имя. Введите пароль к сети, при необходимости. Теперь плата подключена к вашей Wi-Fi сети.



Вы можете убедиться, что плата подключилась нормально, зайдя в браузере по адресу:
http://адрес_платы
с компьютера, который находится в той же локальной сети, что и плата. В примере на картинке это:
http://192.168.0.219
Или напечатайте в консоли:
wpa_cli status

и убедитесь, что статус wpa_state=COMPLETED и IP адрес присвоен.



IoT облако


Данные и правила управления нашей системой хранятся в облаке Intel IoT Analytics. Каждые пять секунд Intel Edison посылает записанное значение температуры в облако, где оно отображается на графике. Система в облаке также проверяет пороговые значения температуры и при необходимости посылает сигнал обратно на плату Intel Edison.



Сайт IoT агента dashboard.us.enableiot.com/ui/auth#/login

Если у вас еще нет аккаунта, вы не установили IoT агента на плату Intel Edison или не активировали устройства, посмотрите инструкции по настройке в статьях Intel® IoT Platforms: Getting Started: Cloud Analytics и Intel Edison. Работа с облаком Intel IoT Analytics: регистрация и отправка данных.

IoT агент уже имеет несколько стандартных компонентов для сбора данных. Для нашей системы климат-контроля хорошо подойдет temperature.v.10 и powerswitch.v1.0. Чтобы зарегистрировать их, введите в окно терминала:

iotkit-admin register temp temperature.v1.0
iotkit-admin register relay powerswitch.v1.0


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

Облако IoT – установка управления


Нажмите кнопку сверху справа, чтобы показать меню сбоку и затем нажмите на «Control». Откроется окно управления, чтобы посылать команды на плату. В разделе «Select Component» выберите ваше устройство «relay». Укажите «LED(0,1)» как имя параметра «Parameter Name», установите значение параметра «Parameter Value» равное «1», затем нажмите добавить действие «Add action». Нажмите сохранить как сложную команду «Save as complex command» и назовите его «ventilator_ON». Повторите это еще раз, только введите значение «0» и назовите «ventilator_OFF».



IoT облако – установка правил


Сейчас вы готовы создать правила для срабатывания команд. Нажмите «Rules» (Правила) на боковом меню, чтобы отрыть окно «My Rules» (Мои правила), которое показывает активные (Active) и архивные (Archived) правила. У нас будет два правила. Одно для температуры меньше 30 градусов, которое посылает уведомление на плату, что надо выключить вентилятор и включить лампу. Другое для температуры выше 40 градусов. Оно посылает уведомление включить вентилятор и выключить лампу обогрева.



Чтобы создать правило «Below 30 C» (Ниже 30), нажмите «Add a rule» (Добавить правило). Дайте ему имя, описание, приоритет и выберите тип уведомления Actuation (Приведение в действие). Выберите действие «ventilator_OFF». Нажмите Next и выберите ваше устройство Intel Edison. Нажмите Next снова и укажите «Enable Automatic Reset» (Включить автоматический сброс), выберите «temp» как «Monitored Measure» (Измеряемое значение) и установите «Trigger When» (условие срабатывания) когда «Basic Condition» установлено в «<30». Затем нажмите Done. Повторите для правила «Above 40» (больше 40), но установите действие «ventilator_ON» и выберите «> 40» для «Trigger When».



Исходный код main.js для Intel® XDK
var mraa = require('mraa');
var dgram = require('dgram');
var mqtt = require('mqtt');
var fs =  require('fs');
var upm_lcd  = require ('jsupm_i2clcd');

var tempSensor = new mraa.Aio(0); // temperature sensor connected to analog IO pin 0 

var powerswitch = new mraa.Gpio(8);
// push button connected to digital IO pin 8

var led = new mraa.Gpio(2); // LED connected to digital IO pin 2

var ventilator = new mraa.Gpio(3);
// ventilator connected to digital IO pin 3, 
// i.e. red cable ( 5 V ) to GPIO 3 on breakout board 
// and black cable ( ground ) to GND.

var relay = new mraa.Gpio(4); // relay connected to digital pin 4
var lcd = new upm_lcd.Jhd1313m1(6,0x3E, 0x62);
// LCD connected to the I2C bus, any connector on I2C will do.

powerswitch.dir(mraa.DIR_IN);

led.dir(mraa.DIR_OUT);
ventilator.dir(mraa.DIR_OUT);
relay.dir(mraa.DIR_OUT);

// Touch Sensor Parameters
var ventilatorON = 0; /* for this demo, ventilatorON is equivalent to light ( =heat source ) off */
var switchstate = 0;

// Temperature Sensor Parameters
var B = 3975;

// Create MQTT Client
var mqttClient =
mqtt.createClient(1884);

// Create UDP Client
var udpClient =
dgram.createSocket('udp4');

// UDP Options
var    rec_port = 41235;

// LCD Parameters
var lcdMessage = "";

// LCD Setup
lcd.write("Intel Edison");
lcd.setCursor(1,0);
lcd.write("TEMP: ");
led.write(0);
ventilator.write(0);
relay.write(1);

// Start Activities
touchActivity();
lcdTempActivity();

function touchActivity()
{
    switchstate = powerswitch.read(); //read the digital value of the pin
   
    if(switchstate == 1 ) /*change ventilatorstate */
    {   
        if ( ventilatorON == 0 )
        {
            relay.write(ventilatorON);
            ventilatorON = 1;
        }
        else
        {
            relay.write(ventilatorON);
            ventilatorON = 0;
        }
        led.write(ventilatorON);
        ventilator.write(ventilatorON);
    }

    //check every second ( = 1000 millisec ) for status of the switch.   
    setTimeout(touchActivity,1000); 
}

function lcdTempActivity()
{
    // Get temperature
    var reading = tempSensor.read();       
   
    // Get the resistance of the sensor
    var resistance = (1023 - reading) * 10000 / reading; 

    // Convert to temperature via datasheet       
    var temperature =
           (1 / (Math.log(resistance / 10000) / B + 1 / 298.15) - 273.15).toPrecision(3);
       
    lcdMessage = temperature + " C";
       
    lcd.setCursor(1,6);   
    lcd.write(lcdMessage);    
       
    if(temperature > 40 )
    {
        lcd.setColor(255,0,0); // Color screen red above 40 degrees
    }
    else if(temperature > 30)
    {
        // color screen orange above 30 (and below 40 ) 
        // -- zone where ventilator will switch on automatically 
        // -- need 2 rules in IOT Analytics tool.
        lcd.setColor(255,100,0); 
    }
    else
    {
        lcd.setColor(0, 255, 0); //Green as long as temp is below 30
    }
       
    // Send observation to the cloud
       
    sendObservation("temp", temperature, new Date().getTime());
    setTimeout(lcdTempActivity,5000); /* update tempearture every 5 sec */
}


// Send observation to the cloud (MQTT)
function sendObservation(name, value, on)
{
    var msg = JSON.stringify({
            n: name,
            v: value,
            on: on});
       
    //console.log("Sending observation: " + msg);     
    mqttClient.publish("data", msg);
}


// listen for UDP message from local agent
udpClient.on("error",
    function (err)
    { 
        console.log("udpClient error:\n" + err.stack);
        udpClient.close();
    }
);

udpClient.on("message",
    function (msg, rinfo)
    { 
        // ventilator is the component defined in the Analytics tool
        var sensorName = "LED";
         
        console.log("udpClient got: " + msg + " from " +
                             rinfo.address + ":" + rinfo.rec_port);
         
        // Ignore messages unless they are local
         
        if(rinfo.address != "127.0.0.1")
        {
            console.log("Ignoring remote UDP message");
            return;
        }
     
        var js = JSON.parse(msg);
        var component = js['component'];
        var command = js['command'];
        var argvArray = js['argv'];
        console.log("component: " + component);
        console.log("command: " + command);
         
        for(var i = 0; i < argvArray.length; i++) 
        {
            var name = argvArray[i]['name'];
            var value = argvArray[i]['value'];
            console.log("name: " + name);
            console.log("value: " + value);
             
            if (name == sensorName)
            {
                  console.log("cloud (de)activation command for ventilator received");
                  if(parseInt(value) == 1 ) /*switch ventilator ON */
                  {  
                      if ( ventilatorON == 0 )
                      {
                          relay.write(ventilatorON);
                          ventilatorON = 1;
                          led.write(ventilatorON);
                         
                          ventilator.write(ventilatorON);
                      }
                  }
                  else
                  {
                      if( ventilatorON == 1 )
                      {
                          relay.write(ventilatorON);
                          ventilatorON = 0;
                          led.write(ventilatorON);
                          ventilator.write(ventilatorON);
                      }
                  }

                  console.log("Ventilator state changed through cloud command to :" 
                               + ventilatorON );
            } 
        }
    }// function
);// on message          

udpClient.on("listening",
    function ()
    {
        var address = udpClient.address();
        console.log("udpClient listening " +
        address.address + ":" + address.port);
    }
);

udpClient.bind(rec_port);

Убедитесь, что в файле package.json указан MQTT в зависимостях (dependencies).

{
"name": "blankapp",
"description": "",
"version": "0.0.0",
"main": "main.js",
"engines":
    {
        "node": ">=0.10.0"
    },
"dependencies":
    {
       "mqtt": "^0.3.8"
    }
}


Об авторе:


Дирк Розиерс — евангелист сообщества IoT Developer в компании Intel в группе SSG (Software and Services Group). Он занимается технической поддержкой сообщества разработчиков Интернета Вещей в регионе EMEA (Европа, Россия, Ближний Восток, Африка).

Комментарии (4)


  1. LSiazsaHrd
    18.12.2015 16:13
    +1

    Дальше было бы интересно систему модернизировать, для более точного управления и более стабильного поддержания уставки температуры, с аналоговых выходом и регулятором (ПИ/ПИД), управляя, например скоростью вращения вентилятора и яркостью свечения лампы, приблизиться к реальным системам климат-контроля.


    1. varerysan
      18.12.2015 23:23

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


  1. Daffodil
    18.12.2015 22:26

    Лет 10 назад кто-то из моих сокурсников делал такой проект как дипломный. Правда с Zigbee вместо Wifi.
    На самом деле применение x86 application процессора здесь это overkill, читать датчики можно и на простом ARM микроконтроллере за пару долларов, а с wifi справляется модуль за 8$.

    Как мне кажется архитектура такой системы должна быть более распределенной: датчики с zigbee или bluetooth long-range разбросаны по всему дому + центральный хаб с linux'ом и веб сервером, на чем-нибудь вроде raspberry PI.


  1. nIx0iD
    21.12.2015 13:42

    Еще будет несложно прикрутить датчик влажности и реле, по которому будет включаться увлажнитель.