- PVSM.RU - https://www.pvsm.ru -
Привет Хабрахабр! Хочу поделится с вами как я подключил Arduino к своему роутеру. Поехали!
Современные роутеры — как небольшие компьютеры, которые выполняют узкоспециализированную задачу для раздачи сетевого трафика. На борту такого небольшого устройства установлена ОС Linux, только без графического интерфейса и с урезанной программной частью. Передо мной встал вопрос, а почему бы не подключить arduino к своему роутеру — Zyxel Keenetic 4G? Немного погуглив я наткнулся на замечательный форум [1], где энтузиасты собирают модифицированные прошивки с поддержкой установки дополнительных, пакетов для серии Keenetic.
В нашем случае управление Arduino происходит через библиотеку php_serial.class.php [2] и легкого веб сервера на основе Lighttpd [3] + php. С помощью этих инструментов будем подавать команды ардуинке на чтение показаний с двух температурных датчиков (дом, улица), записывать ответ в базу данных Sqlite3 [4] и выводить на нашу веб-страничку.
Подготовка маршрутизатора
Первым делом, необходимо настроить наш маршрутизатор. У Zyxel Keenetic 4G очень маленькая внутренняя память, поэтому приобретете простенький usb-хаб и флешку не большого объема. Все тонкости настройки я не буду расписывать, а лишь поделюсь необходимыми ссылками. Сразу приготовитесь к долгой и утомительной процедуре.
Подключение датчиков
Подключаем температурные датчики ds18b20 к arduino. Номинал резисторов — 4,7 кОм
Скетч
Заливаем скетч. За основу взят код из этого урока [10] и немного доработан под нашу задачу.
#include <OneWire.h>
int nc;
OneWire ds(10); // Первый датчик
OneWire ds2(11); // Второй датчик
byte addr[8];
byte addr2[8];
void setup(void)
{
Serial.begin(9600);
ds.search(addr);
ds2.search(addr2);
}
void loop(void)
{
byte i;
byte present = 0;
byte data[12];
int Temp;
int znak;
if (Serial.available() > 0) {
nc = Serial.read();
if (nc==1) {
ds.reset();
ds.select(addr);
ds.write(0x44,1);
present = ds.reset();
ds.select(addr);
ds.write(0xBE);
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}
Temp=(data[1]<<8)+data[0];
Temp=Temp;
znak=((Temp%16)*100)/16;
if (znak<0){
znak=znak*-1;
}
Serial.print(Temp/16);
Serial.print(".");
Serial.print(znak);
Serial.println();
}
if (nc==2) {
ds2.reset();
ds2.select(addr2);
ds2.write(0x44,1);
present = ds2.reset();
ds2.select(addr2);
ds2.write(0xBE);
for ( i = 0; i < 9; i++) {
data[i] = ds2.read();
}
Temp=(data[1]<<8)+data[0];
Temp=Temp;
znak=((Temp%16)*100)/16;
if (znak<0){
znak=znak*-1;
}
Serial.print(Temp/16);
Serial.print(".");
Serial.print(znak);
Serial.println();
}
}
}
Передаем команды, принимаем ответы
Скетч принимает две команды — «1» и «2». Для того что бы отправлять команды в Arduino, я использовал обработку кнопок на java script при помощи известной библиотеки Jquery. На моей страничке находятся 2 кнопки и 2 табличных поля в которые выводятся значения с температурных датчиков(см. index.php). При помощь метода POST, скрипт обращается к arduino.php и передает значения наших команд. Здесь происходит передача команд непосредственно в Arduino и чтение ответа в виде температуры, а так же запись в базу данных Sqlite3 (см. arduino.php). Файл readbd.php нужен для первоначального занесения данных температуры в табличку. Красивое оформление кнопок было позаимствовано из статьи «3D кнопки с помощью CSS3» [11].
index.php:
<?php
include("readbd.php");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ru">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<head>
<link href="style.css" rel="stylesheet" media="all" />
<title>Температура в доме и на улице</title>
<link href="flot/examples/layout.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery.js"></script>
</head>
<body class="body">
<div class="container">
<header>
<h1><span>Температура</span></h1>
</header>
</div>
<div class="ul1" >
<table width="60px" border="0"><tr>
<td><a href="#" id="led6" class="button black" onMouseDown="command(1);">Улица</a></td>
<td><a href="#" id="led6" class="button yellow" onMouseDown="command(2);">Дом</a></td>
</tr><tr>
<td class="c1"><div id="content1" ><?php echo ''.$temp1.""; ?></div></td>
<td class="c1"><div id="content2" ><?php echo ''.$temp2.""; ?></div></td>
</tr>
</table>
</div>
<script>
function command(id)
{
$.ajax({
type:'POST',
url:'arduino.php',
data:{msg:id},
cache: false,
success: function(html){
$("#content"+id).html(html);
}
})
}
</script>
</center>
</body>
</html>
arduino.php:
<?php
include "php_serial.class.php";
$serial = new phpSerial;
//Задаем путь к Arduino (У вас может быть совсем по другому)
$serial->deviceSet("/../../../../dev/ttyACM0");
//Это стандарт
$serial->confBaudRate(9600);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");
$serial->deviceOpen();
//Отправляем команду
$serial->sendMessage(chr($_POST['msg']));
//Читаем ответ Arduino
$read = $serial->readPort();
//Зыкрываем соединение
$serial->deviceClose();
try {
// Создаем или открываем созданную ранее базу данных
$db = new PDO('sqlite:'.dirname(__FILE__).DIRECTORY_SEPARATOR.'arduino.db');
// Создаем таблицу temp, если не найдена
$db->exec('CREATE TABLE IF NOT EXISTS temp (
idtemp INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
temperature VARCHAR(255) NOT NULL,
datetime VARCHAR(255) NOT NULL
)');
$db->exec('CREATE TABLE IF NOT EXISTS temp2 (
idtemp INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
temperature VARCHAR(255) NOT NULL,
datetime VARCHAR(255) NOT NULL
)');
//определяем текущцю дату и время
$d=date("d.m.y, G:i:s");
//Обновляем
//$db->exec('UPDATE temp SET temperature="'.$read.'", datetime="'.$d.'" WHERE idtemp='.$_POST['msg'].'');
if ($_POST['msg']==1){
//Добавляем новую строку в БД
$db->exec('INSERT INTO temp (temperature, datetime) VALUES ("'.$read.'","'.$d.'" )');
//Получаем последнюю запись
$st = $db->query('SELECT MAX(idtemp) as id, temperature FROM temp');
$results = $st->fetchAll();
foreach ($results as $row) {
echo ''.$row['temperature']."n";
}
}
if ($_POST['msg']==2){
$db->exec('INSERT INTO temp2 (temperature, datetime) VALUES ("'.$read.'","'.$d.'" )');
$st = $db->query('SELECT MAX(idtemp) as id, temperature as tempe FROM temp2');
$results = $st->fetchAll();
foreach ($results as $row) {
echo ''.$row['tempe']."n";
}
}
} catch (PDOException $e) {
die($e->getMessage());
}
?>
Проблемы, с которыми я столкнулся
Решения
deviceSet("/../../../../dev/ttyACM0");
if($this->_exec("stty --version") === 0)
{
register_shutdown_function(array($this, "deviceClose"));
}
else
{
trigger_error("No stty availible, unable to run.", E_USER_ERROR);
}
Пару фоток
Скачать все необходимые файлы одним архивом [12]
P.S.
Это лишь небольшой пример того, как можно использовать arduino в связке с роутером. Можно написать более серьезные вещи. Управлять любыми приборами в своем доме при помощи веб-интерфейса и Arduino.
Спасибо за инвайт НЛО!
Автор: Rimidalw
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/arduino/5148
Ссылки в тексте:
[1] форум: http://forum.zyxmon.org/forum6-marshrutizatory-zyxel-keenetic.html
[2] php_serial.class.php: http://www.phpclasses.org/browse/file/17926.html
[3] Lighttpd: http://ru.wikipedia.org/wiki/Lighttpd
[4] Sqlite3: http://ru.wikipedia.org/wiki/Sqlite
[5] Альтернативная прошивка: http://ifolder.ru/29072957
[6] обсуждение: http://forum.zyxmon.org/post4593.html#p4593
[7] opkg: http://code.google.com/p/zyxel-keenetic-packages/wiki/opkg_setup
[8] здесь: http://code.google.com/p/zyxel-keenetic-packages/source/browse/#svn%2Fbinary-packages-r2
[9] Lighttpd и php: http://code.google.com/p/zyxel-keenetic-packages/wiki/Drupal7
[10] урока: http://cxem.net/arduino/arduino17.php
[11] «3D кнопки с помощью CSS3»: http://habrahabr.ru/post/137005/
[12] Скачать все необходимые файлы одним архивом: http://lukjanow.ru/?dl_id=55
Нажмите здесь для печати.