Paranoid App – фреймворк мониторинга дома на Arduino и Raspberry Pi

Добавлено 19 июня 2017 в 00:00

Итак, у вас есть Raspberry Pi и Arduino, и вы хотите разработать систему мониторинга и управления вашим домом. Если я вас правильно понял, то, прочитав эту статью, вы сможете сделать именно то, что хотите.

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

Введение

Прежде всего, почему вы хотите использовать Arduino и Raspberry Pi вместе? Raspberry Pi обладает выводами ввода/вывода общего назначения (GPIO), которые отлично подходят для простых двоичных задач (включить или выключить) и для чтения данных с дешевого датчика температуры. Этого достаточно? Нет! Для более сложных задач вы захотите использовать микроконтроллер для выполнения тяжелой работы. Он имеет аналого-цифровой преобразователь (АЦП, ADC) с несколькими каналами, ШИМ (широтно-импульсно-модулированные, PWM) каналы и очень точную синхронизацию.

Например, если вы захотите измерить потребление электроэнергии в своем доме, вам понадобится трансформатор тока и простая схема, которая выдаст напряжение, которое вы измерите с помощью АЦП. Если вы хотите вывести что-то между 1 и 0, скажем, уменьшить яркость светодиода, вы будете использовать ШИМ выходы. Наконец, вам нужен микроконтроллер, если необходимо что-то с очень точной синхронизацией, например, PID система, мультиплексирование светодиодной матрицы или управление шаговым двигателем. В нашем случае в качестве микроконтроллера мы будем использовать Arduino Uno.

Перечень компронентов и схема

В данном проекте нам понадобится следующее:

  • Arduino Uno (хотя, если хотите, то можете использовать другие продукты Arduino);
  • Raspberry Pi (я использовал Pi Zero, но будет работать и любой другой);
  • источник питания для Rasperry Pi;
  • SD карта с установленной операционной системой Raspbian (Raspbian Lite тоже подойдет);
  • датчики и другие модули для Arduino (тут всё зависит от того, что вы хотите реализовать);
  • базовые знания Arduino IDE, Raspbian, C/C++, HTML и javascript (не пугайтесь; если вы уже знаете C/C++, то этого будет достаточно).

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

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

Код Arduino

Для простоты я покажу вам здесь, только как считывать температуру и влажность воздуха с датчика DHT11 и как дистанционно мигать светодиодом. Для вашего реального проекта вам понадобится что-то более сложное, что можно сделать только с Raspberry Pi. Если вы хотите начать с простого, то вот схема:

Подключение датчика и светодиода к Arduino
Подключение датчика и светодиода к Arduino

Начнем с основ. Данные передаются по последовательному порту со скоростью передачи 9600 бит/с. В основной функции мы читаем последовательный порт и проверяем, что пришло. Если мы приняли строку "thl", это означает, что нам нужно отправить через последовательный порт данные с датчиков. Чтобы эта функция работала правильно, мы используем цикл while и отправляем данные снова и снова, пока не получим "ok", чтобы узнать, что данные достигли сервера. Если мы получим строку "led", то просто начнем мигать светодиодом. Здесь вы можете добавить любую функцию и строку, которую захотите, – просто не забудьте использовать "thl" для отправки данных.

Что вам нужно знать, так это то, что мы отправляем данные в форме JSON (JavaScript Object Notation). JSON – это открытый формат для передачи объектов данных. Мы используем его, потому что можем легко использовать эти данные в main.html с помощью javascript. Чтобы использовать его, нам понадобится библиотека под названием ArduinoJson, которую вы можете найти в архиве, ссылка на который будет в конце статьи. Функция "send_data()" делает то, что подразумевает ее название: она передает данные через последовательный порт в формате JSON. Чтобы добавить данные, вам просто нужно добавить строку внутри этой функции, которая выглядит так:

root["name_of_data"] = function_that_return_data();

где "function_that_return_data()" выглядит так:

int function_that_return_data()
{
  int data;
  // вставить код, которые считывает данные с датчика и сохраняет их в переменной 'data'
  return (data);
}

Вот и всё, что касается Arduino. Ниже вы можете увидеть точный код, который написан для этого конкретного случая, с датчиком DHT11 и светодиодом.

#include "ArduinoJson.h"
#include "dht.h"

dht DHT; // задать имя вашему датчику DHT

#define DHT11_PIN A0 // вывод для данных DHT11
#define LED_PIN A1   // вывод для светодиода

void send_data();
int get_temperature();
int get_humidity();

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  String str;
  str = Serial.readString(); // прочитать последовательный порт
  str.toLowerCase();         // конвертировать в нижний регистр
  if (str == "thl") 
  {
    do
    {
      str = Serial.readString(); // прочитать последовательный порт снова
      send_data();               // вызвать функцию отправки данных
    } while (str != "ok");       // продолжать отправлять данных, пока не получим "ok"
  }
  if (str == "led") 
  {
    digitalWrite(LED_PIN, HIGH);   // включить светодиод (HIGH это уровень напряжения)
    delay(1000);                   // подождать секунду
    digitalWrite(LED_PIN, LOW);    // выключить светодиод, опустив напряжение до уровня LOW
  }

}
void  send_data()
{
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["temp"] = get_temperature();
  root["humidity"] = get_humidity();
  root.printTo(Serial);
  Serial.println();
}

int get_temperature() // функция, которая возвращает температуру как целое число
{
  int temperature;

  DHT.read11(DHT11_PIN);
  temperature = DHT.temperature;
  return (temperature);
}

int get_humidity() // функция, которая возвращает влажность как целое число
{
  int humidity;

  DHT.read11(DHT11_PIN);
  humidity = DHT.humidity;
  return (humidity);
}

Установка веб-сервера на Raspberry Pi

Мы будем использовать Raspberry Pi в качестве веб-сервера с nginx. Рассмотрим как установить его и другие компоненты, которые нам понадобятся, например, PHP.

Давайте разъясним некоторые основы. Прежде всего, вам нужны установленная операционная система Raspbian на ваш Raspberry Pi и сетевое подключение. Теперь вы можете подключить к плате клавиатуру и монитор и открыть терминал, или сделать, как я, и делать всё через SSH. Какой бы метод вы ни использовали, помните, что все команды должны выполняться как root; в противном случае вы получите ошибку разрешения. Это делается путем написания "sudo" перед командой. Теперь, когда всё сказано, начнем.

Сначала давайте обновим репозиторий и пакеты. Если вы не знакомы с Linux, это означает обновление места, из которого устанавливаются пакеты (приложения), а затем обновление их самих.

sudo apt-get update
sudo apt-get upgrade

Мы хотим установить NGINX, PHP и git (это необязательно, но сделает вашу жизнь проще). На вопрос отвечаем "y" и жмем Enter.

sudo apt-get install nginx php5-fpm git

Теперь нам необходимо изменить каталог NGINX по умолчанию и заставить его работать с PHP.

cd /etc/nginx
sudo nano sites-enabled/default

Вам необходимо, чтобы этот файл выглядел так:

server {
	listen 80; ## listen for ipv4; this line is default and implied
	listen [::]:80 default_server ipv6only=on; ## listen for ipv6
	root /var/www;
	index index.html index.php;
	# Make site accessible from http://localhost/
	server_name _;
	location / {
        	index index.html index.php;
		# First attempt to serve request as file, then as 
		# directory, then fall back to the CMS.
		try_files $uri $uri/index.html;  
	}
	
	location /doc/ {
		alias /usr/share/doc/;
		autoindex on;
		allow 127.0.0.1;
		allow ::1;
		deny all;
	}
	location ~ \.php$ {
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi.conf;
        }
}  

Теперь перезапустим NGINX.

sudo service nginx restart

Чтобы проверить, что всё работате, создайте тестовую страницу PHP.

cd /var/www
sudo nano test.php

И добавьте в файл test.php следующее.

<?php
phpinfo();
?>

Теперь откройте в браузере адрес ip_адрес_raspberry_pi/test.php (например, 192.168.0.2/test.php).

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

Тестовая страница
Тестовая страница

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

Последний шаг – это ввести следующую команду, которая открывает доступ к последовательному порту пользователю www-data, который используется NGINX.

sudo usermod -a -G dialout www-data

После этого выполните еще один перезапуск и сделайте перерыв. Вы заслужили это.

Файлы веб-сайта

Подождите, мы почти закончили. Вам просто нужно загрузить файлы на свой Raspberry Pi и отредактировать их под свои нужды.

Вы можете вручную скачать эти файлы и поместить их в каталог /var/www или можете выполнить эту команду и автоматически скачать их с github:

cd /var/www 
sudo git clone https://github.com/alexonaci/Paranoid/tree/AAC

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

  • каталог /img: содержит изображения иконок и фона для начальной страницы;
  • ArduinoCode.ino: файл скетча для Arduino;
  • PhpSerial.php: PHP библиотека, позволяющая нам общаться с Arduino через последовательный порт, используя PHP;
  • Style.css: CSS для страницы;
  • Main.html: самая главная страница, которая содержит javascript, кнопки и визуальные данные;
  • Relay.php: файл, который инициирует соединение с Arduino.

