flash force Wiki
Interactive browser →
Wiki / Protocols
#protocol#ir#rcx

RCX IR protocol

A ~38 kHz infrared carrier, and it runs both ways. Not a remote, a serial port made of light. The RCX talks BOTH ways at 2400 baud over infrared, so a computer can download a program into it and read a sensor back. Every other link here is one-way.

Packet format

0x55 0xFF 0x00   header
then, for every data byte: <byte> <~byte>   (byte followed by its bitwise complement)
payload = opcode, args...
trailer = checksum, ~checksum   (checksum = sum of payload bytes, low 8 bits)

The reply uses the same framing. Opcodes have a toggle bit that flips between consecutive commands so the RCX can ignore duplicates.

What you can send

Authoritative references

The RCX also has a light sensor input (reads reflected/ambient brightness) — same physics VLL exploits, but here it's used for sensing, not comms.

Sources for this block

The handheld remote's frame

LEGO Remote Control (9738) rides the same link. Its payload is one opcode and a big-endian 16-bit mask of which keys are down:

55 FF 00  D2 2D  hi ~hi  lo ~lo  csum ~csum

checksum = (D2 + hi + lo) & 0xFF, sent with its complement. Motor A forward, key 0x0008, comes out as 55 FF 00 D2 2D 00 FF 08 F7 DA 25, which matches a capture of the real remote byte for byte.

No toggle bit. Command opcodes flip bit 0x08 so the brick can reject repeats; the remote sends a fixed 0xD2, and holding a button re-sends the identical packet. The brick answers nothing.

Only the six motor bits combine. The firmware reads those independently, so 0x0018 is A and B forward and 0x0038 is all three. Every other key is dispatched by exact match on the whole 16-bit word, so 0x4008 triggers neither Stop nor motor A. Messages, program slots, Stop and Sound have to travel alone.

Five rules for an emitter: send the combined mask rather than one key per frame; repeat while held, every 50 to 80 ms; on release send 0x0000 and not Stop; send non-motor keys alone; and hold the opcode at 0xD2.

One firmware bug. In firm0309, shipped with RIS 1.0 and 1.5, the test for C-reverse reads the byte after the mask, which is the checksum. Since csum = (0xD2 + hi + lo) & 0xFF, its bit 0 is bit 0 of hi XOR bit 0 of lo, which is C-down XOR Message 1. A lone C-down works by coincidence, and some unrelated masks drive C backwards — Message 1, 0x0001, has an odd checksum and does exactly that. Fixed in firm0328 and firm0332. On a Scout it never applied, because C is the light output there rather than a motor.