Category Archives: hacks

drgb camera

I just bought myself an Asus Xtion PRO Live Depth+RGB camera which I plan to use for robotics experiments. It uses the same technology from PrimeSense for depth as Microsoft Kinect but is about half the size, can be powered solely over USB and weighs around 170g which makes it a better match for robotics.

asus xtion pro live vs. matchbox

xtion_pro_on_wild_thumper_20111221_003

Here are my notes on getting the basic Openni / NITE demos running on ubuntu 11.10:

sudo apt-get install build-essential libusb-1.0-0-dev freeglut3-dev

install openni

mkdir openni
cd openni
git clone https://github.com/OpenNI/OpenNI.git
cd Platform/Linux-x86/CreateRedist
./RedistMaker
cd ../Redist/
sudo ./install.sh

install sensor

git clone https://github.com/PrimeSense/Sensor.git
cd Sensor/Platform/Linux-x86/CreateRedist/
./RedistMaker
cd ../Redist
sudo ./install.sh

install primesense NITE. This seems to be closed source but free of charge
download from http://www.openni.org/Downloads/OpenNIModules.aspx under Middleware binaries. In my case it looks like this:

tar -xf nite-bin-linux64-v1.4.2.3.tar
sudo ./install.sh

this will prompt you for a key, which is: 0KOIk2JeIBYClPWVnMoRKn5cdY4=

then go to directory containing NITE samples and try out some demo apps for example Sample-Players:

cd Samples/Bin/Release
./Sample-Players

This is how SamplePlayers looks when it has identified me in the picture:
openni nite SamplePlayers demo

smart energy

Lately I have been hacking on the home automation project which should at some point tie together my current ad-hoc house and greenhouse control systems. One part of that system will be energy usage optimization with wireless smartplugs, which uses Plugwise smartplugs and the python-plugwise library that I wrote. The main (and more or less the only :-)) appliance that I can make energy savings on using automation is the electric boiler. It’s an old 40-50l heater that hasn’t been cleaned for at least 3 years so it probably contains a lot of limescale and sludge which causes it to use far more power that it should. Hopefully I will get around to cleaning it soon.

I haven’t implemented any fancy logic for controlling it yet and instead I just use a simple crontab that switches the boiler on for 3 hours total each day – somewhere around when we leave for work and again before we get back home.

So far it seems to be enough to provide hot water for 2 persons on working days and it wastes around 2 times less power than it would if it was permanently switched on:
boiler_energy_usage

So assuming this difference holds true for larger periods of time I will get energy savings of ~4kWh per day. If I only use this control method on working days it will give me somewhere around 80kWh savings per month. Currently I pay 0.1026 € per kWh so I should save somewhere around 8 € per month, and 96 € per year on this appliance. So these smartplugs should pay for themselves in about 1.5 years. Currently Estonia has the cheapest price of electricity in Europe which can only go up as the energy market opens up and hidden subsidities are removed so the savings will probably be even more substantial in the not so distant future.

beginnings of greenhouse automation

Last year I bought a new larger greenhouse (lwh: 6x4x2.8m). Currently it looks like this:
greenhouse in winter

Which means that I don’t have to deal with actually growing things at the moment and now is a good time to make preparations for the next season.

My ideal is to automate it as much as possible, so first I will try to automate the obvious things like watering and ventilation. In the future things like heating and growlights might be added too.
I have spent several weekends on that project with my friend Kalle who helps me on the electrical engineering front and finally we have something that more or less works.

The current solution consists of controller board & sensor board in the greenhouse. Controller is run by Arduino and controls 220V power outlet & gathers information from various sensors. Bidirectional datalink with the house is done over ZigBee radio. In the house I have a Beagleboard which logs data, draws nice graphs, serves these over the internet and can control Arduino.

The greenhouse controller looks like this:
controller_smaller
It consists of:

Some of the Arduinos IO pins are connected to the CAT5 cable that runs to small external sensor board:
sensor_board_smaller
The sensor board has following sensors connected to it:

The sensors and connections are protected from the environment mainly by having them covered by a thick layer of hot glue.

First version of the sensor board used LM35 analog temperature sensors which were nice and easy to interface with but thanks to their analog nature were rather sensitive cable length and small voltage flux on the Arduino that was caused by the relay switching and other sensors. Besides LM35 outputs negative voltage for temperatures below 0 deg. C which you can’t measure in a direct way from Arduino.

I haven’t had time yet to document the schematics & connections but for similar well documented project you can take a look here and here.

And here’s how it’s currently “installed”:
ad_hoc_installation_smaller
The power socket/switch that you see right next to the controller box is meant for the water pump and switch is used to override Arduinos decisions if need be.

