Raspberry Pi, NodeJS and Basic Electronics

Now that we have a good project setup it's time to do something with it. If you haven't already I would recommend you read through my previous post Raspberry Pi NodeJS Project Setup with Git Deployment as I will be continuing from where we left off.

In this post we'll be doing some very basic electronics using the Raspberry Pi General Purpose Input/Output aka GPIO. That of course means we will have to play with some LEDs (yay!).

Goals

Here's what we're hoping to accomplish:

  • Light up an LED by wiring it up to the GPIO
  • Using a transistor and code to switch the LED On and Off
  • Using Pulse Width Modulation (PWM) to control the LED brightness

Requirements

If you'd like to play along here's what you will need:

  • Raspberry Pi (ideally setup as per my previous post)
  • Standard 5mm colored LED Picture
  • A 270 ohm resistor (The bands are: Red, Violet, Brown and Gold) Picture
  • BC547B transistor Picture

Those are the essentials, but to make life a lot easier I would also recommend:

  • Raspberry PI GPIO Breakout board such as this one from Maplin in the UK or this one from adafruit in the US.
  • Breadboard Picture
  • Jumper cables Picture
  • Github account

All of the parts above should be very easy to source and cheap from either online electronics shops, as part of starter kits or from hobbyist electronics shops on high streets. Also you will be able to use all of the parts on ton of different projects.

Disclaimer

As you are enjoying your Raspberry Pi and following the instructions below do keep in mind that even though I have tried to be as careful as possible it is possible that the instructions are incorrect and your Raspberry Pi may become permanently damaged, I cannot accept responsibility for this and ask that you only proceed if you are willing to accept this risk.

Simple LED & Resistor

Always unplug your Pi's power supply prior to wiring things up

We'll start by simply wiring up the LED and the resistor to the pins on the Pi.

If you are using a good quality breakout board that labels the pins excellent if not refer to the diagram found here.

Find the 3 volt power supply and the ground pins, usually these are labelled 3V (or 3v3) and GND.

We want to:

  • Connect the 3V to the anode of the LED (the longer leg)
  • Cathode of the LED (the other leg) to the resistor
  • Resistor to the ground

Simple LED circuit

If you now plug in the Pi's power supply you should see the LED light up!

Switching the LED On and Off

Now that was good fun but hardly useful, exciting or anything you wouldn't have done at school so let's step it up a notch or two.

First we'll add a transistor into the mix. More specifically a bipolar transistor. A bipolar transistor is like an electronic switch, it's got 3 legs called Collector, Base and Emitter. When the Base receives an electronic signal it allows for current to flow between the Collector and the Emitter.

Now for what we are doing here we don't actually need a transistor. We could just connect the LED directly to one of the programmable output pins and then turn on the power on that pin to light the LED. But in future projects when we want to control something that draws a lot more current such as high powered LED or a motor we would need to use this kind of setup.

The Raspberry Pi pins can only provide about 16 mA (milli amps) of current and if we plugged in something that drew more power such as a motor it would permanently damage the Pi as the components aren't designed to handle higher currents. By using a transistor we can have a high current going between Collector and Emitter being switched by a tiny amount of current from the Pi's pins.

Always unplug your Pi's power supply prior to wiring things up

We want to wire this up as follows:

  • Connect the 3V to the Collector of the transistor
  • GPIO Pin 17 (or any other number you can remember) to the Base of the transistor
  • The Emitter of the transistor to the anode of the LED
  • Cathode of the LED to the resistor
  • The resistor to the ground

LED with transistor circuit

In my picture the green wire is the 3V, orange is connected to GPIO 17 and yellow is connected to the ground on the breakout board.

Now if you connect the Pi's power supply the LED shouldn't light up, if it does, unplug, check to make sure you have wired up the legs of the transistor correctly.

Installing & Testing Software

To programme the GPIO pins from NodeJS we need to install couple of applications to the Pi first.

Before we get installing do make sure that you have access to Github from your raspberry pi. Github has an excellent guide for generating SSH Keys and adding them to Github here.

