• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 561
  • Last Modified:

how to read and write from the serial port under Windows XP ?

Hi,

  yes, i know, i know, look it up in perldoc or one of the old posts, but all the examples I found were for UNIX. Can someone show me how to read and write from the serial port under Windows XP?

  in unix it is easy: all the installed hardware appears as a filehandle in the hardware folder. What about for windows? How do you acces the hardware driver?

  Thanks!

Tom
0
sapbucket
Asked:
sapbucket
  • 12
  • 6
  • 2
1 Solution
 
Kim RyanIT ConsultantCommented:
0
 
sapbucketAuthor Commented:
I wonder if there is an easier way? I've never used Tie before so I'm not sure what it is all about.

I basically need a port listener. When bytes come in I should be able to either store them to file or read them in my perl program.

I'll up the points...

0
 
sapbucketAuthor Commented:
So I figured out the setup:

use Win32::SerialPort 0.06;

$Configuration_File_Name = 'testconf.cfg';
$PortName = "COM1";
$PortObj = new Win32::SerialPort ($PortName, $quiet) || die "Can't open $PortName: $^E\n";    # $quiet is optional

  $PortObj->user_msg(ON);
  $PortObj->databits(8);
  $PortObj->baudrate(9600);
  $PortObj->parity("none");
  $PortObj->stopbits(1);
  $PortObj->handshake("none");
  $PortObj->buffers(4096, 4096);
  $PortObj->write_settings || undef $PortObj;
  $PortObj->save($Configuration_File_Name);
  # $PortObj->are_match('NL', 'OKW', 'OKH', 'START', 'NEWOK');


  I have my laptop connected to my PC using hyperterminal. I send keys from the laptop, and they appear on hyperterminal - so I know the connection is working. I'm not so sure what the next step is because the code examples are a little obfuscated and I'm not an expert! Any advice about what to do next? I want to be able to capture characters (or even a whole string?! is that possible?).

Thanks for the help!
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
sapbucketAuthor Commented:
what is "stty" ? guess: serial terminal type yummy, serial transmit terminal yodel, lol, ;)

0
 
Kim RyanIT ConsultantCommented:
Have you tried looking through the worked examples in this package? They start from  failry simple cases

    eg/demo1.plx      - talks to a "really dumb" terminal
    eg/demo2.plx      - "poor man's" readline and chat
    eg/demo3.plx      - looks like a setup menu - but only looks :-(
    eg/demo4.plx      - simplest setup: "new", "required param", "restart"
    eg/demo5.plx      - "waitfor" and "nextline" using lookfor
    eg/demo6.plx      - basic tied FileHandle operations, record separators
    eg/demo7.plx      - a Perl/Tk based terminal, event loop and callbacks
    eg/demo8.plx      - command line terminal emulator with Term::Readkey
    eg/demo9.plx      - using debug on a close()
0
 
sapbucketAuthor Commented:
nope i havent

where are they located ?

which package are you referring to? the win32::serialport?
0
 
Kim RyanIT ConsultantCommented:
Yes, its bundled in win32::serialport . Download the following and the files are in the eg folder
http://search.cpan.org/CPAN/authors/id/B/BB/BBIRTH/Win32-SerialPort-0.19.tar.gz
0
 
sapbucketAuthor Commented:
i'm going through the examples now... quick question: why are the examples .plx files instead of .pl? what is the x?
0
 
Kim RyanIT ConsultantCommented:
I was wondering that too. I think it's a window based extentsion for using perl with ISAPI web servers. But the code is just perl so you could rename it to .pl
0
 
sapbucketAuthor Commented:
im stuck on demo1.plx

C:\Shoe\Win32-SerialPort-0.19\SerialPort-0.19\eg>perl demo1.plx
demo1.plx loaded ok 1


++++++++++++++++++++++++++++++++++++++++++
Simple Serial Terminal with echo to STDOUT

type CONTROL-Z on serial terminal to quit


and the terminal seems to freeze up. Control-Z doesn't quit (Control-C, etc. is what I have to do)

Can you think of why it might be doing that?
0
 
sapbucketAuthor Commented:
demo2.plx runs pretty good...

C:\Shoe\Win32-SerialPort-0.19\SerialPort-0.19\eg>perl demo2.plx
demo2.plx loaded ok 1


++++++++++++++++++++++++++++++++++++++++++
Very Simple Half-Duplex Chat Demo

type CAPITAL-Q on either terminal to quit
kyjvgkhvgvjvjkhjbkjhbkjhbjkbhjkhbjkhbjkhbjkhbbjhjbbh
0
 
sapbucketAuthor Commented:
in the code he uses:

for(;;) {

}

what the heck does that do? he didn't give it any iterative information ie for($i=0;$i<@foo;$i++) {;}
0
 
Kim RyanIT ConsultantCommented:
I think Control-Z may be a unix convention, Control-C would be windows eqivalent. I am guessing that for(;;)  is an infinite loop, like while (1) {}, but he always makes sure he returns from inside the loop. Hope te examples are helping
0
 
jmcgOwnerCommented:
Ctrl-Z is an old CP/M and DOS convention for marking EOF.

I'm not sure why that example isn't working for you...perhaps you have to hit return after the ctrl-Z?
0
 
Kim RyanIT ConsultantCommented:
showing your age there jmcq with CP/M ;). I'll do likewise and guess that stty is a serial teletype device, sort of like a dumb terminal but instead of a screen there is a printer
0
 
