Я люблю Raspberry Pi и люблю его настраивать. Raspberry Pi выглядит как очень хорошее хобби, но не связанное с моей профессией веб-разработчика и архитектора в Soluto, но создание проектов на raspberry pi может очень помочь в моей работе. Как? Может быть, эта история проиллюстрирует это — я говорил об этом на встрече Node.js, которую местное сообщество Node.js провело в Soluto, и я думаю, что ее стоит рассказать.

Raspberry Pi — это небольшой и доступный по цене карманный компьютер. На карту памяти Raspberry Pi можно установить любую операционную систему, особенно Linux.

Вы можете использовать его для нескольких программных проектов — например, установить на нем DNS-сервер и заблокировать рекламу и скрипты отслеживания (дополнительные данные см. на странице Pi-Hole). Вы используете его как защищенную точку доступа с VPN — то есть Wi-Fi, к которому вы получаете VPN-соединение, если используете его. Вы можете использовать его для исследовательских станций «человек посередине» и увлекательных программных проектов.

Но Raspberry Pi также может быть отличным инструментом для обучения и создания Интернета вещей (IoT), потому что у него есть шина — набор контактов, которые вы можете использовать для связи.

Некоторые из этих контактов предназначены для электричества, некоторые — для земли, но большинство из них — GPIO — контакты ввода-вывода общего назначения. Вы можете подключить любую простую электрическую цепь к контакту GPIO, и она будет программно передавать ток. Таким образом, вы можете включить или выключить светодиодную лампочку.

Например, в этой настройке я создал простую электрическую цепь с красной светодиодной лампочкой. одна сторона (синяя) подключена к контакту заземления, а другая — к контакту GPIO (GPIO17). Я активирую GPIO17, используя операционную систему Linux, в которой есть драйверы для шины.

Старый способ подключения к GPIO в Linux — использование интерфейса sys/class/gpio. Вот пример:

# Set up GPIO17
echo "17" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio17/direction
# Turn on GPIO17
echo "1" > /sys/class/gpio/gpio17/value

Это отличная команда BASH, но я веб-разработчик и часто использую Node.js для написания своих программ для Raspberry Pi. Как Node.js взаимодействует с GPIO? Большинство модулей Node.js в npm используют собственный модуль файловой системы (fs) для записи информации в sys/class/gpio. Например, так работает большинство модулей npm.

const fs = require('fs');
const pin = 17;
const value = process.argv[2];
console.log(`Writing value ${value} to {pin}`);
fs.writeFile(`/sys/class/gpio/gpio${pin}/value`,
  value,
  console.log
);

Легко, не так ли? Но ребята из Linux изменили правила! Этот простой и удобный интерфейс устарел. Почему? Потому что это было ненадежно. Новый интерфейс — это библиотека libgpiod, и вы можете использовать ее на C++.

Как я могу использовать C++ с Node.js? Что ж, я могу создать проект C++ и запустить его с собственным child_process.spawn Node.js. Или другие хаки, но я заметил, что разработчик по имени Леонардо Сильвейра создал модуль Node.js под названием node-libgpiod, чтобы делать именно это. Я заглянул в код, чтобы увидеть, как он это сделал, и был в восторге, увидев код на C++. Но КАК ЭТО МОЖЕТ БЫТЬ? Как код C++ интегрируется в Node.js? Я, конечно, знал, что Node.js написан на C++, но как он компилируется с Node.js?

В таком случае Леонардо Силвейра любезно объяснил это в своей статье об этом. Он использовал node-gyp!

Node-gyp — это модуль Node.js, который компилирует собственный C++ с Node.js для расширения Node.js. В документации Node.js вы можете узнать больше об этом, но это довольно просто!

Создайте проект npm с пустым index.js

npm install node-gyp

Убедитесь, что Python3 установлен и настроен. Если вы используете RaspberryOS, она уже поставляется с ней.

Поместите binding.gyp с дополнительными данными о вашем расширении в корень проекта.

беги node-gyp configure

Создайте файл C++ — пустой файл с расширением .cc. и поместите в него какой-нибудь код — например:

// hello.cc
#include <node.h>
namespace demo {
  using v8::FunctionCallbackInfo;
  using v8::Isolate;
  using v8::Local;
  using v8::Object;
  using v8::String;
  using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(
  isolate, "world").ToLocalChecked());
}
void Initialize(Local<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
}  // namespace demo

Выполнить node-gyp build .

Отныне вы можете использовать расширение C++ следующим образом:

И это ошеломляет и открывает множество возможностей в Node.js — IoT или не IoT — C++ — это мощный язык со многими интерфейсами, которых нет в родном Node. Теперь я научился комбинировать C++ и Node.js, и это знание пригодится. Почему? Поскольку Raspberry Pi — не единственная реализация, ее используют многие библиотеки и модули. После того, как я понял, как это работает с этой точки зрения, теперь я могу использовать свои новые знания для своей основной профессии: веб-разработки.

Вы получаете это преимущество от настройки Raspberry Pi и других несвязанных проектов. Кроме веселья и славы, конечно.