Big Update

Its been quite a while since my last post, so here’s a big one…..

I’ve been doing a lot of 3D printing since I received my FlashForge Creator Pro 2016. I learned OpenSCAD and FreeCAD, my designs are here. I’ve made various enclosures for Arduino’s and Raspberry Pi’s, as well as USBASP cases, voltmeter cases, solder tip holders, calliper battery savers, resistor forming tools, soldering helping hands, bottle openers, trolley tokens, SD card holders, PIR cases, Dremel accessories, various 3D printer upgrades and the usual calibration prints.

Yesterday I upgraded Dad’s Lenovo B570 laptop to Ubuntu 16.04 from 12.04, which was fun due to its broken EFI setup – basically it has a BIOS and not SecureBoot but the installer sees it as using GPT+EFI instead of a simple MBR. Weirdness such as failure to boot from USB and then failure to boot from HDD once I’d installed from DVD ensued. Boot-Repair fixed the problem, from what I can see it installed some dummy EFI files in the EFI partition, which the 12.04 install obviously nuked. Had to disable hardware acceleration in Chrome to prevent Flash flickering, but otherwise it seems to be working fine.

Today I modified an SG90 servo for continuous rotation, basically removed the wiper on the potentiometer and replaced it with a couple of SMD resistors, and cut the tab off of the largest gear. I found that there is no trimpot to adjust the zero position on my servo so I altered my code to send 100 instead of 90 for “stop”, which I found using some trial and error. Values lower than 100 move clockwise (the lower the number, the faster movement) and greater than 100 moves anti-clockwise (the higher, the faster).

When you write a value to the servo, you’re no longer giving it a degree value, you’re setting a pusle width. So instead of “rotate to 40 degrees” you’re saying “run for 1200uS”, just like a DC motor with H-bridge, which is essentially what is inside a servo. The upside is that the servo can rotate 360 degrees, the downside is that you don’t know where its rotated to as the microcontroller receives no feedback.

My test code is below – its moves it left, right, fast, slow and stop.

continuous_servo.ino

#include <Servo.h>

// create servo object
Servo myservo;

// speeds for my sg90
#define FASTCW  45
#define SLOWCW  90
#define STOP    100
#define FASTACW 135
#define SLOWACW 110

void setup()
{
    // attach servo to D9
    myservo.attach(9);
}

void loop()
{
    myservo.write(FASTCW);
    delay(2000);

    myservo.write(STOP);
    delay(1000);

    myservo.write(FASTACW);
    delay(2000);

    myservo.write(STOP);
    delay(1000);

    myservo.write(SLOWCW);
    delay(2000);

    myservo.write(STOP);
    delay(1000);

    myservo.write(SLOWACW);
    delay(2000);
    
    myservo.write(STOP);
    delay(1000);
}

Makefile

BOARD_TAG = uno
MONITOR_PORT = /dev/ttyUSB0
include /usr/share/arduino/Arduino.mk

I’ve also been making custom power cables lately, such as a USB to DC jack for giving 5v to older projects such as a 555 astable from a powerbank. It seems that microUSB should be the new go-to connector for power instead of 2.1×5.5mm DC jacks these days. I’ve actually got some USB-to-DIP breakout boards as well as the TP4056 Li-On charger boards. I’ve also got some USB boost regulators on the way that apparently can output up to 28v or something silly. My next custom cable will likely be banana plugs to pin headers as its a pain trying to put a male pin header on a screw terminal.

Finally I had a play with a MCP23017 port expander which I was thinking of using when my ESP8266 projects don’t have enough pins – like my RTC clock could have done with 1-2 more buttons. But it seems like a lot of wiring e.g. 8 pins before you’ve even added any I/O, and a lot of calls to the Wire library e.g. 4 calls just to send an output like lighting an LED, so I think I’ll hold out for ESP32’s to be generally available before doing any more pin-intensive projects.

Motion Sensing Nightvision Camera

I fancied figuring out if it was my cat or the neighbourhood cats pooping in my side alley (oh er missus!) so thought I’d find a use for my PiNoIR camera and that spare B+

I usually use RaspiMJPEG for webcam sorts of things like timelapse or somesuch, but it seems in a state of flux – the internal motion-detection system simply doesn’t work it would seem, and the external system is still using Motion and not the MMAL version, so its slow and can only cope with about VGA resolution on a B+, and it doesn’t seem to work in timelapse mode, and seems flaky at best anyway.

MotionEyeOS seemed like it was much more professional and motion-detection with timelapse worked really well, but again was limited to pretty low resolutions with weird aspect ratios. Also doesn’t seem to use motion-mmal anymore (think it did when it was motionpie).

Anyway, I figured the problem was software motion-detection using image analysis, so I decided to go the hardware route and use a PIR. So far I’ve come up with this Python script which is based on the excellent picamera module. It can do useful things like vertically flip the image (on the GPU!) which is handy as my Sainsmart camera module is a bit hard to mount the right way around!

