Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

comment on

( [id://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":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-03-29 00:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found