TGI has asked for the wisdom of the Perl Monks concerning the following question:
I've got a strange problem with Win32::SerialPort, and could really use some help.
I can't seem to get my Belkin F5U109 serial to USB adapter to take a baudrate setting. My normal serial ports work fine, as does my Radioshack #26-183. This problem is consistant between Windows 2000 and XP.
Of course, the adapter works fine with Hyperterm and Bray's terminal emulator. So the question is what am I doing wrong?
Update: The belkin serial port is configured as a 9600 baud serial port through the device manager. Despite that it defaults to 1200 baud and won't allow me to set the baudrate.
Below you'll find some test code that will demonstrate the behavior, as well as its output.
use strict; use warnings; use Win32::SerialPort; use Getopt::Long; # Strings with comport names my $arg_com_a; my $arg_com_b; GetOptions( 'a:s' => \$arg_com_a, # a should be the Belkin 'b:s' => \$arg_com_b, # we vary b to find out what's up ) or die "Bad command line options\n"; # Create a serial port object for the test my $com_a = Win32::SerialPort->new( $arg_com_a ) or die "Error opening $arg_com_a $!\n"; configure_comport($com_a); my $com_b; # a globalto store the b serial port object in. # Begin testing. foreach my $baudrate (qw( 9600 4800 2400 1200 600 300 )) { print "\nA-$arg_com_a: 9600 \tB-$arg_com_b: $baudrate\n"; print '-'x30 . "\n"; $com_b = Win32::SerialPort->new( $arg_com_b ) or die "Error opening $arg_com_b $!\n"; configure_comport($com_b, $baudrate); $com_b->write_settings; # This fails under XP test_send(); test_recv(); $com_b = undef; } exit; # ================================================================== # test_send ====================================== # Try sending data from A to B. sub test_send { my $test_out = "ABCDEFG 1234567\n"; $com_a->write($test_out); my $test_in = read_data($com_b, 5) || ""; # read_data() excludes the lookfor() characters (in this case \n), + so we chomp to make it possible for the test strings to match chomp $test_out; if ( $test_out eq $test_in ) { print "A TX\tSUCCESS: $test_in\n"; } else { print "A TX\t->$test_out<-\nB RX\t->$test_in<-\n\n"; } } # END test_send ================================== # test_recv ====================================== # Try recieving data sent from B. sub test_recv { my $test_out = "ABCDEFG 1234567\n"; $com_b->write($test_out); my $test_in = read_data($com_a, 5) || ""; # read_data() excludes the lookfor() characters (in this case \n), + so we chomp to make it possible for the test strings to match chomp $test_out; if ( $test_out eq $test_in ) { print "B TX\tSUCCESS: $test_in\n"; } else { print "B TX\t->$test_out<-\nA RX\t->$test_in<-\n\n"; } } # END test_recv ================================== # read_data ====================================== # Attempt to read data from a serial port object. # First argument is a serial port object. # Second argument is the timeout period in seconds. sub read_data { my $p = shift; my $timeout = shift || 1; # Store timeout time in millisecond ticks. $timeout = $p->get_tick_count + (1000 * $timeout); $p->lookclear; # Clear lookfor buffers my $gotit = ""; while(1) { # polls until we have a line of data return unless ( defined ($gotit = $p->streamline) ); if ($gotit ne "") { my ($found, $end, $pattern, $instead) = $p->lastlook; return "$gotit"; } # or an error return if ($p->reset_error); if ($p->get_tick_count > $timeout) { my ($match, $after, $pattern, $instead) = $p->lastlook; return ; } } } # END read_data ================================== # configure_comport ============================== # Apply a standard configuration to a comport. # First argument is a serial port object. # Second argument is baudrate, defaults to 9600. sub configure_comport { my $p = shift; my $baudrate = shift || 9600; $p->baudrate($baudrate); $p->parity('none'); $p->databits(8); $p->stopbits(1); $p->handshake('none'); $p->xon_limit(100); # bytes left in buffer $p->xoff_limit(100); # space left in buffer $p->xon_char(0x11); $p->xoff_char(0x13); $p->eof_char(0x0); $p->event_char(0x0); $p->error_char(0); # for parity errors $p->buffers(4096, 4096); # read, write $p->read_interval(100); # max time between read char (milliseco +nds) $p->read_char_time(5); # avg time between read char $p->read_const_time(100); # total = (avg * bytes) + const $p->write_char_time(5); $p->write_const_time(100); $p->error_msg(1); $p->user_msg(1); $p->binary(1); # Win2K really likes this to be true. # Match line endings. $p->are_match( "\n", ); $p->write_settings; # This fails under XP } # END configure_comport ====================
Here's the output of the script when run with the Belkin adapter at COM5 (COM1 is a real serial port).
Update:To clarify what is happening here, I am varying the baudrate of com port B to determine the actual baud rate of com port A. So, when the output says "A-COM5: 9600 B-COM1: 1200" it means that COM5 was configured as 9600 baud, and COM1 was configured as 1200 baud. A line with SUCCESS means that the sent and recieved data match.
C:\Documents and Settings\Mark\Desktop>serialkiller.pl -a=COM5 -b=COM1 A-COM5: 9600 B-COM1: 9600 ------------------------------ Break Signal detected A TX ->ABCDEFG 1234567<- B RX -><- B TX ->ABCDEFG 1234567<- A RX -><- A-COM5: 9600 B-COM1: 4800 ------------------------------ Framing Error detected A TX ->ABCDEFG 1234567<- B RX -><- B TX ->ABCDEFG 1234567<- A RX -><- A-COM5: 9600 B-COM1: 2400 ------------------------------ Framing Error detected A TX ->ABCDEFG 1234567<- B RX -><- B TX ->ABCDEFG 1234567<- A RX -><- A-COM5: 9600 B-COM1: 1200 ------------------------------ A TX SUCCESS: ABCDEFG 1234567 B TX SUCCESS: ABCDEFG 1234567 A-COM5: 9600 B-COM1: 600 ------------------------------ Framing Error detected A TX ->ABCDEFG 1234567<- B RX -><- B TX ->ABCDEFG 1234567<- A RX -><- A-COM5: 9600 B-COM1: 300 ------------------------------ A TX ->ABCDEFG 1234567<- B RX -><- B TX ->ABCDEFG 1234567<- A RX -><-
Note: Based on graff's comment, I decided that needed clarify what I wrote. I hope the few additional sentences help clear up what the nature of my problem is.
TGI says moo
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Can't set baudrate with Win32::SerialPort and Belkin USB adapter
by graff (Chancellor) on Sep 24, 2005 at 04:33 UTC | |
by TGI (Parson) on Sep 24, 2005 at 06:13 UTC | |
|
Re: Can't set baudrate with Win32::SerialPort and Belkin USB adapter
by TGI (Parson) on Sep 26, 2005 at 21:56 UTC |