Also the code uses interrupts so events don’t get missed and the CPU is mostly asleep. I chose to use 1080p resolution, but you could go up to to full 5MP (or 8MP on the new camera boards!) if you wanted to, forget 640×480

The only problem is that the PIR sensor doesn’t work through double-glazing, so I need to mount it in a box outside, which I was going to do eventually anyway.

#!/usr/bin/python

# import module
import picamera
import time
import RPi.GPIO as GPIO

# setup gpio mode
GPIO.setmode(GPIO.BCM)
PIR_PIN = 14
GPIO.setup(PIR_PIN,GPIO.IN)

# instantiate class
camera = picamera.PiCamera()

# vertical flip
camera.vflip = True

# set resolution
camera.resolution = '1080p'

# interrupt function
def onMotion(PIR_PIN):
    filename = time.strftime("image-%Y%m%d-%H%M%S.jpg")
    camera.capture(filename)

try:
    GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=onMotion)

    # loop until interrupted
    while 1:
        time.sleep(100)

except KeyboardInterrupt:
    GPIO.cleanup()

You have to run the script using sudo, or from an init script like /etc/rc.local perhaps, and maybe set a directory to write the files to rather than just cwd.

Edit: just bought a v1.3 Raspberry Pi Zero and cable for this, as it should use a lot less power than the B+ and is a lot smaller to encase.

Simply Dashing!

I’ve finally gotten around to making a web frontend for my Raspberry Pi & Arduino wireless sensor network.

I chose Shopify’s Dashing dashboard, as its opensource and can be installed locally and not via some cloud crap.

Essentially you have a HTML template into which you feed JSON data. I got a bit tied up in the JSON formatting so it took longer than it should have to get working (about 3 hours) but once I realised that most of the job placeholders were a single line of JSON, and not a whole entity, it was quite straightforward. Here’s 90% of my entire dashboard code:

SCHEDULER.every '30m', :first_in => 0 do
    require 'sqlite3'
    db = SQLite3::Database.open "/var/tmp/weather.db"
    
    study = db.execute "SELECT reading FROM weather WHERE node=2 ORDER BY date DESC LIMIT 3"
    send_event('study_temp', { current: study[0][0].round(2), last: study[2][0].round(2) })

    shed = db.execute "SELECT reading FROM weather WHERE node=1 AND type=2 ORDER BY date DESC LIMIT 3"
    send_event('shed_temp', { current: shed[0][0].round(2), last: shed[2][0].round(2) })

    outside = db.execute "SELECT reading FROM weather WHERE node=1 AND type=1 ORDER BY date DESC LIMIT 3"
    send_event('outside_temp', { current: outside[0][0].round(2), last: outside[2][0].round(2) })

    lounge = db.execute "SELECT reading FROM weather WHERE node=3 ORDER BY date DESC LIMIT 3"
    send_event('lounge_temp', { current: lounge[0][0].round(2), last: lounge[2][0].round(2) })
     
    light = db.execute "SELECT reading FROM weather WHERE node=4 ORDER BY date DESC LIMIT 1"    
    send_event('lightsensor', { value: light[0][0].round(1) })

    bedroom = db.execute "SELECT reading FROM weather WHERE node=0 ORDER BY date DESC LIMIT 3"
    send_event('bedroom_temp', { current: bedroom[0][0].round(2), last: bedroom[2][0].round(2) })

    db.close
end

Here’s a screenshot of the finished dashboard, including an additional widget that shows the RPi-1B’s very stretched RAM:

It installed a lot easier on Debian Sid than Raspbian Wheezy, but I hear Raspbian Jessie is easier due to updated bundler/exec_json/nodejs packages – every time I use Ruby I seem to go through dependency hell, Ruby seems to have a lot of issues with backwards/forwards compatibility with Gems – why things like bundler/rvm are necessary I guess. Makes Java look portable.

Vagrant & Ansible

I’ve been getting back into Vagrant and Ansible lately, as I decided I needed a platform to do some Continuous Integration testing of Arduino and packaging of arduino-mk; and also building Kodi on a faster platform than my Atom HTPC.

As luck would have it, the Debian package for Ansible 1.9.2 just hit Sid, so I don’t have to build my own from git with “make deb”, which is a bit Ubuntu-centric and doesn’t work too well on Debian.

So I’ve made a Fedora 22 VM that I can make arduino-mk packages on, an Ubuntu 12.04 VM that I’m building Kodi 15 packages on, and an Ubuntu 14.04 VM that I’m using for both. I also made a Debian Jessie and another Ubuntu Trusty VM along the way.

As I am using the new VirtualBox 5.0rc2, Vagrant 1.7.2 needs this patch.

