20090129

SRF02 Ultra-Sonic Ranger and Linux

Hi everyone,

Recently I've been working on a project that requires the use of an ultra-sonic range detector. The sensor works by emitting an ultrasonic chirp at approximately 40 kHz and timing the delay before the sound wave bounces off something and an echo is received. Given that the speed of sound in air is fixed for a specific humidity, temperature, and air pressure, the SRF02 is able to accurately determine the distance a wavefront has travelled using its built-in microcontroller. The built-in timer feature means that a host computer does not need to constantly poll the sensor to see if the echo has been detected, which saves resources (cpu bandwidth, interrupt, timer, etc) in the long run.

I thought I would post this, just in case another engineer needs to interface with the SRF02 sonar device, using the USB_I2C module from DevanTech.

The USB_I2C module is currently not supported in the Linux kernel as an I2C adapter, but it's easily accessible from userspace through the /dev/ttyUSB0 node. It's very similar to the TinyI2C USB adapter here, but connects using an FTDI chip as opposed to an Atmel controller.

Originally, I saw some example code from Kevin Nickels which seemed to provide the only readily available app to interface with the SRF02 under Linux. It was fairly legible, but still a bit scattered, so I thought I would provide a really simple app written in C for people to test out their units with.

Binary

Source

The USB_I2C is not very well documented, and I found that when reading multiple registers, it would prefix the data with 0x01 and suffix it with 0x00. This meant, for example, that reading all 6 registers of the SRF02 sequentially, actually requires 8 bytes of storage.

int fd;
unsigned char sbuf[8];
...
read(fd, sbuf, 8);     // sbuf should read { 01, 05, 18, 00, 19, 00, 10, 00 } (in hex) 
                       // 01    := prefix
                       // 05    := revision 
                       // 18    := 'unused' register
                       // 00,19 := high / low byte for range          (25cm)
                       // 00,10 := high / low bytes for minimum range (16cm)
                       // 00    := suffix
Please read the source code for more info, and also check out Kevin's work. My future work with this device will include JNI code and Java class for easy interfacing. It would be nice, of course, to have a kernel module for the USB_I2C adapter from DevanTech, as well as an I2C client (device) module for the SRF02, but my early attempts with that show that there is some friction between Linux and the DevanTech I2C code. However, I'll likely end up submitting some kernel source for this eventually after initial work has been done and my project is out the door.

PS: Thanks Kevin for your example code.

4 comments:

Christopher Friedt said...

A few months ago I finished the JNI portion of the code. You can download the source and binaries here.

Anonymous said...

wow...thank you!!

Anonymous said...

the download link is broken, is the source code available somewhere? thanks, nico

Christopher Friedt said...

Hi nico, I moved on from the company who had previously been hosting it, and I guess they finally deactivated my www pages. I'm planning on doing another sonar project in the near future though, and will try and repost the code on, e.g. github or gitorious.

C