{"id":1342,"date":"2018-07-27T11:41:11","date_gmt":"2018-07-27T10:41:11","guid":{"rendered":"https:\/\/ofalcao.pt\/blog\/?p=1342"},"modified":"2018-07-29T23:11:49","modified_gmt":"2018-07-29T22:11:49","slug":"the-ble-properties","status":"publish","type":"post","link":"https:\/\/ofalcao.pt\/blog\/2018\/the-ble-properties","title":{"rendered":"The BLE properties"},"content":{"rendered":"<div class=\"seriesmeta\">This post is part 2 of 2 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/lego-powered-up-remote-control\" class=\"series-337\" title=\"LEGO Powered Up Remote Control\">LEGO Powered Up Remote Control<\/a><\/div><p>First things first: the Remote Control BT Address and friendly name:<\/p>\n<p><a href=\"https:\/\/macaddresschanger.com\/bluetooth-mac-lookup\/A4%3A34%3AF1\">A4:34:F1<\/a>:CE:DC:A2\u00a0 &#8220;Handset&#8221;<\/p>\n<p>The BT address is not a LEGO one like the BOOST (<a href=\"https:\/\/macaddresschanger.com\/bluetooth-mac-lookup\/00%3A16%3A53\">00:16:53<\/a>, &#8220;LEGO System A\/S IE Electronics Division&#8221;) or the Powered Up (<a href=\"https:\/\/macaddresschanger.com\/bluetooth-mac-lookup\/90%3A84%3A2B\">90:84:2B<\/a>, &#8220;LEGO System A\/S&#8221;). It&#8217;s a Texas Instruments chipset, probably something like the <a href=\"http:\/\/www.ti.com\/product\/cc2640\">CC2640<\/a>, a ARM microcontroller with embedded BLE functions.<\/p>\n<p>The usual browsing of properties with gatttool reveals 3 primary services and a few characteristics:<\/p>\n<pre>primary\r\nattr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb\r\nattr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34fb\r\nattr handle: 0x0009, end grp handle: 0xffff uuid: 00001623-1212-efde-1623-785feabcd123<\/pre>\n<pre>characteristics \r\nhandle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb\r\nhandle: 0x000a, char properties: 0x1c, char value handle: 0x000b, uuid: 00001624-1212-efde-1623-785feabcd123<\/pre>\n<pre>char-desc \r\nhandle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb\r\nhandle: 0x0009, uuid: 00002800-0000-1000-8000-00805f9b34fb\r\nhandle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb\r\nhandle: 0x000b, uuid: 00001624-1212-efde-1623-785feabcd123\r\nhandle: 0x000c, uuid: 00002902-0000-1000-8000-00805f9b34fb\r\nhandle: 0x000d, uuid: 00002901-0000-1000-8000-00805f9b34fb<\/pre>\n<p>More details from the Nordic nRF Connect app:<\/p>\n<p>The first primary service (1800, Genneric Access) has 3 chars:<br \/>\nDevice Name: Handset<br \/>\nAppearance: Unknown<br \/>\nPeripheral Preferred Connection Parameters: Connection Interval: 100.00ms-200.00ms, Slave Latency:0, Supervision Timeout Multiplier: 1000<\/p>\n<p>The second primary service (1801, Generic Attribute) is empty. Not unusual since it is optional.<\/p>\n<p>The last primary service has the same UUID already present on BOOST and Powered Up hubs (i.e. &#8220;00001624-1212-efde-1623-785feabcd123&#8221;). And like those it has only one characteristic, &#8220;LWP ProtocolChar&#8221;.<\/p>\n<p>(side note: LWP might mean Light Weight Process or LEGO Wireless Protocol or just Lets Worsen your Pain)<\/p>\n<p>Thats good: since this &#8220;Handset&#8221; shares the same primary service UUID of the other PF2 \/ Powered Up devices, it might also work in the same way.<\/p>\n<p>So lets enable notifications and see what we got:<\/p>\n<pre>char-write-req 0x0c 0100\r\nNotification handle = 0x000b value: 0f 00 04 00 01 37 00 00 00 00 10 00 00 00 10 \r\nNotification handle = 0x000b value: 0f 00 04 01 01 37 00 00 00 00 10 00 00 00 10 \r\nNotification handle = 0x000b value: 0f 00 04 34 01 17 00 00 00 00 10 00 00 00 10 \r\nNotification handle = 0x000b value: 0f 00 04 3b 01 14 00 02 00 00 00 02 00 00 00 \r\nNotification handle = 0x000b value: 0f 00 04 3c 01 38 00 00 00 00 10 00 00 00 10<\/pre>\n<p>Yeap! 4 devices on 5 different ports:<\/p>\n<ul>\n<li>Device &#8217;37&#8217; on ports &#8217;00&#8217; and &#8217;01&#8217;<\/li>\n<li>Device &#8217;17&#8217; present on port &#8217;34&#8217;<\/li>\n<li>Device &#8217;14&#8217; present on port &#8216;3B&#8217;<\/li>\n<li>Device &#8217;38&#8217; present on port &#8216;3C&#8217;<\/li>\n<\/ul>\n<p>Nathan already told me that device &#8217;37&#8217; is associated to the buttons. So two &#8220;pads&#8221; of buttons, one on port &#8217;00&#8217; and other on port &#8217;01&#8217;.<\/p>\n<p>Device &#8217;17&#8217; is the RGB LED on the BOOST. I&#8217;ll look to it later.<\/p>\n<p>Device &#8217;14&#8217; and &#8217;38&#8217;, like Nathan pointed, seem Voltage and Current readings. We can activate each with:<\/p>\n<pre>char-write-req 0x0b 0a0041[3B\/3C]000100000001<\/pre>\n<p>The first (3B) will generate regular messages like &#8217;06 00 45 3b a5 0b&#8217; and the second (3C) also generates regular messages like &#8217;05 00 45 3c cc&#8217;<\/p>\n<p>So the payload is &#8216;3B A5 0B&#8217; and &#8216;3C CC&#8217;, reverting and converting to decimal it gives<\/p>\n<p>0BA53B = 763195 = 7.63\u00a0 Volt ? hard to believe with just 4 AAA batteries<\/p>\n<p>converting to float = 0.00503671 = 5.037 Volt? Perhaps<\/p>\n<p>CC 3C = 52284 = 52 mA ? Why just two bytes and not 4? Hmm&#8230;.<\/p>\n<p>We can also deactivate with<\/p>\n<pre>char-write-req 0x0b 0a0041[3B\/3C]000100000000<\/pre>\n<p>Really not important, at least for now. Let&#8217;s look to the button pads and the RGB LED and give them a good use:<\/p>\n<pre>char-write-req --handle 0x0b --value 080081341151000X<\/pre>\n<p>The command works like the BOOST (just changed the port, &#8217;32&#8217; to &#8217;34&#8217;) and it accepts the same 10 values:<\/p>\n<pre>OFF=0\r\nPINK=1\r\nPURPLE=2\r\nBLUE=3\r\nLIGHTBLUE=4\r\nLIGHTGREEN=5\r\nGREEN=6\r\nYELLOW=7\r\nORANGE=9\r\nRED=9\r\nWHITE=A<\/pre>\n<p>Once again, not sure about the color names but those above are good enough for me&#8230;<\/p>\n<p>Now the buttons, we activate them with:<\/p>\n<pre>char-write-req 0x0b 0a004100000100000001 (Left or 'A')\r\nchar-write-req 0x0b 0a004101000100000001 (Right or 'B')<\/pre>\n<p>so we now receive a notification each time there is a state change:<\/p>\n<p>Left or A+ on then off:<\/p>\n<pre>05 00 45 00 01\r\n05 00 45 00 00<\/pre>\n<p>Left or A- on then off:<\/p>\n<pre>05 00 45 00 ff\r\n05 00 45 00 00<\/pre>\n<p>Left or A Red on then off:<\/p>\n<pre>05 00 45 00 7f\r\n05 00 45 00 00<\/pre>\n<p>And the same happens for Right or B, just the fourth byte is now &#8217;01&#8217; instead of &#8217;00&#8217;.<\/p>\n<p>So we can use our new &#8216;Handset&#8217; with whatever BLE capable device we want.<\/p>\n<p>Next bash shell loops through the 10 RGB possible values:<\/p>\n<pre>#!\/usr\/bin\/env bash\r\n\r\n#colors\r\nOFF=0\r\nPINK=1\r\nPURPLE=2\r\nBLUE=3\r\nLIGHTBLUE=4\r\nLIGHTGREEN=5\r\nGREEN=6\r\nYELLOW=7\r\nORANGE=9\r\nRED=9\r\nWHITE=A\r\n\r\nfunction remoteLED () {\r\n    gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0b --value 080081341151000$1\r\n}\r\n\r\n# activate notifications and keep changing colors\r\ngatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0c --value 0100\r\n\r\nwhile :\r\ndo\r\n    for color in $OFF $PINK $PURPLE $BLUE $LIGHTBLUE $LIGHTGREEN $GREEN $YELLOW $ORANGE $RED $WHITE; do\r\n        remoteLED $color\r\n        sleep 1\r\n    done\r\ndone<\/pre>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"LEGO Powered Up Train Remote Control: RGB LED\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/qzXTLv_wWo0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>And the bash script for ev3dev from the last post:<\/p>\n<pre>#!\/usr\/bin\/env bash\r\n\r\n# identify motors\r\nMOTORA=$(ls \/sys\/class\/lego-port\/port4\/ev3-ports\\:outA\\:lego-ev3-l-motor\/tacho-motor\/)\r\nMOTORB=$(ls \/sys\/class\/lego-port\/port5\/ev3-ports\\:outB\\:lego-ev3-l-motor\/tacho-motor\/)\r\n\r\necho \"outA:\"$MOTORA\r\necho \"outB:\"$MOTORB\r\n\r\nMOTORSPEED=1050\r\nMOTORDELAY=0.1\r\n\r\n# reset motor positions and initialize\r\necho reset &gt; \/sys\/class\/tacho-motor\/$MOTORA\/command\r\necho reset &gt; \/sys\/class\/tacho-motor\/$MOTORB\/command\r\necho brake &gt; \/sys\/class\/tacho-motor\/$MOTORA\/stop_action\r\necho $MOTORSPEED &gt; \/sys\/class\/tacho-motor\/$MOTORA\/speed_sp\r\necho brake &gt; \/sys\/class\/tacho-motor\/$MOTORB\/stop_action\r\necho $MOTORSPEED &gt; \/sys\/class\/tacho-motor\/$MOTORB\/speed_sp\r\n\r\n\r\nfunction finish {\r\n    # terminate all subshells\r\n    kill 0\r\n    # reset all motors\r\n    echo reset &gt; \/sys\/class\/tacho-motor\/$MOTORA\/command\r\n    echo reset &gt; \/sys\/class\/tacho-motor\/$MOTORB\/command\r\n}\r\ntrap finish EXIT\r\n\r\n# activate left pad\r\ngatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0b --value 0a004100000100000001\r\n# activate right panel\r\ngatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0b --value 0a004101000100000001\r\n\r\n# activate notifications and keep listening\r\nwhile read -r line; do\r\n    message=$( echo \"$line\" | cut -f2 -d: )\r\n    \r\n#    echo \"Line: $line\"\r\n#    echo \"Msg: $message\"\r\n\r\n    if  [[ $message = *\"05 00 45 00 01\"* ]]; then\r\n        echo \"L+ ON\"\r\n        echo $MOTORSPEED &gt; \/sys\/class\/tacho-motor\/$MOTORB\/speed_sp\r\n        echo run-forever &gt; \/sys\/class\/tacho-motor\/$MOTORB\/command\r\n\r\n    elif [[ $message = *\"05 00 45 00 7f\"* ]]; then\r\n        echo \"Lr ON\"\r\n\r\n    elif [[ $message = *\"05 00 45 00 ff\"* ]]; then\r\n        echo \"L- ON\"\r\n        echo -$MOTORSPEED &gt; \/sys\/class\/tacho-motor\/$MOTORB\/speed_sp\r\n        echo run-forever &gt; \/sys\/class\/tacho-motor\/$MOTORB\/command\r\n\r\n    elif [[ $message = *\"05 00 45 00 00\"* ]]; then\r\n        echo \"L  Off\"\r\n        echo stop &gt; \/sys\/class\/tacho-motor\/$MOTORB\/command\r\n\r\n    elif [[ $message = *\"05 00 45 01 01\"* ]]; then\r\n        echo \"R+ ON\"\r\n        echo $MOTORSPEED &gt; \/sys\/class\/tacho-motor\/$MOTORA\/speed_sp\r\n        echo run-forever &gt; \/sys\/class\/tacho-motor\/$MOTORA\/command\r\n\r\n    elif [[ $message = *\"05 00 45 01 7f\"* ]]; then\r\n        echo \"Rr ON\"\r\n\r\n    elif [[ $message = *\"05 00 45 01 ff\"* ]]; then\r\n        echo \"R- ON\"\r\n        echo -$MOTORSPEED &gt; \/sys\/class\/tacho-motor\/$MOTORA\/speed_sp\r\n        echo run-forever &gt; \/sys\/class\/tacho-motor\/$MOTORA\/command\r\n\r\n    elif [[ $message = *\"05 00 45 01 00\"* ]]; then\r\n        echo \"R  Off\"\r\n        echo stop &gt; \/sys\/class\/tacho-motor\/$MOTORA\/command\r\n\r\n    fi\r\n\r\ndone &lt; &lt;(gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0c --value 0100 --listen)\r\n<\/pre>\n<p>[edit]<br \/>\nOoops, forgot that EV3 already has an internal BT interface. Sometimes this script works, sometimes don&#8217;t. That&#8217;s because I don&#8217;t specify which BT interface will be used by <strong>gatttool<\/strong> command. We should use &#8216;-i hci0&#8217; or &#8216;-i hci1&#8217; but sometimes the kernel decides that <strong>hci0<\/strong> is the internal one, sometimes it decides that it is the USB one.<\/p>\n<p>Perhaps a udev rule can force hci0 to always be the USB one, don&#8217;t know. Bad quickfix: remove the USB BT adapter and insert it again, this forces ev3dev to switch hci devices.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">This post is part 2  of 2 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/lego-powered-up-remote-control\" class=\"series-337\" title=\"LEGO Powered Up Remote Control\">LEGO Powered Up Remote Control<\/a><\/div><p>First things first: the Remote Control BT Address and friendly name: A4:34:F1:CE:DC:A2\u00a0 &#8220;Handset&#8221; The BT address is not a LEGO one like the BOOST (00:16:53, &#8220;LEGO System A\/S IE Electronics Division&#8221;) or the Powered Up (90:84:2B, &#8220;LEGO System A\/S&#8221;). It&#8217;s a Texas Instruments chipset, probably something like the CC2640, a ARM microcontroller with embedded BLE &hellip; <a href=\"https:\/\/ofalcao.pt\/blog\/2018\/the-ble-properties\" class=\"more-link\">Continuar a ler<span class=\"screen-reader-text\"> &#8220;The BLE properties&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","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":[337],"class_list":["post-1342","post","type-post","status-publish","format-standard","hentry","category-sem-categoria","series-lego-powered-up-remote-control"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2Mhyv-lE","_links":{"self":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1342","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=1342"}],"version-history":[{"count":0,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1342\/revisions"}],"wp:attachment":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/media?parent=1342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/categories?post=1342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/tags?post=1342"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/series?post=1342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}