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

Hello Monks, I'm having troubles in getting a binary stream out of a RS232 device in my code. I know that the messages are all 14 bytes long. THeir structure is clear and are sent each 250ms. I wrote below code but problem is that I get absolutely no output on the console. If I remove the infinite loop, I get the first message and can process it but as I'm looking for a data logger feature it's useless :-) My code is below. Anybody can tell me what I should change/do/read/etc. to make it happen? Thanks!
#!/usr/bin/perl -w # use strict; use warnings; use threads; use Thread::Queue; use Win32::SerialPort; use Data::Dump qw(dump); # GLOBALS my %CONFIG = ( ReaderCOMPort => "COM56", ReaderCOMPortOpen => 1, testTime => 5 # testing time in seconds ); <readmore> my $ob; # Initialize the serial port of the reader initRS232(); $ob->read_interval(250); $ob->read_const_time(10000); $ob->lookclear; while (1) { my ($count, $str) = $ob->read(14); DumpString($str); sleep 1; } undef $ob; exit; sub initRS232 { eval { $ob = Win32::SerialPort->new ($CONFIG{ReaderCOMPort}); # || r +eturn "Can't open $PortName: $^E\n" }; if($@) { # We know it died, but is it an object or a # printable message? if( ref $@ ) { # Assume it's an exception object. Not a # great way to do it, but it works. # # Now, what kind of exception is it? # if( $@->isa( 'IOException' ) ) { } elsif( $@->isa( 'OtherException' ) ) { } else { } } else { # Assume it's an error string } } $CONFIG{ReaderCOMPortOpen} = 1; $ob->user_msg(1); # misc. warnings $ob->error_msg(1); # hardware and data errors $ob->baudrate(2400); $ob->parity("none"); $ob->parity_enable(1); # for any parity except "none" $ob->databits(8); $ob->stopbits(1); #$ob->xon_limit(20); # bytes left in buffer #$ob->xoff_limit(100); # space left in buffer $ob->write_settings; $ob->save("tekpower.cfg"); #$ob->are_match("\xE8"); } # dump the contents of a string as decimal and hex bytes and character +s sub DumpString { my @a = unpack('C*',$_[0]); my $o = 0; while (@a) { my @b = splice @a,0,16; my @d = map sprintf("%03d",$_), @b; my @x = map sprintf("%02x",$_), @b; my $c = substr($_[0],$o,16); $c =~ s/[[:^print:]]/ /g; printf "%6d %s\n",$o,join(' ',@d); print " "x8,join(' ',@x),"\n"; print " "x9,join(' ',split(//,$c)),"\n"; $o += 16; } } </readmore>

Replies are listed 'Best First'.
Re: Blocking on serial port!
by RichardK (Parson) on Apr 24, 2013 at 22:50 UTC

    Does read(14) block until it gets 14 bytes? or will it return fewer bytes? try checking the returned count.

      Yes, read(14) blocks till 14 bytes are received. Thing is I'm sure there are 14 bytes sent every 250ms. I could verify in many ways. Thanks!
Re: Blocking on serial port!
by Random_Walk (Prior) on Apr 25, 2013 at 07:37 UTC

    Perhaps it is a buffering issue. Try turning off buffering with:

    $| = 1;

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!

      Well, that seems to be a good way!

      Thanks, i'll confirm later and post my code. Maybe it can be helpful for someone looking for data logging through serial port with perl.
Re: Blocking on serial port!
by OfficeLinebacker (Chaplain) on Apr 24, 2013 at 23:50 UTC
    May want to put the code in a readmore block.
      Hello Sorry but I'm not sure to understand what you mean. You talk about the code presentation in current thread? Thanks
        Yes, your code takes up a lot of space in the SOPW page it shows up on. If you use the "readmore" tag than it's like showing only a summary of your post when in a collection of other threads, and the whole thing shows once a user clicks on it. It's a courtesy thing.