jmcgOwnerCommented:
Just think of 'stty' as a contraction for 'set/show teletypewriter settings', where 'tty' is an old shortening of 'Teletype' (a brand name) which is short for 'teletypewriter'. I'll admit to being old enough to have spent many hours in front of an ASR33 when I was in college.


http://www.vintage-computer.com/asr33.shtml
0
 
sapbucketAuthor Commented:
I made an Object out of demo5.plx.

to run it you need to run test1.t in \t of Win::SerialPort installation folder.


package ShoeComm;
use Win32::SerialPort 0.15;

use Carp;
use Win32;
use strict;

sub new {
      my $type = shift;
      my $class = ref ($type) || $type;
      my $cfgfile = "COM1_test.cfg";
      my $ob = Win32::SerialPort->start ($cfgfile) or die "Can't start $cfgfile\n";
      my $pass;
      my @wanted;
      my $before;
      my $did_match;
      my $self = {        ob => $ob,
                              pass => $pass,
                              wanted => \@wanted,
                              before => $before,
                              did_match => $did_match
             };
 
      bless($self,$class);
      return $self;
}

sub ob {
    my $self = shift;
    $self->{ob} = shift() if (@_);
    return $self->{ob};
}
sub pass {
    my $self = shift;
    $self->{pass} = shift() if (@_);
    return $self->{pass};
}
sub wanted {
    my $self = shift;
    $self->{wanted} = shift() if (@_);
    return $self->{wanted};
}
sub before {
    my $self = shift;
    $self->{before} = shift() if (@_);
    return $self->{before};
}
sub did_match {
    my $self = shift;
    $self->{did_match} = shift() if (@_);
    return $self->{did_match};
}

# globals: (? this is old-school, rewrite this later to be object like.)
      
      
sub return_string {
      my $self=shift;
      

      my $ob = $self->ob();
      my $pass = $self->pass();
      my $refWanted = $self->wanted();
      my $before = $self->before();
      my $did_match = $self->did_match();
      # =============== execution begins here =======================
      
      # 2: Constructor
      
      
            # next test will die at runtime unless $ob
      
      ### setup for dumb terminal, your mileage may vary
      $ob->stty_echo(1);
      $ob->stty_icrnl(1);
      $ob->stty_onlcr(1);
      $ob->stty_opost(1);
      ###
      
      my $intr = stty_char($ob->stty_intr);
      my $quit = stty_char($ob->stty_quit);
      my $eof = stty_char($ob->stty_eof);
      my $eol = stty_char($ob->stty_eol);
      my $erase = stty_char($ob->stty_erase);
      my $kill = stty_char($ob->stty_kill);
      my $echo = ($ob->stty_echo ? "" : "-")."echo";
      my $echoe = ($ob->stty_echoe ? "" : "-")."echoe";
      my $echok = ($ob->stty_echok ? "" : "-")."echok";
      my $echonl = ($ob->stty_echonl ? "" : "-")."echonl";
      my $echoke = ($ob->stty_echoke ? "" : "-")."echoke";
      my $echoctl = ($ob->stty_echoctl ? "" : "-")."echoctl";
      my $istrip = ($ob->stty_istrip ? "" : "-")."istrip";
      my $icrnl = ($ob->stty_icrnl ? "" : "-")."icrnl";
      my $ocrnl = ($ob->stty_ocrnl ? "" : "-")."ocrnl";
      my $igncr = ($ob->stty_igncr ? "" : "-")."igncr";
      my $inlcr = ($ob->stty_inlcr ? "" : "-")."inlcr";
      my $onlcr = ($ob->stty_onlcr ? "" : "-")."onlcr";
      my $opost = ($ob->stty_opost ? "" : "-")."opost";
      my $isig = $ob->stty_isig ? "enabled" : "disabled";
      my $icanon = $ob->stty_icanon ? "enabled" : "disabled";
      
      $ob->error_msg(1);            # use built-in error messages
      $ob->user_msg(1);
      
      $ob->lookclear;
      
      print "swipe the card.\n";
      ($before, $did_match) = $self->nextline (60, "\nPROMPT:");
      if (defined $before) {
            if ("\n" eq $did_match) { $did_match = "newline"; }
            print $before."\n";
            return $before;            
      }
      
}
sub nextline {
      my $self=shift;
      my $ob = $self->ob();
      my $pass = $self->pass();
      my $before = $self->before();
      my $did_match = $self->did_match();
      
    my $delay = 0;
    my $prompt;
    $delay = shift if (@_);
    if (@_)      { $prompt = shift; }
    else      { $prompt = ""; }
    my $timeout=$ob->get_tick_count + (1000 * $delay);
    my $gotit = "";
    my $fmatch = "";
    my @junk;
      # this count wraps every 49 days or so

    $ob->is_prompt($prompt);
    $prompt =~ s/\n/\r\n/ogs if ($ob->stty_opost && $ob->stty_onlcr);
    $ob->write($prompt);

    for (;;) {
        return unless (defined ($gotit = $ob->lookfor));
        if ($gotit ne "") {
          ($fmatch, @junk) = $ob->lastlook;
            return ($gotit, $fmatch);
      }
      $fmatch = $ob->matchclear;
      return ("", $fmatch) if ($fmatch);
        return if ($ob->reset_error);
      if ( $] >= 5.005 ) {
          select undef, undef, undef, 0.2; # traditional 5/sec.
      }
      elsif ( $] < 5.004 ) {
          Win32::Sleep (200);      # AS 3xx builds
      }
      else {
          sleep 1;      # no easy GSAR equivalent
      }
      return if ($ob->get_tick_count > $timeout);
    }
}