Software wise things are quite simple at the moment – controller periodically gathers data from all the sensors and prints them in a line similar to:

H121 T-28.8 T-10.0 L192

Where letter indicates sensor type and number is determined by the position. Since the arduinos serial output is really connected to the ZigBee module I can just read it from the other side of the radio link as though the devices were directly connected with serial cable.

So the code running on Arduino is just this:

#include <OneWire.h>
#include <DallasTemperature.h>
 
#define ONE_WIRE_BUS 2
 
OneWire oneWire(ONE_WIRE_BUS);
 
DallasTemperature sensors(&oneWire);
 
#define MEASURE_CYCLE_TIME 5000
 
int humidity_pin = 1;// input pin for the humidity sensor
int light_pin = 5; // input pin for the light sensor
int relay_pin = 12;   // relay switch
float val = 0; // variable for storing sensor value
 
void setup() {
  pinMode(relay_pin, OUTPUT);  
  digitalWrite(relay_pin, LOW);
  Serial.begin(9600);
  sensors.begin();
} 
 
float get_temp(int pin) {
  float val;
 
  return sensors.getTempCByIndex(pin);
} 
 
void show_temp(float v) {
  Serial.print("T");
  Serial.print(v);
  Serial.print(" ");  
} 
 
void loop() {
  sensors.requestTemperatures();
  val = get_temp(0);
  show_temp(val);
  val = get_temp(1);
  show_temp(val);
 
  val = analogRead(humidity_pin);
  Serial.print("H");
  Serial.print(val);
 
  val = analogRead(light_pin);
  Serial.print(" L");
  Serial.print(val);
  Serial.print("\n");
 
  delay(MEASURE_CYCLE_TIME);
}

And on the Beagleboard it’s even simpler:

import serial
import os
import time
import traceback
 
SAMPLE_WRITE_TIME = 5*60
DATA_DEVICE = "/dev/ttyUSB0"
 
"""
to create the RRD file:
rrdtool create temperature.rrd --step 300 \
  DS:temp1:GAUGE:600:-273:5000 \
  DS:temp2:GAUGE:600:-273:5000 \
  DS:light:GAUGE:600:0:1000 \
  DS:humidity:GAUGE:600:-273:5000 \
  RRA:AVERAGE:0.5:1:1200 \
  RRA:MIN:0.5:12:2400 \
  RRA:MAX:0.5:12:2400 \
  RRA:AVERAGE:0.5:12:2400
"""
 
last_ts = None
 
ser = serial.Serial(DATA_DEVICE, 9600)
 
def calculate_relative_humidity(raw_humidity_val, temperature_c):
    """converts raw HIH4030 output to relative humidity %"""
    # see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267245927/3 for discussion
    if __debug__:
        print raw_humidity_val,temperature_c
 
    ZERO_PERC_VOLTAGE = 0.8
 
    max_voltage = (3.27-(0.006706*temperature_c))
    relative_humidity = ((((raw_humidity_val/1023)*5)-ZERO_PERC_VOLTAGE)/max_voltage)*100
 
    if relative_humidity > 100.0:
        # if it's  saturated/frozen it outputs raw values around 920 which would lead to
        # RH% in the range on 120 which is theoretically possible but probably just an
        # measurement error / problem with the equation
        return 100.0
 
    return relative_humidity
 
def write_sample():
    global last_ts
 
    l = ser.readline()
    # input is expected to be similar to "T-23 T-10 H100 L20\n"
    if __debug__:
        print "raw:",l,
 
    temp1, temp2, humidity, light = [float(x[1:]) for x in l.strip().split()]
    humidity = calculate_relative_humidity(humidity, temp2)
    if __debug__:
        print temp1,temp2,humidity,light
 
    if last_ts is None or (last_ts + SAMPLE_WRITE_TIME) < time.time():
        cmd = "rrdtool update temperature.rrd N:%f:%f:%f:%f" % (temp1, temp2, light, humidity)
        os.system(cmd)
        last_ts = time.time()
        if __debug__:
            print "cmd:",cmd
 
while 1:
    try:
        write_sample()
    except KeyboardInterrupt:
        raise
    except:
        print "write failed"
        traceback.print_exc()

Here’s some sensor data from today:
temp_211220101
light_21122010
humidity_211220101

live data available through Pachube feed

And here’s a picture of the Beagleboard at the garage that gathers data & serves the graphs
beagleboard_installation

Actually getting the Beagleboard working in a suitable manner turned out to be the most complicated part of the whole project. It took 3-4 days in total over a month or so while I reinstalled different distributions, replaced broken SD card, tried more than 10 different versions of the kernel and u-boot and finally removed a capacitor from the Beagleboard to get it stable. Hopefully I will write a separate post about that in the near future 🙂