Sniffing the LEGO WeDo 2.0 Motion Sensor

Now that I have a working cable to intercept Powered Up signals I no longer need to cut a sensor cable to hijack it.

So let’s start with a simple sensor: the 45304 LEGO WeDo 2.0 Motion Sensor

Procedure:

  1. connect the male plug of the Powered Up Interception Cable to LEGO BOOST Move Hub (port C)
  2. connect a WeDo 2.0 Motion Sensor to the “female” plug of the Interception Cable
  3. connect the Bus Pirate to the “interception” 6-pin header
  4. connect the Bus Pirate to a USB port and set it up as a Transparent UART Bridge (115200 bps, 8N1, floating inputs)
  5. run jpnevulator to read traffic comming from the Bus Pirate
  6. turn of the LEGO BOOST Move Hub
  7. connect to it with gatttool
  8. enable notifications (‘char-write-req 0x0f 0100’)
  9. enable the Motion Sensor on port C (‘char-write-req 0x0e 0A004101000100000001’) in mode ‘0’
  10. watch, watch, watch

So everytime the measured distance change I get a notification in gatttool and a 3-byte message in jpnevulator. And it is simple:

00 => C0 00 3F
01 => C0 01 3E
02 => C0 02 3D
03 => C0 03 3C
04 => C0 04 3B
05 => C0 05 3A
06 => C0 06 39
07 => C0 07 38
08 => C0 08 37
09 => C0 09 36
0A => C0 0A 35

A start byte (‘C0’) plus the payload  plus and end byte (‘3F’ i.e. the complement of ‘C0’ minus the payload).

Great! Not even an initialization sequence!

So disconnect the Interception Cable male plug and replace the Bus Pirate with the FTDI Beefy 3 adapter, set ‘/dev/ttyUSB3’ to 115200 and raw mode and test several bash commands.

Not totally clear yet but this works:

 

#!/usr/bin/env bash

# sync
for i in {1..50000}
do
    echo -e -n "\x00" > /dev/ttyUSB3
done

for i in {1..50000}
do
    echo -e -n "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" > /dev/ttyUSB3
done

(that ‘echo’ command is just a line)

Now the usual voodoo explanation:

The first byte sent is like a read command. I got success with ’02’, ’04’, ‘0F’, ’27’ and ‘FF’ and 3 different behaviors.

The remaining 15 bytes (’00’) are like the inital synchronization commands… I don’t think they are valuable data and sending a ‘break’ to the TX line for enough time would do the same… but I just can’t find a way to send a break.

So the 3 different behaviors:

  • ’02’ gets a lot of 3-byte messages from the Motion Sensor. Probably one message for each ’02’, I suspect 50 messages per second but need to check that. After a few minutes, it stops sending data.
  • ‘FF’ gets much less messages, about 1 per second. And the message is now 5-bytes long: ‘7B C1’ or ‘7B C2’ followed by the 3-byte message above (like ‘C0 00 3F’). And after a few minutes the sensor also stops sending data. So ‘7B C1’ or ‘7B C2’ are warnings from the Sensor stating that it expects something more.
  • Finally ’04’, ‘0F’ and ’27’ (and probably other values) make the Sensor behave in Mode 0 (i.e. just send data when distance changes). But it also expires after a while (I think sooner than other two modes) and the sensor sends a few ‘7B C1’ warnings followed by a read).

Now the interesting part is that if I keep moving something in front of the sensor it doesn’t “expire”. So it is probably some power saving definition, it would be nice if we could disable it.

So perhaps I’ve found a way to make my own sensor: if I can emulate the AutoID of the WeDo 2.0 Motion Sensor (device type ’23h’) I just need to send it short 3-byte messages (just 11 different values but that would be a start).

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *