Some of my recent photos

Sunday, September 25, 2011

And if your Xbee shield is behaving strangely...

If you are combining the CAN-Bus and Xbee shields from SparkFun, it can be very tempting to plonk the EM406 GPS atop the nice flat prototyping area on the Xbee shield. It's a good fit there! But if stuff suddenly and inexplicably stops working, check that the GPS chassis isn't bridging the terminals on the Xbee shield's RESET switch. I felt like a real idiot :-(

Arduino: combining CAN-bus and Xbee shields


A little box of Arduino, originally uploaded by indigoid.

So I created a simple little sketch, based on the TimeGPS sample that comes with the TinyGPS library, that waits for a "p" over the Xbee interface and upon receiving it, sends back the date, time, latitude and longitude data from the GPS. The CAN-bus shield uses pins 4 and 5 for the GPS serial interface. I found that the Xbee modules I have (as supplied in the SparkFun Xbee retail kit) have rather shorter range than I'd hoped for, but at least they work and I am learning about their usage. Here's the sketch:


#include <TinyGPS.h>        //http://arduiniana.org/libraries/TinyGPS/
#include <NewSoftSerial.h>  //http://arduiniana.org/libraries/newsoftserial/
// GPS and NewSoftSerial libraries are the work of Mikal Hart

TinyGPS gps; 
NewSoftSerial serial_gps =  NewSoftSerial(4, 5);  // receive on pin 3

void setup()
{
  Serial.begin(9600);
  serial_gps.begin(4800);
  Serial.println("setup...");
}

void dump_lat_long(float flat, float flong) {
  Serial.print("lat : "); Serial.println(flat);
  Serial.print("long: "); Serial.println(flong);
}

#define pdec(x) { Serial.print(x,DEC); }
#define p(x) { Serial.print(x); }
#define s() p(" ")
#define d() p("-")
#define c() p(":")
void dump_datetime() {
  int year;
  byte month, day, hour, minutes, second, hundredths;
  unsigned long fix_age;
  gps.crack_datetime(&year, &month, &day, &hour, &minutes, &second, &hundredths, &fix_age);
  pdec(year); d(); pdec(month); d(); pdec(day);
  s();
  pdec(hour); c(); pdec(minutes); c(); pdec(second); p("."); pdec(hundredths);
  Serial.println();
}

void loop() {
  float flat, flon;
  unsigned long fix_age;
  String msg;
  byte havedata = 1;
  byte polled = 0;
  while (serial_gps.available() && !polled) {
    if(gps.encode(serial_gps.read())) {
      // returns +- latitude/longitude in degrees
      gps.f_get_position(&flat, &flon, &fix_age);
      if (fix_age == TinyGPS::GPS_INVALID_AGE) {
        msg = "No fix detected";
        havedata = 0;
      } else if (fix_age > 5000)
        msg = "Warning: possible stale data!";
      else
        msg = "Data is current.";
      polled = 1;
      if (Serial.available() && Serial.read() == 'p') {
        Serial.println(msg);
        if (havedata) {
          dump_datetime();
          dump_lat_long(flat,flon);
        }
        delay(100);
      }
    }
  }
}

I also wrote a small Perl script that (via Device::SerialPort from CPAN) interrogates the Arduino every 5 seconds or so, using a USB-attached Xbee Explorer. For Linux you will need to change the serial port device filename to /dev/ttyS0 or similar. No idea about Windows, sorry. Again, I started out with some sample code (this time from the Device::SerialPort distribution) and hacked most of it off. Code follows:


#!/usr/bin/perl

use strict;
use warnings;
use Device::SerialPort;

my $file = "/dev/tty.usbserial-A700fbpg";
my $ob = Device::SerialPort->new ($file) || die "Can't open $file: $!";

$ob->baudrate(9600)     || die "fail setting baudrate";
$ob->parity("none")     || die "fail setting parity";
$ob->databits(8)        || die "fail setting databits";
$ob->stopbits(1)        || die "fail setting stopbits";
$ob->handshake("none")  || die "fail setting handshake";
$ob->write_settings || die "no settings";
$ob->error_msg(1);              # use built-in error messages
$ob->user_msg(1);

while(1) {
  $ob->write("p");
  print $ob->input;
  sleep 5;
}

Monday, September 12, 2011

stairwell sensor light: Arduino!

