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

Oops, it did it again!

Oh no… not again! Last weekend the 2nd disk crashed as you can see below; within 5 months after the first one crashed. I hate downtime, but I just gotta replace Volume 1 with a new HDD. The defective 1TB HDD will be replaced by a Seagate Barracuda 2TB which arrived today – the same model I used 5 months ago. The good thing is, I wont lose a single bit – again! 😉

Another disk crashed

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‘ !