Usage¶
The Message is the Payload, transmitted via a serial line (UART, I2C), byte by byte.
The Message object holds a Data buffer (an array of bytes), the size is defined by a class template parameter. And provides methods to access a specific part of the message (a specific bitfield in the message): It uses offset, in bits, and a bitmask
import microparcel
# creates a message with a 8 bytes payload
msg = microparcel.Message(size=8)
# set the 5th, 6th, 7th bits of the payload (5,6,7 of the first byte) at the value "2"
msg.set(5, 3, 2)
# set the 13th, 14th, 15th bits of the payload (5,6,7 of the second byte) at the value "3"
msg.set(13, 3, 3)
# set the 6th, 7th, 8th, 9th bits of the payload; eg:
# bits 6 and 7 of the first byte, bits 0 and 1 of the second
# at the value "1"
msg.set(6, 4, 1)
# for bisize higher that 8 (one byte), the offset must be aligned on a byte
# bitsize is limited to 16; and the rettype should be change to uint16_t
msg.set(24, 16, 0xFFAF)
# getter works in the same way:
msg.get(5, 3)
msg.get(24, 16)
Frame¶
A Frame encapsulate the Message between a StartOfFrame (SOF) and a CheckSum.
The SOF is an arbitrary value (in our case, 0xAA), and the CheckSum is the sum of all bytes, including the SOF, truncated to 8bits.
It allows a lighweight and fast data integrity validation.
Parser¶
The Parser takes bytes, and builds up a Message from the data stream.
import microparcel
serial = serial.Serial(serial_port, serial_baudrate)
# a Parser Class for Message with a Payload of 6.
TParser = microparcel.make_parser_cls(6)
parser = TParser()
# main loop
while not stop:
ser_in = serial.read()
if ser_in == "":
continue
raw_byte = ord(ser_in)
msg = microparcel.Message(size=6)
# parse byte
status = parser.parse(raw_byte, msg)
if status == parser.Status.Complete:
pass # Handles the message here
if status == parser.Status.Error:
print("Error in parsing Serial Message: recv byte = {}, current msg = {}".format(raw_byte, msg.data))
serial.close()
The Parser also encodes Message into Frames for sending data
import microparcel
serial = serial.Serial(serial_port, serial_baudrate)
# a Parser Class for Message with a Payload of 6.
TParser = microparcel.make_parser_cls(6)
parser = TParser()
def sendMsg(msg):
if serial is None:
raise FrontendError("Can't send message to the hardware, serial port not opened")
frame = parser.encode(msg)
buff = bytearray()
for d in frame.data:
buff.append(d)
serial.write(buff)
# creates a message with a 8 bytes payload
msg = microparcel.Message(size=6)
# set the 5th, 6th, 7th bits of the payload (5,6,7 of the first byte) at the value "2"
msg.set(5, 3, 2)
# set the 13th, 14th, 15th bits of the payload (5,6,7 of the second byte) at the value "3"
msg.set(13, 3, 3)
# ...
sendMsg(msg)