{"id":923,"date":"2016-06-26T20:38:53","date_gmt":"2016-06-26T19:38:53","guid":{"rendered":"http:\/\/ofalcao.pt\/blog\/?p=923"},"modified":"2016-06-26T20:38:53","modified_gmt":"2016-06-26T19:38:53","slug":"wedo-2-0-led-button-service","status":"publish","type":"post","link":"https:\/\/ofalcao.pt\/blog\/2016\/wedo-2-0-led-button-service","title":{"rendered":"WeDo 2.0 LED Button Service"},"content":{"rendered":"<div class=\"seriesmeta\">This post is part 3 of 6 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/wedo-2-0-reverse-engineering\" class=\"series-269\" title=\"WeDo 2.0 - reverse engineering\">WeDo 2.0 - reverse engineering<\/a><\/div><p>And we continue digging into the\u00a0 WeDo 2.0 Hub primary services, now with the &#8220;Nordic LED Button Service&#8221;<\/p>\n<p><a href=\"https:\/\/flic.kr\/p\/HZ3LHo\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/farm8.staticflickr.com\/7201\/27556208400_ebf848cce9_z.jpg?resize=360%2C640&#038;ssl=1\" alt=\"WeDo 2.0 Hub BLE services\" width=\"360\" height=\"640\" \/><\/a><\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; primary\r\n...\r\nattr handle: 0x000c, end grp handle: 0x002f uuid: 00001523-1212-efde-1523-785feabcd123\r\n...<\/pre>\n<p>So this Primary service uses handles from 0x000c to 0x002f. Let&#8217;s look deeper:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; characteristics 000c 002f\r\nhandle: 0x000d, char properties: 0x0a, char value handle: 0x000e, uuid: 00001524-1212-efde-1523-785feabcd123\r\nhandle: 0x0010, char properties: 0x12, char value handle: 0x0011, uuid: 00001526-1212-efde-1523-785feabcd123\r\nhandle: 0x0014, char properties: 0x10, char value handle: 0x0015, uuid: 00001527-1212-efde-1523-785feabcd123\r\nhandle: 0x0018, char properties: 0x12, char value handle: 0x0019, uuid: 00001528-1212-efde-1523-785feabcd123\r\nhandle: 0x001c, char properties: 0x12, char value handle: 0x001d, uuid: 00001529-1212-efde-1523-785feabcd123\r\nhandle: 0x0020, char properties: 0x12, char value handle: 0x0021, uuid: 0000152a-1212-efde-1523-785feabcd123\r\nhandle: 0x0024, char properties: 0x08, char value handle: 0x0025, uuid: 0000152b-1212-efde-1523-785feabcd123\r\nhandle: 0x0027, char properties: 0x0a, char value handle: 0x0028, uuid: 0000152c-1212-efde-1523-785feabcd123\r\nhandle: 0x002a, char properties: 0x02, char value handle: 0x002b, uuid: 0000152d-1212-efde-1523-785feabcd123\r\nhandle: 0x002d, char properties: 0x08, char value handle: 0x002e, uuid: 0000152e-1212-efde-1523-785feabcd123\r\n\r\n[A0:E6:F8:1E:58:57][LE]&gt; char-desc 000c 002f\r\nhandle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb\r\nhandle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x000e, uuid: 00001524-1212-efde-1523-785feabcd123\r\nhandle: 0x000f, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0010, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0011, uuid: 00001526-1212-efde-1523-785feabcd123\r\nhandle: 0x0012, uuid: 00002902-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0013, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0014, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0015, uuid: 00001527-1212-efde-1523-785feabcd123\r\nhandle: 0x0016, uuid: 00002902-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0017, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0018, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0019, uuid: 00001528-1212-efde-1523-785feabcd123\r\nhandle: 0x001a, uuid: 00002902-0000-1000-8000-00805f9b34fb\r\nhandle: 0x001b, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x001c, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x001d, uuid: 00001529-1212-efde-1523-785feabcd123\r\nhandle: 0x001e, uuid: 00002902-0000-1000-8000-00805f9b34fb\r\nhandle: 0x001f, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0020, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0021, uuid: 0000152a-1212-efde-1523-785feabcd123\r\nhandle: 0x0022, uuid: 00002902-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0023, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0024, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0025, uuid: 0000152b-1212-efde-1523-785feabcd123\r\nhandle: 0x0026, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0027, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0028, uuid: 0000152c-1212-efde-1523-785feabcd123\r\nhandle: 0x0029, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x002a, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x002b, uuid: 0000152d-1212-efde-1523-785feabcd123\r\nhandle: 0x002c, uuid: 00002901-0000-1000-8000-00805f9b34fb\r\nhandle: 0x002d, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x002e, uuid: 0000152e-1212-efde-1523-785feabcd123\r\nhandle: 0x002f, uuid: 00002901-0000-1000-8000-00805f9b34fb<\/pre>\n<p>Lot of things here: 10 characteristics and 36 handles!<\/p>\n<p>The first handle (0x000c) just marks the begin of the service (UUID 2800).<\/p>\n<p>Then we see that there are 10 handles with UUID 2803 (Characteristic Declaration Attribute) and also 10 handles with UUID 2901 (Characteristic User Description) &#8211; these handles mark the begin of each characteristic and also defines its properties, so let&#8217;s read them all\u00a0 (char-read-hnd) and translate it:<\/p>\n<pre style=\"padding-left: 30px;\">Name Char               0x000e  read+write\r\nButton Char             0x0011  notify+read\r\nPort Type Char          0x0015  notify\r\nLow Voltage alert       0x0019  notify+read\r\nHigh Current alert      0x001d  notify+read\r\nLow Signal alert        0x0021  notify+read\r\nTurn off device         0x0025  write\r\nVcc port control        0x0028  read+write\r\nBattery type Indicator  0x002b  read\r\nDisconnect Char         0x002e  write<\/pre>\n<p>Some characteristics also have an handle with UUID 2902 (Client Characteristic Configuration). That&#8217;s used for Notifications &#8211; the 5 characteristics that support this feature use this extra handle to activate or deactivate it.<\/p>\n<p>So let&#8217;s read the 7 handles that are readable:<\/p>\n<pre style=\"padding-left: 30px;\">Name Char               75 30 30 30 31 = u0001\r\nButton Char             00\r\nLow Voltage alert       00\r\nHigh Current alert      00\r\nLow Signal alert        00\r\nVcc port control        01\r\nBattery type Indicator  00<\/pre>\n<p>So &#8216;Name char&#8217; contains the friendly name of my Hub. And it is writable, so what happens if I change it?<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-write-cmd 0x000e 4d616a6f72\r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0x00e\r\nCharacteristic value\/descriptor: 4d 61 6a 6f 72<\/pre>\n<p>Well it retains what I wrote.<\/p>\n<p>And if I now read the &#8216;Device Name&#8217; it is no longer &#8216;u0001&#8217;:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-uuid 0x2A00\r\nhandle: 0x0003 \u00a0\u00a0 \u00a0 value: 4d 61 6a 6f 72<\/pre>\n<p>So now my Hub announces a new name:<\/p>\n<pre>$ sudo hcitool -i hci0 lescan\r\nLE Scan ...\r\nA0:E6:F8:1E:58:57 (unknown)\r\nA0:E6:F8:1E:58:57 Major<\/pre>\n<p><a href=\"https:\/\/flic.kr\/p\/HyQjfA\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/farm8.staticflickr.com\/7693\/27282182134_1b0c6907ac_z.jpg?resize=640%2C360&#038;ssl=1\" alt=\"Changing &#039;Device Name&#039; attribute\" width=\"640\" height=\"360\" \/><\/a><\/p>\n<p>Cool, isn&#8217;t it?<\/p>\n<p>Now the &#8216;Button Char&#8217; just reads zero. But if I press the Hub&#8217;s button while I read it:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0011\r\nCharacteristic value\/descriptor: 01<\/pre>\n<p>it reads &#8216;1&#8217;.<\/p>\n<p>And what about &#8216;Port Type Char&#8217;? It&#8217;s not defined as readable (just &#8216;notify&#8217;) but I can try to read it anyway:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0015\r\nCharacteristic value\/descriptor:<\/pre>\n<p>Hmm&#8230; null value.<\/p>\n<p>But I have nothing connected to the Hub. Let&#8217;s try it again with a motor at port 1:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0015\r\nCharacteristic value\/descriptor: 01 01 00 01 01 00 00 00 01 00 00 00<\/pre>\n<p>And removing the motor again:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0015\r\nCharacteristic value\/descriptor: 01 00<\/pre>\n<p>Interesting &#8211; it&#8217;s not null now.<\/p>\n<p>Let&#8217;s do the same again but on port 2:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0015\r\nCharacteristic value\/descriptor: 02 01 01 01 01 00 00 00 01 00 00 00\r\n\r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 0015\r\nCharacteristic value\/descriptor: 02 00<\/pre>\n<p>So the first byte seems to identify the Port (&#8217;01&#8217; or &#8217;02&#8217;) and the second byte the action (&#8217;01&#8217; might be &#8216;device plugged&#8217; and &#8217;00&#8217; might be &#8216;device removed&#8217;). I have no explanation for the third byte and the other 8 bytes bytes seem to be some kind of identification of the motor.<\/p>\n<p>Now let&#8217;s connect a tilt sensor in port 1 (and nothing in port 2):<\/p>\n<pre>01 01 00 22 00 00 00 10 00 00 00 10<\/pre>\n<p>and then move it to port 2:<\/p>\n<pre>02 01 01 22 00 00 00 10 00 00 00 10<\/pre>\n<p>Now just a distance sensor in port 1:<\/p>\n<pre>01 01 00 23 00 00 00 10 00 00 00 10<\/pre>\n<p>and move it to port 2:<\/p>\n<pre>02 01 01 23 00 00 00 10 00 00 00 10<\/pre>\n<p>Now just the motor again in port 1 and then the tilt sensor in port 2 (two readings):<\/p>\n<pre>01 01 00 01 01 00 00 00 01 00 00 00\r\n02 01 01 22 00 00 00 10 00 00 00 10<\/pre>\n<p>So &#8216;Port Type Char&#8217; doesn&#8217;t describe the ports state, it just shows the last action detected at ports. I think that&#8217;s the reason it&#8217;s not defined as &#8216;notify + read&#8217;, it&#8217;s purpose is just to notify that a change ocurred on ports.<\/p>\n<p>Now we have 3 characteristics named &#8220;Alert&#8221;: Low Voltage Alert, High Current Alert and Low Signal Alert. Their names seem clear enough to understand their purpose and since all read zero everything seems to be OK. But let&#8217;s try to force an &#8220;High Current Alert&#8221; &#8211; make the motor run, block it and read the handle:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 00 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 00 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 00 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 00 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 01 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 01 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 01 \r\n[A0:E6:F8:1E:58:57][LE]&gt; char-read-hnd 001d\r\nCharacteristic value\/descriptor: 00<\/pre>\n<p>When I block the motor with my hand, the Hub beeps and flashes the LED twice (in yellow). And sometimes the Alert reads &#8217;01&#8217;.<\/p>\n<p>But instead of reading several times the handler, we can activate &#8216;Notifications&#8217; by turning ON the &#8216;notification&#8217; flag in the &#8216;Client Characteristic Configuration&#8217; and then just wait for the Hub to send the notification when the High Current Alert changes it&#8217;s state:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-write-req 001e 0100 -listen\r\nCharacteristic value was written successfully\r\n[A0:E6:F8:1E:58:57][LE]&gt; char-write-cmd 003d 01010164\r\nNotification handle = 0x001d value: 01 \r\nNotification handle = 0x001d value: 00<\/pre>\n<p>We used a different write command: &#8216;char-write-req&#8217; instead of &#8216;char-write-cmd&#8217; expects an answer from the device and &#8216;-listen&#8217; keeps listening for future &#8216;answers&#8217;.<\/p>\n<p>Now the &#8216;Vcc port control&#8217; name isn&#8217;t much clear about it&#8217;s purpose. It reads &#8216;1&#8217; but it&#8217;s also writable&#8230; does it allows us to control power in the ports? No matter what I write to 0x003d it seems to retain only &#8216;0&#8217; or &#8216;1&#8217; and when I write &#8216;0&#8217; to it while the motor is running it keeps running.<\/p>\n<p>&#8216;Battery type indicator&#8217; reads zero, I guess that it identifies the kind of battery being used. I&#8217;m using 2 AA alcaline batteries, will try again with the LiPo battery when I get it.<\/p>\n<p>And finally the 2 writable-only characteristics: &#8216;Disconnect Char&#8217; and &#8216;Turn off device&#8217;. They also seem quite clear about their purpose:<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-write-cmd 002e 01\r\n[A0:E6:F8:1E:58:57][LE]&gt; \r\n(gatttool:8257): GLib-WARNING **: Invalid file descriptor.\r\n\r\n[A0:E6:F8:1E:58:57][LE]&gt; connect\r\nAttempting to connect to A0:E6:F8:1E:58:57\r\nConnection successful<\/pre>\n<p>Writing to &#8216;Disconnect Char&#8217; makes the Hub disconnects but keeps it in discovery mode so I cpuld reconnect to it.<\/p>\n<pre>[A0:E6:F8:1E:58:57][LE]&gt; char-write-cmd 0025 01\r\n[A0:E6:F8:1E:58:57][LE]&gt; \r\n(gatttool:8257): GLib-WARNING **: Invalid file descriptor.\r\n\r\n[A0:E6:F8:1E:58:57][LE]&gt; connect\r\nAttempting to connect to A0:E6:F8:1E:58:57\r\n[A0:E6:F8:1E:58:57][LE]&gt; \r\nError: connect error: Connection refused (111)<\/pre>\n<p>Writing to &#8216;Turn off device&#8217; really turns it off.<\/p>\n<p>So that&#8217;s it for &#8216;Nordic LED button service&#8217;. What LED, you ask? Well, the Android App is from Nordic and they have some examples on the Net with this UUID so my explanation is that LEGO used part of their code for the &#8216;button&#8217; part without changing the UUID so the App recognizes it this way.<\/p>\n<p>Next post: Motors and LED.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">This post is part 3  of 6 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/wedo-2-0-reverse-engineering\" class=\"series-269\" title=\"WeDo 2.0 - reverse engineering\">WeDo 2.0 - reverse engineering<\/a><\/div><p>And we continue digging into the\u00a0 WeDo 2.0 Hub primary services, now with the &#8220;Nordic LED Button Service&#8221; [A0:E6:F8:1E:58:57][LE]&gt; primary &#8230; attr handle: 0x000c, end grp handle: 0x002f uuid: 00001523-1212-efde-1523-785feabcd123 &#8230; So this Primary service uses handles from 0x000c to 0x002f. Let&#8217;s look deeper: [A0:E6:F8:1E:58:57][LE]&gt; characteristics 000c 002f handle: 0x000d, char properties: 0x0a, char value &hellip; <a href=\"https:\/\/ofalcao.pt\/blog\/2016\/wedo-2-0-led-button-service\" class=\"more-link\">Continuar a ler<span class=\"screen-reader-text\"> &#8220;WeDo 2.0 LED Button Service&#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":[269],"class_list":["post-923","post","type-post","status-publish","format-standard","hentry","category-sem-categoria","series-wedo-2-0-reverse-engineering"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2Mhyv-eT","_links":{"self":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/923","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=923"}],"version-history":[{"count":0,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/923\/revisions"}],"wp:attachment":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/media?parent=923"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/categories?post=923"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/tags?post=923"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/series?post=923"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}