So I wanted a small light at the bottom of the short set of stairs that lead from the door of my apartment into the main living area. I've been learning about Arduino lately, so I figured this might be a practical experiment. I decided to use a reed switch to sense when the door had been opened.

After getting frustrated at the reed switch functioning just fine when closed (Arduino digitalRead() returning HIGH) but bouncing around randomly when it should have been staying open, I did some Googling and found that I should have used a pullup resistor to coax the current in the right direction. I don't pretend to understand why this works, but I intend to find out.

Anyway, I used a circuit based very much on this one, plus of course an RGB LED to do the actual lighting. The next step is to grab a couple more RGB LEDs (I only had one on hand that had been supplied in the Sparkfun Inventors Kit) and make it brighter.

Learning about and experimenting with Arduino has been a lot of fun so far. Am working on a larger project for the bike. Along the way I've dramatically improved my soldering skills, though they are still pretty terrible!

#include <Time.h>

// pins
const int reedswitch = 2;
const int red = 9;
const int green = 10;
const int blue = 11;

// door states
const int DOOR_OPEN = 0;
const int DOOR_CLOSED = 1;

// minimum time the courtesy light will stay on for (seconds)
const int MIN_OPENTIME = 10;

///////////////////////////////////////////

int door = DOOR_CLOSED;
int last_open_at = 0;

void setup() {
  pinMode(reedswitch, INPUT);
  setTime(0);
}

void rgbled(int r, int g, int b) {
  analogWrite(red,r);
  analogWrite(green,g);
  analogWrite(blue,b);
}

void loop() {
  int reedswitch_state = digitalRead(reedswitch);
  if (reedswitch_state == HIGH && now() >= last_open_at + MIN_OPENTIME) {
    door = DOOR_CLOSED;
  } else if (reedswitch_state == LOW) {
    last_open_at = now();
    door = DOOR_OPEN;
  } else {
    // no change in state, do nothing
  }
  if (door == DOOR_OPEN) {
    rgbled(255,255,255);
  } else {
    rgbled(0,0,0);
  }
  delay(500);
}

Monday, December 27, 2010

K1200GT tyre pressure adjustment technique

Note that this probably also works with other BMW models with the tyre pressure monitoring (RDC) option fitted, but I have only tried it on my K1200GT.

If you need to adjust your tyre pressures and you don't have a tyre pressure gauge with you:

  1. ride the bike until the dash starts displaying the pressures
  2. stop the bike and then stop the engine, without touching the key in the ignition. Use the kill-switch
  3. adjust pressures, noting that as you do so, the dash display changes
  4. ride the bike :-)

This may be obvious to people smarter than me.  RDC is a wonderful feature to have.

End of year roundup

A quick blog post to wrap up 2010...

Work: Happy, challenged, excited. No serious complaints. Learning about AIX and Puppet, and of course Linux sysadmin continues to be my main role. Looking forward to the SAGE-AU conference in Melbourne, in September 2011. Didn't take as much time off as I should have, but riding my bike to and from Hobart for the 2010 SAGE-AU conference was extremely satisfying and gave me a good chance to be out of the office and clear my head.

Not-work: In May I started living and working in Sydney full-time. Have been appreciating commuting by train. I ditched my Nokia E71 for an iPhone 3GS and am loving it; it has been the single most satisfying tech purchase I have ever made. Haven't spent as much time in the gym as I should have, but this sorry state of affairs will not continue. I haven't spent nearly as much quality time with Anna as I'd like (we do live in different cities, after all), but I am hoping that this can improve in 2011.

Motorcycling, overall: I put about equal kilometres on the Dakar and K1200GT this year, and in total, rather fewer than last year. I don't have an odometer figure for the K-bike as of January 1 this year, but I do for the Dakar. A combined total of about 35000km, I think. The K1200GT odometer currently reads 51610km, and the Dakar odometer tells a very similar tale. My BMW Roadside Assistance subscription proved worthwhile as I achieved four punctured tyres in three months of riding.

K1200GT: This year saw a lot of warranty repair work on the K-bike, mostly at the time of the 40000km service, where it was at the dealer for a month or more. It now has a K1300 gearbox and clutch, and this does appear to be a bit better than the old units, but still not nearly as good as your average Japanese bike, such as a friend's Blackbird that I had the significant pleasure of borrowing.

