DIY video monitoring system, Node.js, Raspberry Pi

DIY video monitoring system – Part V Servo control using Node.js

This time we’ll step away from cameras and videos, and learn how to use Raspberry Pi’s GPIOs to control servos using Node.js and pulse-width modulation (PWM).

This is part V of the “DIY video monitoring system” series. If you haven’t read the previous entries, I highly recommend doing so.

The intro to this post contains a number of abbreviations and terms that need to be explained before we go any further.

Let’s start with GPIO.

GPIO

GPIO, also known as general purpose input/output, is a generic pin on a computer board acting as a physical interface between the device and outside world.

Recent models of Raspberry Pi come with 40-pin expansion headers, 26 of those pins can be used as GPIOs and can be configured as inputs or outputs. The rest are ground or power pins.

Servo

A servomotor, servo for short, is a small actuator, usually used for RC modelling or small robotics. Typically, it consists of a tiny motor driving a train of reduction gears, and a potentiometer connected to the output shaft. The potentiometer output is constantly compared with the value coming from the controller, whenever a discrepancy is detected, the motor moves to reduce the error. Once the error signal reaches zero, the servo stops moving.

RC servos are connected using 3 wires – two wires for DC power supply (ground and 5V) and one control wire carrying a PWM (pulse-width modulation) signal.

PWM

Puls-width modulation is a method of generating an analogue signal based on a digital source. A square wave is generated, switching between “on” (5v in our case) and “off” (0v) states. The duration of “on” state is called the pulse width or the duty cycle. A typical duty cycle for a small, 9-gram servo is between 500 and 2500µs.

By cycling a digital signal on and off at a fast enough rate and certain duty cycle, we can achieve a constant voltage like in an analogue signal.

Wiring

In my example, I’ll be powering the servos directly from Raspberry Pi’s GPIOs. Bear in mind this isn’t the recommended way of doing it, but with so small and weak servos the risk of breaking anything is really low. I’ll be using GPIO22 and GPIO23 pins to connect the signal wires. Here’s the wiring diagram:

Pan and tilt servo connection diagram
Pan and tilt servo connection diagram
Pan and tilt servo connection wiring
Pan and tilt servo wiring

Here’s a cheap pan-tilt head I’ll be using. Important thing to notice – you should centre the servos first before assembling the pan-tilt head!

Pan/tilt head
Pan/tilt head

And a picture showing how the actual wiring looks like. I had to take apart the original 3-pin servo plugs to make it possible to connect the servos to GPIO pins. Notice the heat-shrink tubes securing the connections from shorting the circuit.

Cable plugs secured with heat-shrink tubes to avoid short circuit

Implementation

To test out the PWM servo control, we’ll write a short, Node.js script capturing keyboard arrow keys and moving two servos – pan and tilt – accordingly.

We’ll start our implementation with installing a couple of Node modules that will take care of communication with GPIOs and allow keyboard controls – pigpio and keypress.

Before we do this, there’s one additional step for Raspbian Jessie Lite users – we need to install the pigpio C library first:

Once it’s done, let’s create a new directory, e.g. /home/pi/servo, enter it and run:

Now it’s time for our script, let’s call it servo.js:

Let’s quickly run through it. We start with loading additional modules, defining a bunch of constants and configuring GPIO pins. By the way, you may need to adjust the min/max constants to avoid servo “buzzing” when reaching edge values and/or limit the movement range of your pan/tilt head.

Then, we define a small helper function that will simplify limiting the servo pulse width values to predefined ranges.

Next, we calculate the pulse width for the servo centre positions and send them to servos using the servoWrite() method.

Once that’s done, we run a piece of code that will set up the keypress capturing and, based on the keys we press, will move the pan-tilt head.

Testing

One limitation of all Node GPIO libraries I found was that they require root privileges to enable PWM signal control. This means we have to start our script with the sudo command:

Once it loads, press keyboard arrows to control your servos. To stop the script, press ctrl+c.

Summary

In this post we’ve learned about:

  • GPIOs in Raspberry Pis
  • Servomotors
  • Pulse-width modulation
  • Controlling PWM using Node.js
  • Capturing keyboard inputs in Node.js

As always, the code created in this post is available in my Github repository.

Next time we’ll modify our servo control script to allow controlling servos over the Internet using WebSockets. Stay tuned!

by Greg

No Comments »

Leave a Reply

Your email address will not be published. Required fields are marked *