Upgrading my home network

For a number of years, I’ve been using a TL-WR1043ND running DD-WRT as my home router, even going as far as replicating the same setup for friends and family, as it struck a happy midpoint of being powerful enough to be useful, but also simple and stable enough for the slightly less technically literate to manage. The DD-WRT setup was surprisingly simple, and I’ve been reasonably impressed by the performance and capabilities of the software, even on such a basic consumer model of router. That said, around 12 months ago I realised that my home network was rapidly outgrowing this basic setup, and I felt the need to lean towards something a bit more “prosumer“. There are quite a few different companies targeting this market, but one in particular stood out to me – Mikrotik.

Around 12 months ago I took the dive and bought a RB2011UiAS-2HnD-IN (that’s quite the product name!) – one of their mid-line models which seemed quite reasonably priced, and got stuck into learning the intricacies of RouterOS. Their own WinBox software provides a very usable GUI for configuring their hardware, granting a view to the myriad of different features of the board while keeping the learning curve shallow enough to avoid you becoming swamped by options. I’ve gradually tweaked and enabled more and more services, to the point where the single device is providing:

  • PPPoE to my ISP
  • DHCP
  • DNS (local and external)
  • Firewall
  • WiFi (more on this below)
  • L2TP connection to a VPN provider, with certain traffic automatically routed through this
  • … and a whole lot more!

Additionally, when I moved into my new house earlier this year, I set about removing the need for using HomePlug to connect various devices in different rooms, as I found that these tended to be unstable, causing slow transfer speeds and a high rate of dropped connections. I ended up running CAT6 from my study through to several other rooms in the house (I may blog about that project some time in the future!), which eliminated the need for the HomePlugs, but highlighted how poor my WiFi setup was (having previously blamed this on the dodgy connections). While researching ways to improve coverage, I struck upon a feature of RouterOS that I hadn’t yet taken advantage of – CAPsMAN (Controlled Access Point System MANager). This essentially allows you to delegate control of various MikroTik device radios to a central ‘manager’, which pushes out the WiFi configuration to create a seamless network across all access points. I picked up a couple of Home Access Points (hAP) and set these up as slaves to CAPsMAN running on the main router (as well as the radios on the router itself being delegated to CAPsMAN, not something that’s recommended officially but seems to work for me), and I haven’t had any complaints about sub-par WiFi performance since!

My next step involves upgrading the heart of my network to something with a few more gigabit speed ports – I’ve already run out of capacity in my “rack” (a re-purposed IKEA bookshelf) – so I’m looking at getting a CRS125-24G-1S-2HnD-IN (there we go again with the brilliant product names!) to act as the core router, and demoting the current RB2011UiAS-2HnD-IN to act as a switch and access point in the living room instead of the “dumb” switch in there currently.

While I realise there are quite a few alternative offerings coming to market that simplify home networking (Google WiFi, Ubiquiti Unifi etc), I’m more than happy with what Mikrotik have to offer both in terms of the hardware and software, and I continue to be impressed by how straightforward yet powerful my home network has become now that there’s something more powerful behind it. I might even start suggesting an upgrade to the parents network!

Unable to load libcec.so on Kodi

As part of a complete re-vamp of my home media setup (blog post coming soon on that!), I found myself trying to connect a Sony TV to an Intel NUC running Kodi v16 via one of PulseEight‘s brilliant USB-CEC Adapters. However, no matter what I tried (combinations of cables, all the settings on the TV, different ports on the NUC etc) I could not get Kodi to recognise the adapter. Despite the Kodi Wiki page on CEC suggesting that this should plug-and-play, I did not get any suggestion from either the TV or Kodi that the CEC dongle was being recognised.

After quite a lot of searching in the wrong place (at first I was convinced that my fresh install of Kodibuntu wouldn’t be the root cause), I found a couple of log lines that finally pointed me in the right direction:

DEBUG: Loading: libcec.so.3.0
ERROR: Unable to load libcec.so.3.0, reason: libcec.so.3.0: cannot open shared object file: No such file or directory

