Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Help adding STX and ETX to data string in Perl

by BillKSmith (Monsignor)
on Jul 20, 2022 at 22:48 UTC ( [id://11145615]=note: print w/replies, xml ) Need Help??


in reply to Help adding STX and ETX to data string in Perl

Let sprintf do all the work.
use strict; use warnings; sub myMessage { my $payload = shift; my $format = "\N{STX}" . '%08u' # Byte count . '0' x 8 # Reserved . '%s' # Pay load . "\N{ETX}" ; return sprintf $format, 18 + length($payload), $payload; } my $result = myMessage("<PAYLOAD>"); print $result, "\n"; print unpack 'H*', $result;

RESULT:

>perl CuriousMark.pl .0000002700000000<PAYLOAD>. 02303030303030323730303030303030303c5041594c4f41443e03 >

Note: Non-printing characters replaced with '.' in forum only. Hex dump is accurate.

Bill

Replies are listed 'Best First'.
Re^2: Help adding STX and ETX to data string in Perl
by cavac (Parson) on Jul 21, 2022 at 06:22 UTC

    Hex encoding is very inefficient to handle because it's a non-contiguous part of the ASCII table. I usually use "cavcode"(*), because that's easy to implement in most programming languages, including in C for stuff like Arduinos. And of course it works very well with framing bytes.

    sub frame2packet { my @frame = @_; my $packet = ''; foreach my $byte (@frame) { my $lowbyte = ($byte & 0x0f) + 65; my $highbyte = ($byte >> 4) + 65; $packet .= chr($highbyte); $packet .= chr($lowbyte); } return $packet; } sub packet2frame { my $packet = shift; my @chars = split//, $packet; my @frame = (); # Decode to bytes while(@chars) { my $high = shift @chars; my $low = shift @chars; my $val = ((ord($high) - 65) << 4) + (ord($low) - 65); push @frame, $val; } return @frame; }

    Writing, for example, the counterpart encoder for Arduino is also quite easy. No need for a lookup table and stuff, this can be done with very low RAM usage:

    highbyte = 0x02; Serial.write(highbyte); for(inoffs = 0; inoffs < PKT_LEN; inoffs++) { intmpbyte = inpacket[inoffs]; highbyte = ((intmpbyte >> 4) & 0x0f) + 65; lowbyte = (intmpbyte & 0x0f) + 65; Serial.write(highbyte); Serial.write(lowbyte); } highbyte = 0x03; Serial.write(highbyte);

    (*) cavcode stands for "cavac encode". Yes, named it after myself, and nobody can stop me.

    PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
      Note: There is absolutely no "hex encoding" in my solution. I added a hex dump of my result in order to display the control characters (and ASCII zero's) unambiguously in this forum.
      Bill

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11145615]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-16 22:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found