Ранее на нашем сайте мы уже рассматривали различные варианты управления светодиодом с помощью платы Raspberry Pi: непосредственно при помощи программы на Python, через Bluetooth, по радиоканалу, из приложения Telegram. Чтобы расширить горизонты применения платы Raspberry Pi в данной статье, мы рассмотрим управление светодиодом с помощью веб-сервера на Node.js, представляющую собой весьма популярную платформу для программирования на JavaScript. При этом светодиодом можно будет управлять как локально (со своего рабочего места), так и глобально (из сети интернет). Первоначально платформа Node.js была разработана для браузера Google Chrome, но позже компания Google сделала ее продуктом с открытым исходным кодом. Более подробно про данную платформу вы можете прочитать в статье про использование Node.js в плате Arduino.
В данной статье мы будем управлять светодиодом, подключенным к плате Raspberry Pi, двумя способами:
- Сначала мы просто напишем код JavaScript используя Node.js чтобы мигать светодиодом.
- Затем мы создадим HTML страницу с размещенными на ней двумя кнопками: для включения и выключения светодиода. Эта веб-страница будет располагаться (хоститься) на Raspberry Pi и может быть открыта в любом веб-браузере. Таким образом, плата Raspberry Pi будет работать в качестве веб-сервера.
Необходимые компоненты
- Плата Raspberry Pi (купить на AliExpress) с установленной операционной системой.
- Светодиод (купить на AliExpress).
Установка Node.js на Raspberry Pi
Для установки платформы Node.js на плату Raspberry Pi выполните следующую последовательность шагов.
Шаг 1. Проверьте arm версию вашей платы Raspberry Pi с помощью команды:
1 |
uname -m |
На момент написания данной статьи ее авторами (конец 2018 г.) у них номер версии был 7.
Шаг 2. Скачайте установщик Node.js с помощью следующей команды. Не забудьте изменить номер версии в представленной ссылке на скачивание.
1 |
wget https://nodejs.org/dist/v4.6.1/node-v4.6.1-linux-armv%5bversion%5dl.tar.gz |
Шаг 3. Извлеките файлы скачанного установщика с помощью команды:
1 |
tar -xvf node-v4.6.1-linux-armv[version]l.tar.gz |
Шаг 4. Выполните следующие команды чтобы добавить некоторые важные файлы в локальный каталог.
1 2 |
cd node-v4.3.1-linux-armv[version]l sudo cp -R * /usr/local/ |
Теперь Node.js установлена на вашу плату Raspberry Pi. Проверить номер ее версии можно с помощью команды:
1 |
node –version |
Перед тем, как разворачивать веб-сервер Node.js, мы сначала рассмотрим как написать скрипт для мигания светодиодом с помощью Node.js.
Мигание светодиодом с помощью Node.js
Чтобы управлять контактами ввода/вывода (GPIO) платы Raspberry Pi с помощью Node.js мы используем onoff module (модуль включения/выключения).
Мы используем менеджер пакетов npm для установки onoff модуля:
1 |
npm install onoff |
После этого мы напишем скрипт для мигания светодиодом. Откройте редактор nano и задайте имя для файла с помощью команды:
1 |
nano blink_led.js |
Если вы начинающий в Node.js и его пакетах, вы можете изучить документацию по npm для лучшего понимания рассматриваемого в данной статье скрипта.
Объяснение скрипта на Node.js для мигания светодиодом
Полный код скрипта приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом объявим переменные для светодиода, задержки (интервала между миганиями) и GPIO. Для подключения светодиода мы использовали контакт GPIO 4.
1 2 3 |
var Gpio = require('onoff').Gpio; var LED = new Gpio(4, 'out'); var blinkInterval = setInterval(blinkLED, 500); |
После этого запрограммируем функцию для мигания светодиодом.
1 2 3 4 5 6 7 8 |
function blinkLED() { if (LED.readSync() === 0) { LED.writeSync(1); //set output to 1 i.e turn led on } else { LED.writeSync(0); //set output to 0 i.e. turn led off } } |
Также запрограммируем функцию для остановки мигания светодиода.
1 2 3 4 5 6 7 |
function endBlink() { clearInterval(blinkInterval); LED.writeSync(0); LED.unexport(); // Unexport GPIO to free resources } setTimeout(endBlink, 10000); |
Скопируйте и вставьте код скрипта, приведенный в конце статьи, в созданный нами файл led_blink.js, сохраните его используя Ctrl+x, затем нажмите Y и затем enter.
Чтобы запустить скрипт на выполнение, откройте окно терминала и выполните следующую команду:
1 |
node blink_led.js |
В результате выполнения этой команды вы увидите как светодиод будет мигать в течение 10 секунд, после чего он перестанет мигать. Более подробно все эти процессы вы можете посмотреть на видео, приведенном в конце статьи.
Схема для мигания светодиодом с помощью Node.js
Схема для мигания светодиодом с помощью платформы Node.js и платы Raspberry Pi представлена на следующем рисунке.
Внешний вид собранной схемы на макетной плате:
Веб-сервер на Raspberry Pi с использованием Node.js
В этой части проекта мы сделаем свой собственный веб-сервер, с помощью которого можно будет управлять контактами ввода/вывода (GPIO) платы Raspberry Pi с использованием веб-страницы.
Для этого нам необходимо сделать HTML страницу и написать скрипт, который будет выполнять задачу для конечного пользователя (back-end task), то есть управлять контактами GPIO платы Raspberry Pi. Для этого выполните следующую последовательность шагов.
Шаг 1. Создадим каталог чтобы хранить все файлы проекта в одном месте.
1 |
mkdir nodejs_server |
Шаг 2. Внутри каталога nodejs_server создадим еще один каталог, в котором мы будем хранить HTML файл.
1 2 |
cd nodejs_server mkdir views |
Шаг 3. Если вы хотите добавить изображения на свою html страницу, то вам необходимо создать еще один каталог для хранения изображений внутри каталога nodejs_server.
Шаг 4. Теперь приступим к созданию HTML страницы. Для этого перейдем в наш основной каталог, откроем текстовый редактор nano и создадим файл index.ejs. В скрипте, который мы хотим написать, нет ничего сверхъестественного – он будет просто создавать кнопки On (включение) и Off (выключение).
Скопируйте следующий фрагмент HTML кода в текстовый редактор nano и сохраните изменения в файле.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<meta name="viewport" content="width=500, initial-scale=1"> <div class="BorderMargin"> <image src = '/images/circuitdigest.jpg' alt="LED" style="width:500px;height:250px;" align="left"> <h1>Welcome to Nodejs Server</h1> <form action="/led/on" method="post"> <button type="submit" class="button">LED On </button> <button type="submit" formmethod="post" formaction="/led/off" class="button button3">LED Off</button> </form> <a>Led Status: <%=status %></a> </div> |
Шаг 5. Теперь мы приступим к написанию кода JavaScript. Мы будем использовать node express framework чтобы отвечать на http запросы, формируемые пользователем.
Откройте окно терминала и текстовый редактор nano, в редакторе nano создайте файл index.js в каталоге nodejs_server, затем скопируйте в этот файл нижеприведенный фрагмент кода java script и сохраните изменения в файле.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
var express = require('express'); var app = express(); var path = require('path'); var gpio = require('rpi-gpio'); gpio.setup(7, gpio.DIR_OUT); app.set('view engine', 'ejs'); app.use(express.static(path.join(__dirname, 'public'))); console.log(path.join(__dirname, 'public')); app.get('/', function(req, res){ res.render('index',{status:"Press Button"}); }); app.post('/led/on', function(req, res){ gpio.write(7, true, function(err) { if (err) throw err; console.log('Written True to pin'); console.log(path.join(__dirname, 'public')); return res.render('index', {status: "Led is On"}); }); }); app.post('/led/off', function(req, res){ gpio.write(7, false, function(err) { if (err) throw err; console.log('Written False to pin'); console.log(path.join(__dirname, 'public')); return res.render('index',{status: "Led is Off"}); }); }); app.listen(3000, function () { console.log('Server Started on Port: 3000!') }) |
Шаг 6. Внутри каталога nodejs_server необходимо выполнить следующую команду чтобы установить библиотеки платформы node.js.
1 |
npm install |
Шаг 7. Теперь ваш сервер готов к работе. Чтобы запустить в работу наш локальный сервер выполните следующую команду внутри каталога nodejs_server:
1 |
node index.js |
После выполнения этой команды вы увидите сообщение в терминале о том, что ваш сервер начал работу на определенном порту.
Шаг 8. Откройте ваш браузер и откройте URL Raspberry Pi с номером порта, то есть необходимо открыть адрес raspberrypi:3000.
Убедитесь в том, что ваша плата Raspberry Pi и ваш компьютер, на котором вы открываете браузер, находятся в одной и той же сети.
Если все идет так, как надо, вы должны увидеть следующую страницу в браузере:
На этой странице вы можете нажимать кнопку LED On чтобы включать светодиод и кнопку LED Off чтобы выключать светодиод.
Исходные коды программ
Код программы для мигания светодиодом с помощью Node.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var Gpio = require('onoff').Gpio; var LED = new Gpio(4, 'out'); var blinkInterval = setInterval(blinkLED, 500); function blinkLED() { if (LED.readSync() === 0) { LED.writeSync(1); //включаем светодиод } else { LED.writeSync(0); //выключаем светодиод } } function endBlink() { clearInterval(blinkInterval); LED.writeSync(0); LED.unexport(); // Unexport GPIO to free resources (освобождаем занятые ресурсы) } setTimeout(endBlink, 10000); |
Код программы для управления светодиодом с помощью Node.js веб-сервера
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
var express = require('express'); var app = express(); var path = require('path'); var gpio = require('rpi-gpio'); gpio.setup(7, gpio.DIR_OUT); app.set('view engine', 'ejs'); app.use(express.static(path.join(__dirname, 'public'))); console.log(path.join(__dirname, 'public')); app.get('/', function(req, res){ res.render('index',{status:"Press Button"}); }); app.post('/led/on', function(req, res){ gpio.write(7, true, function(err) { if (err) throw err; console.log('Written True to pin'); console.log(path.join(__dirname, 'public')); return res.render('index', {status: "Led is On"}); }); }); app.post('/led/off', function(req, res){ gpio.write(7, false, function(err) { if (err) throw err; console.log('Written False to pin'); console.log(path.join(__dirname, 'public')); return res.render('index',{status: "Led is Off"}); }); }); app.listen(3000, function () { console.log('Server Started on Port: 3000!') }) |