Arm Link Reference

The Arm Link library, firmware, and software will allow you to control the RobotGeek Arm by sending an absolute value to each coordinate. These coordinates are sent over a serial port connection to the Geekduino that controls the arm. The Geekduino will receive the coordinates, do any required calculations, and then move the servos appropriately.

The Arm Link library and software was initialliy designed for the InterbotiX line of Robotic Arms but it is fully compatible with the RobotGeek Snapper Arm.


Firmware and Software

The Arm Link Library and Firmware examples are installed within the Geekduino Libraries files installed during the Geekduino Getting Started Guide. Alternatively they can be found here. Details on installing the library manually and loading the ArmLinkSerial firmware can be found here.

A demo application, the Arm Link PC Control Software is also available. This open source application allows a computer to control the robot arm. This application can set arm position, as well as control digital I/O and read analog input.

Arm Modes

The Snapper Arm currently only supports Cartesian IK mode. Other modes will be available in the future

Serial Port Settings

To support the Arm Link protocol, your programming language will need to support sending byte data over a serial port. See the documentation for your language to see if it is capable of sending byte packets over a serial port.

The Arm can also be controlled by other microcontrollers using a serial port.

Your serial connection should have the following settings to communicate with the Robot Arm.

  • Baud: 38400
  • Parity: None
  • Data Bits: 8
  • Stop Bits: 1

Arm Link Packet Structure

The Arm Link packet holds the coordinate data to be sent from a computer or other controller to the Geekduino. The packet is always 17 bytes long. Packets 10 and 11 are not used by the snapper arm - send a '0' on each of these packets.

Positional packets can be sent discretely or at a regular interval. The Arm will finish a movement before it performs the next movement. If you are sending packets at an interval, do not send them faster than 30hz (one packet every 33ms).

Packet # Cartesian Mode
1 Header (0xFF/255)
2 X-Axis Coordinate High Byte
3 X-Axis Coordinate Low Byte
4 Y-Axis Coordinate High Byte
5 Y-Axis Coordinate Low Byte
6 Z-Axis Coordinate High Byte
7 Z-Axis Coordinate Low Byte
8 Wrist Angle High Byte
9 Wrist Angle Low Byte
10 Wrist Rotate High Byte
11 Wrist Rotate Low Byte
12 Griper High Byte
13 Gripper Low Byte
16 Delta Byte
15 Button Byte
16 Extended Instruction Byte
17 Checksum

Low Byte/High Byte Calculations

Arduino serial communications sends data as discrete byte-sized packets. An 8-bit byte can only hold values from 0-255. This is too small for the X/Y/Z coordinate values and the absolute servo positions values. To compensate for this, each parameter is split into two bytes - a low byte and a high byte. Once received by the Robot Arm, these bytes will be combined into the original value.

Value (Decimal) High Byte (Decimal) Low Byte (Decimal) Value (Binary) High Byte (Binary) Low Byte (Binary) Value (Hex) High Byte (Hex) Low Byte (Hex)
128 0 128 0000000010000000 00000000 10000000 0080 00 80
781 3 13 0000001100001101 00000011 00001101 030D 03 0D
1023 3 255 0000001111111111 00000011 11111111 03FF 03 FF
1435 05 155 0000010110011011 00000101 10011011 059B 05 9B

The low byte corresponds to the first 8 bits of the value. To obtain this value we simply remove anything past the first 8 bits of the value. This can be done many ways, but the easiest way is to use the modulus operator (%).

Low Byte Pseudo Code

//coordinate is a previously defined integer value 
byte lowByte = coordinate % 256 ;

The low byte corresponds to the second 8 bits of the value. First we will shift the second byte down 8 values. To do this we can divide the value by 28 or 256. As these operations are being done on integers/bytes, the lower byte is discarded. Once we have shifted the second byte, we will use the modulus operator to ensure that only a single byte is isolated.

High Byte Pseudo Code

//coordinate is a previously defined integer value 
byte highByte = (coordinate / 256)%256;

Here's an alternative way to come up with the high/low byte using bitwise operators

//coordinate is a previously defined integer value 
	byte highByte = (coordinate >> 8) & 0xFF; //shift the value down 8 bits and mask it with 255/0xFF to isolate the byte 
	byte lowByte = coordinate & 0xFF; //mask the value with 255/0xFF to isolate the byte 


The Delta value determines how long it will take for the arm to move from its current position to the new position. The amount of time that the move takes is calculated by multiplying Delta by 16. The result will give you the time interval in milliseconds.

Time Interval = Delta * 16 

For example, a delta of 125 means that the move will take 2000 milliseconds, or 2 seconds.

Button Byte Structure

The button byte can control digital outputs on the Geekduino. These outputs can be connected to LEDs, Buzzers, Lasers, or any other 5v digital output. Relays can be used to activate higher voltage devices.