The Precise VM (with 8 cores and 4Gb RAM assigned) builds Kodi in 35mins – about half the time it takes the Atom, which isn’t that impressive, but its an improvement.

Setting up an Ubuntu 12.04 build environment for Kodi again was a right PITA though, mainly as “apt-get build-dep” doesn’t actually fetch half the dependencies, and you need newer versions of libyajl2, libyajl-dev, taglib and JsonSchemaBuilder, as well as now having to install gcc 4.9 as they’ve just switched to C++11 today!

So that’s basically this lot wrapped in an Ansible playbook:

add-apt-repository ppa:ubuntu-toolchain-r/test
apt-get update
apt-get build-deps xbmc
apt-get install libssh-dev libxslt1-dev git libmp3lame-dev swig libcec-dev openjdk-7-jdk gcc-4.9 g++-4.9
dpkg -i libyajl2_2.0.4-4_amd64.deb libyajl-dev_2.0.4-4_amd64.deb libtag1x8_1.8-0precise17_amd64.deb
cp /home/vagrant/kodi/packaging/deps/JsonSchemaBuilder /usr/local/bin/JsonSchemaBuilder
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 40
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 60
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 40
update-alternatives --install /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/gcc-4.9 60
update-alternatives --install /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/gcc-4.6 40
update-alternatives --install /usr/bin/x86_64-linux-gnu-g++ x86_64-linux-gnu-g++ /usr/bin/g++-4.9 60
update-alternatives --install /usr/bin/x86_64-linux-gnu-g++ x86_64-linux-gnu-g++ /usr/bin/g++-4.6 40

Ubuntu 14.04 is much easier, and you just need some basic tasks in your Playbook.yml

- name: install dependencies
  apt: name=xbmc state=build-dep

- name: install libxslt
  apt: name=libxslt1-dev state=present

- name: install git
  apt: name=git state=present

- name: install libcec-dev
  apt: name=libcec-dev state=present

VMWare ESXi

I’ve recently been using VMWare ESXi 5.5 in anger – with real VM’s rather than just testing shell commands. Plus it seems the last couple of versions of VirtualBox can no longer run ESXi as a guest.

Anyway, its soooo Windows-centric vendor-locked its unbelievable. I mean you can’t even load a bunch of ISO’s on a USB stick and put them in the back of the machine, you have to transfer them using the VSphere client over the network. I’ve not tried scp but I doubt that would work due to the cut-down SSH server and shell. Seems its not even called ESXi anymore, its VSphere Hypervisor or something.

Also there’s no way to find the physical network interface name/number/ID from the virtual nics! It seems VMWare assumes everyone is either using flat networks with no vlans/subnets or only use multiple interfaces for nic teaming/bonding; and have never needed to know which ethernet cable should go to which switchport and map to which network device in the VM.

The only good point is that the vmware-tools are now in some distro’s like RHEL so you don’t need to install kernel source, gcc and make to rebuild the kernel modules every time you do an upgrade.

There’s an annoying “feature” with the console – if you click on the console tab in VSphere it shows the console, but if you click the console icon, it then shows another one, and there doesn’t seem to be a way to disconnect the tab one and you get an annoying popup telling you there’s 2 connections all the time!

It still seems a bit flaky regarding screen resizing and networking, and the whole virtual switch thing is a mess as you end up having to define one switch per interface with only that interface in it if you want your guest to have multiple network cards. It seems more like a virtual router to me.

I’ve also installed a CentOS7 virtual machine, but don’t like it much, networking seems very buggy – especially the new interface naming conventions described here, and that NetworkManager doesn’t seem to track changes made with ifconfig. Systemd is a pain and I even found that rpcbind can’t be disabled using the systemdctl command, you have to symlink rpcbind.service and rpcbind.socket to /dev/null

I’ve just soldered the pins on my Arduino Pro Mini, and found its not well documented – probably because its not an official Arduino (its kind of based on the Arduino Mini) its a SparkFun board that’s been revised and cloned a lot. I finally figured out the pinout for uploading using a CP2102 – its RX-RX, TX-TX, GND-GND, 5V-VCC, DTR-DTR and don’t connect the reset pins or use resistors or capacitors as some sites say.

The Makefile for the 5V 16MHz ATmega328p board is:

BOARD_TAG    = pro5v328
MONITOR_PORT = /dev/ttyUSB0
include /usr/share/arduino/Arduino.mk

Rather annoyingly I’d soldered the rear analogue headers on before I realised that it wouldn’t fit breadboard anymore, so I’ve removed them again and may put right-angled headers on at some point. I much prefer the Nano or even Pro Micro.

I just compiled XBMC 14a4 from git and pretty much nothing seems to have changed from 13.2 other than the Kodi name. Had to disable the Google Test Framework to get it to build as its now enabled by default.

I also upgraded the blog to WordPress 4.0