Serial communicator enabling to communicated with a peripheral device over a Channel using binary messages. The first 2 bytes of every message have a fixed semantic:
| CRC|KIND|...
|0xXX|0xYY|...
First byte is a checksum and the second byte is a MessageKind. The rest of the message depends on the implementation of a concrete MessageKind. The maximum length of a message is determined by the Channel.maxPacketSize. If necessary a message needs to be split to different packets.
A communicator manages three threads: connection thread, inbound thread, and outbound thread.
The connection thread in State.CONNECTING interrupts both, inbound and outboud, communication threads, if such are alive. Clean up the connection and tries to start new set of inbound and outbound communication threads. In all other states it just sleeps.
The inbound thread waits for nextMessage, which is expected to be implemented as a blocking function. Only non empty messages are considered.
First byte of that message is extracted as a message-checksum calculated by the sender. Then the rest of the message is used to calculate a checksum on the receiver side. If both, the received and the calculated, checksums match, the message is considered as valid for further processing. Otherwise, the message is discarded.
A MessageKind is then determined based on the second byte. All non-CRC messages a CRC checksum is send back to the sender containing the calculated checksum:
| CRC|KIND|CONTENT|
|0xXX|0x00| 0xXX |
A MessageKind.CRC message will store the received CRC to compare with the last sent message. This way the communicator determines when a sent message was successfully received by the other side.
A MessageKind.IDD message implements a protocol to initialize a connection and determine its stability.
Any other MessageKind will be simply forwarded using the CommunicatorListener.onMessageReceived and has to be implemented further.
Last, the outbound thread monitors 2 queues: the checksum queue and the message queue. The checksum queue has priority over the message queue. The checksum queue contains a list of checksum bytes of recently received messages to be confirmed to the sender. The message queue contains a list of binary messages to be send to the receiver without the checksum byte (the 1st byte). The checksum will be calculated freshly before any send attempt.
The following flows and situactions are considered during communication between the sender and the receiver. Both side share this implementation:
In good case transmitting a message works first time and is being confirmed right-away:
One typical error case is when a message does not reach its target. In this case the message is resend again after a certain timeout (by default 500ms - MESSAGE_CONFIRMATION_TIMEOUT, but can be overwritten for different MessageKind - MessageKind.delay).
In the same way it may happen, that the message got received corretly, but the CRC was not. Each MessageKind needs to be implemented in a idempotent way so receiving multiple same messages after each other should not result in errors.
To prevent resent starvation, one message is retried up to 20 times by default (MAX_SEND_ATTEMPTS) and then it is dropped. The developer is responsible for resolution of such situations.
The connection can be in one of the following states:
|==============|
| (A) CRC |
|--------------|
| 0 | 1 | 2 |
| CRC|KIND| CRC|
|==============|
- CRC : Checksum of the packet
- KIND: Message kind
ID of device message
|=============================|
| (A) Ping |
|-----------------------------|
| 0 | 1 | 2 | |
| CRC|KIND| RND| |
|=============================|
| (B) State |
|-----------------------------|
| 0 | 1 | 2 | 3 | |
| CRC|KIND| RND|STAT| |
|=============================|
| (B) Response |
|-----------------------------|
| 0 | 1 | 2 | 3 | 4... 5 |
| CRC|KIND|0x00|STAT| PAYLOAD |
|=============================|
CRC
: Checksum of the packetKIND
: Message kindRND
: Random number to force different CRCSTAT
: Requested state0x00
: Request capabilities0x01
: Request device name
PAYLOAD
: Payload A, depending onSTAT
:0x00
: Capabilities. Bits:0
: Bluetooth connectivity1
: USB connectivity2
: Temperature, Humidity sensor3
: LCD capability4
: Registry available5
: Motion sensor6
: N/A7
: N/A8
: RGB strip9
: RGB LEDs (e.g. WS281x)10
: RGB LED Light (e.g. ES281x)11
: N/A12
: N/A13
: N/A14
: N/A15
: N/A
0x01
: Device name
|========================|
| (A) Request w/ part |
|------------------------|
| 0 | 1 | 2 | | |
| CRC|KIND|PART| | |
|========================|
| (B) Response w/ part |
|------------------------|
| 0 | 1 | 2 | 3 | |
| CRC|KIND|PART|CKSM| |
|========================|
CRC
: Checksum of the packetKIND
: Message kindPART
: Part to checkCKSM
: State machine checksum
|============================================|
| (A) Pull |
|--------------------------------------------|
| 0 | 1 | 2 | | | | | | |
| CRC|KIND|PART| | | | | | |
|============================================|
| (A) Pull part using starting address |
|--------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | | |
| CRC|KIND|PART|ADRH|ADRL|LENH|LENL| | |
|============================================|
| (B) Push |
|--------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7...X |
| CRC|KIND|PART|ADRH|ADRL|LENH|LENL| DATA |
|============================================|
CRC
: Checksum of the packetKIND
: Message kindNUM
: Data number/IDADRH
: Starting address in this packet high byteADRL
: Starting address in this packet low byteLENH
: Length high byteLENL
: Length low byteDATA
: Data till end of the packet
Plain message
|===================|
| (A) Plain message |
|-------------------|
| 0 | 1 | 2...LEN|
| CRC|KIND| DATA |
|===================|
CRC
: Checksum of the packetKIND
: Message kindDATA
: Message
|===================|
| (A) Request |
|-------------------|
| 0 | 1 | 2 | |
| CRC|KIND|PORT| |
|===================|
| (B) Set/Response |
|-------------------|
| 0 | 1 | 2 | 3 |
| CRC|KIND|PORT| BIT|
|===================|
CRC
: Checksum of the packetKIND
: Message kindPORT
: IO port numberBIT
: Bit value,BIT & 0x80
means setting, otherwise it is a response.
|=============================|
| (A) Request sensor count |
|-----------------------------|
| 0 | 1 | | | | |
| CRC|KIND| | | | |
|=============================|
| (B) Response sensor count |
|-----------------------------|
| 0 | 1 | 2 | 3 | | |
| CRC|KIND|0xFF| CNT| | |
|=============================|
| (C) Request |
|-----------------------------|
| 0 | 1 | 2 | | | |
| CRC|KIND| NUM| | | |
|=============================|
| (D) Response |
|-----------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 |
| CRC|KIND| NUM| TEMPx10 | RH |
|=============================|
CRC
: Checksum of the packetKIND
: Message kindNUM
: DHT11 numberCNT
: CountTEMPx10
: Temperature in °C multiplied by 10 (TEMP = TEMPx10 / 10
)RH
: Relative humidity in %
LCD display message
|=======================================|
| (A) Request LCD count |
|---------------------------------------|
| 0 | 1 | | | | | | |
| CRC|KIND| | | | | | |
|=======================================|
| (B) Response LCD count |
|---------------------------------------|
| 0 | 1 | 2 | | | | | |
| CRC|KIND| CNT| | | | | |
|=======================================|
| (C) Request a line |
|---------------------------------------|
| 0 | 1 | 2 | 3 | | | | |
| CRC|KIND| NUM|LINE| | | | |
|=======================================|
| (D) Send/receive command |
|---------------------------------------|
| 0 | 1 | 2 | 3 | 4 | | | |
| CRC|KIND| NUM|0xFF| CMD| | | |
|=======================================|
| (E) Set/Response |
|---------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6...X |
| CRC|KIND| NUM| CMD|LINE| LEN| VAL |
|---------------------------------------|
| X = 6 + LEN |
|=======================================|
CRC
: Checksum of the packetKIND
: Message kindNUM
: LCD device num (to support multiple displaysCMD
:0x7B
= Clear display (only in B)0x7C
= Reset display (only in B)0x7D
= Backlight0x7E
= No backlight
LINE
: Line -LINE = 0x80
will request all lines. This limits the number of lines to128
. IfLINE >= 0x80
means to request a item on indexLINE - 0x7F
and continue withLINE + 1
.LEN
: Value lengthVAL
: Value
|=======================================|
| (A) Request all registries |
|---------------------------------------|
| 0 | 1 | 2 | | | | | |
| CRC|KIND|ADDR| | | | | |
|=======================================|
| (B) Request a registry |
|---------------------------------------|
| 0 | 1 | 2 | 3 | | | | |
| CRC|KIND|ADDR| REG| | | | |
|=======================================|
| (C) Response/Write a registry |
|---------------------------------------|
| 0 | 1 | 2 | 3 | 4 | | | |
| CRC|KIND|ADDR| REG| VAL| | | |
|=======================================|
| (D) Response/Write multiple registries|
|---------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 ... CNT |
| CRC|KIND|ADDR| REG| CNT| VAL1...VALx |
|=======================================|
CRC
: Checksum of the packetKIND
: Message kindADDR
: SPI/I2C addressREG
: (Starting) Registry.CNT
: Registry countVAL
: Value
|=====================================================================|
| (A) Request strip count |
|---------------------------------------------------------------------|
| 0 | 1 | | | | | | | | | | | | |
| CRC|KIND| | | | | | | | | | | | |
|=====================================================================|
| (B) Response strip count |
|---------------------------------------------------------------------|
| 0 | 1 | 2 | | | | | | | | | | | |
| CRC|KIND|SCNT| | | | | | | | | | | |
|=====================================================================|
| (C) Request a configuration item of a strip |
|---------------------------------------------------------------------|
| 0 | 1 | 2 | 3 | | | | | | | | | | |
| CRC|KIND| NUM| IDX| | | | | | | | | | |
|=====================================================================|
| (D) Set configuration of a strip |
|---------------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7...8 | 9 | 10| 11 | | |
| CRC|KIND| NUM|PATN| R | G | B | DELAY | MIN| MAX|TOUT| | |
|=====================================================================|
| (E) Response |
|---------------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9...10 | 11 | 12 | 13 |
| CRC|KIND| NUM| CNT| IDX|PATN| R | G | B | DELAY | MIN| MAX|TOUT|
|=====================================================================|
CRC
: Checksum of the packetKIND
: Message kindSCNT
: Strip countNUM
: Strip numberCNT
: Configuration count.IDX
: Index of item to request.IDX & 0x80
will request all items. This limits the number of items in a list to128
.IDX > 0x80
means to request a item on indexIDX - 0x7F
and continue withIDX + 1
.PATN
: Animation pattern.PATN & 0x80
will replace the list with this one item, otherwise a new item will be added to the end of the list.0x00
: Off0x01
: Light0x02
: Blink0x03
: Fade in0x04
: Fade out0x05
: Fade in/out
R
,G
,B
: Red, green and blue component of the requested colorDELAY
: Animation delay (depends on pattern implementation)MIN
,MAX
: Minimum and maximum color values (depends on pattern implementation)TOUT
: Number of times to repeat pattern animation before switching to next item in the list
|================================================================|
| (A) Request strip count |
|----------------------------------------------------------------|
| 0 | 1 | | | | | | | | | | | |
| CRC|KIND| | | | | | | | | | | |
|================================================================|
| (B) Response strip count |
|----------------------------------------------------------------|
| 0 | 1 | | | | | | | | | | | |
| CRC|KIND|SCNT| | | | | | | | | | |
|================================================================|
| (C) Request an LED |
|----------------------------------------------------------------|
| 0 | 1 | 2 | 3 | | | | | | | | | |
| CRC|KIND| NUM| LED| | | | | | | | | |
|================================================================|
| (D) Set all LEDs |
|----------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | | | | | | | |
| CRC|KIND| NUM| R | G | B | | | | | | | |
|================================================================|
| (E) Configuration for concrete strip and LED |
|----------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4| 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
| CRC|KIND| NUM| LED|PATN| R | G | B | DELAY | MIN| MAX| |
|================================================================|
| (F) Response |
|----------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| CRC|KIND| NUM| CNT| LED|PATN| R | G | B | DELAY | MIN| MAX|
|================================================================|
CRC
: Checksum of the packetKIND
: Message kindSCNT
: Strip countNUM
: Strip numberCNT
: LED count in the stripLED
: LED index.LED & 0x80
will request all LEDs. This limits the number of LEDs to128
.LED > 0x80
means to request a LED on indexLED - 0x7F
and continue withLED + 1
.PATN
: Animation pattern.0x00
: Off0x01
: Light0x02
: Blink0x03
: Fade in0x04
: Fade out0x05
: Fade in/out
R
,G
,B
: LED colorDELAY
: Animation delay (depends on pattern implementation)MIN
,MAX
: Minimum and maximum color values (depends on pattern implementation)
|===============================================================================|
| (A) Request light count |
|-------------------------------------------------------------------------------|
| 0 | 1 | | | | | | | | | | | | | | |
| CRC|KIND| | | | | | | | | | | | | | |
|===============================================================================|
| (B) Response light count |
|-------------------------------------------------------------------------------|
| 0 | 1 | | | | | | | | | | | | | | |
| CRC|KIND|SCNT| | | | | | | | | | | | | |
|===============================================================================|
| (C) Request an configuration item of a light |
|-------------------------------------------------------------------------------|
| 0 | 1 | 2 | 3 | | | | | | | | | | | | |
| CRC|KIND| NUM| IDX| | | | | | | | | | | | |
|===============================================================================|
| (D) Add/set configuration for concrete strip NUM |
|-------------------------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 ... 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | |
| CRC|KIND| NUM|PATN| RGB0...RGB6 | DELAY | W | FAD| MIN| MAX|TOUT| | |
|===============================================================================|
| (E) Response |
|-------------------------------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 ... 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
| CRC|KIND| NUM| CNT| IDX|PATN| RGB0...RGB6 | DELAY | W | FAD| MIN| MAX|TOUT|
|===============================================================================|
CRC
: Checksum of the packetKIND
: Message kindSCNT
: Strip countNUM
: Strip numberCNT
: Item countIDX
: Index of item to request. In (A)IDX & 0x80
will request all items. This limits the number of items in a list to128
.IDX > 0x80
means to request a item on indexIDX - 0x7F
and continue withIDX + 1
.PATN
: Animation pattern.PATN & 0x80
will replace the list with this one item, otherwise a new item will be added to the end of the list.0x00
: Off0x01
: Light0x02
: Blink0x03
: Fade in0x04
: Fade out0x05
: Fade in/out0x06
: Fade toggle0x07
: Rotation0x08
: Wipe0x09
: Lighthouse0x0A
: Chaise0x0B
: Theater
RGBx
: 7 colors (x = 0..6
), each consists of 3 bytes in theR
,G
,B
order (7 * 3 = 21 bytes
)DELAY
: Animation delay (depends on pattern implementation)W
: Animation width (depends on pattern implementation)FAD
: Animation fading (depends on pattern implementation)MIN
,MAX
: Minimum and maximum color values (depends on pattern implementation)TOUT
: Number of times to repeat pattern animation before switching to next item in the list
|==================================|
| (A) Request |
|----------------------------------|
| 0 | 1 | | | | | |
| CRC|KIND| | | | | |
|==================================|
| (B) Set/Response |
|----------------------------------|
| 0 | 1 | 2 | 3...8 | 9...24 |
| CRC|KIND|PMOD| PIN | NAME |
|==================================|
CRC
: Checksum of the packetKIND
: Message kindPMOD
: Pairing mode0x00
: PIN0x01
: Just Work0x02
: Passkey0x03
: User confirmation
PIN
: PIN codeNAME
: Device name
|===========================================================|
| (A) Set/Action |
|-----------------------------------------------------------|
| 0 | 1 | 2 | 3 | 4 | 5...LEN1| .. | | | ...LENx|
| CRC|KIND| CNT|DEV1|LEN1| DATA1 | .. |DEVx|LENx| DATAx |
|===========================================================|
CRC
: Checksum of the packetKIND
: Message kindCNT
: State countDEVx
: Device of statex
LENx
: Length of statex
DATAx
: Data of statex
|=============================|
| (A) Input |
|-----------------------------|
| 0 | 1 | 2 | 3 | 4...LEN|
| CRC|KIND| NUM| LEN| VALUE |
|=============================|
CRC
: Checksum of the packetKIND
: Message kindNUM
: NumLEN
: LengthVALUE
: Value
Not applicable (N/A)
Not applicable (N/A)
This library is licensed under GNU Lesser General Public License (LGPL) 3.0