Turns out that Kodi is built against libcec.so.3.0, however the version in the repository (I believe that was bundled or at least suggested by Kodibuntu) is 3.1. Kodi should (theoretically) be built against libcec.so.3 (note the missing .0), which the appropriate symlinks would have taken care of, however it seems there are some changes between 3.0 and 3.1 that Kodi doesn’t like, so some simple switching of the links (I tried creating /usr/local/lib/libcec.so.3.0 -> /usr/local/lib/libcec.so.3.1, which in hindsight isn’t a great idea) caused various crashes that I wasn’t prepared to start debugging – so instead I used the suggestion in this forum thread:

$ apt-get install --reinstall libcec3=3.0.1-1~trusty

Which will put the old version of libcec on your machine. After a quick reboot, Kodi instantly recognised the CEC dongle as promised, and it has been working beautifully ever since!

Raspberry Shake: IoT for your boring appliances

My latest project (now I have some spare time again!) has been something quite simple – I’m terrible at putting the washing machine on, and then forgetting about it for the rest of the day, leaving a load of wet clothes inside to fester for hours on end. I know some washers and dryers come with alarms that beep at you when they’re finished, and I wanted to emulate this with an Internet of Things vibe.

So I came up with the Raspberry Shake – quite simply it’s an accelerometer connected up to a Raspberry Pi Zero with some LEDs to indicate status, all shoved inside a small box with some magnets attached, so it can cling to the side of any appliance. The Pi Zero runs a bit of Python code that checks for any movement, and sends notifications when the appliance starts and stops. I’ve made two so far, with plans for a third, and they’re working great!

You can see a full writeup and a video of the build on the Raspberry Shake project page

Talking to a LIS3DH via Python on a Raspberry Pi

For my latest project (details coming soon available here) I acquired a couple of LIS3DH triple-axis accelerometers. As most of the products available through Adafruit are fairly well used, I didn’t bother checking what libraries were available before buying, but unfortunately for me only a C++ library had been written. I didn’t feel like learning C just for the purpose of this project, and so the only option left was to write my own Python library!

Thankfully I had some excellent starting points with the aforementioned C++ library, as well as the Python I2C library that Adafruit have published. I found myself referring back to the manufacturer datasheet quite often as well, mainly to clarify what each register contained.

While the task initially looked rather daunting (having had zero prior experience with bit-bashing through registers) – I found that with some pre-existing code to crib from, the various functions took shape rather quickly, and within an afternoon I’d produced a library exposing all the basic functions I’m likely to need for this project. I’ve put my code on Github in the hope that people will contribute to filling in the gaps, and improving where necessary.

PCTV tripleStick 292e with TVHeadend

I’ve blogged before about my home AV set up, but something I’ve not talked about is the recent addition of a couple of TV tuners so that I can watch and record live Freeview channels. Until recently I’d been using TVHeadend version 3.2 on a Raspberry Pi, with a PCTV nanoStick T2 that worked out of the box on Raspbian for me. However, the time came when I wanted to be able to record and/or view multiple channels at once, so I set about getting a second tuner to be able to do this. Through a lack of attention paid while ordering, I ended up with a PCTV tripleStick rather than a second nanoStick, and this one sadly was not as easy to set up. I bounced around a lot of forums and blog posts in getting mine working, so I thought I’d consolidate my learnings here, in the hope that someone else may find this useful!

First off, the chipset on the tripleStick (Silicon Labs Si2168) is different to the nanoStick (Sony CXD2820R), hence the incompatibility with the old drivers. There’s a very detailed teardown and comments at Antti’s LinuxTV Blog which does a great job of explaining what’s under the hood, and the comments do offer some useful guidance (but also some misdirection!). I was previously running an older version of Raspbian (kernel 3.12 if I recall correctly), which failed to recognise the tripleStick as a DVB tuner at all, but several sources suggested that firmware was included in 3.16 and higher. I updated my Raspberry Pi with the usual apt-get update; apt-get upgrade; apt-get dist-upgrade to move up to a newer kernel version (3.18) which did get the dongle recognised in TVHeadend, however it appeared to not get any signal, despite being plugged in to the same aerial as the working nanoStick.

