circuitben

FIRST OI

NOTE - This describes the 2001-2003 OI. The newer OIs are slightly different and I haven't had a chance to figure out how to do equivalent tricks with them. I don't actually know what year my OI came from, but the datecodes on the chips suggest it was 2001.

The OI is cool, mainly because it has lots of switches and flashing lights and can be connected to even more switches and lights. It's a useful input box since it has many analog and digital inputs and is easy to connect to anything with a serial port.

In order to use the OI for your own nefarious purposes, you need to build a tether adapter. This consists of two female DB-9 connectors with pins 2, 3, and 5 wired straight through and pins 8 and 9 connected together on the OI side (it's safe to connect them on both sides since they are inputs on the computer, but don't connect them if you make a null-modem or connect them to any device that drives those pins). All other pins should be left unconnected. The tether uses normal RS-232 signal levels so no conversion circuitry is required.

Tether Adapter
My tether adapter

The two connectors on my adapter look different because they were bought from different places and have different plating. Otherwise they are identical. I used two one-inch hex standoffs to hold it together.

Tether pinout:

PinDescription
1OI power from robot
2TXD (to robot)
3RXD (from robot)
4
5GND
6
7
8RC tether sense
9OI tether sense

Tether 8 (RC tether sense) is 220 ohms to Vcc. Tether 9 (OI tether sense) is 10k to GND, diode clamp to Vcc/GND (no Ri), U3 /RE, MCU RD3/PSP3.

When tether is not present (low), U3 receiver is enabled. When tether is present (high), tether pin 9 is driven high to disable U3 receiver.

The tether data is just the 26-byte packets that would have been sent to and received from the radio if it were plugged in.

Packet formats

The dashboard spec describes only the packets sent from the RC, and it labels the CRC bytes as "Reserved". The following packet formats are based on actual observations of a 2001(?) OI and RC.

I number bytes from 0 instead of 1 (like the IFI docs) because I usually program in C and it's easier this way.

Packets sent from the OI to the RC:

OffsetDescription
0Packet header, always 0xff
1Packet header, always 0xff
2Port 2 X
3Bits:
7: Port 3 aux switch 2
6: Port 3 aux switch 1
5: Port 3 thumb
4: Port 3 trigger
3: Port 1 aux switch 2
2: Port 1 aux switch 1
1: Port 1 thumb
0: Port 1 trigger
4Port 1 X
5Bits:
7: Port 4 aux switch 2
6: Port 4 aux switch 1
5: Port 4 thumb
4: Port 4 trigger
3: Port 2 aux switch 2
2: Port 2 aux switch 1
1: Port 2 thumb
0: Port 2 trigger
6Port 4 X
7Bits:
7-5: ???
4: Robot reset (1=Normal operation, 0=Reset)
3-0: Team number bits 11-8
8Port 3 X
9Team number bits 7-0
10Port 2 Y
11Bits:
7: Disabled
6: Autonomous
5-0: Channel number
12Port 1 Y
13Packet number
14Port 4 Y
15CRC low
16Port 3 Y
17CRC high
18Port 2 wheel
19Port 1 wheel
20Port 4 wheel
21Port 3 wheel
22Port 2 aux analog
23Port 1 aux analog
24Port 4 aux analog
25Port 3 aux analog

Packets sent from the RC to the OI:

OffsetDescription
0Packet header, always 0xff
1Packet header, always 0xff
2
3Bits:
7-3: ???
2: Switch 3
1: Switch 2
0: Switch 1
4
5
6
7Bits:
7-4: ???
3-0: Team number bits 11-8
8
9Team number bits 7-0
10
11Bits:
7-6: ???
5-0: Channel number
12
13Packet number
14
15CRC low
16Battery level
17CRC high
18OI Port 2 Y
19Bits:
7: Relay 2 green
6: Relay 2 red
5: Relay 1 green
4: Relay 1 red
3: PWM 2 red
2: PWM 2 green
1: PWM 1 red
0: PWM 1 green
20OI Port 1 Y
21OI Port 4 Y
22OI Port 3 Y
23OI Port 2 Wheel
24OI Port 1 X
25Bits:
7: Aux fuse
6: BASIC run
5: BASIC run error
4: Low battery
3: BASIC init
2: Valid RX
1: No data
0: Tether detect

The unlabelled bytes in the RC packet are probably as documented by IFI, but I haven't checked them.

The RC sends back several OI inputs. I guess this is done so you can monitor both OI and RC activity from the dashboard port.

The packet number always increases by one from one packet to the next. This can be used to detect dropped packets.

The mapping from battery voltage to the value of RC byte 16 appears to be nonlinear.

The OI to RC packet format appears to be unchanged as of 2006, but the CRC has changed (see below).

The CRC

All packets sent by the OI and RC have a 16-bit CRC for error detection. Each device will ignore any packet with the wrong CRC. If you are just using the OI for input and you have a hard connection to the OI (no radios), then you can ignore the CRC. If you are using radios, then you should check the CRC to make sure the data was not corrupted in transit.

If you want to send data to the OI, you must set bytes 15 and 17 (counting from 0) of the packet to the lower and upper 8 bits of the CRC respectively.

There are many CRC implementations on the Internet, and some of them are not mathematically correct (they don't actually calculate a CRC). The OI CRC is a correct LSB-first CRC which can be calculated with this code:

#include <stdint.h>

#define CRC_START 0xffff
#define CRC_POLY 0xc6f6

uint16_t crc_packet(uint8_t *data)
{
    int i, bit;

    uint16_t crc = CRC_START;
    for (i = 0; i < 26; i++)
    {
        if (i == 15 || i == 17)
            continue;

        crc ^= data[i];

        for (bit = 0; bit < 8; bit++)
        {
            if (crc & 1)
            {
                crc = (crc >> 1) ^ CRC_POLY;
            } else {
                crc >>= 1;
            }
        }
    }

    return crc;
}

The CRC was different in 2006, and was probably changed when the control system changed in 2004.

Code

Here's an example of code that talks to the OI: xmms_oi.tar.gz.

This is an XMMS plugin that uses an OI joystick port to control playback and volume. The robot feedback LEDs indicate volume. Three of the robot controller LEDs indicate playback status:

ColorLabelDescription
GreenValid RXPlaying
YellowLow BatteryPaused
RedAux FuseStopped

This code shows how to interpret packets received from the OI and how to build correct packets to send to the OI.

Code to dump and generate OI packets in Linux: tether.c
This is another good example. This program is useful for monitoring data from the OI or RC.