2026-01-25 15:36:43 +01:00
2026-01-25 17:22:02 +01:00
2026-01-25 15:36:43 +01:00
2026-01-25 18:24:49 +01:00
2026-01-25 15:36:43 +01:00
2026-01-25 15:36:43 +01:00
2026-01-25 15:36:43 +01:00
2026-01-25 18:24:49 +01:00

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

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#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.

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

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.

Using The Library

This section describes how to get the library working in a project of your own.

Importing Into A New Project

To import the library in to a project of your own there are only two files you need to bring in. One is src/serialConnector.cpp and the other is its associated header file include/serialConnector.h. Once those two are coppied these two in to your project make sure the includes are still correct. Then in your main.cpp you need to create a new instance of the SerialConnector class and to parse any incomming commands you need to call the newly created instance's cycle method. Bellow is an example of what that would look like.

#include <serialConnector.h>

SerialConnector *conn = new SerialConnector()

void setup() {}

void loop()
{
    conn->cycle();
}

Any time the cycle method is called it scans the serial buffer for any new commands and if there's something it processes those incomming commands it automatically processes that command, checks it's integrity and executes any handler functions associated with it.

Sending A Command

The instance of the SerialConnector class contains a method called sendCommand which takes in two parameters as Strings. The first parameter is the name of the command being sent and the second parameter are any arguments associated with the command. So if we wanted to send the example command from above ERR#Something went wrong#4342@ it would look something like this

#include <serialConnector.h>

SerialConnector *conn = new SerialConnector()

void setup() {}

void loop()
{
    conn->sendCommand("ERR", "Something went wrong");
}

The code above will automatically generate the command packet and send it, and process the incomming acknowledge or repeat packets from the receiver.

Registering A New Command

Registering new commands is by far the most difficult part of using the library, however it is still quite easy to do. Since the library works on the principle of event based call-back functions they need to be created and registered. The way that is done is by first creating the definitions for the handler functions and the and their registration functions.

Creating handler definitions

To do that first open the serialConnector.h file and go to the Command Handlers section near the top of the file. This is where you need to create a function pointer which takes in a string as an argument and follows the naming convention <COMMAND NAME>Handler. So if we were to register a handler for a function called error it would look something like this.

void (*errorHandler)(String args);

NOTE: Make sure that you surround the function name with brackets

Then you also need to create the definition for the registration function. This is done in the Command Handlers Registers section near the bottom of the document. Here create a function which function with a return type of void and takes in an argument of void (*handler)(String args). Here there is also a naming convention of on<COMMAND NAME> so for the error function it would look like this.

void onError(void (*handler)(String args));

Defining the registration functions

Now it's time to make the registration functions work. For this first open the serialConnector.cpp file and go near the bottom to the Command Handlers Registers section and assign each handler a callback function like this

void SerialConnector::onError(void (*handler)(String args))
{
    errorHandler = handler;
}

Calling the handler

Now it's time to make sure the handler gets called whenever the cycle function receives a command for it. To do that go in to the Command Dispatcher section of the cycle function in the serialConnector.cpp file and in the else-if statement which is there put the name of your command and in the if statemnt call the handler with the args argument. For the ERR command it would look like this.

    if (cmd == "ERR")
    {
        if (errorHandler)
            errorHandler(args);
    }
    else
    {
        // Unknown/unused command
    }

To add on any extra commands just add another else to that else-if statement.

Assigning a callback function

Finally it's time to make the command do stuff. This is done by passing in a callback function to the registration command created earlier. Here is an example of how that would look like in the main.cpp file.

#include <serialConnector.h>

SerialConnector *conn = new SerialConnector()

void error(String args) {}

void setup() 
{
    conn->onError(&error);
}

What this code does is it executes the error function any time an ERR command is received and passes on any of the received arguments in to the error functions args argument for the user to use in the error function.

Description
No description provided
Readme 116 KiB
Languages
C++ 100%