At this point I attempted upgrading to TVHeadend 4.0, something I should have done a considerable time ago anyway, however this had no effect and the dongle continued to show no signal through TVHeadend. Checking my logs, I found that my /var/log/syslog had repeated entries referring to “found a 'Silicon Labs Si2168' in cold state“, and claiming that firmware files had not been found. Many different message boards carried many different links to firmware, and suggesting different combinations that needed to be installed, several of which I found to be corrupt, however the one that worked for me was installed using the following:

$ wget http://palosaari.fi/linux/v4l-dvb/firmware/Si2168/dvb-demod-si2168-02.fw -O /lib/firmware/dvb-demod-si2168-02.fw

There are many suggestions that the file dvb-demod-si2168-b40-01.fw is also needed from that same source, however it seems to be working fine for me without this present. I’ve seen some reports that the tuner should appear as two separate entries in TVHeadend (one as a DVB-T tuner, and another as a a DVB-S), however since I’m only using DVB-T I’ve not seen any problems – your mileage may vary!

AlarmPi: The Raspberry Pi Smart Alarm Clock

When I left my previous job around 18 months ago, I promised myself I’d do something productive with the time I had between employment. During that time, I realised how much I hated my alarm clock going off every morning, and also how stupid and inflexible most alarm clocks are. I managed to achieve very little with that spare time between jobs, but this hatred of alarm clocks has been driven home even further since I’ve started working shifts in my new job – no alarm clock I could find had the ability to vary the alarm time based on a shift pattern (I suppose that’s a fairly niche feature!), and very few had decent internet radio connectivity to allow me to listen to music I like in the morning.

That productive feeling drew me to buy some parts from Adafruit and have a play with some electronics projects – the furthest I got was playing around with a LCD display as documented in this other blog post. More recently, my old alarm clock started to fail in rather interesting ways (ever been woken up at 3:27AM by a piercing screaming & static noise?), so I decided it was time to build my own, and the AlarmPi was born!

The core of the project is a Raspberry Pi connected up to a series of fairly basic components, all controlled by a Python script which takes input from all manner of sources, and shows information through the two front displays. I’ve put together a short video explaining some of the main features which can be viewed below, and you can read more about the AlarmPi on the project page

Using 20×4 RGB LCD over i2c with a Raspberry Pi

Now there’s a specialist blog post title if ever there were one…

Recently, I’ve been dabbling with electronics to fill the void of spare time I’ve found myself with while I’m between jobs. I’m currently working on a half-baked idea to create some sort of digital assistant who will take instructions in some form, and then read stuff back to me in a Siri-esque manner. Nothing sounds more awesome than having twitter @replies read out to you, right?! To kick off this project, and get me motivated to actually do something, I ordered a boatload of parts from Adafruit, and set about learning how to use them. First challenge – connecting up their 20×4 RGB backlight negative LCD screen to my Raspberry Pi.

In order to assist with this, I also bought the i2c / SPI character LCD backpack in order to save some GPIO pins for other uses. Due to my lack of attention while ordering, I failed to notice that the LCD backpack only has 16 pins, whereas the LCD screen I ordered has 18 (2 more for the extra background LEDs). Rather than giving up and being limited to only a single channel of control for the backlights, I decided to connect pins 14 to 18 direct into the Pi, and mash two separate libraries together to give myself full control. This is what I ended up with (click for big):

2013-05-02 21.36.11

Now, that looks like an absolute mess. That’s because it is. In an attempt to make that a bit more readable, here’s a Fritzing diagram of how it’s wired (again, click for big).

lcd_test_bb

Now, that’s even more confusing as I couldn’t find a Fritzing library with the right parts – so I’ve fudged a few things. Imagine there are ports 17 and 18 on the LCD, and that the LCD itself is 20×4 rather than 16×2. Secondly, imagine the chip in the middle is actually the i2c backpack mentioned above, so everything on the bottom is connected straight to ports 1 to 16 on the LCD, and the VCC/GND/CLK/DAT are connected to the Pi. So, in terms of wiring we get:

  • LCD #1 to #14 -> i2c backpack #1 to #14
  • LCD #15 -> 5V0
  • LCD #16 -> Raspberry Pi GPIO 17
  • LCD #17 -> Raspberry Pi GPIO 27
  • LCD #18 -> Raspberry Pi GPIO 22
  • i2c backpack GND -> GND
  • i2c backpack VCC -> 5V0
  • i2c backpack CLK -> Raspberry Pi SCL
  • i2c backpack DAT -> Raspberry Pi SDA

