PacketSerial
An Arduino Library that facilitates packet-based serial communication using COBS or SLIP encoding.
PacketSerial.h
1 //
2 // Copyright (c) 2013 Christopher Baker <https://christopherbaker.net>
3 //
4 // SPDX-License-Identifier: MIT
5 //
6 
7 
8 #pragma once
9 
10 
11 #include <Arduino.h>
12 #include "Encoding/COBS.h"
13 #include "Encoding/SLIP.h"
14 
15 
27 template<typename EncoderType, uint8_t PacketMarker = 0, size_t ReceiveBufferSize = 256>
29 {
30 public:
39  typedef void (*PacketHandlerFunction)(const uint8_t* buffer, size_t size);
40 
50  typedef void (*PacketHandlerFunctionWithSender)(const void* sender, const uint8_t* buffer, size_t size);
51 
54  _receiveBufferIndex(0),
55  _stream(nullptr),
56  _onPacketFunction(nullptr),
57  _onPacketFunctionWithSender(nullptr)
58  {
59  }
60 
63  {
64  }
65 
84  void begin(unsigned long speed)
85  {
86  Serial.begin(speed);
87  #if ARDUINO >= 100 && !defined(CORE_TEENSY)
88  while (!Serial) {;}
89  #endif
90  setStream(&Serial);
91  }
92 
97  void begin(unsigned long speed, size_t port) __attribute__ ((deprecated))
98  {
99  switch(port)
100  {
101  #if defined(UBRR1H)
102  case 1:
103  Serial1.begin(speed);
104  #if ARDUINO >= 100 && !defined(CORE_TEENSY)
105  while (!Serial1) {;}
106  #endif
107  setStream(&Serial1);
108  break;
109  #endif
110  #if defined(UBRR2H)
111  case 2:
112  Serial2.begin(speed);
113  #if ARDUINO >= 100 && !defined(CORE_TEENSY)
114  while (!Serial1) {;}
115  #endif
116  setStream(&Serial2);
117  break;
118  #endif
119  #if defined(UBRR3H)
120  case 3:
121  Serial3.begin(speed);
122  #if ARDUINO >= 100 && !defined(CORE_TEENSY)
123  while (!Serial3) {;}
124  #endif
125  setStream(&Serial3);
126  break;
127  #endif
128  default:
129  begin(speed);
130  }
131  }
132 
136  void begin(Stream* stream) __attribute__ ((deprecated))
137  {
138  _stream = stream;
139  }
140 
169  void setStream(Stream* stream)
170  {
171  _stream = stream;
172  }
173 
181  Stream* getStream()
182  {
183  return _stream;
184  }
185 
193  const Stream* getStream() const
194  {
195  return _stream;
196  }
197 
209  void update()
210  {
211  if (_stream == nullptr) return;
212 
213  while (_stream->available() > 0)
214  {
215  uint8_t data = _stream->read();
216 
217  if (data == PacketMarker)
218  {
219  if (_onPacketFunction || _onPacketFunctionWithSender)
220  {
221  uint8_t _decodeBuffer[_receiveBufferIndex];
222 
223  size_t numDecoded = EncoderType::decode(_receiveBuffer,
224  _receiveBufferIndex,
225  _decodeBuffer);
226 
227  if (_onPacketFunction)
228  {
229  _onPacketFunction(_decodeBuffer, numDecoded);
230  }
231  else if (_onPacketFunctionWithSender)
232  {
233  _onPacketFunctionWithSender(this, _decodeBuffer, numDecoded);
234  }
235  }
236 
237  _receiveBufferIndex = 0;
238  _recieveBufferOverflow = false;
239  }
240  else
241  {
242  if ((_receiveBufferIndex + 1) < ReceiveBufferSize)
243  {
244  _receiveBuffer[_receiveBufferIndex++] = data;
245  }
246  else
247  {
248  // The buffer will be in an overflowed state if we write
249  // so set a buffer overflowed flag.
250  _recieveBufferOverflow = true;
251  }
252  }
253  }
254  }
255 
270  void send(const uint8_t* buffer, size_t size) const
271  {
272  if(_stream == nullptr || buffer == nullptr || size == 0) return;
273 
274  uint8_t _encodeBuffer[EncoderType::getEncodedBufferSize(size)];
275 
276  size_t numEncoded = EncoderType::encode(buffer,
277  size,
278  _encodeBuffer);
279 
280  _stream->write(_encodeBuffer, numEncoded);
281  _stream->write(PacketMarker);
282  }
283 
302  {
303  _onPacketFunction = onPacketFunction;
304  _onPacketFunctionWithSender = nullptr;
305  }
306 
339  void setPacketHandler(PacketHandlerFunctionWithSender onPacketFunctionWithSender)
340  {
341  _onPacketFunction = nullptr;
342  _onPacketFunctionWithSender = onPacketFunctionWithSender;
343  }
344 
369  bool overflow() const
370  {
371  return _recieveBufferOverflow;
372  }
373 
374 private:
376  PacketSerial_& operator = (const PacketSerial_&);
377 
378  bool _recieveBufferOverflow = false;
379 
380  uint8_t _receiveBuffer[ReceiveBufferSize];
381  size_t _receiveBufferIndex = 0;
382 
383  Stream* _stream = nullptr;
384 
385  PacketHandlerFunction _onPacketFunction = nullptr;
386  PacketHandlerFunctionWithSender _onPacketFunctionWithSender = nullptr;
387 };
388 
389 
392 
395 
void(* PacketHandlerFunctionWithSender)(const void *sender, const uint8_t *buffer, size_t size)
A typedef describing the packet handler method.
Definition: PacketSerial.h:50
void begin(unsigned long speed, size_t port) __attribute__((deprecated))
Deprecated. Use setStream() to configure a non-default port.
Definition: PacketSerial.h:97
void setPacketHandler(PacketHandlerFunctionWithSender onPacketFunctionWithSender)
Set the function that will receive decoded packets.
Definition: PacketSerial.h:339
const Stream * getStream() const
Get a pointer to the current stream.
Definition: PacketSerial.h:193
void(* PacketHandlerFunction)(const uint8_t *buffer, size_t size)
A typedef describing the packet handler method.
Definition: PacketSerial.h:39
bool overflow() const
Check to see if the receive buffer overflowed.
Definition: PacketSerial.h:369
void setPacketHandler(PacketHandlerFunction onPacketFunction)
Set the function that will receive decoded packets.
Definition: PacketSerial.h:301
Stream * getStream()
Get a pointer to the current stream.
Definition: PacketSerial.h:181
~PacketSerial_()
Destroy the PacketSerial_ device.
Definition: PacketSerial.h:62
void update()
The update function services the serial connection.
Definition: PacketSerial.h:209
void setStream(Stream *stream)
Attach PacketSerial to an existing Arduino Stream.
Definition: PacketSerial.h:169
PacketSerial_()
Construct a default PacketSerial_ device.
Definition: PacketSerial.h:53
void begin(unsigned long speed)
Begin a default serial connection with the given speed.
Definition: PacketSerial.h:84
void begin(Stream *stream) __attribute__((deprecated))
Deprecated. Use setStream() to configure a non-default port.
Definition: PacketSerial.h:136
A template class enabling packet-based Serial communication.
Definition: PacketSerial.h:28
void send(const uint8_t *buffer, size_t size) const
Set a packet of data.
Definition: PacketSerial.h:270