Rolling over before reaching 256 (8051)Started by 3 years ago●7 replies●latest reply 3 years ago●94 views
I have an idea where I can transmit data on the packet to avoid byte stuffing. The way I would do it is to limit the possible byte combinations to one of 253 (instead of 256) since four are used for synchronizing data, and stop and start markers.
Sometimes the data I want to put in the packet is a 24-bit number.
The problem I have which I think seems ridiculously simple to solve which I can't figure out is how to convert a normal 24-bit number to one that I can fit within the packet requirements.
I know that dividing each byte in the original number by 64 works but it slows down the processor and I lose lots of possible number combinations for the 24-bit number itself.
So what I'm looking for is a code that can do this:
Take the low byte of the 24-bit number and if it's between 252 and 255 then replace it with something unique and flag it. Then same with the remaining two bytes of the 24-bit number.
Now if my problem was that each byte can't go past 255 instead of 252, then my problem would be solved as follows if my 24-bit number was B:DPTR (where B is the high 8-bits)
mov A,DPL add A,#1h mov DPL,A mov A,DPH addc A,#0h mov DPH,A mov A,B addc A,#0h mov B,A
But how would I do it so that when I convert any 24-bit number to the bytes to transmit in the packet, that each byte would never be equal to 253, 254, or 255?
It sounds like you’re trying to reserve a few byte values for control, but if these values show up in your data, you need to replace them so your serial communication doesn’t de-synchronize. There’s a good article on this site from @jms_nh covering constant-overhead byte stuffing.
This technique allows you to transform your data packet to replace data bytes which otherwise would mimic synchronization bytes to the protocol. It’s definitely worth checking out
Yes! COBS is a great approach, it allows you to use a single 0x00 between packets to delimit packet boundaries. COBS guarantees 0x00 doesn't appear in the encoded packet data, You no longer need a unique start-of-packet byte. You could still use one if you find it comforting, but replacing it with your packet byte count makes more sense. For your short packets the encoding overhead will be 0 or 1 additional byte.
Seems like I made this suggestion last spring or summer in an earlier thread of yours, and buffer storage was an issue. You can decode on-the-fly as bytes are received, but transmit requires a buffer for the encoded packet.
I already am implementing that, but that counteracts another thing I'm trying to achieve in my project which is speed.
With COBS, an extra byte (called escape character) is introduced each time I use one of the special characters as data.
The more bytes there are to transmit, the longer it takes for transmission to complete.
Take a look at either uuencode or base64. They both transform a 3-byte (i.e. 24-bit) block to 4 bytes where all 4 bytes are printable ASCII characters.
uuencode has been in use for about half a century, base64 maybe 25-30 years.
Uuencode with 1 byte overhead is a great idea. You wouldn't even need to encode in this case, just send the four 6-bit values in a byte with 00 in the two MS bits.
If you have a fixed format packet, would it help if you know which byte is the start of the packet. You could use the 9th bit option on the 8051 to indicate the first byte.
Alternatively, Although the 9th bit is sometimes called the address bit, it is not restricted to that. If you wanted to indicate a 4 byte number that needed special attention (e.g. numbers greater than 253) then you could set the flag for those bytes.
It sounds like you want to be able to encode 256^3 possible values with only 253^3 encodings? This is like looking for a way to encode 4 values in 2 bits using only 3 of the 4 possible 2 bit encodings. Perhaps I'm missing something, but I don't think you can get there.