Вам нужно беспокоиться только о странице main.html; всё остальное оставим как есть. Конечно, если хотите, вы можете настроить их по своему вкусу – это ведь ваш проект в конце концов.

Посмотрим, как добавлять элементы. Чтобы добавить новую кнопку, просто добавьте эту строку:

<div class="col-sm-2" class="jobs">
  <h2 class="header-default" class="jobs-header"><img width=100 src="img/Thumbnail_Image"></h2>
  <button type="button" id="Name_action" class="btn btn-danger">
    <span class="glyphicon glyphicon-off"></span>
    On/Off
  </button>    
</div>

Thumbnail_Image – это путь к изображению, которое вы хотите использовать в качестве иконки (не забудьте поместить его в каталог /img). Name_action – это название того, что вы хотите выбрать для своей кнопки. Здесь вы можете проверить типы кнопок, которые можете использовать.

Перейдите в конец файла, где вы можете увидеть строку "$("#led-button").click(blinkLED);", и добавьте ниже следующее:

$("#Name_action").click(Function_Name);

Теперь добавьте выше функцию, связанную с новой кнопкой:

function Function_Name (){
   $.get(url + "Parameter")	
}

"Parameter" – это строка, которая будет отправлена на вашу плату Arduino через последовательный порт при нажатии кнопки. Она должна быть связана с функцией в коде скетча. Мы говорили об этом в разделе «Код Arduino».

Чтобы добавить на экран новый элемент, который отобразит значение, которое посылает Arduino, например, данные датчика, добавьте этот тип элемента:

<div class="col-sm-2" class="jobs"//>
  <h2 class="header-default" class="jobs-header"><img width=100 src="img/Thumbnail_image"></h2>
  <h3>Display_data: </h3>
  <div id="DataID"></div>
</div>

где "Display_data" – это название, которое будет отображаться перед данными, например, "Температура:"; а DataID – это идентификатор.

Помните, когда я сказал, что мы будем получать данные в формате JSON? Здесь он пригодится. Найдите функцию “getLuminosityTemperatureHumidity()” и просто добавьте в ее конец:

$("#DataID").html(parsedJSON.name_of_data);

Где "name_of_data" – это строка, которую вы выбрали для данных в разделе «Код Arduino».

Есть также еще одна функция, которая будет вызывать данную функцию каждые 10 секунд.

setInterval(getLuminosityTemperatureHumidity,10000);

Если хотите, то можете изменить время.

Всё, что осталось, объяснить, как работает скрипт relay.php. Он открывается каждый раз, когда вызывается функция "getLuminosityTemperatureHumidity()". Для работы он использует библиотеку PhpSerial. Первые 8 строк, начинающиеся с "$serial->", устанавливают последовательное соединение с Arduino.

ВНИМАНИЕ! Каждый раз, когда этот скрипт выполняется, Arduino перезапускается. Если вы этого не хотите, то просто подключите конденсатор 10 мкФ отрицательным выводом на вывод GND, а положительным выводом на вывод RESET.

Продолжим. Строка "sleep(2);" необходима, потому что Arduino не отвечает в первые моменты, после открытия последовательного соединения. После этого мы отправляем параметр, который получили через метод GET, "$_GET["command"]", на Arduino; и если это была команда "thl", считываем данные, приходящие от микроконтроллера, отправляем "ok" и возвращаем данные. Вот и всё.

Вот так ваш проект должен выглядеть после выполнения этих шагов:

Внешний вид тестового приложения на Paranoid App
Внешний вид тестового приложения на Paranoid App
Внешний вид тестового приложения на Paranoid App
Внешний вид тестового приложения на Paranoid App

Отладка

Если у вас возникли проблемы, например, если вы не получили данные, самое простое место для начала отладки – это ваш браузер. Вам необходимо использовать Chrome для данных инструкций: просто нажмите F12, перейдите на вкладку Network, кликните на ней, нажмите F5, чтобы обновить страницу, и кликните на "relay.php?command=thl". Если всё будет работать, данные должны будут появиться как на скриншоте ниже:

Отладка Paranoid App в браузере
Отладка Paranoid App в браузере

Наслаждайтесь вашей системой мониторинга дома. Оставляйте комментарии.


На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.


Сообщить об ошибке