SRF-08 in Perl

Use the following code to read out the SRF-08 Ultrasonic Range Sensor in Perl:

#!/usr/bin/perl -w

use strict;
use Device::SerialPort;
use bytes;
use Data::Dumper;
use Time::HiRes qw(usleep);
use Term::ANSIColor qw(:constants);
$Term::ANSIColor::AUTORESET = 1;

my $ret;	# result byte (0x00 for NOK, otherwise OK)
my $count = 0;	# byte count for read / write
my $data;	# packed string of bytes

# -----------------------------------------------------------------------------
# Setup serial communications
# -----------------------------------------------------------------------------
#my $port = '/dev/ttyUSB0';
my $port = '/dev/sensor'; # edit serial info in /etc/udev/rules.d/10-local
my $ob;
setCom();
setGain();

# -----------------------------------------------------------------------------
# Main loop
# -----------------------------------------------------------------------------
while(1) {

	ping();

	my $buffer = readI2C();
	my ($hex) = unpack('H*', $buffer);
	#print "raw: $hex\n";

	my ($b0, $b1, $b2, $b3) = unpack('H2' x length($buffer), $buffer);
	#print "result:\nb0: $b0\nb1: $b1\nb2: $b2\nb3: $b3\n";
	my $cm = 0;
	$cm = $b2 << 8;
	$cm = (hex $cm | hex $b3);

	print "dist: $cm\n";

	usleep(100_000);

}

# clean up
undef $ob;

# -----------------------------------------------------------------------------
# Sends a ping (range in cm). Returns 0x01 if success
# -----------------------------------------------------------------------------
sub ping {

	#print "sending ping...";
	$data = "\x55\xE0\x00\x01\x51";
	$count = $ob->write($data);
	#print "$count bytes written\n";
	usleep(100_000);
	($count, $ret) = $ob->read(1); # $ret should be 0x01, ignore for now
	return $ret;

}

# -----------------------------------------------------------------------------
# Reads a raw buffer from port
# -----------------------------------------------------------------------------
sub readI2C {

	#print "reading data...";
	$data = "\x55\xE1\x00\x04";
	$count = $ob->write($data);
	#print "$count bytes written\n";
	usleep(100_000);
	my ($this_count, $buffer) = $ob->read(255);
	return $buffer;

}

# -----------------------------------------------------------------------------
# Set serial parameters
# -----------------------------------------------------------------------------
sub setCom {

	$ob = Device::SerialPort->new($port);
		die "error opening port $port\n" unless ($ob);
	$ob->baudrate(19200)	|| die "fail setting baudrate";
	$ob->parity('none')	|| die "fail setting parity";
	$ob->databits(8)	|| die "fail setting databits";
	$ob->stopbits(2)	|| die "fail setting stopbits";
	$ob->handshake('none')	|| die "fail setting handshake";

}

sub setGain {

	print "set gain...";
	# gain (last byte) can be 00 to 0F. Experiment!
	$data = "\x55\xE0\x01\x01\x00";
	$count = $ob->write($data);
	print "$count bytes written\n";
	usleep(80_000);
	($count, $ret) = $ob->read(1); # $ret should be 0x01, ignore for now
	return $ret;

}

Comments

One Response to “SRF-08 in Perl”

  1. justme says:

    Tanks man!
    That worked. I’ve been looking ages for this.

Leave a Reply