|
PacketSerial
An Arduino Library that facilitates packet-based serial communication using COBS or SLIP encoding.
|
First, it might be worth it to read the background introduction.
This project can be installed using the Arduino IDE. Navigate to the Tools > Manage Libraries ... menu item and search for PacketSerial.
Alternatively, this library can be downloaded or cloned from github and to your Arduino libraries folder.
PacketSerial class wraps the Arduino Stream class to automatically encode and decode byte packets that are sent and received. Typically serial communication uses the default Serial object, which implements the Stream class. In most cases, PacketSerial should be given exclusive access to the serial Stream (e.g. for a default setup using Serial, users should avoid calling functions like Serial.print(), Serial.write(), etc directly). Data should be sent via the send(const uint8_t* buffer, size_t size) const method and received in a PacketSerial callback function (see below).
To use the default Serial object and the default communication settings (usually SERIAL_8N1), set up PacketSerial like this:
For a non-default Serial connection, a class implementing the Stream interface should be configured and then set for the PacketSerial instance.
Any class that correctly implements the Stream interface should work, which includes some network communication objects.
In order to processing incoming serial packets, the user must call the update() method at the end of the loop() method.
All packets are received via handler functions. A typical handler function would be registered in the void setup() function like:
The onPacketReceived function can take two forms. The simplest looks like this:
For more advanced programs with multiple PacketSerial instances and a shared handler, it may be useful to know which PacketSerial instance received the packet. In this case you could define a callback like this:
Finally, it is also possible to set arbitrary packet handlers that point to member functions of a given class instance using lambda functions. For example:
To send packets call the send() method. The send method will take a packet (an array of bytes), encode it, transmit it and send the packet boundary marker. To send the values 255 and 10, one might do the following:
On boards with multiple serial ports, this strategy can also be used to set up two Serial streams, one for packets and one for debug ASCII (see this discussion for more).
In some cases the receive buffer may not be large enough for an incoming encoded packet.
To check for overflows, call the receiveBufferOverflowed() method after calling update().
For example:
The state of the overflow flag is reset every time a new packet marker is detected, NOT when the overflow() method is called.
The PacketSerial_ class is a templated class that allows us to statically set the encoder type, packet marker and buffer size at compile time.
The the template parameters are as follows:
The PacketMarker has a default of 0 while the BufferSize has a default of 256 bytes.
Thus, if you define your class as:
You will use the COBS encoder type and a default PacketMarker of 0 and buffer size of 256.
Currently there are three default PacketSerial_ types defined via typedef for convenience:
To use a custom encoding type, the EncoderType class must implement the following functions:
See the Encoding/COBS.h and Encoding/SLIP.h for examples and further documentation.
For example, to increase the buffer size for a standard COBS encoder to 512, one can defined the templated class like this:
This uses the COBS encoder type, a PacketMarker of 0 and a buffer size of 512.
Likewise, a custom SLIP encoder with a buffer size of 512 bytes would be defined like this: