Monday, December 31, 2007

Win32 client to read serial data

After trying the perl client on Win32 I realized it is not going to work (will not work easily). First of all installing all perl accessories was a pain in the neck on windows ( ActivePerl + Win32::API + Win32::SerialPort ) and most probably no user will venture into that. I did and soon realized that the Win32::SerialPort library is not working the same way as Device::SerialPort on linux. Instead of finding out why this is happening, I wrote a standalone Win32 executable that is not dependent on complicated installations.

I was looking for a free C/C++ compiler for Windows and I found that a version of VC++ was free. After some googling I wrote a client that reads the serial port and dumps the data on the console. As with the perl client my TODO list includes logging and sending data to a web server. Current code is available in the projects CVS repository. Usage example:


si_reader.exe com4



The si_reader.exe client reads both the serial and USB inputs (from a virtual com port), although they are different for the same SI card (both main stations are in autosend mode). Hope this mystery will be revealed soon, for now I am in urgent need of some web/database application that receives and understand raw data.

Tuesday, November 20, 2007

The BSF7-RS232 main station has arrived

Thanks to Joe Scarborough, the local SportIdent dealer I got a really good price on this little hardware, that arrived yesterday evening.

BSF7-RS232

First, I used the SI Manger software on Windows to make sure the station is set up to read SI cards and the Autosend box is checked. This makes things somewhat simple as the station just sends card data out to the serial port without any input from the computer.

All I needed now is a client on the PC, that reads the binary input from the serial port. Perl makes a lot of sense for a lot of reasons, most of all portability. I am a beginner in perl at best, but after hours of googling I came up with the following script that does the job:

#!/usr/bin/perl

use strict;
use vars qw($OS_win);

BEGIN {
$OS_win = ($^O eq "MSWin32") ? 1 : 0;
print "Perl version: $]\\n";
print "OS version: $^O\\n";

if ($OS_win) {
print "Loading Windows modules\\n";
eval "use Win32::SerialPort";
die "$@n" if ($@);
}
else {
print "Loading Unix modules\\n";
eval "use Device::SerialPort";
die "$@\\n" if ($@);
}
}

die "\\n\\nno port specified\\n" unless (@ARGV);
my $port = shift @ARGV;

my $serial_port;
if ($OS_win) {
$serial_port = new Win32::SerialPort ($port,1);
}
else {
$serial_port = Device::SerialPort->new ($port );
}
die "Can't open serial port $port: $^E\\n" unless ($serial_port);

my $name = $serial_port->alias;
print "\\nopened serial port $port as $name\\n";

$serial_port->databits(8);
$serial_port->baudrate(4800); # or 38400 depending on the station setup
$serial_port->parity("none");
$serial_port->stopbits(1);

my $count = 0;
my $hexa = "";
my $timeout;
my $time_on = 0;
while (1) {

my $char = $serial_port->input;

if ($char) {
$time_on = 0;
my $len = length $char;

$count += $len;

$hexa .= unpack("H$($len*2)",$char);

if($count >= 1000) {
print "Len: $count\\n".$hexa."\\n";
$hexa = "";
$count = 0;
}

} else {
if($time_on) {
if($timeout < time) {
$time_on = 0;
if($count) {
print "Len: $count\\n".$hexa."\\n";
$hexa = "";
$count = 0;
}
}
}
else {
$time_on = 1;
$timeout = time + 2;
}
}

select(undef, undef, undef, 0.1);
}


I named it si_client.pl, so it starts like this:

$ si_client.pl /dev/ttyS0


Yes, /dev/ttyS0 is the serial port on my linux box the device is connected to. Although I never tried, the script should work on Win32 as well (use COM1, etc. for the portname). Note, that your perl installation might not have the SerialPort library, in which case do this on Ubuntu:

$ sudo apt-get install libdevice-serialport-perl

or something similar on a different platform.

Note, that this client needs some more work as we want to send the raw card data to a webserver.

Monday, November 19, 2007

Make an Arduino on the cheap

Arduino boards are fun to play with and they will likely have a major role in this project. USB based boards start at about $35 if one buys an original. Fortunately, there are a number of other hardware options, that work with the ingenious Arduino software, such as:

These all require the FTDI USB to TTL cable (only once for about $20) and some soldering.

If you don't mind the RS232 interface, you can go with the serial Diecimila board or build your own Arduino compatible board. This is what I did, as I already had an AVR-P28 from Olimex and an ATMega168-20PU chip, plus a 16MHZ crystal.

Simply connected pin 2 and 3 of the chip to TX and RX on the board so the microcontroller is connected to the serial port.




The board is really helpful in writing the Arduino bootloader on the chip. Once it is done, the board can accept code from the Arduino software. I found, that in is less seamless then the factory USB arduino. The upload and the reset button on the board must be pressed almost simultanously to get a successful upload.

I have also added 2 female header boards, that can be seen on the above pictures. Those are optional of course.

The RS232 port already on the board will come handy when interfacing with the SportIdent serial main station.