From e7f8de347c595a69bf6a82c280cbb1f0e2336a64 Mon Sep 17 00:00:00 2001 From: Lyubomir Penev Date: Sun, 25 Jan 2026 17:22:02 +0100 Subject: [PATCH] Added high level comms overview --- README.md | 15 ++++++++++++--- docs/CommsProtocol.png | Bin 0 -> 31307 bytes 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 docs/CommsProtocol.png diff --git a/README.md b/README.md index a1c5020..3636eff 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,23 @@ -# Example Arduino Code For The Serial Communications Protocol +# Example Arduino Code For Serial Communications Protocol This is an Arduino example/library of my serial communications protocol which implements checksums, acknowledge and repeat commands to normal serial communication, while still keeping the end user experience simple and intuitive. ## Command Packet Contents + Bellow is an illustration of a command packet which is sent out by the library. ![image](docs/CommandPacket.png) Each command packet consists of an instructions packet, a checksum and an end bit, with each part being seperated by a separator bit. The istructions packet consists of a command and a data part, which are again separated by a bit. In the current form of the protocol the separator bit is a `#` and the terminator bit is a `@`. -An example command would look something like this `ERR#Something went wrong#4324@`. In the above example we are sending a command `ERR` with the arguments of `Something went wrong` and the `4324` is an auto generated checksum. +An example command would look something like this `ERR#Something went wrong#4342@`. In the that example we are sending a command `ERR` with the arguments of `Something went wrong` and the `4342` is an auto generated checksum. -All the data is currently being transmitted in plain-text, however in future versions of the library they will be encoded in hex and sent that way. \ No newline at end of file +All the data is currently being transmitted in plain-text, however in future versions of the library they will be encoded in hex and sent that way. + +## High Level Communications Overview + +Bellow is a high level overview on how the communications protocol works and what gets sent between the two communicating devices. The left side of the diagram represents the communication when the command arrives to the receiver intact and on the right is a representation of what happens when the checksum is wrong(i.e. The command packet is malformed). + +![image](docs/CommsProtocol.png) + +It is important to note that the user never sees the ACKG/RPT commands be sent or the validation process take place. All the end user sees is the action assigned to a given command be executed once it's been confirmed as intact. \ No newline at end of file diff --git a/docs/CommsProtocol.png b/docs/CommsProtocol.png new file mode 100644 index 0000000000000000000000000000000000000000..01c61b10bb647fffcbd7ec8924a37d524f74c7a0 GIT binary patch literal 31307 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 aEnTUbT8d6!Uj|cwr>dx_P%L*T@c#j4Zf$A+ literal 0 HcmV?d00001