Open questions
What I haven't figured out yet, roughly ordered by value for effort.
1. Finish the tile colour codes
When the train reads an action tile, the TAG mode reports a code. I know 2
of the 7 codes. My earlier guesses for the rest fell apart when two tiles
turned out to have been swapped partway through testing.
| TAG code | Colour | Confidence |
|---|---|---|
| 0 | nothing read yet | certain |
| 1 | yellow | confirmed directly |
| 37 | white | likely |
| 21, 119, 191, 402 | ? | unknown |
Don't guess from the order of a sequence; that is what went wrong. Identify each code against a single tile you can see:
./duplo next --timeout 0
next creeps forward until exactly one new tile is read, then stops and
prints its code. Put the train before a tile, note the colour, run it, write
down the code. Six runs. Rearranging the track in between can't spoil the
result, because nothing depends on order.
Also worth checking: are all six LEGO tile colours in the firmware's list, and what is reported for a colour that isn't a valid tile? Tiles are read optically (coloured paper works), so there may be many more than six codes.
2. Why are some tiles missed?
Sometimes the train drives over a tile without reading it. Ruled out so far: speed (18–30%), direction (both), and the sensor going "deaf" while the hub plays the previous tile's action (approaching the same tile after a different neighbour didn't help).
Still worth trying:
- The sensor's height above that particular tile
- A dirty, faded or slightly different-shade tile. Swap in a known-good tile of the same colour and see whether the miss follows the tile or the position.
delta 0onTAGacross the miss, to see whether the sensor reports the code briefly (and the stored value is the problem) or nothing arrives at all- Whether misses happen while the hub is still reacting to the previous tile.
Measure it rather than guess: subscribe to
EVENTSandTAGtogether and look at the order of messages.
3. Can tile actions be turned off?
Right now I overrule the tiles by sending my motor speed 20 times a second. It works, but it's brute force: a write every 50 ms, and the hub still briefly fights back.
Places a real on/off switch might be hiding:
- Port 52
DEBUG(mode 2, 4×int32): never read or written - Port 52
EVENTSas an output: its mask says it accepts output, but I never tried writing structured values to it - Hub property IDs beyond the standard set
- Port 50 mode 1
SPEEDinstead of mode 0POWER: possibly the hub decides differently which command wins
A warning: writing to undocumented diagnostic ports on a toy is how you "brick" it (break the firmware for good). The firmware update service (OAD) is right there.
4. Can it play sounds?
I never managed to play a sound on purpose. There is no speaker port like
the 2018 train's (0x2a type), and TAG, the obvious candidate, rejects
writes with 0x06 invalid use for every index from 0 to 20.
Sounds did play during testing, but those were the hub reacting to tiles on its own, not anything I triggered.
Still open: can the speaker be reached over LWP3 (the LEGO Bluetooth protocol)
on this hub at all, or is it internal only? If TAG accepted writes with the
right parameters, that would be the way in. The 0x06 error means the command
was understood but the parameters were wrong, which isn't quite the same as
"read-only". Worth trying: other startup_completion values, mode 1 or higher
on that port (the hub only declares mode 0, so probably not), and 1-byte
instead of 2-byte payloads.
5. Unexplored modes
Each port has one or more modes (kinds of reading or output). These are unexplored:
| Port | Mode | Status |
|---|---|---|
| 50 | 1 SPEED |
never used; may differ from POWER in which command wins or how speed ramps |
| 52 | 0 VERS |
read once: 0x10010004 ×3 then 0x00310031; not decoded |
| 52 | 2 DEBUG |
never read |
| 53 | 1 VLT S |
never read; probably averages voltage over a different time window than VLT L |
| 54 | 1 COUNT |
never read; int32 but with a declared range of only −8..8, which is strange for a counter. A working odometer would be useful if that range is wrong. |
| 54 | 2 VELO |
never read; signed RPM ±400 |
COUNT is the interesting one: a real odometer would tell you where the train
is on the loop, instead of working it out from timing.
6. Combined mode
Only one mode per port can be active at a time, so you have to choose between
the speedometer's SPEED, COUNT and VELO. LWP3 has a message for reading
several at once (Port Input Format Setup, CombinedMode, 0x42), but it only
works on ports that say they support combining. This hub's capability flags are
known to be wrong, so it's worth simply trying rather than trusting them.
7. Does EVENTS report anything else?
Every EVENTS message I saw had 0xa001 as its first word and
100 + motor speed as its second. If other event IDs exist, some might be tile
events, which would be a cleaner signal than the stored TAG value.
8. Keeping the hub awake
The hub powers off after about 30 s standing still; sending commands doesn't help. Is there a keep-alive: a hub property, a regular read, or a zero-power motor command that counts as activity? Without one, you can't leave it running to monitor it passively.
9. The 2018 train is untested
All the 2018 train support in the tool (ports 0x00/0x01/0x11, sound and
LED commands) comes from community sources and has never been tested on real
hardware by me. It's plausible, not verified.
10. Split messages
The tool assumes each LWP3 message arrives in one Bluetooth notification, which held for everything this train sent. A client for hubs with more ports should rejoin split messages using the leading length byte.