Seb Lee-Delisle


Fading LEDs with PWM on all pins with Pi Zero & Node.js

I’ve been converting my ST4i workshop from Arduino to Node.js/Raspberry Pi and one of limitations is a lack of built-in PWM pins. PWM or Pulse Width Modulation can be used to fade LEDs up and down rather than just turn them on and off. If you’re new to PWM, here’s a full explanation at Sparkfun.

On the Pi Zero, you can only enable 2 hardware PWM pins at one time, and the library I’m using to control the GPIO pins doesn’t support PWM at all! (The ubiquitous onoff node module).

After a bit of searching, I found the pigpio Node.js module, and this, in turn is a wrapper for the Pigpio C library.

As far as I can tell, it manages the PWM duty cycle in software, so it’s not as performant as the built-in hardware PWM pins, but as it’s written in C I’m sure it’s fast and certainly my experience so far suggests it’s super smooth.

If you want to try it for yourself, follow the instructions on the github page. I had a slight amount of weirdness, it didn’t seem to install straight away, but I deleted everything and started again and it seemed better.

I also had another problem – somehow I had started the pigpiod daemon and this clashed with the Node.js module code. Either the installer for pigpio did it or else I ran in manually while trying to get things running. sudo killall pigpiod should sort it out.

And a final thing to look out for – if you have node 0.10.29 on your Raspberry Pi (the version that comes with Raspbian Jesse) you’ll have a problem running any Node.js module that uses Nan, the native addon library. I first encountered this when I updated the LED matrix library to work with newer versions of Node.js, but it’s simple enough to fix. See this thread on github for solutions.

Once you have it installed you can do PWM output on any GPIO pin, here’s a set up for 9 LEDs like in the image above.

9 Leds on a Raspberry Pi

You can then use this code to get the nice pulsing effect in the animation.

var Gpio = require('pigpio').Gpio; 
// change these to match your LED GPIO pins : 
var ledPins = [21,20,16,12,26,19,13,6,5]; 
var leds = [];
// initialise all the pins
for (var i = 0; i<ledPins.length; i++) { 
	var led = new Gpio(ledPins[i], {mode: Gpio.OUTPUT});    
// get a loop running 60 times a second (1000/60 = 16.6)
setInterval(loop, 16); 
function loop() { 
	for(var i = 0; i<leds.length; i++) { 
		var led = leds[i]; 
		// calculate a sin wave for brightness dependent on time and 
		// position in the row of LEDs
		var brightness = Math.sin(((*5))*0.2)*0.5 + 0.5; 
		// a quick way to do a cubic ease in - it means the LEDs get brighter
		// slower. It compensates for the fact that LEDs get bright quick. 
		// the pigpio library complains if you send it a floating point number
		// so we have to round it down.
		brightness = Math.floor(brightness*255);

Note the issue with sending floating point numbers – I’m surprised that this isn’t handled at the other end but it’s easy enough to fix with a Math.floor.

And also notice how I’m using cubic easing to smooth out the brightness curve on the LEDs.

You can also use the pigpio library to control hobby servo motors. That’s what I’ll be doing next!

More about my ST4i workshops.

This entry was posted in Node.js, Raspberry Pi, ST4I. Bookmark the permalink.

2 Responses to Fading LEDs with PWM on all pins with Pi Zero & Node.js