Bit # 8 7 6 5 4 3 2 1
Geekduino Digital Output N/A 13 12 11 8 7 4 2
Hex Decimal Binary Digital Outputs Active
0x00 0 00000000 none
0x01 1 00000001 2
0x02 2 00000010 4
0x0f 15 00001110 4,7,8
0x7F 127 01111111 2,4,7,8,11,12,13

Extended Byte Structure

The extended instruction byte allows the user to perform various actions or request data from the arm.
Hex Decimal Action
0x00 0 Move Arm to Position*
0x60 96 Put Arm in Sleep mode - move to sleep position and turn servo torque off
0x70 112 ID Packet Request
0x80 128 IK Status Request (Not Implemented)
0xC8 200 Request Analog Packet on Analog 0
0xC9 201 Request Analog Packet on Analog 1
0xCA 202 Request Analog Packet on Analog 2
0xCB 203 Request Analog Packet on Analog 3
0xCC 204 Request Analog Packet on Analog 4
0xCD 205 Request Analog Packet on Analog 5
0xCE 206 Request Analog Packet on Analog 6
0xCF 207 Request Analog Packet on Analog 7

*Sending the arm an extended byte of 0 will send it to the current coordinates based on packets 2-15. Sending a packet with any other extended byte will ignore packets 2-15


The checksum is a dynamic value that will change if any of the values in the packet changes. This allows the arm to confirm the packet was received without any errors. The checksum can be calculated as follows:

  • Add up bytes 2 - 16 (do not include the header)
  • Isolate the low-byte of the sum (%256)
  • Invert the byte (255-)

The Pseudo Code for this operation would be

	sum = xHighByte + xLowByte +  yHighByte + yLowByte +  zHighByte + zLowByte +  wristAngleHighByte + wristAngleLowByte +  wristRotateHighByte + wristRotateLowByte +  gripperHighByte + gripperLowByte + deltaValBytes + buttonByte + extValBytes;//add up bytes 2-16
	invertedChecksum = sum % 256;//isolate the lowest byte
	checksum = 255 - invertedChecksum; //invert value to get file checksum

Negative/Offset Values

The parameters X and WristAngle both can have negative values. However all of the values transmitted via the ArmControl serial packet are unsigned bytes that are converted into unsigned integers - that is, they can only have positive values. To compensate for this fact, X and WristAngle are transmitted as offset values.

Add 512 to X to obtain the value to transmit over Arm Link.

Transmitted Value Interpreted X-Coordinate Value
362 -150
512 0
662 150

Add 90 to Wrist Angle to obtain the value to transmit over Arm Link.

Transmitted Value Interpreted Wrist Angle
45 -45
90 0
135 45

Arm Limits & Defaults

The following list of limits are all 'interpreted' values. Parameters with a '*' must be offset to a positive range before transmission.

Snapper Arm | Cartesian Positioning | Straight Wrist
Parameter Lower Limit Upper Limit Default
X-Axis Coordinate* -150 150 0
Y-Axis Coordinate 50 150 200
Z-Axis Coordinate 20 150 250
Wrist Angle* -45 45 0
Gripper 0 512 512
Delta 0 255 125
Button 0 255 0
Extended 0 255 0

Notes on Values


A '0' value will close the gripper all the way while a '512' value will open it all the way.

Reading Analog Data

It is possible to read Analog Data from the Geekduino and send the data back over the serial link. Sending the arm a specific extended instruction will cause the arm to report the current value of the corresponding analog value. See the Extended Table to see which instructions correspond to which analog ports.

Packet # Packet Info
1 Fixed Header - 0xff
2 Extended Instruction Echo
3 Analog Value High Byte
4 Analog Value Byte
5 Checksum

Arm ID Response Packet

Sending a packet with the extended instruction of 112 will cause the arm to send an ID response packet. This can be useful for determining what arm you are communicating with, or just to check if the arm is available.

The arm will also send this ID packet after its mode is changed, including sleep mode

The arm will respond with a 5-byte packet with the following data.

Packet # Packet Info
1 Fixed Header - 0xff
2 Arm ID#
3 IK Mode
4 Fixed - 0
5 Checksum
Arm IDs
Robot Arm Arm ID
InterbotiX PhantomX Pincher Arm 1
InterbotiX PhantomX Reactor Arm 2
InterbotiX WidowX Arm 3
RobotGeek Snapper Arm 5
IK mode
Robot Arm Arm ID
Cartesian - Normal Wrist 1
Cartesian - 90° Wrist 2
Cylindrical - Normal Wrist 3
Cylindrical - 90° Wrist 4
Backhoe/Joint Mode 5

Arm Link Packet Calculator

You can find a basic Arm Link calculator here

Arm Link Packet Examples

You can find basic Arm Link example packets here

Getting Started