hydrodog has asked for the wisdom of the Perl Monks concerning the following question:

I needed to talk to two serial port devices, one I had working some time ago on Linux, and the other I got working within 10 minutes on Linux, but porting to windows proved to be quite hard. I got ActivePerl, installed Win32::Serial using the package manager:
ppm install Win32::SerialPoint ppm install Win32::API
the code that works on Linux opens a file handle and uses stty to set the baud rate:
use strict; my $deckbox = "/dev/ttyUSB0"; open(DECK, "+<$deckbox") || die('Couldn\'t open GPS'); system("stty -F $deckbox 19200"); while (my $line = <DECK>) { print $line; print DECK "\$CCPDT,1,4,0,0,3000,1,0,0,0\r\n"; }
Elegant and simple, right? On windows, there is no stty, so barring installing cygwin, which I would rather not have to do, I had to use the Win32::Serial package. It works fine for a GPS, but for this device, inexplicably no. Perhaps its one of many parameters of the serial port, so I will paste in the output to stty -a -F/dev/ttyUSB0 on linux:
stty -a -F /dev/ttyUSB0 speed 19200 baud; rows 0; columns 0; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; +eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; + min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixo +n -ixoff -iuclc -ixany -imaxbel opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs +0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -ec +hoprt echoctl echoke
The windows code that gives back gibberish:
require 5.003; use Win32::SerialPort qw( :STAT 0.19 ); use strict; my $line; my $deck = openSerial("com3:", 19200, 'none', 8, 1); # $deck->handshake("xon"); # $deck->buffers(4096,4096); do { my $bytesWritten = $deck->write('$CCPDT,1,4,0,0,3000,1,0,0,0' . "\r\n"); $line = rawReadSerial($deck); } while (1); sub readLineSerial { my ($ser) = @_; my ($numChars, $c); my $line = ''; do { do { ($numChars, $c) = $ser->read(1); } while ($numChars < 1); $line .= $c; } while ($c ne "\n"); return $line; } sub rawReadSerial { my ($ser) = @_; my ($numChars, $c); my $line = ''; do { do { ($numChars, $c) = $ser->read(1); #print "$numChars read=$c\n"; } while ($numChars < 1); print $c; $line .= $c; } while ($c ne "\n"); return $line; }
Can anyone tell me what I'm missing?

Replies are listed 'Best First'.
Re: serial port control on Windows
by BrowserUk (Patriarch) on Apr 23, 2008 at 18:22 UTC

    What do you get from the mode comN: command after you've configured it?

    require 5.003; use Win32::SerialPort qw( :STAT 0.19 ); use strict; my $line; my $deck = openSerial("com3:", 19200, 'none', 8, 1); # $deck->handshake("xon"); # $deck->buffers(4096,4096); print `mode com3:`; ...

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Wow, that was interesting.

      First of all, thanks for the mode command, I forgot that even existed.

      When I click into device manager, it tells me the USB to serial port converter is on COM3. It also told me the baud rate was 9600. I manually changed it to 19200. I got out of device manager in case it might be interfering.

      mode COM3: before opening the device gives me a baud rate of 1200, n, 7, 1. So much for my setting the port to 19200 in the device manager. When the code opens the port, mode says the device is not available. So at least perl grabbed the right device, but I can't tell what the settings are.

        When the code opens the port, mode says the device is not available. So at least perl grabbed the right device, but I can't tell what the settings are.

        Did you try setting the port then closing it before using the mode command? They (usually) retain the last set of settings until something changes them.

        Another old technique for setting up serial ports initially is to do everything from the command line:

        mode com3: ... copy con com3: type whatever the device is expecting here ^Z ## see what response you get copy com3: con

        If you need to send or receive binary , then judicious use of /b on the copy commands may be in order--though it is a pain entering Alt-nnn, Alt-nnn.

        Also, if the device doesn't respond then you will probably have to kill cmd.exe from the task manager to get control back.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: serial port control on Windows
by sgifford (Prior) on Apr 23, 2008 at 19:33 UTC