Once you have added your public key run the following in the SSH prompt:

ssh -T git@github.com  

You should receive a personalised message and it should include "You've successfully authenticated".

The first piece of software we will be installing is quick2wire GPIO Admin. This allows us to use the GPIO pins from our NodeJS application without having to run the application with root privileges.

To install quick2wire GPIO Admin run the following statements in the SSH:

mkdir ~/tools && cd ~/tools  
git clone git@github.com:quick2wire/quick2wire-gpio-admin.git  
cd quick2wire-gpio-admin  
make  
sudo make install  
sudo adduser pi gpio  

This will, create a tools directory, pull the source code for GPIO Admin from Github, builds and installs the software and adds our pi user to the gpio group of users which have permission to access the GPIO pins.

Now disconnect from the SSH session and reconnect again to ensure that the correct permissions get applied.

To test whether everything is working so far we can run the following commands:

gpio-admin export 17  
echo out > /sys/devices/virtual/gpio/gpio17/direction  
echo 1 > /sys/devices/virtual/gpio/gpio17/value  

If everything is well the LED should now light up! To turn the LED off again run the following commands:

echo 0 > /sys/devices/virtual/gpio/gpio17/value  
gpio-admin unexport 17  

Woooo!

Let's code!

Hope you got some awesome nerd chills from that; I know I did the first time I did that. So let's do that in code now!

You should have the base project setup from last article so we'll carry on with that as we already have it setup to deploy on the pi.

Now some of the NodeJS packages we'll be using will have native addon modules as to enable us to use them we need to install a handy tool called node-gyp.

Installation is simple just run the following on the PI:

npm install -g node-gyp  

This might take a bit of time so make yourself a cuppa or say hello to me on twitter @efexen.

Now that's done we'll move to work on our development machine. First we'll install a lovely little package onoff. onoff allows us to easily turn the GPIO pins on the Pi on or off (I see what they did there...) from your NodeJS code!

Navigate to the folder where you created the project last time and run:

npm install onoff --save  

Next we need to add the node_modules folder to our .gitignore file, we need to do this as some of the native modules built on your development machine won't be compatible with the Pi and should be built on the Pi instead.

To do this we can just edit the .gitignore file at the root of the project folder. If this file doesn't exist just create it and add the following line:

node_modules/  

Next let's write our index.js file:

var http = require('http');  
var url = require('url');  
var Gpio = require('onoff').Gpio;

var led = new Gpio(17, 'out');

http.createServer(function (req, res) {

  res.writeHead(200, {'Content-Type': 'text/html'});
  var command = url.parse(req.url).pathname.slice(1);
  switch(command) {
    case "on":
      led.writeSync(1);
      res.end("It's ON");
      break;
    case "off":
      led.writeSync(0);
      res.end("It's OFF");
      break;
    default:
      res.end('Hello? yes, this is pi!');
  }

}).listen(1337);

Let's break it down:

var http = require('http');  
var url = require('url');  
var Gpio = require('onoff').Gpio;  

This loads the HTTP module and URL module of NodeJS and the onoff module.

var led = new Gpio(17, 'out');  

This creates the Gpio object to represent our LED located at pin 17 and it should be an output as we want to either turn it on or off rather than reading values from it.

http.createServer(function (req, res) {  

This creates our HTTP server and creates a callback function that will be called whenever the server receives a request.

res.writeHead(200, {'Content-Type': 'text/html'});  

This writes status code 200 (OK) to the response and sets the Content-Type header to text/html advising the connecting client to expect HTML response. This will be handy later on if we want to return HTML such as a link to turn the led on or off.

var command = url.parse(req.url).pathname.slice(1);  

This uses the URL module of the NodeJS to parse the requested url to it's components, we take the pathname component which is anything after the host and port. Finally we call slice(1) on this which drops the first character.

What we are left with is the last part of the URL in our variable so for instance:

Requesting: http://192.168.1.90:1337/on has the pathname of "/on", if we then slice off the first character we are left with "on", likewise if we request: http://192.168.1.90:1337/off the command will be "off".

We then use a switch statement to act depending on the command we received.

led.writeSync(1);  

This line is executed when the command is "on" and it will synchronously write the value of 1 (ON for our purposes) to the led we setup earlier.

res.end("It's ON");  

This writes the text "It's ON" to the response and closes the request.

The various branches of the switch command either write 0 to the LED and respond with different text or by default just greets you with a silly message.

}).listen(1337);

