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

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
Hi there I've come up with a routine that performs a serial read using the Win32:SerialPort library for a script I am writing. My issue is that everytime I run the script my output for the @buffer array is not completely what I expect. The size of the buffer is maximum of 80 bytes, any data beyond this point is ignored unless the 80 bytes collected do not include the packet of interest of which the collected data are disposed of and new data coming is stored. I am using a program called Docklight to simulate a serial port and test out various conditions for a packet that is built up of only [STX|VARIABLE PAYLOAD|ETX]. They are:
* STX / ETX have been found, example: 02 30 39 44 CE26 03 * > 80 bytes received on the serial line * > 80 bytes received but no STX/ETX needed packet found * A NAK was received
Ideally a packet of the type described in the first condition is needed, the other packets tested for the other conditions are ignored and the test for the right packet type is resumed again. My problem is that all of this is working just fine however if I send in any condition(s) other than the correct first one...and then I sent the proper condition at the end my results for the @buffer are like: G GC(G 4 4L2[STX09D&ETX] The part of the packet I've highlighted in brackets is the correct packet of interest. The data in front is junk and of which I don't need. The more error conditions that I test for (that is, send the error ridden packets) before I send the correct packet the more junk I get in front of the correct packet. However if I just submit the correct "condition" and not test out the other problematic scenarios I get the proper packet return with no junk in front: [STX09D&ETX] here's my serial read code:
sub readSerialPort { my $stx_rx = 0; my $etx_rx = 0; my $nak = 0; @buffer = (); # Empty the buffer before the next packet read while ((!$etx_rx) || ((!$etx_rx) && ((scalar(@buffer) > 79)))) { $byte=$port->read(1); if (ord($byte) == 0) #if it's a space, skip { next; } if (($byte eq chr(0x15) && (scalar(@buffer) < $MAX_BUFFER))) # + if a NAK is found anywhere and the buffer is not filled yet { print "\nNAK was found! " . $byte . "\n"; $nak = 1; $retry_if_fail = 1; # Flag to tell the script to continue wa +iting for the proper packet after buffer reset print "\nRetry var changed to " . $retry_if_fail . "\n"; STDOUT -> flush(); print "BUFFER RETURNED WITH NAK => " . @buffer . "\n\n"; return; } if ($byte eq chr(0x02)) # if it's STX run this condition { $stx_rx = 1; print "\nSTX was found! " . $byte . "\n"; } elsif (($stx_rx == 1) && ($byte eq chr(0x03))) # if both the S +TX and ETX are found { print "\nETX was found! " . $byte . "\n"; $etx_rx = 1; $retry_if_fail = 0; # Zero indicates the SUCCESS condition STDOUT -> flush(); print "BUFFER RETURNED AT ALL OKAY => " . @buffer . "\n\n"; print "BUFFER RETURNED AT ALL OKAY => " . join("",@buffer) +. "\n\n"; } if (($stx_rx == 1) && ($etx_rx == 0) && ((scalar(@buffer) > ($ +MAX_BUFFER-1)))) # if only STX was found within 80 bytes { print "\nOnly STX was found! " . $byte . "\n"; $retry_if_fail = 1; # Flag to tell the script to continue w +aiting for the proper packet after buffer reset print "\nRetry var changed to " . $retry_if_fail . "\n"; STDOUT -> flush(); print "BUFFER RETURNED WITH ONLY STX => " . @buffer . "\n\n +"; return; } if (($stx_rx == 0) && ($etx_rx == 0) && scalar(@buffer) > ($M +AX_BUFFER-1)) { print "\n80 bytes seen but no STX/ETX was found within 80 +byte range! " . $byte . "\n"; $retry_if_fail = 1; # Flag to tell the script to continue +waiting for the proper packet after buffer reset print "\nRetry var changed to " . $retry_if_fail . "\n"; STDOUT -> flush(); print "BUFFER RETURNED with no STX or ETX=> " . @buffer . +"\n\n"; return; } push(@buffer, $byte); #if($retry_if_fail == 0) { # until (@buffer eq chr(0x02)) # { # shift(@buffer); # } # return @buffer; #} print "Contents of buffer is " . join("",@buffer) . "\n"; print "Buffer length is " . scalar(@buffer) . "\n"; print "Byte received : ".$byte."\n"; } } while(1) { STDOUT -> flush(); if ($retry_if_fail == 1) { # FAILED CONDITION readSerialPort(); print "Total Received Packet on failure was: " . join("",@buffer) . + "\n\n"; print "Error encountered! Continuing to look for incoming packets.\ +n"; } else { # SUCCESS CONDITION print "Okay cool I found what I was looking for -> " . @buffer . " +\n\n"; print "Okay cool I found what I was looking for -> " . join("",@bu +ffer) . "\n\n"; $retry_if_fail = 0; # Time to exit this loop and get on with life! +! last; } }
All advice appreciated guys! I've tried out various ways to remove the junk data that's in front of the correct packet but to no avail. I need the packet of interest (of type: STX_PAYLOAD_ETX) without any junk on the side for processing. Ideally I want it so that the junk data is not stored at all in the buffer and only the correct packet is stored however I am having trouble in getting this to work. Thank you EDIT: What I have noticed is that reducing the value of $MAX_BUFFER (set to 80) appears to reduce the amount of junk in front however I think for me this is not an option since I need this variable to be at 79/80 for my "conditions checks" to take place properly. EDIT2: Screenshot of error: The data circled in red is the junk data whereas the data on the right of it is the packet of interest.

In reply to Buffer in Serial read routine seemingly not working?? by jagexCoder

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?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others chanting in the Monastery: (5)
    As of 2018-05-24 16:35 GMT
    Find Nodes?
      Voting Booth?