Sunday, September 23, 2012

My UKHAS 2012 Conference talk: "HAB Software Woes"

Yesterday I have a talk at the UKHAS 2012 Conference about software problems in High-Altitude Ballooning. The slides are here:

Friday, September 21, 2012

A water rocket made from household bits and bobs

Last year I made a 'Ponyo' boat out of an aluminium can and a juice carton following the instructions from Science Toy Maker. This summer when the weather was nice enough I followed his instructions for a simple water rocket launcher made from a pen and a piece of PVC tube.

The nice thing about Science Toy Maker is that all the stuff he makes uses the minimum number of tools and a maximum of common items. The water rocket launcher needs the following: a bicycle pump, a "Bic" pen, a length of PVC tube, a candle, and some glue. Add a drinks bottle for the rocket.

Here's the finished launcher.
It's pretty simple. The length of PVC tube is pinched at the bottom end (on the right) to seal it, a hole is made for the bicycle pump connector made from the pen and a neck is made to rest the bottle on. Since the PVC melts at a low temperature he uses a candle to do all the work.

The first job is to heat the PVC pipe at the point where the drinks bottle rocket's neck will rest while it is pumped full of air.
All you do is heat up the pipe a bit (rotating it around for even heating) above the candle flame and then gently push to make a little bulge in the pipe. That's where the neck of the upside down drinks bottle sits.

Next you cut up a small pen to make the bicycle pump adapter. I used a simple "Bic" pen like this.
Then you make a hole in the PVC pipe near the bottom and heat the hole up until it's possible to push the pen segment in. I glued it all around with rubber-toughened superglue.
The finally stage is to seal the bottom of the tube. That's done with the candle again to soften it up, then pinch it and let it cool. Any space can be filled with glue.
After that you just attach the bicycle pump to the connector, partially fill the drinks bottle with water, stick it on the top, pump and let it fly. Check out this video from Science Toy Maker.

Friday, September 14, 2012

The UK has an entire IPv4 /8 that it isn't using (UPDATED)

IMPORTANT UPDATES BELOW

If you take a look at the list of IPv4 allocated /8 blocks there's one interesting block in there:

51.0.0.0/8 UK Government Department for Work and Pensions 1994-08 whois.ripe.net LEGACY

That block of addresses, all 16.8 million of them, is completely unused. A check of the ASN database will show that there are no networks for that block of addresses. Right when IPv4 is running out there's a huge block sitting unused.

That's an extremely valuable asset. One recent article valued an entire /8 at between "$500 million to $1.5 billion".

So, Mr. Cameron, I'll accept a 10% finder's fee if you dispose of this asset :-)

PS A comment draws my attention to a Freedom of Information Act response from the Department for Work and Pensions concerning this block. The FOI response says that the block is used internally by the government and there are no plans to release it.

PPS This Cabinet Office document says that 51.0.0.0/8 is used internally by government and routing it onto the Internet is not desired.  So, doesn't look like this block is 'unused' just not used on the Internet.

PPPS Someone wrote and asked why I blogged this rather than investigating first. Actually, I did. I wrote to both my local MP and the Department for Work and Pensions in February and received no reply at all. I figured 6 months without a reply was long enough.

The Joy of Bit-Banging

One of the joys of doing things with microcontrollers is the ability to bit-bang: to simulate the serial interface to a device so it can be controlled by the microcontroller without special hardware. The digital I/O pins on microcontrollers are ideal for interfacing to a variety of serial devices.

For example, I've used software controlled serial to connect to various things...

1. A Lassen IQ GPS module as part of my high-altitude balloon flight. The code is here and used a software serial interface to communicate with Lassen's binary TSIP protocol.

2. On the same flight I bit-banged an interface to a DS1821 temperature sensor. This was typical of many small devices where the serial interface is entirely controlled (including the clock signal) by the microcontroller. Details here.

3. A string of addressable RGB LED Christmas lights for my home made 7x7 display. The code for that serial protocol is here.

4. Yesterday, I blogged about interfacing to an optical mouse sensor using this code.

Microcontrollers can also be used for other software signal generation quite successfully:

1. On my high-altitude balloon flight the 50 baud RTTY radio signal was generated in software using two digital pins.

2. And in my games console in a can, software was used to generate a PAL or NTSC television signal.

If you want to get into using microcontrollers like this I recommend you get a logic analyzer that lets you spy on the signals being used and generated. I have a Salae Logic which is very, very handy.

Here's a screenshot of the logic analyzer looking at the GE Color Effects 50 Christmas lights used in the 7x7 display.


There tend to be only three things to worry about when bit-banging: the timing of signals, whether any pull up or pull down is needed on the lines and the voltage level of the logic being used.

The big disadvantage of not using specialized interface hardware is that your microcontroller spends time on the communication because it has to generate the signal; in my home projects that's vastly outweighed by the advantage of just being able to hook up directly to some digital I/O pins and get on with the project.

Thursday, September 13, 2012

Conversion of cheap optical mouse to robot odometer