Finally this line starts our server listening on port 1337.

If we now commit and push the changes to the pi with following commands:

git add -A  
git commit -m "LED On Off"  
git push pi  

Do note that the deployment might take some time initially as the onoff package is installed using NPM and the native modules are compiled. Once the deployment has finished you should be able to connect to the pi using your browser: http://192.168.1.90:1337/

You should see a message, if however you navigate to http://192.168.1.90:1337/on the LED should turn on! and /off will turn it off again!

Pulse Width Modulation

So cool! But we're not quite done yet! Turning the LED ON and OFF is nice and all but wouldn't it be nice to have little more control. The GPIO pins on the Raspberry Pi (and most other micro controllers) have two states ON or OFF, not very handy if we want to control the brightness of the LED or something like a motor.

Enter PWM, Wikipedia has a great indepth article about it but in simple terms: By turning the on/off swith really fast we can create a voltage which is lower than the supplied voltage. For instance we can half the 3V input to 1.5V by turning switching the pin really fast between on and off so that it is on only 50% of the time.

We don't have to worry about duty cycles or how to get the Pi to switch the pin that fast here as we'll be using a great tool called pi-blaster. pi-blaster allows us to easily use PWM on our Raspberry Pi!

So let's open an SSH connection to the Pi again and run the following commands:

sudo apt-get install autoconf  
cd ~/tools  
git clone git@github.com:sarfata/pi-blaster.git  
cd pi-blaster  
./autogen.sh
./configure
make  
sudo make install  

Again this might take some time.

Great let's get back to our code, we'll install a new NodeJS package pi-blaster.js. This allows us to use the pi-blaster tool from our Node code.

So on the development machine back in our project directory:

npm install pi-blaster.js --save  

Next we'll change our index.js to utilise our cool new stuff:

var http = require('http');  
var url = require('url');  
var piblaster = require('pi-blaster.js');

http.createServer(function (req, res) {

  res.writeHead(200, {'Content-Type': 'text/html'});
  var brightness = url.parse(req.url).pathname.slice(1);

  if (brightness.length === 0 || isNaN(brightness)) {
    res.end('hello? yes, this is pi!');
  } else {
    piblaster.setPwm(17, brightness / 100);
    res.end('Brightness set to: ' + brightness + '%');
  }

}).listen(1337);

So let's have a look at the files that are different from last:

var piblaster = require('pi-blaster.js');  

Load the piblaster module.

if (brightness.length === 0 || isNaN(brightness)) {  

We want to check if the brightness (previously command) is empty "" or if non number was input. We'll respond with a silly message again, if a number was entered instead:

piblaster.setPwm(17, brightness / 100);  

We use the piblaster module to set the duty cycle of the pin 17 to be our input brightness divided by 100. We divide by 100 as the piblaster treats 0 as off and 1 as 100% duty cycle.

So if we commit and push the changes to the pi again we can see this in action.

Navigating to the root url http://192.168.1.90:1337/ still just shows the silly message but now if we navigate to http://192.168.1.90:1337/50 we get the LED light up with 50% of the full brightness, changing to /10 we get 10% and so on.

What now?

Now you go and do all sorts of cool stuff with this!! Using the NodeJS timers it's easy to create a fading effect for the LED or maybe an app with a slider that works like a dimmer. Very similar circuit and code can be used to control motors which could be part of a robot or your browser controlled window blinds or or or or...

I hope this has helped you get started with your Pi creating first simple projects and provided with enough information to continue creating.

Let me know what you think on twitter @efexen or via email [fxn at fxndev dot com] and stay tuned for the next article where we'll be playing with the physical-web project, the Pi, NodeJS and our LED stuff so far!