Staircase project, part 6: finished!

And it looks great too!

This post should have been made 6 weeks ago or so, but I just couldn’t find the time with all the other things I wanted (and some which I just had) to do. But this week  I realized that delaying this post any longer would probably mean it would never be made, so I sat down, read my last post about this project to see where I had ended.

The Arduino Ethernet has been replaced by an Arduino Duemilanove, because when I found out how easy it is to flash an Arduino from a Raspberry Pi, the Arduino Ethernet wasn’t the best tool for the job anymore – an Arduino Duemilanove was a better choice actually – powered by a USB cable between the Arduino and a RPi meant that I didn’t need a power supply and flashing became a breeze. Another great plus was that I could now use Serial() on the Arduino instead of Ethernet.

So how does this contraption work? The Raspberry Pi that’s near the Arduino runs a Node.JS script. This script basically controls the ‘state’ in which the Arduino is.  With the serialport module this Node script can send commands to the Arduino like ‘reset’, ‘on’, ‘off’, ‘day’, ‘night’, ‘demo’, ‘stop’.

The reset command triggers a ‘reboot’ of the Arduino by jumping to address 0. The on/off commands are used to tell the Arduino whether it should act on the light barriers being broken or not, day and night tell the Arduino whether it’s day or night in our world (which has it’s effect on the brightness of the LED strips), and the demo command… well, you can do amazing stuff with 13 individual LED strips! 😉

And of course the Arduino is Serial.print()-ing everything it does: it reports when a light barrier triggers, changes in brightness levels of the LED strips and so on.