Now that’s all set up, you can use the standard AdafruitLcd Python library (nice adaptation that I used can be found here) to control the text shown on screen, but we need something bespoke for our background lighting. For future projects, I wanted the ability to control each colour individually, so I can set arbitrary RGB values on the screen, and also brighten/dim appropriately. The latest version of RPi.GPIO will let you do software Pulse Width Modulation, which will achieve this quite nicely for us. To install the latest version (0.5.2a at the time of writing), you’ll need to run the following on your Pi (as root):

$ wget https://pypi.python.org/packages/source/R/RPi.GPIO/RPi.GPIO-0.5.2a.tar.gz
$ tar xf RPi.GPIO-0.5.2a.tar.gz
$ cd RPi.GPIO-0.5.2a
$ python setup.py install

So, combining some standard example code for PWM on the Pi with the AdafruitLcd library, I developed my own little library for controlling a LCD wired up in this manner. To get up and running with the code I wrote, you will need (again, as root):

$ mkdir lcdtest
$ cd lcdtest
$ svn co http://projects.mattdyson.org/projects/LCDControl@889 .
$ git clone https://github.com/PDKK/RpiLcdBackpack.git
$ touch RpiLcdBackpack/__init__.py
$ python testLCD.py

Note: If you see IOError: [Errno 5] Input/output error when running testLCD.py, you may need to edit RpiLcdBackpack/RpiLcdBackpack.py and change the line self.__bus=smbus.SMBus(0) to self.__bus=smbus.SMBus(1). This should only happen on newer versions of the Pi, where the i2c bus number changed to 1 from 0.

Note 2 (added 15/10/14): The version of my LCDControl library that you’re checking out with the above command is now out-dated, I’ve updated the library to use pigpio instead of RPi.GPIO, as the latter was causing me flickering problems when the Pi was under load. To get the latest version, remove the @889 from the svn co command, you will need to have pigpio installed and running for this to work.

Once you run testLCD.py, you should see the screen flash a series of colours, followed by some messages appearing on the screen. Yaaay – it works!

The LCDControl class I’ve written is pretty basic (I’m still learning Python… slowly!) but allows you to set RGB or individual colour values for the backlights, and also pass in any message without worrying about formatting. Currently (version 1.0 at the time of writing), the LCDControl.setMessage method will split by the newline character (\n) and do the logic regarding line numbers for you (as the third display line on the LCD is actually carried over from the first line passed to the controller, and the fourth with the second) – future iterations of this code will allow you to do things such as full text wrapping, and scrolling text.

So there we have it – a 20×4 RGB LCD screen talking to a Raspberry Pi over i2c, retaining individual control over the background LEDs. As always, please leave a comment if you spot anything wrong with what I’ve written here, or have any feedback/suggestions/requests!

Using an Xbox 360 Wireless Controller with Raspberry Pi

As part of a project I’m working on at the moment (more information to come soon… more information here) I’ve been attempting to get my Xbox 360 Wireless Controller for Windows talking to my Raspberry Pi. Having spent a fair amount of time chasing various options around the internet, I thought I would share my eventual (and rather simple) solution here.

The first thing I found was PyGame – a python library that offers support for joysticks and gamepads, but primarily designed for game development. This post suggested that PyGame may solve the connectivity problems, and gives some example code for echoing out events, however I could not get this to work.

The Ubuntu wiki suggested a module called xpad, which is included by default on Ubuntu, but not on the Rasbian image I am using (Rasbian “wheezy”), although it is available through apt-get in the default repository. Unfortunately, this didn’t work for me either.

