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

Spent some real time on this, but am totally stuck - help would be greatly appreciated. I have an astro camera that is controlled by a serial interface and was provided with a small control program (dotnet). The camera and program work fine on my Win7 PC with a Serial-USB connection and I am using Device Monitoring Studio to see the data going to the serial port. I want to migrate the control to Strawberry Perl, so I created the following test program:
#! C:\perl\bin\perl.exe use strict; use warnings; use Win32::SerialPort ; my $PortObj = new Win32::SerialPort ("COM1") || die "Can't open port\n"; $PortObj->baudrate(9600); $PortObj->parity("none"); $PortObj->databits(8); $PortObj->stopbits(1); $PortObj->write_settings || undef $PortObj; my $stt = pack 'H16', 'FF010003005F630A' ; $PortObj->write($stt); $PortObj->close || warn "Close Failed!\n"; undef $PortObj;
The serial monitor shows that my program is initializing the serial port and able to set baud, etc. However, the write command does not cause any serial output at all. I replaced the hex pack string with a simple text string as a test with a \n and a \r, but again, the command does nothing. I set perl.exe to run as administrator but that did not matter. It almost seems as if Windows is preventing me from writing to the serial port in some way. I turned off Windows Firewall but that did not help. Any ideas on how I can debug this one?

Replies are listed 'Best First'.
Re: can't write-Win32::SerialPort
by kschwab (Vicar) on May 15, 2014 at 18:28 UTC

    Downloaded your script and ran it on a Windows 7 box, and I see FF010003005F630A going out the port.

    Your problem is probably one of:

    1. Bad serial monitor. There aren't many software serial monitors that actually work on Windows 7. I use "Advanced Serial Port Monitor", which does work.
    2. Serial port permissions. Run your script under a shell that you started with right click -> run as administrator.
    3. Wrong serial port. Start device manager (under control panel) and make sure you see COM1, without any yellow or red warning symbols about the device state. This one seems likely. It's unusual (not impossible) for windows to assign COM1 to a USB to serial device. I bet your serial port is actually COM3.
      Thanks for such speedy input! 1. Serial monitor: I see output from the dotnet program so the monitor is working. 2. I opened a privileged command prompt and still get the same problem. 3.I reassigned the com port to 1 and am using it successfully with the dotnet program. I don't get an open error on Com 1. It did not work on com 3, which as you point out, was the initial default. I updated the program and have some error messsges output:
      #! C:\perl\bin\perl.exe use strict; use warnings; use Win32::SerialPort ; my $count_out = 0; my $PortObj = new Win32::SerialPort ("COM1") || die "Can't open port\n"; $PortObj->baudrate(9600); $PortObj->parity("none"); $PortObj->databits(8); $PortObj->stopbits(1); $PortObj->handshake("none"); $PortObj->write_settings || undef $PortObj; my $stt = pack 'H16', 'FF010003005F630A' ; # $PortObj->write($stt); $count_out = $PortObj->write($stt); warn "write failed\n" unless $count_out; warn "write incomplete\n" if $count_out != length($stt); $PortObj->error_msg(1); $PortObj->user_msg(1); $PortObj->close || warn "Close Failed!\n"; undef $PortObj; # output from program: # C:\Users\Frank\Desktop>micro-2.pl # Write failed # Use of uninitialized value $count_out in numeric ne (!=) at C:\Users +\Frank\Deskttop\micro-2.pl line 34. # Write incomplete

        Place the two statements $PortObj->error_msg(1); $PortObj->user_msg(1); before the initialization (i.e. just after new). Also, please follow all of the advice from this node.

        Also, this thread is starting to sound incredibly similar to this one, in which the problem was reportedly solved by using 32-bit Strawberry Perl instead of 64-bit. Another user reported similar problems.

Re: can't write-Win32::SerialPort
by Anonymous Monk on May 15, 2014 at 18:26 UTC

    A few debugging ideas:

    1. $PortObj->error_msg(1); $PortObj->user_msg(1);
    2. Check for error messages from the module, e.g. ... or die "Error: $^E";
    3. my $count_out = $PortObj->write($output_string); warn "write failed\n" unless $count_out); warn "write incomplete\n" if $count_out != length($output_string);
    4. Check if you need to set up any flow control, if not, use $PortObj->handshake("none");
    5. Make sure you're setting the CTS, DTR, etc. lines appropriately, if they are connected and being used in hardware.