В наше время обычная вещь, подключённая к интернету, начинает становиться обыденностью. Даже появилось понятие — «интернет вещей» (Internet of Things, IoT). Но как подступиться к этому своеобразному интернету новичку — не всегда понятно, потому что хотя статей по данной теме много, но каждому хочется, чтобы статья была простой для воспроизведения и чтобы в ней разбиралось что-то очень близкое и приятное для читателя.
Поэтому попробуем подключить к интернету самое простое — светодиод, взятый из сломанной оптической мыши. Будем через страницу в интернете включать и выключать светодиод, управлять частотой его мерцаний.
Схема подключения светодиода к интернету будет следующая:

Итак, соберём все детали на столе и спаяем нашу простую схемку. Из мышки достаём светодиод и резистор в 220 Ом. Резистор нужен для ограничения тока, он мелкий и его еле можно разглядеть на конце провода. Для соединения проводов с GPIO использую коннекторы, которые выпросил в сервисе, ремонтирующем компьютеры.

На сервере и «малинке» должен стоять node.js и npm (node package manager). Устанавливаем по данной инструкции.
Для того, чтобы node.js смог работать с GPIO, требуется установить модуль rpi-gpio. А для соединения с сервером RPi потребуется
Следующий код на сервере создаёт сервер на порту 3141 и принимает команду setfps и рассылает её дальше всем браузерам и Raspberry Pi.
Запускаем скрипты следующим образом. На RaspberryPi — с правами рута:
На странице своего сайта включаем код для слайдера jquery-ui и socket.io с нашего сервера. При получении сигнала от node.js-сервера слайдер выставляет текущее значение fps и наоборот — при передвижении слайдера мы на сервер отсылаем новое значение fps, которое сервер затем рассылает всем клиентам в браузеры и на Raspberry Pi.
А вот и видео, описывающее, что получилось:
Вот, собственно, и всё, светодиод подключен к интернету. Теперь с любого устройства с интернетом мы можем управлять его мерцанием. Простор для дальнейшего творчества большой. Можно к выводам подклю��ить модуль-реле и кнопкой на своём сайте включать и выключать любое оборудование. Модулей для Raspberry Pi продаётся очень много, поэтому полёт фантазии почти не ограничен, особенно если в наличии восторженный восьмилетний почитатель электроники.
Документация Socket.io;
Документация Node.js;
Пакет rpi-gpio;
Документация на jquery-ui слайдер;
Распиновка GPIO на Raspberry Pi;
Модуль respawn для автоматического запуска nodejs-приложения (но я выбрал crontab).
Код можете взять из rpi-led на гитхабе.
Поэтому попробуем подключить к интернету самое простое — светодиод, взятый из сломанной оптической мыши. Будем через страницу в интернете включать и выключать светодиод, управлять частотой его мерцаний.
Для нашего эксперимента потребуется
- Интернет через ethernet кабель
- Raspberry Pi
- Сломанная оптическая мышка, провода, паяльник
- Доступ к сайту на vps с правами рута
Собираем схему
Схема подключения светодиода к интернету будет следующая:

Итак, соберём все детали на столе и спаяем нашу простую схемку. Из мышки достаём светодиод и резистор в 220 Ом. Резистор нужен для ограничения тока, он мелкий и его еле можно разглядеть на конце провода. Для соединения проводов с GPIO использую коннекторы, которые выпросил в сервисе, ремонтирующем компьютеры.

