StackModIO I2C Robot Control Protocol

StackModIO is a serial protocol created by Paul Bupe Jr to help facilitate the creation of modular robotics systems by abstracting the transfer of data between modules. This I2C protocol is designed to be simple, human-readable, and is suitable for transmission over I2C or Serial. All data are passed as ASCII characters between 0x24 (36) and 0x7D (125).

Why StackModIO?

Modular design in robotics requires the compartmentalization of behaviors and functions into discrete and, ideally, interchangeable modules. As I started building more complex systems with multiple “brains” working together (Raspberry Pis, BeagleBones, and Arduinos), I eventually created a language that could be used to more easily facilitate communication among to all these controllers over I2C. After tweaking that language for various projects, I decided to standardize it and create a formalized protocol, which I am documenting for anyone to use.

There are a lot of full-featured and extensive protocols and libraries out there (Firmata being at the top) and this does not attempt to replace or compete with those. It’s a simple single-purpose protocol with the sole focus of use for robotic systems with no overhead or fancy features.

The Protocol

Packet Structure

<START><SRC_ADDRESS><DST_ADDRESS><ACTION><COMMAND><DATA><END><CHECKSUM>

  • The START byte is ASCII “{” (123 decimal, 0x7B).
  • The SRC_ADDRESS byte is any value from 64 to 95 decimal (0x40 to 0x5F, ASCII “@” to “_”).
  • The DST_ADDRESS byte is any value from 64 to 95 decimal (0x40 to 0x5F, ASCII “@” to “_”).
  • The ACTION byte is an ASCII “?” for GET and ASCII “$” for SET.
  • The COMMAND bytes are three characters.
  • The DATA bytes are variable length and are described in the Data section.
  • The END byte is ASCII “}” (125 decimal, 0x7D).
  • The CHECKSUM is calculated by subtracting 32 from all the characters in the packet (excluding the start and end bytes) and summing them. The modulo 95 of this value is then calculated and 32 is added back to that value.
int calculate_checksum(String packet) {
   int sum = 0;
   int c = packet.length();
   for (int i = 0; i < c; i++) { sum += packet[i] - 32;}
   return (sum % 95) + 32;
}

Available Actions and Commands

The available commands for this revision are listed in the table below.

Command Description
ARM Arm / Disarm System
MTR Motor Speed
SRV Servo Position / Speed
ULT Ultrasonic Distance
IRS IR Value
DGT Digital Pin
ANL Analog Pin

Example MTR GET Command and Response

MTR GET command. This packet requests the speed of motor number 2.

{@e?MTR02}X
Character Description
{ Start byte
@ Source address
e Destination address
? GET action
M Command byte 1
T Command byte 2
R Command byte 3
0 Motor number byte 1
2 Motor number byte 2
} End byte
< Checksum

MTR GET response. This packet returns the speed of motor number 2.

{e@?MTR02+078}C
Character Description
{ Start byte
e Source address
@ Destination address
? GET action
M Command byte 1
T Command byte 2
R Command byte 3
0 Motor number byte 1
2 Motor number byte 2
+ Motor speed sign byte
0 Motor speed byte 1
7 Motor speed byte 2
8 Motor speed byte 3
} End byte
Checksum

Arduino Library

The Arduino implementation of this I2C protocol as a library is currently hosted on this Github repository. It is still a work in progress.