Using Node.js to control your Raspberry Pi

Introduction

The Raspberry Pi is a credit card-sized computer that plugs into your TV and a keyboard. It is a capable little computer which can be used in electronics projects, and for many of the things that your desktop PC does, like spreadsheets, word processing, browsing the internet, and playing games – raspberrypi.org

Of course, there are many other things you can use your pi for as you can see here and here.

The raspberry pi runs on mainly a linux based operation system known as Raspbian, however, beginner users have often used NOOBS to get started. You can view a list of officially supported images on the downloads page. My personal preference is the RASPBIAN JESSIE which comes in 2 versions, the full version with a GUI or a headless version for you super techy linux power users which only has a terminal.

So now that you have your raspberry pi running how do you start doing all the cool projects like controlling lights and reading temperatures etc? Simple, you write a program.You have to use the GPIO pins, The raspberry pi provides easy access to to GPIO pins and from there you can either write or read values form each of them. For example you could switch on a light(if it’s directly connected to the board it should be a small LED, the pi is not powerful enough to power a normal light bulb) by setting the output value of that pin to the maximum voltage.

Controlling Your GPIO Pins

There are 2 approaches to doing this. The first is to directly manipulate the GPIO registers much like one would do when programming a micro controller without an operating system or memory management unit. The advantage of this method is that by bypassing the os and you’re shaving some latency off of read/write times. Bypassing the OS however means that if two processes are trying to access the same physical GPIO registers at the same time, a unsafe resource conflict can happen.

The other approach is to use the inbuilt Linux drivers to access the gpio pins. This is a much safer, albeit slower approach.

Most of the time you need not worry about these approaches as the programming language you using will take care of it for you. Almost every programming language supported by the raspberry pi has its own GPIO control library. For most starter projects the best approach would be to use the OS to toggle pins as you need not worry about resource conflicts.

Programming You PI

Python has long being touted as the official language of the PI. The Raspberry PI foundation recommends as a language for learners do you its expressive style and simple syntax.  However, ny language which will compile for ARMv6 (Pi 1) or ARMv7 (Pi 2) can be run on your pi, so Python is not your only option. C, C++, Java, Scratch, and Ruby all come installed by default on the Raspberry Pi however, if this is your first project I recommend using Python for a number of reasons, which I will discuss later. If you notice, Node,js is not on that list, that is because until recently it was not possible to use Node.js to control gpio pins. However, I recently found a rather excellent library for reading and writing to GPIO pins called rpi-gpio,

The library, and the idea of using Node.js for this task, is pretty young and not yet popular however I thought I would give it a try to see what it’s like.

Scenario:

  1. Turn on a series of lights one by one is quick succession with a uniform delay in between.
  2. Once all the lights are switched on, turn them off in the same order with the same uniform delay.
  3. Repeat until script is exited.

The node script:

var gpio = require('rpi-gpio');
var allPins = [7, 11, 13, 15, 12];
//delay in milliseconds
var DELAY = 500;
setupPins(allPins, function() {
    console.log('Setup Done');
    startLoop();
});

function setupPins(pins, callback) {
    console.log('Start Setup');
    setupPin(0, pins, callback);
}
//recursive function since node is async
function setupPin(key, pins, callback) {
    var currentKey = key;
    if (currentKey > (pins.length - 1)) {
        callback();
        return;
    }
    gpio.setup(pins[currentKey], gpio.DIR_OUT, function(err) {
        console.log('Setting up ', pins[key]);
        if (err) {
            console.log("Error in setup of pin " + pins[key]);
        }
        var incrementKey = currentKey + 1;
        setupPin(incrementKey, pins, callback);
    });
}

function startLoop() {
    console.log("Starting loop");
    turnAllOn(allPins, function() {
        console.log('All On');
        turnAllOff(allPins, function() {
            console.log('All Off');
            startLoop();
        });
    });
}

function turnAllOn(pins, callback) {
    console.log('Starting to turn all on');
    writeToPin(0, pins, true, callback);
}

function turnAllOff(pins, callback) {
    console.log('Starting to turn all off');
    writeToPin(0, pins, false, callback);
}
//recursive function
var writeToPin = function(key, pins, value, callback) {
    var currentKey = key;
    if (currentKey > (pins.length - 1)) {
        callback();
        return;
    }
    setTimeout(function() {
        console.log('Writing to ', pins[key]);
        gpio.write(pins[currentKey], value, function(err) {
            if (err) {
                console.log("Error in writing of pin " + pins[key]);
            }
            var incrementKey = currentKey + 1;
            writeToPin(incrementKey, pins, value, callback);
        });
    }, DELAY);
};

The equivalent python script:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
pin_list=[7,11,13,15,12]
GPIO.setup(pin_list,GPIO.OUT)

def pin_handler(pin,value):
	GPIO.output(pin,value)
	return;

#delay between light actions, in seconds
delay=0.5
#simple variable to make an infinite loop
guard=1
#condition to make infinite loop
while(guard==1):
	# setting all pins on with a delay in beetween
	for pin in pin_list:
		pin_handler(pin,GPIO.HIGH)
		time.sleep(delay)
	# switching all pins off with delay in between
	for pin in pin_list:
	    pin_handler(pin,GPIO.LOW)
	    time.sleep(delay)
	print("Next Cycle")

As you can see, the controlling of the pins themselves are pretty easy. All you have to do is import the library , set the board numbering mechanism , set up a pin, and then write/read to/from it.

With node and python the main difference is that since node is async you have to use the callback to ensure one action is completed to start the next. You could use a library like async.js to make the code within a block synchronous but I wanted to demonstrate the code as simple as possible.

Conclusion

Python is and will be (for awhile at least) the easiest and most convenient language for programming on the pi. There is support right out of the box, unlike node js.

There are also libraries for virtually every sensor available on the market written in python which means to use a sensor all you have to do is download the respective library and use it. Node.js currently does not have any libraries like this. This means that to read data from a pin you will have to get your hands on the manufatures hardware spec and learn what the voltages and voltage cycles mean and how the data is transferred and write this all by yourself, my advice, unless you gave a degree in electrical engineering as well as a thorough understanding of low level programming, don’t expect to

As you can see, the python code is much more readable and verbose, the node js script due to using callbacks and recursion becomes much more complex than it needs to be.

However, take a different scenario. You want to control some lights form your mobile phone or website. How do you do it? You could write a web socket server on the pi and listen for changes and control the lights accordingly, for this case I would definitely go for a Node.js implementation simply because of how easy it is to set up a server and get it deployed. However, long term python might be the more beneficial choice, but for cool proof of concepts and demos, Node.js is a good choice.

http://www.hertaville.com/introduction-to-accessing-the-raspberry-pis-gpio-in-c.html

https://www.raspberrypi.org/help/faqs/#softwareOS

https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s