Paranoid App – фреймворк мониторинга дома на Arduino и Raspberry Pi
Итак, у вас есть 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. Если вы хотите начать с простого, то вот схема:
Начнем с основ. Данные передаются по последовательному порту со скоростью передачи 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" и возвращаем данные. Вот и всё.
Вот так ваш проект должен выглядеть после выполнения этих шагов:
Отладка
Если у вас возникли проблемы, например, если вы не получили данные, самое простое место для начала отладки – это ваш браузер. Вам необходимо использовать Chrome для данных инструкций: просто нажмите F12, перейдите на вкладку Network, кликните на ней, нажмите F5, чтобы обновить страницу, и кликните на "relay.php?command=thl
". Если всё будет работать, данные должны будут появиться как на скриншоте ниже:
Наслаждайтесь вашей системой мониторинга дома. Оставляйте комментарии.