{"id":5476,"date":"2017-09-21T10:41:52","date_gmt":"2017-09-21T01:41:52","guid":{"rendered":"https:\/\/gunmagisgeek.com\/wordpress\/?p=5476"},"modified":"2017-09-21T12:11:40","modified_gmt":"2017-09-21T03:11:40","slug":"microbit-web-bluetooth-api-%e3%81%a7led-matrix%e3%82%92%e3%83%81%e3%82%ab%e3%83%81%e3%82%ab%e3%81%95%e3%81%9b%e3%82%8b%e3%80%82","status":"publish","type":"post","link":"https:\/\/gunmagisgeek.com\/blog\/microbit\/5476","title":{"rendered":"Micro:bit + Web Bluetooth API \u3067LED Matrix\u3092\u30c1\u30ab\u30c1\u30ab\u3055\u305b\u308b\u3002"},"content":{"rendered":"<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\">\n<p lang=\"en\" dir=\"ltr\">Web Blutooth API + Micro:bit LED matrix <a href=\"https:\/\/twitter.com\/hashtag\/microbit?src=hash&amp;ref_src=twsrc%5Etfw\">#microbit<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/chibibit?src=hash&amp;ref_src=twsrc%5Etfw\">#chibibit<\/a> <a href=\"https:\/\/t.co\/CGoAyFm8A7\">pic.twitter.com\/CGoAyFm8A7<\/a><\/p>\n<p>&mdash; \u6e05\u6c34\u6b63\u884c (@_shimizu) <a href=\"https:\/\/twitter.com\/_shimizu\/status\/909941838567530496?ref_src=twsrc%5Etfw\">September 19, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p><a href=\"https:\/\/shimz.me\/example\/WebBluetooth\/LEDmatrix\/\">example<\/a><\/p>\n<h2>\u6982\u8981<\/h2>\n<p>Web bluetooth API\u3092\u4f7f\u3063\u3066maicro:bit\u306eLED on\/off\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb\u3059\u308b\u3002<\/p>\n<h2>\u4e8b\u524d\u6e96\u5099<\/h2>\n<ul>\n<li>\u30da\u30a2\u30ea\u30f3\u30b0\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u89e3\u9664\u3057\u3001\u3059\u3079\u3066\u306eBLE\u30b5\u30fc\u30d3\u30b9\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\u4ee5\u4e0b\u306e\u4f5c\u696d\u3092\u884c\u3046\u5fc5\u8981\u304c\u3042\u308b\u3002\u53c2\u8003\uff1a<a href=\"https:\/\/github.com\/sandeepmistry\/node-bbc-microbit#flashing-microbit-firmware\">Flashing micro:bit firmware<\/a>\n<ol>\n<li><a href=\"https:\/\/github.com\/sandeepmistry\/node-bbc-microbit\/tree\/master\/firmware\">hex\u30d5\u30a1\u30a4\u30eb<\/a>\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u3002<\/li>\n<li>USB\u30b1\u30fc\u30d6\u30eb\u3092\u4f7f\u7528\u3057\u3066\u30de\u30a4\u30af\u30ed\u30d3\u30c3\u30c8\u3092PC\u306b\u63a5\u7d9a\u3002<\/li>\n<li>hex\u30d5\u30a1\u30a4\u30eb\u3092micro\uff1abit\u30c7\u30a3\u30b9\u30af\u30c9\u30e9\u30a4\u30d6\u306b\u30b3\u30d4\u30fc\u3059\u308b\u3002<\/li>\n<li>micro:bit\u3092\u518d\u8d77\u52d5\u3059\u308b\u3002<\/li>\n<li>LED\u306b\u30c9\u30c3\u30c8\u304c\u8868\u793a\u3055\u308c\u308b\u306e\u3067\u3001\u50be\u3051\u3066\u5186\u3092\u63cf\u304f(\u30ad\u30e3\u30ea\u30d6\u30ec\u30fc\u30b7\u30e7\u30f3)<\/li>\n<\/ol>\n<\/li>\n<li>\u30b5\u30fc\u30d3\u30b9\uff0f\u30ad\u30e3\u30e9\u30af\u30bf\u30ea\u30b9\u30c6\u30a3\u30c3\u30af\u306eUUID\u3092\u8abf\u3079\u3066\u304a\u304f\u3002<br \/><a href=\"https:\/\/lancaster-university.github.io\/microbit-docs\/resources\/bluetooth\/bluetooth_profile.html\">\u3053\u3053<\/a>\u3067\u78ba\u8a8d\u3067\u304d\u307e\u3059\u3002<\/li>\n<\/ul>\n<h2>\u30b5\u30f3\u30d7\u30eb<\/h2>\n<pre class=\"lang:xhtml decode:true \" title=\"index.html\" >&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;meta charset=\"utf-8\" \/&gt;\r\n&lt;meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"\/&gt;\r\n&lt;title&gt;Micro:bit LED MATRIX\u9001\u4fe1&lt;\/title&gt;\r\n&lt;style&gt;\r\nform {\r\n    margin-top:1em; \r\n}\r\nlabel{\r\n  display:inline-block;\r\n  height:10px;\r\n  width:10px;\r\n  cursor: pointer;\r\n  padding:5px;\r\n  border: 1px solid #434343;\r\n  border-radius: 5px;\r\n  background-color:gray;\r\n}\r\ninput{\r\n  display: none;\r\n}\r\n.check_box:checked + .label {\r\n  background-color: red;\r\n}    \r\n&lt;\/style&gt;\r\n\r\n&lt;\/head&gt;\r\n\r\n&lt;body&gt;\r\n&lt;h1&gt;Micro:bit LED MATRIX\u9001\u4fe1&lt;\/h1&gt;\r\n&lt;button id=\"connect\"&gt;\u63a5\u7d9a&lt;\/button&gt;\r\n&lt;button id=\"disconnect\"&gt;\u5207\u65ad&lt;\/button&gt;\r\n&lt;br&gt;\r\n&lt;form&gt;\r\n    &lt;div&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb1-1\" name=\"cb1-1\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb1-1\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb1-2\" name=\"cb1-2\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb1-2\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb1-3\" name=\"cb1-3\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb1-3\"&gt;&lt;\/label&gt;&lt;input type=\"checkbox\" class=\"check_box\" id=\"cb1-4\" name=\"cb1-4\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb1-4\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb1-5\" name=\"cb1-5\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb1-5\"&gt;&lt;\/label&gt;\r\n    &lt;\/div&gt;\r\n    &lt;div&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb2-1\" name=\"cb2-1\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb2-1\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb2-2\" name=\"cb2-2\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb2-2\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb2-3\" name=\"cb2-3\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb2-3\"&gt;&lt;\/label&gt;&lt;input type=\"checkbox\" class=\"check_box\" id=\"cb2-4\" name=\"cb2-4\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb2-4\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb2-5\" name=\"cb2-5\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb2-5\"&gt;&lt;\/label&gt;\r\n    &lt;\/div&gt;\r\n    \r\n    &lt;div&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb3-1\" name=\"cb3-1\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb3-1\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb3-2\" name=\"cb3-2\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb3-2\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb3-3\" name=\"cb3-3\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb3-3\"&gt;&lt;\/label&gt;&lt;input type=\"checkbox\" class=\"check_box\" id=\"cb3-4\" name=\"cb3-4\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb3-4\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb3-5\" name=\"cb3-5\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb3-5\"&gt;&lt;\/label&gt;\r\n    &lt;\/div&gt;\r\n    \r\n    &lt;div&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb4-1\" name=\"cb4-1\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb4-1\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb4-2\" name=\"cb4-2\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb4-2\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb4-3\" name=\"cb4-3\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb4-3\"&gt;&lt;\/label&gt;&lt;input type=\"checkbox\" class=\"check_box\" id=\"cb4-4\" name=\"cb4-4\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb4-4\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb4-5\" name=\"cb4-5\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb4-5\"&gt;&lt;\/label&gt;\r\n    &lt;\/div&gt;\r\n    \r\n    &lt;div&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb5-1\" name=\"cb5-1\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb5-1\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb5-2\" name=\"cb5-2\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb5-2\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb5-3\" name=\"cb5-3\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb5-3\"&gt;&lt;\/label&gt;&lt;input type=\"checkbox\" class=\"check_box\" id=\"cb5-4\" name=\"cb5-4\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb5-4\"&gt;&lt;\/label&gt;\r\n        &lt;input type=\"checkbox\" class=\"check_box\" id=\"cb5-5\" name=\"cb5-5\" \/&gt;\r\n        &lt;label class=\"label\" for=\"cb5-5\"&gt;&lt;\/label&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/form&gt;\r\n\r\n&lt;script src=\"\/\/cdnjs.cloudflare.com\/ajax\/libs\/d3\/4.3.0\/d3.min.js\"&gt;&lt;\/script&gt;    \r\n    \r\n&lt;script src=\"index.js\"&gt;&lt;\/script&gt;    \r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<pre class=\"lang:js decode:true \" title=\"index.js\" >var bluetoothDevice;\r\nvar characteristic;\r\n\r\n\/\/chibi:bit BLE UUID\r\nvar LED_SERVICE_UUID                        = 'e95dd91d-251d-470a-a062-fa1922dfa9a8';\r\nvar LED_MATRIX_CHARACTERISTIC_UUID          = 'E95D7B77-251D-470A-A062-FA1922DFA9A8'.toLowerCase();\r\n\r\n\r\n\/\/\u30dc\u30bf\u30f3\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u30fc\r\nd3.select(\"#connect\").on(\"click\", connect);\r\nd3.select(\"#disconnect\").on(\"click\", disconnect);    \r\nd3.select(\"#send\").on(\"click\", sendMessage);    \r\n\r\n\r\n\r\n\/\/chibi:bit\u306b\u63a5\u7d9a\u3059\u308b\r\nfunction connect() {\r\n  let options = {};\r\n\r\n  \r\n  \/\/options.acceptAllDevices = true;\r\n  \r\n  options.filters = [\r\n    {services: [LED_SERVICE_UUID]},\r\n    {name: \"BBC micro:bit [vaget]\"}\r\n  ];\r\n  \r\n\r\n  navigator.bluetooth.requestDevice(options)\r\n  .then(device =&gt; {\r\n    bluetoothDevice = device;\r\n    console.log(\"device\", device);\r\n    return device.gatt.connect();\r\n  })\r\n  .then(server =&gt;{\r\n    console.log(\"server\", server)\r\n    return server.getPrimaryService(LED_SERVICE_UUID);\r\n  })\r\n  .then(service =&gt; {\r\n    console.log(\"service\", service)\r\n    return service.getCharacteristic(LED_MATRIX_CHARACTERISTIC_UUID)\r\n  })\r\n  .then(chara =&gt; {\r\n    console.log(\"characteristic\", chara)\r\n    alert(\"BLE\u63a5\u7d9a\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002\");\r\n    characteristic = chara;\r\n    \r\n  })  \r\n  .catch(error =&gt; {\r\n    console.log(error);\r\n  });    \r\n}\r\n\r\n    d3.select(\"form\").on(\"change\",sendMessage)\r\n\r\n\/\/LED\u306b\u8868\u793a\u3059\u308b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1\r\nfunction sendMessage() {\r\n   if (!bluetoothDevice || !bluetoothDevice.gatt.connected || !characteristic) return ;\r\n    \r\n    var input = d3.select(this).selectAll(\"input\");\r\n    var values = [];\r\n    input.each(function(d){\r\n      values.push({id:this.id, value:this.checked ? \"1\" : \"0\"})\r\n    });\r\n    \r\n    var nested = d3.nest()\r\n        .rollup(function(d){ return d.reduce(function(a, b) {\r\n            return { value:a.value + b.value } ;\r\n        })})\r\n        .key(function(d){ return d.id.split(\"-\")[0] })\r\n        .entries(values);\r\n\r\n    var buffer = new Uint8Array(nested.length);\r\n    \r\n    nested.forEach(function(d,i){\r\n        buffer[i] = parseInt(d.value.value, 2);\r\n    });\r\n        \r\n  characteristic.writeValue(buffer);\r\n}\r\n\r\n\r\n\/\/BEL\u5207\u65ad\u51e6\u7406\r\nfunction disconnect() {\r\n  if (!bluetoothDevice || !bluetoothDevice.gatt.connected) return ;\r\n  bluetoothDevice.gatt.disconnect();\r\n  alert(\"BLE\u63a5\u7d9a\u3092\u5207\u65ad\u3057\u307e\u3057\u305f\u3002\")\r\n}\r\n<\/pre>\n<h2>\u30dd\u30a4\u30f3\u30c8<\/h2>\n<p>\u30ad\u30e3\u30e9\u30af\u30bf\u30ea\u30b9\u30c6\u30a3\u30c3\u30af\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u307e\u3067\u306e\u624b\u9806\u306f\u3001<a href=\"https:\/\/gunmagisgeek.com\/blog\/microbit\/5456\">\u4ee5\u524d\u306e\u8a18\u4e8b<\/a>\u3068\u5909\u308f\u3089\u306a\u3044\u3002<br \/>\nLED Matrix State\u3078\u306e\u66f8\u304d\u8fbc\u307f\u306b\u306f\u30018 \u30d3\u30c3\u30c8\u7b26\u53f7\u306a\u3057\u6574\u6570\u5024\u306e\u914d\u5217(ArrayBuffer)\u3092\u6e96\u5099\u3057\u3001\u305d\u3053\u3078\uff15\u6841\u306e\uff12\u9032\u6570\u3067\u66f8\u304d\u8fbc\u3080\u3002<br \/>\n\u4f8b\u3048\u3070\uff11\u884c\u76ee\u306e\u4e00\u756a\u53f3\u306eLED\u3092on\u306b\u3059\u308b\u306a\u3089\u4ee5\u4e0b\u3002<\/p>\n<pre class=\"lang:js decode:true \" >var buffer = new Uint8Array(5);\r\nbuffer[0] = perseInt(\"00001\", 2);<\/pre>\n<p>5\u884c\u76ee\u306e\u4e00\u756a\u5de6\u306eLED\u306a\u3089\u3053\u3093\u306a\u611f\u3058<\/p>\n<pre class=\"lang:js decode:true \" >var buffer = new Uint8Array(5);\r\nbuffer[4] = perseInt(\"10000\", 2);<\/pre>\n<p>\u4e0a\u8a18\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u3067\u306f\u3001\u30c1\u30a7\u30c3\u30af\u30dc\u30c3\u30af\u30b9\u3092\u4e26\u3079\u305fUI\u3092\u4f5c\u6210\u3057\u3001checked true\u3092&#8221;1&#8243;\u306b\u3001false\u3092&#8221;0&#8243;\u306b\u5909\u63db\u3057\u3066\u66f8\u304d\u8fbc\u3080\u3068\u3044\u3046\u4ed5\u7d44\u307f\u306b\u306a\u3063\u3066\u3044\u308b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Web Blutooth API + Micro:&hellip;<\/p>\n","protected":false},"author":1,"featured_media":5477,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[70],"tags":[],"class_list":["post-5476","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microbit","has-post-thumbnail-archive"],"_links":{"self":[{"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/posts\/5476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/comments?post=5476"}],"version-history":[{"count":0,"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/posts\/5476\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/media\/5477"}],"wp:attachment":[{"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/media?parent=5476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/categories?post=5476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gunmagisgeek.com\/blog\/wp-json\/wp\/v2\/tags?post=5476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}