Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
I've got a network device connected to my COM1 (serial) port, which is itself connected to several data collecting devices (barcode readers, etc). when these child devices have data, they send it to this parent network device, which stores the data until MY machine polls it for data (by sending a 'POLL' character, the ASCII ENQ char). if it's polled but has no data to send, it responds with a 'RESET' character (the ASCII EOT char)

I'm using Win32::SerialPort to handle all the dirty stuff, and I just need to receive the data in a stream. I know the network device will always send data in chunks LESS THAN $BUFFER amount of bytes, so I tried to read() or sysread() that many bytes from the serial port, but that seems to block until it gets AT LEAST that many bytes.

I guess i need a way to read UP TO $BUFFER amount of bytes until the stream is empty, then return control.

::takes a breath:: So..can anyone help me figure out WHAT to do and HOW to do it? i greatly appreciate the help :)
#!/usr/bin/perl ## Includes #################################################### # import any modules or pragmas we may need use strict; use Win32::SerialPort qw( :STAT 0.19 ); ## Initialization ############################################## # get everything defined and set up for the main loop, which # will sit on COM1, soliciting (polling) the controller # This hash contains all control character acronyms as hash keys, # with their respective ASCII values as corresponding hash values my %IM = ( 'SOM' => chr(2), #Start of message (STX) 'EOM' => chr(3), #End of message (ETX) 'AFF' => chr(6), #Affirmative Acknowledge (ACK) 'NEG' => chr(21), #Negative Acknowledge (NAK) 'POL' => chr(5), #Poll for data (ENQ) 'SEL' => chr(7), #Alarm (BEL) 'EOR' => chr(13), #End of record (CR) 'DLE' => chr(16), #DLE 'RES' => chr(4), #Reset (EOT) ); # Software-side buffer size, the maximum amount of data that # any single transmission will contain my $BUFFER = 2048; # create object bound to COM port, tie it to filehandle SERIAL, # and load settings from a config file my $PortObj = tie (*SERIAL, 'Win32::SerialPort', "C:\\com.cfg") || die + "Can't open COM1: $^E\n"; # some global variables for stat tracking (not yet implemented) my($upstream,$downstream) = 0; # create a flag variable initialized to zero... my $EXIT = 0; # ...when system signal INTERRUPT is sent, set flag to 1 $SIG{INT} = sub { $EXIT = 1 }; # begin new append to logfile open(LOG,">>C:\\COMDUMP.LOG"); print LOG "\n\nBEGIN: ",time,"\n"; ## Main Loop ################################################### # poll host for data every second, when data is recieved, print # it to STDOUT and a logfile (for now) print "\nPress Ctrl+C to exit\n\n"; my $temp; # main loop, continues until user sends INTERRUPT (ctrl+c) while($EXIT == 0) { $temp = pollForData(); if(defined($temp)) { print $temp; print LOG $temp; } sleep(1); } ## Cleanup ################################################### # close any COM ports, untie any filehandles, undefine objects, # and just tidy up in general before we exit close(LOG); $PortObj->close || die "failed to close"; untie *SERIAL; undef $PortObj; ## Subroutines ################################################# # any repetetive actions that can be reused, we'll store in here # as callable subroutines # polls the controller, retreives, and returns data, or returns # undef if there is no data sub pollForData { my($length,$buffer); # Poll controller to send any pending data (if there is none, # it will send back a 'RES' control character print SERIAL $IM{'POL'}; $upstream++; # read in $BUFFER amount of bytes $length = sysread(SERIAL,$buffer,$BUFFER); # update num of bytes received so far $downstream += $length; # if reset signal sent, there's no data pending, return undef if($buffer eq $IM{'RES'}) return undef; # otherwise, return data return $buffer; }

__________
Give a man a match and he'll be warm for an hour. Set him on fire and he'll be warm for the rest of his life.


In reply to issues reading from serial port by EvanK

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (3)
    As of 2021-04-22 21:14 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found

      Notices?