ModBot is a simple robotics platform created for testing sensors, algorithms, vision systems, and everything else in between. I designed this platform with modularity in mind (thus the name) which requires the compartmentalization of behaviors and functions into discrete and, ideally, interchangeable modules. Since this is an experimental platform I opted not tie it to ROS (even though it still uses a Linux environment so ROS can be used) and created a very simple ASCII protocol for communication between modules. Lastly, I added teleoperation capabilities using a PlayStation DualShock 4 controller.
Robotics Platform Block Diagram and Design
The base is the fairly standard four-wheel differential drive design. A Raspberry Pi controls the motors via a dedicated Arduino Nano microcontroller that has motion profiles/velocity curves for each motor.
I utilized standard sockets and connectors so that controllers and other components could be swapped out without full disassembly of the robot. Notably, I used RJ45 Keystone jacks so that I can use standard Cat 5 cables as module interconnects. Multiple microcontrollers can be added to the system using the I2C protocol I created for communication.
All the core components of this robotics platform are kept under the upper deck, which is used to hold whatever component or sensor is being tested. The ports for the Raspberry Pi and other components are oriented such that cables can be plugged in or removed without removing the cover.
Serial Communication Protocol
To help facilitate modularity, I created a simple serial protocol to abstract the transfer of data between modules.
Why Create a Custom Protocol?
As I started building more complex systems with multiple “brains” working together (Raspberry Pis, BeagleBones, and Arduinos), I founding myself needing a simple protocol that could be used to more easily facilitate communication to all these controllers over I2C. Over various projects I standardized formalized the following protocol.
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 simple robotic systems with no overhead or fancy features.
Robotics Platform Communication Protocol
This I2C protocol is designed to be simple, human-readable, and is suitable for transmission over a serial bus. All data are passed as ASCII characters between 0x24 (36) and 0x7D (125). The protocol is simple enough that it can be debugged without any special decoding as show in the screenshot from my oscilloscope below.
This is just a basic overview and not meant to be full documentation of 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 “?
” forGET
and ASCII “$” forSET
. - 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.
Checksum Calculation
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;
}
Example 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 |
X | 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 |
C | Checksum |
Teleoperation Test Run
Here’s a short clip of me testing the motion profiles and mixing of the inputs from the controller joystick. As you can probably tell there was still a bit of tweaking to be done when I took this video but overall the robotics platform was quite responsive.