linux serial port programming with perl

linux serial port programming with perl

Post by Jason Prieb » Thu, 03 Sep 1998 04:00:00

Pardon the cross-post, but I'm not sure if this is a system issue or a
Perl issue.  I'm using a RH 5.0 Linux box (x86) to communicate with a
Davis Instruments Weather Monitor II.  My intent is to collect real-
time weather data for online publication.

I am having problems communicating with the box.  I've tried just about
every combination of arguments to stty to get things to work, with no
real success.

Basically, what I was seeing was that the first command I sent to the
Weather Monitor after turning it on would be received fine.  I got an
ACK and the requested data.  Every subsequent command was not
understood by the WM, (I got the ascii 33 decimal from the WM, its
response when it doesn't understand a command).

I found after _much_ trial-and-error that if I closed the serial port
after issuing the command and reading the results, then opened the
port again using sysopen(), sent a null command, and closed the port,
I could then issue another command to the WM, and it would understand!
It seems that the sysopen() call reset something on the communication

So the sysopen() seems to flush something, but the communications are
still a bit flaky, so I had to add the select() call to pause after
each reading.  Even with that, I'm seeing some values misread.  I'd
appreciate _any_ insight!   TIA

BTW -- the WM has been used sucessfully with the bundled 32-bit windows
software, so the hardware definitely works properly.

Here's my code if anybody is interested:

use Fcntl

$cr = 0x0d;

`stty sane`;
`stty raw -clocal 2400 < /dev/$dev`;

if(&send_command('WRD', chr(0x22) . chr(0x5e), 1))
  $wind_speed = unpack('C', $buffer);
  print "wind speed = $wind_speed\n";


sub send_command

  my $retval = 1;

  #### open serial port and unbuffer input
  open(PORT, "+</dev/ttyS0")
   || die "Can't open port 1 for read/write:$!\n";
  select(PORT); $| = 1;

  print PORT "$command$args$cr";

    $num_bytes_read = read(PORT, $buffer, $bytes_expected);
    ($num_bytes_read != $bytes_expected) && ($retval = 0);
    $retval = 0;


  #### somehow, this stuff seems to flush something that the stuff
  #### above leaves open....
  sysopen(PORT, "/dev/$dev", O_RDWR|O_NDELAY|O_NOCTTY);
  print PORT "$cr";

  #### sleep for 1/2 second
  select(undef, undef, undef, 0.5);



sub get_ack
  $num_bytes_read = read(PORT, $reply, 1);

  $reply_num = unpack('C', $reply);
  if($reply_num == 0x06)
    #print "command was understood ($reply, $reply_num).\n";
    return 1;
    #print "command was not understood ($reply, $reply_num).\n";
    return 0;



1. Parallel Port programming question, was "Serial Port Programming"

All right, it was a unanaimous response to use the parallel port instead of
the serial port to twiddle pins on a IO port.  Anyone have a quick snipit
of code or direction to go.  I have the IOport programming howto which shows
how to set up port to be talked to, but does not explain how to exactly
talk to the port itself.  Any help would be appreciated.
| Andrew F. Nelson      Computer Science                                |

| URL:                           |
| Title:                WWW Administrator / Systems Staff               |
|                       Computer Science and Institute of Technology    |
| "Murphy's Law isn't just a saying, it is a way of life!"              |

2. X compressions for slow lines

3. How to set up serial port when programming serial communication

4. Question about Apache proxy support and secure sites

5. apache-1.3.6 vhosting with firewall

6. HOW TO program the serial port on linux

7. sendmail on Solaris 2.5 uses NIS domain instead of hostname

8. Linux serial port programming

9. Serial port programming for linux

10. Example Programs using the Parallel/Serial Port (Linux)

11. Linux Serial Port Programming problem - ioctl -