What a humble web developer can learn from Raspberry Pi.
I love Raspberry Pi, and I love tweaking with it. Raspberry Pi looks like a very nice hobby, but unrelated to my professions as a web developer & architect at Soluto, but creating projects in raspberry pi can help a lot in my work. How? Maybe this story will illustrate it — I’ve talked about it at the Node.js meetup that the local Node.js community held at Soluto, and I think it is worth telling.
Raspberry Pi is a small and affordable pocket computer. You can install any operating system on Raspberry Pi’s memory card, especially Linux flavored.
You can use it for several programming projects — for example, install on it a DNS server and block commercials and tracking scripts (See Pi-Hole page for more data). You use it as a secured access point with a VPN — i.e., wi-fi that you are getting a VPN connection if you are using it. You can use it for man-in-the-middle research stations and exciting software projects.
But Raspberry Pi can also be an excellent tool for learning and making the Internet of Things (IoT) because it has a bus — sets of pins that you can use for communication.
Some of those pins are for electricity, some are for ground, but most are GPIO — General Purpose Input\Output pins. You can connect any simple electric circuit to a GPIO pin, and it will transfer current programmatically. In that way, you can switch on or off a LED light bulb.
For example, in this setting, I created a simple electric circuit with a red LED bulb. one side (blue) is connected to a ground pin, and the other is connected to a GPIO pin (GPIO17). I am activating GPIO17 using Linux operating system that has drivers for the bus.
The old way for connection to GPIO with Linux is by using sys/class/gpio
interface. Here is an example:
# 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
It is an excellent BASH command, but I am a web developer, and I often use Node.js to write my Raspberry Pi programs. How is Node.js dealing with communication to GPIO? Most of the Node.js modules in npm utilize the file system native module (fs) to write information to sys/class/gpio
. For example, this is how most npm modules work.
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
);
Easy peasy, right? But Linux guys changed the rules! This simple, easy-to-use interface is deprecated. Why? Because it was unreliable. The new interface is libgpiod library, and you can use it in C++.
How can I use C++ with Node.js? Well, I can create a C++ project and run it with Node.js native child_process.spawn
. Or other hacks, but I’ve noticed that a developer named Leonardo Silveira created a Node.js module called node-libgpiod to do just that. I’ve peeked into the code to see how he’s done it, and I was thrilled to see a C++ code. But HOW CAN IT BE? How is A C++ code integrated into Node.js? I knew, of course, that Node.js is written in C++, but how is it compiled with Node.js?
In that case, Leonardo Silveira was kind enough to explain it in his article about it. He used node-gyp!
Node-gyp is a Node.js module that compiles native C++ with Node.js to extend Node.js. In Node.js documentation, you can learn more about it, but it is pretty simple!
Create an npm project with empty index.js
npm install node-gyp
Make sure that Python3 is installed and configured. If you are using RaspberryOS, it comes with it already.
Place binding.gyp
with more data on your extension at the root of the project.
run node-gyp configure
Create a C++ file — empty file with a .cc extension. and put some code in it — for example:
// 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
Run node-gyp build
.
From now on, you can use The C++ extension like this:
And this is mind-blowing and opens many opportunities in Node.js — IoT or not IoT — C++ is a powerful language with many interfaces that native Node doesn’t have. Now I’ve learned how to combine C++ and Node.js, and this knowledge is practical. Why? Because Raspberry Pi is not the only implementation, many libraries and modules use it. After I understood how it works from that perspective, I can now utilize my new knowledge for my primary profession: Web development.
You get this advantage from tweaking with Raspberry Pi and other unrelated projects. Besides the fun and glory, of course.