The Node.JS script on the Raspberry is partly controlled by the rules engine I use (for day- and night-mode obviously, and for ‘off’ when nobody’s at home.

But not everything went as smooth as I thought it would. After installing everything near the stairs (RPi, Arduino, 16-channel LED driver) something continuously triggered the IR light barriers! What the …? I checked every wire, and again, and again… but I couldn’t find anything wrong, so the only thing I could do was go back in time and reconstruct everything to how it was when it did work. From there I moved forward again until the problem came back. Conclusion, after a really long Sunday: interference. I used UTP cable (a single pair) to connect the IR light barrier LEDS to the Velleman MK120 PCB – this worked well during testing in the lab, but not in the cupboard under the stairs! Too many cables over there that influenced the signal on the unshielded wires I used. Stupid, I should have known this, I guess. I just have to face the fact that I’m not good at this kind of things… after replacing the wire with a piece of shielded microphone wire everything worked again.

Some last minor adjustments in the code here and there like the interval between each LED strip switching on and the project was finished – everything worked just the way I wanted it to, the visual result is impressive and worth all the time & energy that were needed to complete it all.

And here’s the long awaited video and some pictures I made of the end result; enjoy!

sc1sc0

Staircase project, part 5: the end is in sight

Today some important milestones were achieved – painting is finished now as well as soldering the 16 channel LED driver. Birthdays, parties, the flu and other physical discomfort delayed the whole thing more than we anticipated but hey, who cares – we sure don’t 😉

16 Ch. LED driver in its enclosureEspecially soldering all the components for the 16 channel LED driver on a piece of perfboard was quite a job – but now that it’s finished and all 16 channels are tested and working, I’m very pleased with it.

The sketch for the Arduino Ethernet is also progressing nicely – MQTT is operational, i2c is working fine too  and I haven’t seen any glitches which I did see when the Raspberry Pi was controlling the LED driver. So all that’s left to do is connecting the light barriers as inputs to the Arduino so that the sketch knows when someone’s walking up or down the stairs.

And of course, I still have to saw 12 aluminum profiles to the right length, put in the LED strips, solder wires to the strips and mount those profiles under the steps. So I think I’ll need another weekend to finish the hardware side before I can focus on the software – but the end is in sight. Now that I think of it – how do I change the behavior of the sketch without having to flash new firmware every time I want to change something in how the LED strips are being controlled… maybe an alternative bootloader and the SD card can help here?

Staircase project, part 4: progress and changes

Almost finished A small update. As you can see the stairs are almost done. The banisters still need to be painted and some minor ‘errors‘ need to be resolved, but the major part of the things I’m not good at are done!

Now I can finally spend some more time to spend on the fun part: the LED strips, the light barriers and creating some nice light effects with it all. Can’t wait to see it in action 😉

The light barriers have been on a desk in my lab for quite some time and are working very well. The only thing left to be done is conditioning the signal so I can feed it to a I/O pin.

I’ve also had a piece of LED strip connected to a RPi-controlled Dimmer Plug on that same desk for more than a week or so; not because I like having a LED strip next to me which is constantly changing in brightness, but because I wanted to be sure that the non real-time way of controlling the Dimmer Plug wouldn’t result in visible effects like pausing or flickering LED strips. It’s about lighting, so even the smallest hick-up will be seen.

And guess what, in a period of say 20 hours I noticed that the LED strips were indeed flickering, about 3 times – they were not doing what I instructed! I could only think of 1 reason for this: the Operating System  of the RPi decided that something else had a higher priority than my LED strip program. OK, I know this is not much of a scientific approach, there are other possible causes (Node.JS and its garbage collection?), but I didn’t like what I saw so I decided to buy a Arduino Ethernet, just for the sake of convenience. The Arduino should be able to control the DimmerPlug & LED strips much more real-time and hence more smoothly all the time.

Last week the 4 x 5m. LED strip arrived, including 12 x 1m. aluminum profile with opal cover. And about 16 x IRLZ34N, terminal blocks, perfboard, etcetera. With what I have laying around, this should be enough to create a box with 16 screw terminal for 16 LED strips. I don’t need all 16 of ’em for this staircase project, but I’ve already got some things in mind for the remaining 4.

Testing (again)The last thing I did (last evening) was that I successfully soldered a screw terminal, MOSFET and a resistor on a piece of perfboard occupying a surface small enough so that I could solder another 15 copies of it on a piece of perfboard that would still fit in the enclosure that I want to use. And of course, I also did a live test with the Dimmer Plug, a 12V adapter and 5m. LED strip: beautiful!

Staircase project, part 3: Velleman MK120

After my NAS was fixed, I could continue working on some components I need for our staircase renovation. One of those components is the Velleman MK120 Infrared Light Barrier.

But I needed some proof of how well (or not) these light barriers would work, so I did some tests with the soldered kit on my desk. Well, with about 70 cm. between the transmitter and receiver, even moving a forefinger (or cat paws..) through the beam triggered the buzzer. I also did some test to let the IR beams bounce on nearby objects and that did have an effect on detecting objects, but I hope I can minimize that effect.

Domotica should be invisible if possible, so I decided to keep the IR LEDs off the PCB and solder headers instead. This way I can locate the PCB’s somewhere out of sight. Also the buzzer was not soldered on the PCB, but connected with headers and wire (just for testing purpose, it’s really loud!). Now all I need is a good place in the schematic to tap a good signal that I can use on a MCU or maybe a Raspberry Pi; more on that in a future post.

After the positive results of the tests, I moved on and started drilling some holes here and there and pulling wires, so that the only remaining visible items of these light barriers would be the LEDs.

After some exploratory drilling (I hit some steel reinforcements a couple of times…) I found a way to keep the wires out of sight as much as possible. All the holes are drilled now, including those for the LED strips; a total of at least 17 holes were needed to keep all the wires out of sight. Now my wife can start painting all the wooden parts and I can start finishing the steps…

Next: the light barrier as input for my Domotica system – but that post can take a while, cause there’s a lot of manual labor to be done first!

Below some pictures of the progress so far (click for a larger image).
IR Transmitter PCB IR receiver PCB

IR Transmitters working! IR Receiver LED, bottom

Holes for the transmitter LEDs Hole and wires for top light barrier

Hole and wires for top light barrier

Staircase project, part 2: Raspberry Pi and i2c

After rediscovering the Dimmer Plug  a few days ago, the time had come to see if I could use the Dimmer Plug directly from a Raspberry Pi.

Before I could connect the Dimmer Plug to the Raspberry Pi, I had to enable i2c on the Raspberry Pi; because out of the box, i2c is disabled (because there’s not much to learn about i2c? ;-))

Here’s a short list of what had to be done:

  • Remove i2c from blacklist

The file /etc/modprobe.d/raspi-blacklist.conf had to be modified so that it looked like this:

#blacklist spi-bcm2708
#blacklist i2c-bcm2708

The ‘#’ turns the 2 lines into comment lines, so that those 2 modules are no longer blacklisted/disabled; I also enabled spi which is not really necessary for this.

  • 2 lines had to be added to /etc/modules:

i2c-bcm2708
i2c-dev

  • Installing i2c-tools:
sudo apt-get install i2c-tools
  • Sufficient access rights for user pi:
sudo adduser pi i2c && reboot

After the reboot, I had 2 new devices:

pi@rpi3 ~ $ ls -rtl /dev/i2c*
crw-rw---T 1 root i2c 89, 0 Sep 12 21:43 /dev/i2c-0
crw-rw---T 1 root i2c 89, 1 Sep 12 21:43 /dev/i2c-1

And after I connected the Dimmer Plug, a scan of the i2c bus resulted in the following:

pi@rpi3 ~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@rpi3 ~ $

Well that wasn’t too hard… The Dimmer Plug with address 0x40 is being detected, so we’re ready to go… The next thing that had to be done was getting i2c working from Node.JS. Fortunately there’s a Node module for i2c, so that part is already covered. A driver for the PCA9635 IC wasn’t hard either – all I had to do was sending the same bytes to the PCA9635 as the JeeLib driver did.

The things I want to do with the LED strips involves sending certain ‘patterns’ to the LED driver at specific intervals. Will the Raspberry be able to do this in a reliable way? I don’t know yet, cause right now the Raspberry which I’m using to test this LED driver, has (almost) nothing else to do than run a single Node app that uses this LED driver. But what if more drivers are running, all consuming CPU cycles, or what if the OS feels it’s time to do something else for a change, just when the LED strips need to be adjusted in brightness? We’ll see.. maybe not now, but too much delay or other irregularities should be visible right away, so I decided to just wait and see how this turns out in practice.

The PCA9635 driver code is quite small and simple, actually:

/**
 * PCA9635 LED driver I2C library for Node.JS
 * Based on the JeeLib Dimmer Plug driver
 * (https://github.com/jcw/jeelib)
 */

i2c = require('i2c');

var modes = {
        MODE1:0, MODE2:1,
        PWM0:2, PWM1:3, PWM2:4, PWM3:5, PWM4:6, PWM5:7, PWM6:8, PWM7:9,
        PWM8:10, PWM9:11, PWM10:12, PWM11:13, PWM12:14, PWM13:15, PWM14:16, PWM15:17,
        GRPPWM:18, GRPFREQ:19,
        LEDOUT0:20, LEDOUT1:21, LEDOUT2:22, LEDOUT3:23,
        SUBADR1:24, SUBADR2:25, SUBADR3:26, ALLCALLADR:27};

function DimmerPlug(device, address) {
  this.device = device || '/dev/i2c-1';
  this.address = address || 0x40;
}

DimmerPlug.prototype.initialize = function() {
  this.i2cdev = new i2c(this.address, {device : this.device});
  this.setReg(modes.MODE1, 0x00); // normal
  this.setReg(modes.MODE2, 0x14); // inverted, totem-pole
  this.setReg(modes.GRPPWM, 0xff); // set group dim to max brightness
  this.setMulti(modes.LEDOUT0, [0xff, 0xff, 0xff, 0xff]); // all LEDs group-dimmable
}

DimmerPlug.prototype.setReg = function (reg, value) {
  this.i2cdev.writeBytes(reg, [value]);
}

DimmerPlug.prototype.setMulti =  function(reg, values){
  this.i2cdev.writeBytes(reg | 0xe0, values);
}

module.exports = DimmerPlug;
module.exports.modes = modes;

Now the Node app… I decided to follow the dimmer_demo sketch, cause if I’d get the same results with the RPi as with the JeeNode I knew everthing was OK. And now the code for the Node app becomes  a bit awkward… it’s a demo, constantly changing the brightness of all the LEDs, but there are no real events, so there’s nothing to trigger on.

This app does its job totally isolated from the rest of the world.. and things get even ‘uglier’, cause the JeeLib demo contains a few delay() statements – which (for the obvious reasons) is not available in Node – yes, there’s setTimeout(), but that doesn’t pause execution! This was the first time I had to think about how to do something in Node.. I needed something to control the program flow; normally (in my case) a driver gets its events from either MQTT messages or incoming data from the hardware, but both are not the case here (yet). I decided to use the async module for that and create a series of functions that should be executed after each other. This is how the Node version of the dimmer demo looks like:

var dimmerplug = require('./dimmerplug');
var async = require('async');

