You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: README.md
+99-34
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ _PacketSerial_ is an small, efficient, library that allows [Arduinos](http://www
11
11
12
12
## Background
13
13
14
-
_"Why do I need this?"_ you may ask. The truth is that you may not need it if you are converting your values to ASCII strings and separating them with a known character (like a carriage return `\r` and a line feed `\n`) before sending them. This is what happens if you call and `Serial.println()`. For instance, if you just want to send a byte with the value of 255 and follow it with a new line character (i.e. `Serial.println(255)`) the Arduino automatically converts the number to the equivalent printable ASCII characters, sending 5 bytes total. As a result the receiver won't just receive a byte for the number and two bytes for the carriage return and new line character. Instead it will receive a stream of 5 bytes:
14
+
_Why do I need this?_ you may ask. The truth is that you may not need it if you are converting your values to ASCII strings and separating them with a known character (like a carriage return `\r` and a line feed `\n`) before sending them. This is what happens if you call and `Serial.println();`. For instance, if you just want to send a byte with the value of 255 and follow it with a new line character (i.e. `Serial.println(255);`) the Arduino automatically converts the number to the equivalent printable ASCII characters, sending 5 bytes total. As a result the receiver won't just receive a byte for the number and two bytes for the carriage return and new line character. Instead it will receive a stream of 5 bytes:
15
15
16
16
```
17
17
50 // ASCII '2'
@@ -21,7 +21,7 @@ _"Why do I need this?"_ you may ask. The truth is that you may not need it if yo
21
21
10 // ASCII '\n'
22
22
```
23
23
24
-
The receiver must then collect the 3 ASCII characters `{ '2', '5', '5' }`, combine them and convert them back into a single byte with a value of `255`. This process can get complicated when the user wants to send large quantities of structured data between the Arduino and a receiver.
24
+
The receiver must then collect the 3 ASCII characters { '2', '5', '5' }, combine them and convert them back into a single byte with a value of `255`. This process can get complicated when the user wants to send large quantities of structured data between the Arduino and a receiver.
25
25
26
26
One way to send a _packet_ of data without this library is to send each byte separated by a comma or space and terminate the sequence with a new line character. Thus, to send the value `255` and the value `10`, one might call:
27
27
@@ -46,7 +46,14 @@ The receiver will actually see a stream of 7 bytes:
46
46
47
47
In this case, the receiver must then collect the ASCII characters, combine them, skip the delimiter (the comma in this case) and then process the packet when a new line is encountered. While effective, this method doesn't scale particularly well. Bytes with values larger than 9 are encoded as 2 bytes and bytes with values larger than 99 are encoded as 3 bytes, etc. If the user would like to send the number 4,294,967,295 (the maximum value of a 4 byte `unsigned long`), it would be encoded as 10 bytes. This means that there is an overhead of 6 extra bytes to transmit a 4 byte `unsigned long`.
48
48
49
-
An alternative to ASCII encoding is to write the bytes directly to using the `Serial.write()` methods. These methods do not convert the byte values to ASCII. So if the user wants to send a single byte with the value of 255 and follow it with a new line character (i.e. `Serial.write(255); Serial.write('\n');`), the receiver will see a stream of 2 bytes:
49
+
An alternative to ASCII encoding is to write the bytes directly to using the `Serial.write()` methods. These methods do not convert the byte values to ASCII. So if the user wants to send a single byte with the value of `255` and follow it with a new line character:
50
+
51
+
```c++
52
+
Serial.write(255);
53
+
Serial.write('\n');
54
+
```
55
+
56
+
the receiver will see a stream of 2 bytes:
50
57
51
58
```
52
59
255 // The value transmitted.
@@ -59,82 +66,139 @@ Another coding available in PacketSerial is [Serial Line Internet Protocol](http
59
66
## Use
60
67
### PacketSerial
61
68
62
-
The `PacketSerial` class wraps the standard Arduino `Serial` class to automatically encode and decode byte packets. Thus users can still call methods on the `Serial` object (e.g. `Serial.write()`, the built in `serialEvent()` callback etc), but it is not recommended. Users are advised to let PacketSerial manage all Serial communication via the packet handler callback for incoming packets and the `send(const uint8_t* buffer, size_t size) const` method for outgoing packets. Mixing raw Serial calls with `PacketSerial`may lead to unexpected encoding and decoding results, as the endpoint will not know what data is encoded and what data is not.
69
+
`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).
63
70
64
71
### Setup
72
+
#### Basic
65
73
66
-
For Arduino boards with more than one serial port, `PacketSerial` the desired serial port can be specified with the `begin` method, i.e.
74
+
To use the default `Serial` object and the default communication settings (usually `SERIAL_8N1`), set up `PacketSerial` like this:
67
75
68
76
```c++
69
-
voidbegin(unsigned long speed, uint8_t config, size_t port = 0)
| _Arduino_ Serial Port | _PacketSerial_ Port Number |
75
-
| ------------- |:-------------:|
76
-
| `Serial` | 0 |
77
-
| `Serial1` | 1 |
78
-
| `Serial2` | 2 |
79
-
| `Serial3` | 3 |
103
+
#### Using Secondary Serial Ports (e.g. Serial1, Serial2, etc)
80
104
81
-
Alternatively, to use a software serial port or other pre-configured network stream you can use an alternate `begin` method, this time with only a `Stream*` as argument, e.g.:
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](https://github.com/bakercp/PacketSerial/issues/10) for more).
130
+
#### Other Streams
97
131
98
-
To receive decoded packets, the user should register a packet callback. The packet callback should be placed in your main Arduino Sketch and should have a method that looks like this:
132
+
Any class that correctly implements the `Stream` interface should work, which includes some network communication objects.
133
+
134
+
### Loop
135
+
136
+
In order to processing incoming serial packets, the user must call the `update()` method at the end of the `loop()` method.
99
137
100
138
```c++
101
-
void onPacket(const uint8_t* buffer, size_t size)
139
+
void loop()
102
140
{
103
-
// Process your decoded incoming packet here.
141
+
// Your program here.
142
+
143
+
144
+
// Call update to receive, decode and process incoming packets.
145
+
myPacketSerial.update();
104
146
}
147
+
105
148
```
106
149
107
-
Your callback can have any name and should be registered in the `setup()` method like this:
150
+
### Receiving Packets
151
+
152
+
All packets are received via handler functions. A typical handler function would be registered in the `void setup()` function like:
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:
// Do something with the packet from myPacketSerial.
182
+
}
183
+
else if (sender == &myOtherPacketSerial)
184
+
{
185
+
// Do something with the packet from myOtherPacketSerial.
186
+
}
123
187
}
124
188
125
189
```
126
190
127
191
### Sending Packets
128
192
129
-
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 (usually `0`). To send the values 255 and 10, one might do the following:
193
+
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:
130
194
131
195
```c++
132
196
133
197
// Make an array.
134
-
uint8_t myPacket[] { 255, 10 };
198
+
uint8_t myPacket[2] = { 255, 10 };
135
199
136
200
// Send the array.
137
-
serial.send(myPacket, 2);
201
+
myPacketSerial.send(myPacket, 2);
138
202
```
139
203
140
204
## Examples
@@ -151,5 +215,6 @@ See the included examples for further usage options.
0 commit comments