Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re: Buffer in Serial read routine seemingly not working??

by graff (Chancellor)
on Dec 03, 2012 at 00:02 UTC ( #1006768=note: print w/replies, xml ) Need Help??

in reply to Buffer in Serial read routine seemingly not working??

I'm not sure I understand your script, but let me see if I at least understand your task. What follows is actually a different plan from what you seem to be trying to do in the OP code, but (if I understand what you said about your sample data strings) I think it might be a useful approach (and might be easier to implement, relative to what you've tried so far):

  1. You want to read bytes continuously from a serial port
  2. Every time you receive STX (0x02), you want start capturing/storing input
  3. Having started capture/storage, you want to stop it when you receive ETX (0x03) and do something with the stored byte sequence, clear the capture buffer, and return to step 2.
  4. But if you get NAK (0x15) or if more than 79 (80?) bytes get stored before receiving ETX, you want to ditch the capture buffer without further ado and return to step 2.
  5. Something you didn't mention (but should be considered): if a second STX arrives before an ETX, NAK or 80 bytes have appeared, you should either treat this 2nd STX as data, or else ditch the capture buffer and start a fresh capture.

In other words, a simple 2-state machine would do what you want. The initial state stores nothing and just watches for STX. Once STX is found, you switch to storing input and looking for ETX. You'll stop storing when either ETX or NAK is found or when 80 bytes are stored, whichever comes first, and return to the initial state; if ETX was found first, you'll do something with the stored data, otherwise you'll ditch it.

If that isn't what you meant to describe, please try again to see if you can explain the task more clearly. If that is what you meant, then that description should lead you to a fairly simple script, along the lines of:

my $capture_state = 0; # looking for STX my @buffer; while (1) { $byte = $port->read(1); if ( $byte == 0x02 ) { # got STX $capture_state = 1; @buffer = (); # (if we were already capturing for a prev STX, + ditch that) } if ( $capture_state ) { if ( $byte == 0x15 or @buffer > 79 ) { # got NAK or too many +bytes @buffer = (); $capture_state = 0; } else { push @buffer, $byte; if ( $byte == 0x03 ) { # got ETX printf "Received complete message of %d bytes:", scala +r @buffer; printf " %02x" for ( @buffer ); print "\n"; @buffer = (); $capture_state = 0; } } } }
If you want a 2nd STX in the input to be treated as data, just comment out the @buffer = (); line in the first "if" clause.

(update: made a minor fix to the 2nd "printf" format, to put a space between consecutive byte values)

Replies are listed 'Best First'.
Re^2: Buffer in Serial read routine seemingly not working??
by Anonymous Monk on Dec 03, 2012 at 05:26 UTC
    Thank you so much!! With some slight modifications this solution is working perfectly! :-) have a nice day.
Re^2: Buffer in Serial read routine seemingly not working??
by Anonymous Monk on Dec 03, 2012 at 00:39 UTC
    Yup you hit the hammer on the nail! I'll try out your advice later on today. Thank you
Re^2: Buffer in Serial read routine seemingly not working??
by Anonymous Monk on Dec 03, 2012 at 02:56 UTC
    So as per your method I would not be modifying my serial read() routine, just the infinite while loop I have at the bottom. Did I get that right? Thanks!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1006768]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2017-11-20 04:58 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (284 votes). Check out past polls.