For a small robot project I'm working on I needed a way to measure the robot's progress across the floor. There are various possibilities, such as: use stepper motors (expensive and am recycling some old continuous run servos), add an encoder to the wheels (would need to go buy some parts for that), or use the optical sensor for a mouse.


I had a really old PS/2 optical mouse lying around which contains an MCS-12085 optical sensor that has a rather simple serial interface suitable for connection to a microcontroller. Inside there are two separate areas of components. On the right in the picture above is the PS/2 interface chips and four nice extras that I desoldered for later use (three microswitches and a quadrature encoder). On the left is the red LED that illuminates the surface and the 8 pin square MCS-12085 that has the camera.

The only description of the chip was for a related optical sensor, the MCS-12086. The difference between the two appears to be that the MCS-12085 requires an external oscillator. A quick comparison of one of the designs in the datasheet and the PCB reveals the simple circuit that runs the chip:


Here's a marked up picture of the mouse internals:
The reverse side shows that there's a nice clean separation between the optical sensor side and the PS/2 interface.
So, after taking a hacksaw to the PCB and case, exposing some copper tracks with sand-paper and drilling four holes for +5V, GND, SDIO and SCLK it was possible to attach a small piece of the PS/2 cable and some connecting pins to have a stand-alone optical sensor unit for my robot.
Then it's just a question of software. For this project I'm using an Arduino Uno which can easily supply the 5V that the sensor needs and two digital pins can be used to generate the clock and I/O signals to read the movement of the sensor. I've created a small Arduino code module called mcs12085 that reads the delta-X and delta-Y values from the sensor as it moves.
Each call to mcs12085_dx() and mcs12085_dy() gives the distance the sensor has moved in the X and Y directions in dots with the range -128 to 127. Note that the sensor has a default accuracy of 1,000 dpi so it will overflow in either direction if the sensor moves more than 3.2mm in any direction.
The code uses one digital pin to act as the clock and generates the relevant clock signal, and another pin to read and write from the sensor.
Before I dismantled it I used a Salae Logic analyzer to observe what the PS/2 interface chip was doing to communicate with the sensor. Here's a screen shot of the complete cycle. The top shows the clock signal and the bottom the data.
It clocks in 8 bits of data corresponding to 0x02 (this is the read DX register command), pauses and reads out 8 bits (in this example the read bits were all 0). Then it clocks in 0x03 (the read DY register command), pauses and reads out 8 bits.
More details of the commands possible are in this document. At some point I'll add some of them to the project.

Wednesday, September 12, 2012

An intuition/reality clash in Go

The following Go code doesn't compile:
package main

import "log/syslog"

type MyThing struct {
 writer *syslog.Writer
}

func NewMyThing() (thing *MyThing) {
 thing = new(MyThing)
 thing.writer, err := syslog.Dial("", "", syslog.LOG_ERR, "")
 return
}

func main() {
}

It fails with the error prog.go:11: non-name thing.writer on left side of :=.  You can try it yourself here. (Ignore the fact that if it did compile there would be a different error because err is not used; the goal here is a small example).

The reason this fails is that := must be thought of as a declaration and not as an assignment. In fact, := is a declaration with the special exception that if one of the variables on the LHS is already declared in the same block then it is not redeclared it is assigned.

If you think of := as an assignment that sometimes declares you run into trouble because thing.writer can never be declared there (it's already declared in the struct). Just remember that := is a declaration that can assign.

Friday, September 07, 2012

A Go Gotcha that Got Me

Here's a little Go program that has a surprising output:
package main

import (
 "fmt"
 "net"
 "crypto/tls"
)
 
func main() {
 var c net.Conn

 c, err := tls.Dial("tcp", "www.jgc.org:80", nil)

 fmt.Printf("%v %v\n", c, err)

 if c == nil {
  fmt.Printf("Nil\n")
 } else {
  fmt.Printf("Not nil\n")
 }
}
This program tries to connect to my web site using TLS on the non-TLS port 80. That's done to force there to be a TLS error. The output is a little surprising:
  <nil> local error: record overflow
   Not nil
The Printf gives the value of c as but when the test c == nil is performed it's non-nil. 

So, what's going on? 

The answer is in the Go FAQ: Why is my nil error value not equal to nil?

In short, c is an interface (a net.Conn). The implementation of an interface is a type and a value. The type gives the actual type that implements that interface (in the case above it's a *tls.Conn) and the value is a pointer to the concrete example of that type. 

When the error occurs in the code above tls.Dial returns nil, err. The nil is a nil pointer to a tls.Conn. When the assignment to c happens c becomes non-nil (its type is now *tls.Conn) but its value is nil (since tls.Dial returned a nil pointer). Thus the nil test fails. 

The bottom line is that my code above is the wrong thing to do. Don't do nil tests on interface variables.

PS A lot of people have been asking me why I wasn't checking the value of err. In the real code I was, but a defer statement was acting on c and in it I had the code

if c != nil {
  c.Close()
}

In figuring out why that failed sometimes I discovered the gotcha.