The eventual solution that worked for me came up in a blog post by Zephod about using an Xbox controller to run a remote control car, which suggested using Xboxdrv – a userspace driver for the Xbox controllers in Linux. There were suggestions on the Raspberry Pi forums that this would require building, but a simple `apt-get install xboxdrv` on the Pi worked for me. Once installed, execute the program (as root), and then re-sync the Xbox controller – this had me stumped for quite a while, and seemingly only needs to be done the first time you attempt to use the controller since the module was loaded. A re-sync for the wireless controller means holding the button on the reciever for ~3 seconds until it starts to flash, and then holding the button on top of the controller (to the right of where ‘Microsoft’ is written) until the lights flash. Once this has completed, you should see a new line in stdout for every event that happens on the controller – so press a button and see what happens!

This is the output I saw when starting up xboxdrv (having already done the sync) and pressing the “A” button on my controller – notice the A:1 changing to A:0 as I release the button (about 3/4 of the way across the terminal). Success! (Click for a larger image)

Zephod has written a small Python class to read from the output of xboxdrv and allow it to be read in a more usable format – I’ve not yet had chance to fully digest what it does and how it works (this is an exercise in me learning Python as well!), but it looks very promising, and I’m looking forward to continuing with my project!

Update 05/01/2013
I’ve had chance to play around with the xbox_read.py file I linked above – and it works a treat! I’ve set up a quick test python script that you can use to print out events. In order to use it, do:

$ git clone https://github.com/zephod/lego-pi.git legopi
$ touch legopi/__init__.py
$ wget http://projects.mattdyson.org/projects/robotarm/readEventTest.py
$ sudo python readEventTest.py

You may have to re-sync your controller as described above, and then once you start to move sticks/press buttons you should see a single line for each event! Magic!

Sound the alarm!

My colleague and partner in crimes against PHP has “not a blog”-ed about a recent waste of my Friday afternoon at work. There’s a pretty awesome video of it in action as well. Kudos to GrahamB on the light-triggered panic in the background.

Essentially, this wonderous creation boils down to an off-the-shelf novelty fuzz-light connected to a 13A 4-way extension lead that was adapted to be controlled via a USB relay. Only simple modification needed (I don’t trust myself with anything electrical usually) – snip the neutral cable on the extension lead and run through the relay (even I can’t cock that up). Through the use of some really dodgy python (not PHP, as Tom alludes to, for a change) that was adapted from numerous tutorials – the relay can then be controlled via a HTTP GET request to the relevant port with /on or /off as the request string.

This is then hit via a command to our work IRC bot, so you can type !emergency into any channel to turn the light on, or !emergencyover to turn it back off again, which will create the appropriate HTTP hit, and return appropriate witticisms from the bot. I’m not going to paste that code here though. Make your own.

You may wonder what the point of this probably-lethal waste of money & time is. Good question. I’m still asking myself that, but it’s pretty damn fun to control a flashing light from your computer…

The pyweb/serial shonky python script used for control:

"""
USB Relay HTTP Control Script

Accepts HTTP GET requests to /on and /off, sends the requisite serial commandto the USB relay board

Matt Dyson, 2012
http://mattdyson.org/blog/2012/11/sound-the-alarm/
"""
import serial
import web
from struct import *

commands = {
    'relay_1_on': 0x65,
    'relay_1_off': 0x6F,
    'relay_2_on': 0x66,
    'relay_2_off': 0x70,
    'info': 0x5A,
    'relay_states': 0x5B,
}

urls = (
    '/(.*)', 'relay'
)
app = web.application(urls, globals())

class relay:
    def GET(self, arg):
        if not arg:
            return 'No action given'
        elif arg=='on':
                return 'Turning light on' + send(commands['relay_1_on'])
        elif arg=='off':
                return 'Turning light off' + send(commands['relay_1_off'])
        else:
                return 'Unknown action'

def send(cmd):
    ser = serial.Serial('/dev/ttyACM0', 9600)
    ser.write(chr(cmd)+'\n')
    ser.close()
    return ". Done"

if __name__ == "__main__":
    app.run()

The code still contains the necessary commands for getting information/relay states/relay 2 control (currently unused), but these aren’t exposed via HTTP. We’ve not dreamt up a use for the second relay yet, I suspect further evil will happen at some point again in the future.