sub waitfor {
      my $self=shift;
      my $ob = $self->ob();
    croak "parameter problem" unless (@_ == 1);
    $ob->lookclear;
    nextline ( shift );
}

sub stty_char {
    my $n_char = shift;
    return '%%%%' if ($n_char eq "");
    return $n_char if (2 >= length($n_char));
    my $pos = ord $n_char;
    if ($pos < 32) {
        $n_char = "^".chr($pos + 64);
    }
    if ($pos == 127) {
        $n_char = "DEL";
    }
    return $n_char;
}



1;
0
 
sapbucketAuthor Commented:
Thanks for the help :)
0
 
sapbucketAuthor Commented:
I am having problems installing Win32::SerialPort 0.15 on a second computer.

I get the following errors:

C:\Shoe\SerialPort-0.19>perl Makefile.PL

Creating new t/DefaultPort.pm

             Win32::SerialPort and Win32API::CommPort
                           VERSION 0.19
                  No 'Makefile' will be created
                  Test with:    perl test.pl
                  Install with: perl install.pl

              Test with nothing connected to COM1
           or for different port: perl test.pl PORT
         Timeout tests can take up to 30 seconds per test

Creating new test.pl
Creating new install.pl

C:\Shoe\SerialPort-0.19>perl test.pl
t/test1....Can't locate Win32/API.pm in @INC (@INC contains: . ./t ./lib ../lib
C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at lib/Win32/SerialPort.pm line 4.
BEGIN failed--compilation aborted at lib/Win32/SerialPort.pm line 4.
Compilation failed in require at t/test1.t line 17.
BEGIN failed--compilation aborted at t/test1.t line 17.
t/test1....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-275
        Failed 275/275 tests, 0.00% okay
t/test2....Can't locate Win32/API.pm in @INC (@INC contains: . ./t ./lib ../lib
C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at lib/Win32/SerialPort.pm line 4.
BEGIN failed--compilation aborted at lib/Win32/SerialPort.pm line 4.
Compilation failed in require at t/test2.t line 17.
BEGIN failed--compilation aborted at t/test2.t line 17.
t/test2....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-145
        Failed 145/145 tests, 0.00% okay
t/test3....Can't locate Win32/API.pm in @INC (@INC contains: . ./t .. ./lib ../l
ib C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at lib/Win32/SerialPort.pm line 4.
BEGIN failed--compilation aborted at lib/Win32/SerialPort.pm line 4.
Compilation failed in require at AltPort.pm line 7.
BEGIN failed--compilation aborted at AltPort.pm line 7.
Compilation failed in require at t/test3.t line 17.
BEGIN failed--compilation aborted at t/test3.t line 17.
t/test3....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-244
        Failed 244/244 tests, 0.00% okay
t/test4....Can't locate Win32/API.pm in @INC (@INC contains: . ./t .. ./lib ../l
ib C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at lib/Win32/SerialPort.pm line 4.
BEGIN failed--compilation aborted at lib/Win32/SerialPort.pm line 4.
Compilation failed in require at AltPort.pm line 7.
BEGIN failed--compilation aborted at AltPort.pm line 7.
Compilation failed in require at t/test4.t line 17.
BEGIN failed--compilation aborted at t/test4.t line 17.
t/test4....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-516
        Failed 516/516 tests, 0.00% okay