Подготавливаем софт
На сервере и «малинке» должен стоять node.js и npm (node package manager). Устанавливаем по данной инструкции.
Для того, чтобы node.js смог работать с GPIO, требуется установить модуль rpi-gpio. А для соединения с сервером RPi потребуется
socket.io-client. Устанавливаются пакеты командой sudo npm install rpi-gpio и sudo npm install socket.io-client. Скрипт для node.js на Raspberry Pi:
var socket = require('socket.io-client')('vpssite.domain:3141'); var gpio = require('rpi-gpio'); var fs = require('fs'); // hack due to error fs.exists = require('path').exists; var async = require('async'); // pin GPIO4 var pin = 7; // current fps var piFps = 0; var currentValue = false; var timemanager; var set0 = function(err, results) { if (err) console.log(err); console.log('Pin ' + pin + ' closed'); directWrite(pin, false, function() { clearTimeout(timemanager); }); }; var blinkexec = function() { delayedWrite(7, true, function() { delayedWrite(7, false, blinkexec) }); }; var blink = function(err, results) { if (err) console.log(err); console.log('Pin ' + pin + ' blinking'); blinkexec(); }; function directWrite(pin, value, callback) { return gpio.write(pin, value, callback); } function delayedWrite(pin, value, callback) { var delay = Math.round(1000 / piFps / 2); clearTimeout(timemanager); timemanager = setTimeout(function() { directWrite(pin, value, callback); }, delay); } var release = function() { console.log('Writes complete, pause then unexport pins'); setTimeout(function() { gpio.destroy(function() { console.log('Closed pins, now exit'); return process.exit(0); }); }, 500); }; socket.on('connect', function() { console.log('connected'); socket.on('setfps', function(data) { console.log(data); if (data.fps > 0) { piFps = data.fps; gpio.setup(pin, gpio.DIR_OUT, blink); } else { gpio.setup(pin, gpio.DIR_OUT, set0); } }); socket.on('disconnect', function() { console.log('disconnect'); release(); }); });
Следующий код на сервере создаёт сервер на порту 3141 и принимает команду setfps и рассылает её дальше всем браузерам и Raspberry Pi.
Скрипт для node.js на vps
var app = require('express')(); var server = require('http').Server(app); var io = require('socket.io')(server); var allClients = []; var count = 0; var fpsPi = 0; server.listen(3141); server.on('error', function(e) { if (e.code == 'EADDRINUSE') { console.log('Address in use, exit...'); process.exit(); } }); app.get('/', function (req, res) { res.send('Fps is ' + fpsPi); console.log('requested / - show ' + fpsPi); }); function getDate() { var datas = new Date(); return datas.getHours() + ':' + datas.getMinutes() + ':' + datas.getSeconds() + '.' + datas.getMilliseconds() } function consolelog(msg) { console.log(getDate() + ' ' + msg); } io.on('connection', function (socket) { io.emit('setfps', {fps: fpsPi}); // browser subscribes to listen to the station socket.on('subscribe', function(data) { socket.json.emit('subscribed', {fps: fpsPi}); io.emit('setfps', {fps: fpsPi}); }); // disconnect on error. Browser will reconnect socket.on('error', function() { socket.disconnect(); }); // client disconnects socket.on('disconnect', function() { consolelog('Client disconnected.'); }); // save to RPi and browsers new fps socket.on('setfps', function(fps){ fpsPi = fps; consolelog('setfps ' + fpsPi); io.emit('setfps', {fps: fpsPi}); }); });
Запуск работы
Запускаем скрипты следующим образом. На RaspberryPi — с правами рута:
sudo nodejs led.js, а на сервере — просто добавляем в кронтаб * * * * * cd /var/www/apps; node server.js >> cron_rpi.log, это не так красиво, зато всегда сервер будет запущен и можем о нём забыть. На странице своего сайта включаем код для слайдера jquery-ui и socket.io с нашего сервера. При получении сигнала от node.js-сервера слайдер выставляет текущее значение fps и наоборот — при передвижении слайдера мы на сервер отсылаем новое значение fps, которое сервер затем рассылает всем клиентам в браузеры и на Raspberry Pi.
Код, размещаемый на странице сайта
<script src="http://vpssite.domain:3141/socket.io/socket.io.js"></script> <script> function setSlided(val) { if (val == 0) { $('#freq').html('Выключен'); $('#freq2').hide(); } else { $('#freq').html(val); $('#freq2').show(); } } $(function() { // соединяемся с nodejs на сервере var socket = io.connect('http://bk-it.ru:3141'); socket.emit('subscribe'); // при ответе сервера выставляем текущую fps socket.on('subscribed', function(data) { if (!data.error) { setSlided(data.fps); $("#loading").hide(); $("#slider").slider({ min: 0, max: 20, value: data.fps, slide: function(event, ui) { $("#slider").slider({ disabled: true }); socket.emit('setfps', ui.value); //setSlided(ui.value); } }); } }); socket.on('setfps', function(data) { if (!data.error) { setSlided(data.fps); $("#slider").slider({value: data.fps}); $("#slider").slider({ disabled: false}); } }); }); </script> <h1>Светодиод, подключённый к интернету</h1> <link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script> <div class="panel panel-info"> <div class="panel-heading">Управляйте светодиодом через сайт</div> <div class="panel-body"> <div class="row"> <div class="col-md-6"> <div style="height:40px;position:relative;top:12px;"> <div id="slider"><div id="loading" style="position:relative;top:-4px;">Соединяемся <img src="/img/loading.gif" alt=""></div></div> </div> </div> <div class="col-md-6"> <div class="well-sm">Частота мерцания <b id="freq">Выключен</b> <span id="freq2" style="display:none;">раз/сек</span></div> </div> </div> </div> <div class="panel-footer"> Не так часто встречаете светодиод, подключённый к интернету? </div> </div>
Результаты работы
А вот и видео, описывающее, что получилось:
Вот, собственно, и всё, светодиод подключен к интернету. Теперь с любого устройства с интернетом мы можем управлять его мерцанием. Простор для дальнейшего творчества большой. Можно к выводам подклю��ить модуль-реле и кнопкой на своём сайте включать и выключать любое оборудование. Модулей для Raspberry Pi продаётся очень много, поэтому полёт фантазии почти не ограничен, особенно если в наличии восторженный восьмилетний почитатель электроники.
Полезные ссылки, помогшие эксперименту
Документация Socket.io;
Документация Node.js;
Пакет rpi-gpio;
Документация на jquery-ui слайдер;
Распиновка GPIO на Raspberry Pi;
Модуль respawn для автоматического запуска nodejs-приложения (но я выбрал crontab).
Код можете взять из rpi-led на гитхабе.