F650GS Dakar: 2010 saw this bike back on the road after a bit of a hiatus, and I still have a deep, abiding love for it, especially the delightful little Rotax engine. 40000 and 50000km services were done, and I with the aforementioned Blackbird owner's help, I finished the Pro-Oiler install. The bike still needs more work, though, needing new chain/sprockets, new tyres and (for the second time) new steering head bearings. Michelin's perennial supply problems caused me to get Pirelli's gimmicky new Angel ST tyres instead of my usual Pilot Road2, and this was a mistake that I won't repeat.

Projects: In 2010 I acquired a Honda XL250 K0 (early 1970s model) and the other day I also acquired (Free! Thanks, Norm!) a Honda CT110 "postie" bike. The XL250 has a long road ahead, as I'd like to fully restore it. The CT110 on the other hand I would like to have registered and ridable as soon as possible. I don't think it will cost very much at all to get there. Job #1 is to transport it to my Sydney garage from its current location.

Wednesday, September 22, 2010

Corporate acquisitions: a quick survival guide

Almost three years ago, my employer was acquired by its major competitor. Having been through a very similar situation at a previous employer that ended in a fairly nasty fashion, this initially had me rather worried. Now, having had time to watch the intricate corporate dances play out, I can see that the two situations are chalk and cheese, and I'm rather happy about that.

Along the way, I learned a few lessons. I learned them from talking to other people involved, on both sides of the corporate fence and from my own experiences.

Most important, I think, is to embrace change. You're going to get it, whether you like it or not. It can be very hard work to remain positive in times of corporate upheaval, especially if some of your colleagues are incurable cynics and doomsayers, but in the long run it is worth it.

The next most important thing, in my opinion, is to engage with your new peers. Don't just listen passively in interminable phone conferences if you can avoid it. Get over there in person and talk to them! Stop thinking of them as competition. They're people, just like you, and it is extremely likely that each side can learn something from the other.

One of the first serious engagements I had with my new peers was a meeting to talk about the deployment of the acquiring company's standard operating environment for corporate desktop PCs.

I vividly recall attending a phone conference with my manager and a group of tech and managerial staff from the other side. My manager and I were on the receiving end of what seemed like an unreasonably hard sell, and given our relative inexperience with large-scale desktop management, we were actually extremely eager to adopt the desktop standard that was being pushed at us.

At one point I politely interrupted the meeting and made it crystal clear that we were just as interested in it as them, since desktop management was something we'd never really succeeded at to any degree. We wanted them to do it so that we could get on with our real work! The SOE proponents seemed thoroughly shocked, but with that part out of the way, we got down to details that actually mattered. The sailing was much smoother after that, and the end result thoroughly positive.

A nice side-effect of embracing change, as we did with desktops, is that it helps your new peers to see you in a positive light right from the start. You sure don't want to be thought of as that toxic old guy in the corner who hates anything new or different. First impressions are lasting impressions.

That pattern has repeated several times over the last three years, and the learning has continued on both sides. There have been exceptions, of course. There were people (from both sides of the acquisition, it must be said) that appeared unable to fully accept the reality of the acquisition. That's fine --- it was their choice. Just don't let their choices ruin it for you.

Friday, August 6, 2010

K1200GT update

Recently my K1200GT had its 40000km service, and at the same time I asked the dealer to investigate the gearbox and suspension.

The gearbox had been exhibiting three nasty behaviours.

First, it was extremely clunky. BMW bike gearboxes are infamous in this regard, but my bike was notably worse than usual.

Second, it would occasionally pop out of gear while decelerating with the throttle closed, ie. engine braking.

Third, it would sometimes appear to get wedged such that the gear lever had no impact on gear selection. When this happened, the gear display on the dash would go completely dark. Blipping the throttle sometimes freed up the gear selection. This was particularly annoying when pulling up at traffic lights, as I would typically be stuck in 3rd or 4th gear.

The suspension, meanwhile, had become extremely hard and uncomfortable. Unacceptable on the Princes Hwy in Sydney.

The dealer was happy to address these problems. The gearbox was replaced, and while they were in there they replaced the clutch as well. The entire rear suspension damper was replaced, and the ESA wiring for the front damper was also replaced. They also replaced the front brake pads and, somewhat worryingly, rebuilt the final drive unit. All of this work was warranty work and not charged for.

I am somewhat unhappy about the whole situation. The bike, a late 2008 model, only has 45000km on it as of today. I don't expect that it has much resale value left. Will reassess the situation when the 50k service rolls around.