t/test5....Can't locate Win32/API.pm in @INC (@INC contains: . ./t ./lib ../lib
C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at t/test5.t line 17.
BEGIN failed--compilation aborted at t/test5.t line 17.
t/test5....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-166
        Failed 166/166 tests, 0.00% okay
t/test6....Can't locate Win32/API.pm in @INC (@INC contains: . ./t .. ./lib ../l
ib C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at lib/Win32/SerialPort.pm line 4.
BEGIN failed--compilation aborted at lib/Win32/SerialPort.pm line 4.
Compilation failed in require at AltPort.pm line 7.
BEGIN failed--compilation aborted at AltPort.pm line 7.
Compilation failed in require at t/test6.t line 17.
BEGIN failed--compilation aborted at t/test6.t line 17.
t/test6....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-315
        Failed 315/315 tests, 0.00% okay
t/test7....Can't locate Win32/API.pm in @INC (@INC contains: . ./t ./lib ../lib
C:/Perl/lib C:/Perl/site/lib) at lib/Win32API/CommPort.pm line 5.
BEGIN failed--compilation aborted at lib/Win32API/CommPort.pm line 5.
Compilation failed in require at lib/Win32/SerialPort.pm line 4.
BEGIN failed--compilation aborted at lib/Win32/SerialPort.pm line 4.
Compilation failed in require at t/test7.t line 17.
BEGIN failed--compilation aborted at t/test7.t line 17.
t/test7....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-88
        Failed 88/88 tests, 0.00% okay
Failed Test Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
t/test1.t      2   512   275  550 200.00%  1-275
t/test2.t      2   512   145  290 200.00%  1-145
t/test3.t      2   512   244  488 200.00%  1-244
t/test4.t      2   512   516 1032 200.00%  1-516
t/test5.t      2   512   166  332 200.00%  1-166
t/test6.t      2   512   315  630 200.00%  1-315
t/test7.t      2   512    88  176 200.00%  1-88
Failed 7/7 test scripts, 0.00% okay. 1749/1749 subtests failed, 0.00% okay.





Do you know why these errors are occuring? It says it can't find win32 in the @inc but I clearly have my path environment variable set:

C:\Perl\bin\;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Program Files\ActiveState Komodo 3.1\;c:\perl\bin\;c:\perl\lib\;c:\path\;c:\perl\site\lib\


Thanks for any advice - I don't know why it installed fine on one computer and not the other.

0
 
sapbucketAuthor Commented:
so i reinstalled the win32 api (is that weird or what - it comes with the perl distribution). And that got me past the above error but I now have this:

It should be trying to open COM6, as I have specified on the command line, but it insists on looking at COM1.

C:\Shoe\SerialPort-0.19>perl test.pl COM6
t/test1....defined(@array) is deprecated at t/test1.t line 445.
        (Maybe you should just omit the defined()?)
t/test1....ok 1/275could not open port COM1
t/test1....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 6-275
        Failed 270/275 tests, 1.82% okay
t/test2....ok 1/145can't open file: COM1_test.cfg at t/test2.t line 93
t/test2....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED tests 2-145
        Failed 144/145 tests, 0.69% okay
t/test3....defined(@array) is deprecated at t/test3.t line 444.
        (Maybe you should just omit the defined()?)
t/test3....ok 2/244could not open port COM1
t/test3....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 3-244
        Failed 242/244 tests, 0.82% okay
t/test4....ok 1/516can't open file: COM1_test.cfg at t/test4.t line 95
t/test4....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED tests 2-516
        Failed 515/516 tests, 0.19% okay
t/test5....ok
t/test6....ok 1/315can't open file: COM1_test.cfg at t/test6.t line 94
t/test6....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED tests 2-315
        Failed 314/315 tests, 0.32% okay
t/test7....ok 1/88can't open file: COM1_test.cfg at t/test7.t line 98
t/test7....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED tests 2-88
        Failed 87/88 tests, 1.14% okay
Failed Test Stat Wstat Total Fail  Failed  List of Failed
------------------------------------------------------------------------------
t/test1.t      2   512   275  539 196.00%  6-275
t/test2.t      1   256   145  287 197.93%  2-145
t/test3.t      2   512   244  483 197.95%  3-244
t/test4.t      1   256   516 1029 199.42%  2-516
t/test6.t      1   256   315  627 199.05%  2-315
t/test7.t      1   256    88  173 196.59%  2-88
Failed 6/7 test scripts, 14.29% okay. 1572/1749 subtests failed, 10.12% okay.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 12
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now