var level = 0x1fff;
var dimmer = new dimmerplug();

async.series(
  [
    function(callback) {
      dimmer.initialize();
      dimmer.setMulti(dimmerplug.modes.PWM0, [255, 255, 255, 255,
                                        255, 255, 255, 255,
                                        255, 255, 255, 255,
                                        255, 255, 255, 255]);
      // set up for group blinking
      dimmer.setReg(dimmerplug.modes.MODE2, 0x34);
      // blink rate: 0 = very fast, 255 = 10s
      dimmer.setReg(dimmerplug.modes.GRPFREQ, 50);
      // blink duty cycle: 0 = full on, 255 = full off
      dimmer.setReg(dimmerplug.modes.GRPPWM, 100);
      // let the chip do its thing for a while
      setTimeout(function(){callback(null, '1');},10000);
    },
    function(callback) {
      // set up for group dimming
      dimmer.setReg(dimmerplug.modes.MODE2, 0x14);
      // gradually decrease brightness to minimum
      for (i = 100; i < 255; ++i) {
          dimmer.setReg(dimmerplug.modes.GRPPWM, i);
      }
      setTimeout(function(){callback(null, '2');},2000);
    },
    function(callback) {
      while(true){
        brightness = ++level;
        if (level & 0x100){
            brightness = ~ brightness;
        }
        r = level & 0x0200 ? brightness : 0;
        g = level & 0x0400 ? brightness : 0;
        b = level & 0x0800 ? brightness : 0;
        w = level & 0x1000 ? brightness : 0;
        // set all 16 registers in one sweep
        dimmer.setMulti(dimmerplug.modes.PWM0, [w, b, g, r,
                                      w, b, g, r,
                                      w, b, g, r,
                                      w, b, g, r]);
      }

    },
  ],
  function(err, response) {
    console.log(response);
  }
);

A bit weird, but it works. The Node demo worked just as well like the JeeNode version, so another part of this staircase project is done – the power MOSFETs have already been ordered, so as soon as they arrive I can connect real LED strips the the Dimmer Plug – can’t wait to see the results!

Dimmer Plug connected to Raspberry Pi

Oh, and in the meantime, it might be good to start working on the real renovation job as well.. 😉

Staircase project, part 1: the Dimmer Plug

Renovation is always a good opportunity to think about some nice automation projects, cause renovating almost always means (partly) breaking down some things and then rebuilding it in a somewhat different way. That’s the right time to do some extra – drilling holes, pulling wires, cable ducts and so forth.

So when we decided to renovate our staircase, I immediately had a great plan: mounting LED strips under the steps to light the stairs. Automatically of course, and with some cool gadgets thrown in as well 😉

I also got the idea to use 2 light barriers at both ends of the stairs to detect that someone is walking up or down the stairs and control all the 12 LED strips independently; so if someone goes upstairs, the LED strips increase in brightness with an interval: starting with the lowest LED strip, going up. And if some goes downstairs, the strips go on from top to bottom. Sounds nice..

OK, but how do I control 12 LED strips independently? And not just on/off, but also in brightness. I didn’t like the idea of using 4 RGB LED controllers, so I started searching for a >12 channel LED controller. After some days I finally got the inspiration I needed – a JeeLabs Dimmer Plug! The Dimmer Plug uses a PCA9635 IC to drive and dim up to 16 LEDs independently.. that should do it! The Dimmer Plug uses I2C to communicate with the outside world, so that shouldn’t be a problem either.

Yesterday evening I soldered a JeeNode, finished the Dimmer Plug (headers etc.), connected 4 3mm LEDS to the Dimmer Plug, uploaded the dimmer_demo sketch from the JeeLib library to the JeeNode and I saw all 4 LEDs doing their own ‘thing’ independently; so far so good.

JeeNode + Dimmer Plug

But why should I use a JeeNode to control the Dimmer Plug? I mean, I have a couple of Raspberry Pi‘s running here, I could just as well use a Raspberry Pi (RPi) for the I2C communication, right? That saves me the hassle of talking from a RPi to the JeeNode, which in turn talks to the Dimmer Plug… so I decided to leave the JeeNode out and connect the Dimmer Plug directly to the Raspberry Pi.

Connecting the Dimmer Plug to the Raspberry Pi will be done in the next couple of days…  part 2 of the ‘staircase project‘ !