in reply to Device::SerialPort Examples..

This should get you started. It's a script I use to read my weather station. And, it will run either *nix, or Win32 platforms.

#!/usr/bin/perl -w # # What we use # use strict; require 5.005; use vars qw($OS_win); my $debugGlobal = 0; my $portName = 0; my $logPath = 0; # # Run early to determine whether to load Win32::SerialPort (Win32) or + Device::SerialPort (Linux) # BEGIN { $OS_win = ($^O eq "MSWin32") ? 1 : 0; # print "Perl version: $]\n"; # print "OS version: $^O\n"; # # This must be in a BEGIN in order for the 'use' to be conditional # if ($OS_win) { eval "use Win32::SerialPort 0.14"; die "$@\n" if ($@); } else { eval "use Device::SerialPort"; die "$@\n" if ($@); } } # # Main entry point. If "action" is not defined, we default to login. # { my $data = 0; # # Enable flushing, && if debugging, kick out the content type # $| = 1; if (OS_Linux ()) { $logPath = "/home/system/weather/runlog.log"; $portName = '/dev/ttyS0'; } else { $logPath = "c:/perl/scripts/weather/runlog.log"; $portName = 'COM1'; } $debugGlobal && (open (LOG, ">>$logPath") || die "runlog.log: $!"); $debugGlobal && LOG->autoflush (1); runlog ('Starting run'); $data = read_wx_station (); runlog ("Exiting...\n"); exit; } # # Return 0 if running Windows, 1 if running anything else (Linux) # sub OS_Linux { return ($^O eq 'MSWin32' ? 0 : 1); } # # # sub read_wx_station { my $ob = 0; my $c = 0; my $record = ""; my $errcnt = 0; my $totalinbytes = 0; my $starttime = 0; if (OS_Linux ()) { $ob = new Device::SerialPort ($portName, 1); } else { $ob = new Win32::SerialPort ($portName, 1); } runlog ("Can't open serial port $portName: $^E\n") unless ($ob); die unless ($ob); runlog ('Setting serial port conditions'); $ob->baudrate (2400); $ob->parity ('none'); $ob->databits (8); $ob->stopbits (1); $ob->handshake ('none'); $ob->stty_icrnl (1); $ob->stty_ocrnl (1); $ob->stty_onlcr (1); $ob->stty_opost (1); $ob->write_settings (); runlog ('Waiting for a full weather record'); $starttime = time; for (;;) { my $blockingflags = 0; my $inbytes = 0; my $outbytes = 0; my $errflags = 0; # # See if we can read anything from the port # ($blockingflags, $inbytes, $outbytes, $errflags) = $ob->status o +r warn "could not get port status\n"; # # Did we get an 8250 error? # if (!OS_Linux ()) { if ($errflags & ($ob->CE_RXOVER | $ob->CE_OVERRUN | $ob->CE_R +XPARITY | $ob->CE_FRAME)) { if ($errcnt++ == 10) { runlog ("Aborted due to more than 10 errors\n"); die; } runlog ('Purging port'); $ob->purge_rx; $record = ""; } } # # Add the number of bytes read to the running total. Die if to +o many bytes without a record. Just for # grins, if we get too many, try shifting the baud rate and set +ting back so the UART will re-sync. # $totalinbytes += $inbytes; if ($totalinbytes > 1000) { if ($errcnt++ == 3) { runlog ("1000+ bytes read with no good data (wrong mode?)\ +n"); runlog ($record); die; } else { runlog ("purge for 1000+ bytes read with no good data"); $ob->baudrate (4800); $ob->write_settings (); $ob->baudrate (2400); $ob->write_settings (); $totalinbytes = 0; $starttime = time; } } # # If input is present in the buffer, read it, and add it to our + cumulative string # if ($c = $ob->input) { $c =~ s/\r//g; $c =~ s/\n//g; $record .= $c; if ($record =~ m/(!!)/) { runlog ("U2000 is in datalogging mode!\n"); die; } elsif ($record =~ m/(\$ULTW)/i) { runlog ("U2000 is in packet mode!\n"); die; } last if $record =~ /(&CR&).*(&CR&)/; } # # See if we've been doing this serial thing for too long. # if ((time - $starttime) > 30) { runlog ("Over 30 seconds with no good data (U2000 connected?) +\n"); die; } # # Basically sleep for .2 seconds # select undef, undef, undef, 0.2; } runlog ('Port read complete'); $ob->close or die "Close failed: $!\n"; undef $ob; runlog ('Starting weather data parsing'); $record =~ s/^.*?(&CR&)//; $record =~ s/(&CR&).*//; $record =~ s/^/&CR&/; runlog ('Returning 1 complete weather record'); return ($record); } # # # sub runlog { my $text = shift; $debugGlobal && print LOG scalar (localtime ()), ": $text\n"; }
--Chris

e-mail jcwren

Replies are listed 'Best First'.
Re: (jcwren) Re: Device::SerialPort Examples..
by reyjrar (Hermit) on Feb 23, 2001 at 02:28 UTC
    Very nice.. There's one thing I did notice about your example that doesn't apply to what I'm doing.. I need to read and write to/from a serial device.. I tried a few things to no avail.. I'm working on my third try now and will post my code for criticism and possibly help if it dosen't work..
    Thanks much jcwren, beautiful code I wish I could ++ it more than once. ;)

    -brad..