-
Notifications
You must be signed in to change notification settings - Fork 3
NodeJS plugin
To install Nodejs, simply download the last version from one of the existing depot. Do not use the default one with apt-get on raspbian, because you won't be able to compile node plugins.
wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb
You should now be able to test if node is here with node -v
and npm -v
for its packet manager.
node-gyp allows you to easily build C++ plugins to Nodejs on any platform (even if in our case it will only work on unix). It use its own 'kind of' Makefile, which it uses to generate every informations needed to compilation and linking.
npm install -g node-gyp
To use node-gyp and build your first plugin, the best is to follow the simple tutorial available on the Nodejs website https://nodejs.org/api/addons.html .
I won't talk much about the basic configuration, because nodejs' documentation is easy to read and provides a lot of useful examples.
From now, your binding.gyp
file should looks like this (with a project name addon and only one source file) :
{
"targets": [
{
"target_name": "addon",
"cflags": [ "-Wall" ],
"sources": [ "test.cc" ]
}
]
}
This plugin will use C++11 and wiringPi. You should install wiringPi if not already done. WiringPi provides an interface to talk to the GPIO pins of the raspberry, and can be found here : http://wiringpi.com/download-and-install/
To use C++11 we need to add -std=c++0x
to g++. We'll only add that to the cflag
array. Every element here is added to each file defined in the sources
array when compiled.
Using wiringPi is a little more difficult. Once you've installed and compiled wiringPi it will be installed. Your first tough was certainly to simply add a -lwiringPi
in the cflags
array, but that won't work. Why? Because you only need to give it to the linker once, and clfags are used for every compiled file. Fortunately, you can add static libraries instead of shared one to your binding file.
First, you'll need to generate the .a you need. Go to the wiringPi directory, then in the wiringPi subdirectory. Here, simply run :
make install-static
To generate the static library. it will usually be generated at /usr/local/lib/libwiringPi.a
. Now you can add an array named libraries
with the previous path to add it to your project setup.
From now, your binding file should looks like this :
{
"targets": [
{
"target_name": "addon",
"cflags": [ "-std=c++0x", "-Wall" ],
"sources": [ "test.cc" ],
"libraries": [ "/usr/local/lib/libwiringPi.a" ],
}
]
}
As you may have noticed, the latest version of wiringPi performs an exit()
if its launch fail. But since we are in a node plugin, we don't want this behavior. The problem is there is an easy way, defining an env variable, to overcome this new behavior, which don't work when used with a node plugin. I don't know why, but I suspect that nodejs may not give it access to the shell env variables.
The only way I've found is to actually comment the line 598 (which may change in future version) in the source file wiringPi.c
of wiringPi (method wiringPiFailure
) before generating the static library.
With the previous file, we will only use a small C++ file that will only launch wiring pi with wiringPiSetup
and nothing else:
#include <node.h>
#include <iostream>
#include <stdlib.h>
#include <wiringPi.h>
using namespace v8;
void RunCallback(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
int ret = wiringPiSetup();
Local<Number> num = Number::New(isolate, ret);
args.GetReturnValue().Set(num);
}
void Init(Handle<Object> exports, Handle<Object> module) {
NODE_SET_METHOD(module, "exports", RunCallback);
}
NODE_MODULE(demo, Init)
The JavaScript file will only launch the demo, get the result, and show a short text:
var demo = require('./build/Release/demo');
ret = demo();
if(ret == -1)
console.log("Error with wiringPi");
else
console.log("Everything works fine :)");
And you should be able to use test everything. Note that wiringPi need root right :