{"id":1428,"date":"2018-09-03T18:22:34","date_gmt":"2018-09-03T17:22:34","guid":{"rendered":"https:\/\/ofalcao.pt\/blog\/?p=1428"},"modified":"2018-09-03T18:56:52","modified_gmt":"2018-09-03T17:56:52","slug":"sniffing-the-lego-wedo-2-0-motion-sensor","status":"publish","type":"post","link":"https:\/\/ofalcao.pt\/blog\/2018\/sniffing-the-lego-wedo-2-0-motion-sensor","title":{"rendered":"Sniffing the LEGO WeDo 2.0 Motion Sensor"},"content":{"rendered":"<p>Now that I have a working cable to intercept Powered Up signals I no longer need to cut a sensor cable to hijack it.<\/p>\n<p>So let&#8217;s start with a simple sensor: the 45304 LEGO WeDo 2.0 Motion Sensor<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/i0.wp.com\/le-www-live-s.legocdn.com\/images\/423923\/live\/sc\/Products\/45304\/45304_Prod_01\/acacc0a4d70d3b6219bf6e8611080409\/2639b12b-0f69-4f23-b950-a4c0007113a1\/original\/2639b12b-0f69-4f23-b950-a4c0007113a1.jpg?resize=405%2C280&#038;ssl=1\" width=\"405\" height=\"280\" \/><\/p>\n<p>Procedure:<\/p>\n<ol>\n<li>connect the male plug of the <a href=\"https:\/\/ofalcao.pt\/blog\/2018\/powered-up-interception-cable\">Powered Up Interception Cable<\/a> to LEGO BOOST Move Hub (port C)<\/li>\n<li>connect a WeDo 2.0 Motion Sensor to the &#8220;female&#8221; plug of the Interception Cable<\/li>\n<li>connect the Bus Pirate to the &#8220;interception&#8221; 6-pin header<\/li>\n<li>connect the Bus Pirate to a USB port and set it up as a Transparent UART Bridge (115200 bps, 8N1, floating inputs)<\/li>\n<li>run <strong>jpnevulator<\/strong> to read traffic comming from the Bus Pirate<\/li>\n<li>turn of the LEGO BOOST Move Hub<\/li>\n<li>connect to it with <strong>gatttool<\/strong><\/li>\n<li>enable notifications (&#8216;char-write-req 0x0f 0100&#8217;)<\/li>\n<li>enable the Motion Sensor on port C (&#8216;char-write-req 0x0e 0A004101000100000001&#8217;) in mode &#8216;0&#8217;<\/li>\n<li>watch, watch, watch<\/li>\n<\/ol>\n<p>So everytime the measured distance change I get a notification in gatttool and a 3-byte message in jpnevulator. And it is simple:<\/p>\n<pre>00 =&gt; C0 00 3F\r\n01 =&gt; C0 01 3E\r\n02 =&gt; C0 02 3D\r\n03 =&gt; C0 03 3C\r\n04 =&gt; C0 04 3B\r\n05 =&gt; C0 05 3A\r\n06 =&gt; C0 06 39\r\n07 =&gt; C0 07 38\r\n08 =&gt; C0 08 37\r\n09 =&gt; C0 09 36\r\n0A =&gt; C0 0A 35<\/pre>\n<p>A start byte (&#8216;C0&#8217;) plus the payload\u00a0 plus and end byte (&#8216;3F&#8217; i.e. the complement of &#8216;C0&#8217; minus the payload).<\/p>\n<p>Great! Not even an initialization sequence!<\/p>\n<p>So disconnect the Interception Cable male plug and replace the Bus Pirate with the FTDI Beefy 3 adapter, set &#8216;\/dev\/ttyUSB3&#8217; to 115200 and raw mode and test several bash commands.<\/p>\n<p>Not totally clear yet but this works:<\/p>\n<p>&nbsp;<\/p>\n<pre>#!\/usr\/bin\/env bash\r\n\r\n# sync\r\nfor i in {1..50000}\r\ndo\r\n    echo -e -n \"\\x00\" &gt; \/dev\/ttyUSB3\r\ndone\r\n\r\nfor i in {1..50000}\r\ndo\r\n    echo -e -n \"\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" &gt; \/dev\/ttyUSB3\r\ndone\r\n<\/pre>\n<p>(that &#8216;echo&#8217; command is just a line)<\/p>\n<p>Now the usual voodoo explanation:<\/p>\n<p>The first byte sent is like a read command. I got success with &#8217;02&#8217;, &#8217;04&#8217;, &#8216;0F&#8217;, &#8217;27&#8217; and &#8216;FF&#8217; and 3 different behaviors.<\/p>\n<p>The remaining 15 bytes (&#8217;00&#8217;) are like the inital synchronization commands&#8230; I don&#8217;t think they are valuable data and sending a &#8216;break&#8217; to the TX line for enough time would do the same&#8230; but I just can&#8217;t find a way to send a break.<\/p>\n<p>So the 3 different behaviors:<\/p>\n<ul>\n<li>&#8217;02&#8217; gets a lot of 3-byte messages from the Motion Sensor. Probably one message for each &#8217;02&#8217;, I suspect 50 messages per second but need to check that. After a few minutes, it stops sending data.<\/li>\n<li>&#8216;FF&#8217; gets much less messages, about 1 per second. And the message is now 5-bytes long: &#8216;7B C1&#8217; or &#8216;7B C2&#8217; followed by the 3-byte message above (like &#8216;C0 00 3F&#8217;). And after a few minutes the sensor also stops sending data. So &#8216;7B C1&#8217; or &#8216;7B C2&#8217; are warnings from the Sensor stating that it expects something more.<\/li>\n<li>Finally &#8217;04&#8217;, &#8216;0F&#8217; and &#8217;27&#8217; (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 &#8216;7B C1&#8217; warnings followed by a read).<\/li>\n<\/ul>\n<p>Now the interesting part is that if I keep moving something in front of the sensor it doesn&#8217;t &#8220;expire&#8221;. So it is probably some power saving definition, it would be nice if we could disable it.<\/p>\n<p>So perhaps I&#8217;ve found a way to make my own sensor: if I can emulate the AutoID of the WeDo 2.0 Motion Sensor (device type &#8217;23h&#8217;) I just need to send it short 3-byte messages (just 11 different values but that would be a start).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;s start with a simple sensor: the 45304 LEGO WeDo 2.0 Motion Sensor Procedure: connect the male plug of the Powered Up Interception Cable to LEGO BOOST Move Hub (port &hellip; <a href=\"https:\/\/ofalcao.pt\/blog\/2018\/sniffing-the-lego-wedo-2-0-motion-sensor\" class=\"more-link\">Continuar a ler<span class=\"screen-reader-text\"> &#8220;Sniffing the LEGO WeDo 2.0 Motion Sensor&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[],"series":[],"class_list":["post-1428","post","type-post","status-publish","format-standard","hentry","category-sem-categoria"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2Mhyv-n2","_links":{"self":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1428","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/comments?post=1428"}],"version-history":[{"count":0,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1428\/revisions"}],"wp:attachment":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/media?parent=1428"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/categories?post=1428"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/tags?post=1428"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/series?post=1428"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}