LEGO Remote Control (9738)
The handheld infrared remote for MINDSTORMS, sixteen keys on one faceplate, sold as set 9738 from 1998 to 1999. It sends no consumer infrared code: it speaks the RCX infrared link itself, 38 kHz at 2400 baud, so an RCX or a Scout obeys it with no program running and no computer in the room.
Reach
| Capability | State | Note |
|---|---|---|
| Two Scout motors, no program on the brick | works | on a Scout the A and B keys are the two real motors |
| Scout built-in behaviours on the message keys | works | Msg 1 seek dark, Msg 2 seek light, Msg 3 bug dance |
| A Micro Scout puppeted through a Scout | works, untested here | on a Scout, C is the VLL lamp output and not a motor, so C up and C down relay VLL forward and backward: remote to Scout to Micro Scout in P mode, no computer and no tower |
| Three RCX motors, no program on the brick | works, untested here | 0x0008 0x0010 0x0020 drive A B C forward, 0x0040 0x0080 0x0100 reverse; momentary while held, not latched |
| Two motors at once | works, untested here | both bits in ONE frame, 0x0018; send 0x0008 then 0x0080 and only B runs, because the second frame has no A bit and therefore stops A |
| Letting go without killing the program | works, untested here | the empty mask 0x0000 has its own handler, which writes off to all three motors; the handler is in the firmware, but no capture of a physical remote sending it exists |
| Holding a key | works, untested here | any motor frame reloads a 101-tick watchdog and expiry turns everything off, so a held key has to be re-sent; the real remote's rate is about 50 ms, which is eleven bytes of eleven bits at 2400 baud |
| The five RCX program keys | works, untested here | 0x0200 P1, 0x0400 P2, 0x0800 P3, 0x1000 P4, 0x2000 P5, select and run program slots 1 to 5, each needing a downloaded program; edge-triggered, so holding one fires it once |
| The three RCX message keys | works, untested here | 0x0001 0x0002 0x0004 deliver infrared message 1, 2 and 3 to a running program, NQC Message(); with no code to read them, nothing happens |
| The Stop key | works, untested here | 0x4000 stops the motors AND the running program, and that second job is its only reason to exist, so it is not the way to let go |
| The Sound key | works, untested here | 0x8000, a beep |
C reverse on firm0309, the RIS 1.0 and 1.5 firmware | works, untested here | the test reads the byte after the mask, which is the checksum, so a lone 0x0100 works only by coincidence and unrelated masks drive C backwards: Msg 1, 0x0001, has an odd checksum and does exactly that. Fixed in firm0328 and firm0332, which read the real high byte |
| Scout program keys, Stop and Sound | unknown | the Scout holds one program slot, not five, so P1 to P5 has no clean mapping; stop and beep are plausible and never confirmed |
What it hears
It only transmits, and nothing answers: one opcode and a 16-bit mask of which keys are down, on the same link a computer uses to reach an RCX. The frame, the checksum, the missing toggle bit, which bits may combine and the five rules for building an emitter are all in RCX IR protocol. One mask carries all sixteen keys: six motor arrows, A B and C in both directions, five program keys, three message keys, Stop and Sound.
What decides whether driving feels solid is one property of that mask: it is a snapshot of what is held right now, not a list of events. The firmware re-derives all three motors from the current frame alone — forward bit means forward, else reverse bit means reverse, else off — and that last "else" is the whole story. A motor frame also reloads the watchdog, so one frame is a pulse and a held key has to be re-sent. Non-motor keys are the opposite, edge-triggered: holding a program key fires it once, not ten times a second. And a message, program or sound frame slipped into a stream of motor frames skips the motor stage entirely, so it never refreshes the watchdog and the motors stop mid-drive.
All of that comes out of the stock firmware and applies to the stock firmware only: leJOS and brickOS replace it and describe their own behaviour instead. The Scout runs different firmware again, so none of it is proved there, and the Scout rows above were measured on the brick.
Reaching it today
Any 38 kHz infrared emitter can be this remote, because the whole remote is one opcode and a mask.
- Flash Force carries it as a library layout and sends the frames through the bridge. The page holds one mask per on-screen control and transmits the union, so two thumbs on two motor controls make a single frame instead of two that cancel each other out. By hand the command is
raw d2 <hi> <lo>. - The bridge's own infrared LED reaches a real Scout at good range. Aim at the brick's middle infrared port and not at the light sensor, with the Scout idle and its options off, and send the frames with no toggle bit, the way the real remote sends them.
- A page speaking Web Serial can build the same frames itself and stream them to the bridge.
Links
- Set 9738 (Brickset, Rebrickable). The remote is BrickLink part x124.
- Related: RCX · Scout · Micro Scout · RCX IR protocol · How the links work.
- leJOS source
RemoteControlSensor.javaandOpcode.java—OPCODE_REMOTE_COMMAND = 0xd2, and the bit-by-bit button map read out ofRemoteControlSensor.inspect(), confirmed against a real infrared capture: lejos.sourceforge.io - O Falcão, Decoding RCX IR command protocol — a real capture of
D2 00 08, the framing, and "2 motors + Scout LED": ofalcao.pt - LUGNET, Mike Kollross, Scout third motor / MicroScout hack — the Scout takes motor commands from the remote with no program running, and Motor C is the VLL output: news.lugnet.com
- NQC source,
#define kRCX_Remote 0xd2. - The one-minute test that would settle it, on real hardware: standard firmware, no program, motors on A and B. Stream
D2 00 08for two seconds so A spins, then switch the stream toD2 00 80with no gap. If A stops the instant B starts, the mask is a snapshot of what is held and the reading above is right; if both keep spinning, it latches and the reading is wrong. Then sendD2 00 18and confirm both spin together.
- No toggle bit anywhere in it. The dispatcher holds
0xD2and never0xDA, so a held button re-sends a byte-identical packet and a receiver cannot tell a hold from a repeat. Every infrared remote of the era that alternates a bit does it to make that distinction, and this one does not. - LEGO's own firmware, disassembled. In
firm0309the infrared dispatcher resolves0xD2to0x9700through the 57-entry opcode table at0x9655and the address table based at0x968c; the handler's second stage exact-matches the 11-entry value table at0x97e6,{0000,0001,0002,0004,0200,0400,0800,1000,2000,4000,8000}, against the address table at0x97fa; the mask-0x0000handler sits at0x9812and the watchdog decrement at0x837eto0x8396. Same shape infirm0328(handler0x9c7c, zero-mask0x9eae) andfirm0332(handler0x9f6c, zero-mask0xa19e). - The watchdog's 101 ticks are either about 100 ms or about 300 ms, depending on which scheduler tick re-arms the slot; brickOS independently picking a 100 ms timeout hints at the shorter reading.
- RCX Internals (Kekoa Proudfoot) does not document
0xD2, and the mralligator table derived from it mislabels the opcode "start task download", so the canonical reference is not usable here. - Faithful reimplementations to compare an emitter against: Hoenicke's brickEmu, which runs the real ROM and firmware and keeps one
buttonstateword, setting and clearing bits on press and release; and Bricx CC's remote window, which rebuilds the word every timer tick as the union of whichever buttons are down.