Spybotics IR protocol
The Spybotics infrared protocol in two layers:
- Physical — a 76 kHz carrier (76 kHz IR family), bits ≈ 208 µs (short) / 624 µs (long), ~23-bit frames. Reverse-engineered by JorgePe (ir-spybotics).
- Logical — the message/command model, recovered from the Spybotics CD-ROM (
data2.cab→Program Files/Include/:Spybot.h,Messages.h,Events.h,GameIDs.h— LEGO's own firmware / LASM API).
Together they let you both decode what Spybots emit and synthesize valid messages — pings, targeting, combat, VLL output, even impersonating RCX or the RC remote.
Message format
Every IR command is 4 bytes: [nBot] [command] [hiByte] [loByte]
nBot— target ID (see IDs).command— high nibble = type (mask0xF0), low nibble = subcommand.hiByte/loByte— 16-bit payload (meaning per command).
Command table — send / отдача
The full command set (Messages.h). The same codes appear on the wire whether sent by a controller, a bot, the PC, or an RCX.
| Code | Command | Type | param1 / param2 |
|---|---|---|---|
0x00 | NoCommand | — | — |
0x10 | Start | Game | — |
0x11 | GameCommand | Game | — |
0x12 | GetVar | Game | (request a variable) |
0x13 | Value | Game | (variable reply) |
0x14 | Win | Game | — |
0x15 | Lose | Game | — |
0x16 | Blink | Game | — |
0x17 | Give | Game | — |
0x18 | Take | Game | — |
0x1F | FromRCX2 | Game | command issued by an RCX 2.0 |
0x21 | FireLaser | Fire | target aspect / strength |
0x22 | FireSpinner | Fire | target aspect / strength |
0x23 | FireElectroNet | Fire | target aspect / strength |
0x31 | ReactTo GigaMesh | React (0x30+species) | range / strength·time |
0x32 | ReactTo Snaptrax | React | range / strength·time |
0x33 | ReactTo Shadowstrike | React | range / strength·time |
0x34 | ReactTo Technojaw | React | range / strength·time |
0x41 | Magnet | Tell (token) | 0 / time |
0x42 | Repulse | Tell | 0 / time |
0x43 | FlashBlind | Tell | 0 / time |
0x44 | Freeze | Tell | 0 / time |
0x45 | Slow | Tell | 0 / time |
0x46 | Reverse | Tell | 0 / time |
0x47 | Dizzy | Tell | 0 / time |
0x48 | TakeControl | Tell | 0 / time |
0x50 | User | User | custom frame (see envelope) |
0x60 | Spare | — | — |
0x70 | VLL | VLL out | drives a Micro Scout / Code Pilot |
Transmit envelope — how a message goes out
Set in the firmware message[] table (Spybot.h):
| Field (index) | Values |
|---|---|
iTxType (23) | Spybot=0 · RCX=1 · RC=2 · User=3 — transmit as a Spybot, an RCX, the RC remote, or custom |
iTxChannel (25) | FrontLeft=0 · FrontRight=1 · Back=2 · HighPower=3 · PC=4 — directional emitters |
iTxBaud (24) | 2400=0 · 4800=1 · 9600=3 |
iIndex (21) | flags Broadcast=0x80, Linkcast=0x40, InvalidRxIndex=0x20 |
| User frame | iUserPreamblePos (47), iUserPreambleLen (48), iUserChecksum (49: none=0/sum=0x04/zerosum=0x08), iUserBiPhase (50) |
iLock (51) | Unlock=0 · LockIR=1 · LockPC=2 |
Receive side — приём (what bots sense & emit autonomously)
Pings — autonomous ID beacons
Bots broadcast periodic IR pings carrying their ID. ping[iInterval] (9), 10 ms steps: Disable=0, Min=10, Default=25 (250 ms), Max=255. ping[iMyID] (10, R/O).
world[16] — the "radar" each bot builds from received pings
For every detected bot (up to cMaxWorldEntries=16):
| Field (index) | Values |
|---|---|
iShortID (1) | bot's short ID |
iLinkID (2) | link ID |
iRange (3) | Nowhere=0 · Anywhere=1 · There=2 · Here=3 |
iDirection (4) | Left=0 · LeftOfCentre=1 · Centre=2 · RightOfCentre=3 · Right=4 (centre split only in the Here zone) |
iAspect (5) | FrontLeft=0 · Front=1 · FrontRight=2 · BackRight=3 · Back=4 · BackLeft=5 |
iInfo (6), iNote (7) | extra info / user note |
A target[] table mirrors these fields for the currently-targeted bot. iRxChannel (20): source = IR=1 / PC=2.
Events fired on receive (Events.h)
Bump (bumper) · Enter (a bot entered range / world.enter) · Target (target change) · Post (message received) · Blink (opto / light sensor) · VLL (VLL received).
IDs & species
- IDs: controllers
1–6, PC7, bots8–255. Each bot has a short ID + 4-byte LongID. - Species (
eeprom[eSpecies]):Gigamesh=1(3806) ·Snaptrax=2(3807) ·Shadowstrike=3(3808) ·Technojaw=4(3809).
Control nuances
- PC cable link = 2400 baud, 8-O-1 (odd parity, 1 stop) — same UART params as the RCX; the comms DLLs (
PbkComm32.dll,SpybotComm32.dll) string this verbatim, plus a9600 N81mode. - VLL output (cmd type
0x70, andled[iVLL]): a Spybot can emit VLL to command a Micro Scout / Code Pilot — Spybotics is in the VLL family too. - RCX interop:
cCommandFromRCX2 = 0x1F+iTxType=RCXare how an RCX drives Spybots (and vice-versa). - EEPROM (256 B) stores name (32 B), species, scores (runs/wins/loses/points), play time, mission flags (
eMissionsPlayed, 1 bit/mission), high score, tokens. - Receiving is disabled while transmitting (shared IR front-end).
Programming "beads" (high-level blocks → compile to these commands)
Combat: FireLaser, FireSpinner, FireElectroNet, SendMindControl, Shocked, Take, Give, DeactivateAnyToken · Movement/goal: AdvanceForever, RetreatForever, GoalPointTo, GoalPointToward, GoalTurnAway, Power, Limit, Monitor{Dir,Vector}, ShowDir, TargetID · Sensing: CountBots(/Mode/Range), CountControllers(/Range) · Game/score: Score, Points, Penalty, GameOver, Won/LostGame, UpdateEndGame, Clear{Game,State,User}Timer, Resend, Note · Code-puzzle: CodeClue, RandomCode, DisplayCodeGuess, PlayCodeGuess · LED: Full/Red/GreenScale, Yellow · Misc: RndVar, PlayWait, StopAll.
Source / provenance
Logical layer decoded from the Spybotics CD-ROM (Internet Archive: lego-spybotics-english → data2.cab → Program Files/Include/*.h). Physical layer: JorgePe — ir-spybotics · ofalcao — decoding old LEGO IR. See Spybotics, 76 kHz IR family.