# ゼミナールB # プロジェクト1 マイクロコントローラとPC間で情報のやり取りを無線でできるようにする。 # 無線通信の方法を選ぶ 一、micro:bitの無線通信についてWebページで調べる。 その結果、micro:bitには二つの無線通信機能があることを知った。 一つ目はBluetooth Low Energy(BLE)である。 二つ目はCPUのなかにある独自の無線機能である。 二、無線通信の方法を選ぶ ここでBLEを使って、無線通信を実現したいと考えている。 # micro:bitの設定 三、Bluetoothを利用してPCとの接続 Bluetoothを使って、PCとの接続方法を調べた。その結果、micro:bitとPC両方の設定が必要であることを知った。 ここで、まずmicro:bit側の設定を行いたいと思う。 **1、micro:bitのBluetooth機能の設定** micro:bitの無線通信機能は二つあるが、それらを同時に使うことはできない。 何の設定も入れない状態だとBluetooth機能がoffの状態である。 ここで、まずはCPUの無線機能をoffにして、Bluetooth機能をonにする。     これで、Bluetooth機能がonになった。 この後、文字列の受信送信ができるように、micro:bitの初期設定を行う。  ブロックは作って、ダウンロードし、実行する。  このように、点灯すれば、micro:bit側の準備が完了となる。 # PCの設定 **2、PCの設定** PCでは「Web Bluetooth API」を作成し、micro:bit との通信を実現する。 今回はPCからmicro:bitにメッセージを送ったり、micro:bitのメッセージを受信したりするためにUART RXとUART TX両方のポートを使用する。 PC側の設定では、htmlファイルを作成し、それをChromeで開いてmicro:bitと無線通信して、情報を受けたり、送ったりする。 htmlファイルは自力で作れたら、ここに貼り付ける。 ...... htmlファイルの作成ができたら、右クリックで開き方法を選択する。  このように、Chromeを選択し、開いたらこの様なページが出てくる。  ここで接続を押して、自分の持っているmicro:bitとペアする。 ペアができたら、micro:bitの表情は無表情から笑顔になる。  この様に、笑顔になったら、micro:bitとPCの接続が完了し、無線通信ができるようになった。 # 動いてみる まずはAを押したら、この様になる。  次に、Bを押してみる。  最後に、ABを同時に押してみる。  この様に、ボタンを押したことで、自分の設定したように文字をPCに送ることができる。 逆に、送信する内容を決めて、micro:bitにて表示することもできる。  今は最大19文字のアルファベットしか送信できない。 それ以上送信する場合、反応がしなくなる。 promiseについて # 漢字機能を追加 漢字の表示方法について、調べてみた。 得た情報が少ない。けど、拡張機能のところに、カタカナという機能があることを知った。 それを追加すると  が出てくる。  この様に作って、実行が可能になる。 実行してみたら、半角のカタカナ文字しか出力できないことがわかった。 本題に戻る。 もしかしたら、プログラムをそのまま実行すると、表示できるんじゃないのかなー やってみて  文字化けが出た。 原因を探してみる。 受信内容<textarea id="recieve_text" ></textarea> この行を書き換えたら表示できるかも 結局、色々調べて変えてみたが、できなかった。 よくよく考えると  このブロックでは、アルファベットした送れないかもしれない。 日本語の文を送る時に文字化けが起きた。 ここでやり方を変えてみる。  この様にやるのは一番簡単だけど、LEDの表示になってしまう。(文字のやり取りではなくなる) # プログラムを改善してみる(1) 前回の発表を通して、プログラムに問題があることを知った。 今回はプログラムの修正をしていきたいと思う。 とりあえず受信に関するところをみる。 まずは文字コードをUTF-8、UTF-16、SHITF JISに変えて、実行してみる。 実行してみた結果、直らなかった。 ``` <meta charset="UTF-8"> ``` この文に問題がないと推定する。 ``` <div> <button type="button" id="connect">接続</button> 受信内容<textarea id="recieve_text"></textarea> </div> ``` この文は前回調べて、そのままで大丈夫であるはず ``` <div> <button type="button" id="connect">接続</button> 受信内容<textarea id="recieve_text"></textarea> </div> ``` 最後に後の文を調べてみる。 ``` const text = new TextDecoder().decode(e.target.value) ``` textの後ろに文字がくるはず。 ここでこの様に書いて実行してみる ``` const text = '私' ``` その結果  正しく表示できる。 ここからわかることは、その文に問題があると判断した。 問題あるというか、文字への変換ができない。 ここで、以下のように直してみた。 # プログラムを改善してみる(2) 前回先生のアドバイスを受けて、この様にプログラムを書き換えて、色々実行してみる。 ``` let y= new TextEncoder().encode('私'); let text=new TextDecoder().decode(e.target.value) console.log(e.target.value); console.log(y); ``` 「私」という文字を符号なし8ビット整数の配列に転換してみた。 その結果、  になった。 また、「私」と受け取ったはずのe.target.valueも変換して、調べてみる。 その結果、  なぜか、謎の「193」が得られた。 正しく転換できるabcにして、結果を見てみる。  ブロックをこの様に作って、実行する。 その結果、  となった。 半角のabcにした場合、両方同じ結果が得たことがわかる。 連続しているabcであるため、結果も97、98、99といった連続の数字になった。 漢字がだめなら、全角の数字を入れてみる。  ``` let y= new TextEncoder().encode('123'); let text=new TextDecoder().decode(e.target.value) console.log(e.target.value); console.log(y); ``` この様に、ブロックの中身を書き換えて、実行してみる。 やはり、正しく表示できない。ここから、日本語ばかりでなく、全角文字は全部出力不可とわかった。 では、console.logした結果を見てみる。  このような結果になった。 やはり、e.target.valueの結果はおかしい。 ここまで、わかったのはプログラムに問題がなくて、microbitから文字列を受け取った時点で問題が生じたことである。 ここで文字コード表を調べる。  この表にある123を転換してみると、下正しく表示したのはUTF8に当てはまることがわかった。 上はどちらとも当てはまらないが、UTF16の後ろの1ビットとは当てはまる。 ここで推測だが、もしかしたら、後ろの1ビットだけ受け取ったじゃないのかな。 この推測を確かめるのは、先ほどの「私」をみる。 193だけ受け取った。これは16進数のC1である。 表を調べてみると  UTF16であることと、後ろの1ビットだけ受け取ったことがわかる。 さっきの推測も確かめられた。 次からはmicrobit側の改善をする。 microbit側に問題があるとわかって、改善してみる。 以下のように、microbit側のプログラム書き換える。 bluetooth.uartWriteString(0xE7A781) 直接書き換えて、これで表示できるかを確かめる その結果、エラーが出た。 # 最終回 今までやったことから、最後の1Bだけ送信される。 全角2文字を字数に渡すと、2文字の最後の1Bだけ送信できる。 これを利用して、工夫すると、表示したい文字列が表示できるようになると考えている。 例えば、「私」を送信したい場合、79C1を分けて送信する。 79とC1に分ける。 ここで、文字列表を調べて、XX79とXXC1の文字を使って、この2文字を送信する。 PC側では、79とC1を受信し、Decodeすると「私」になる。 と言う考えである。 ``` <!DOCTYPE html> <html lang="ja"> <meta charset="UTF-8"> <script src="encoding.min.js"></script> <title>Micro:bit UART 通信</title> <style type="text/css"> * { font-size: 3vmin; padding: 3vmin; } body { text-align: center; } textarea { vertical-align: middle; } </style> <h1>プロジェクト1:Micro:bit UART 通信</h1> <form> <div> <button type="button" id="connect">接続</button> 受信内容<textarea id="recieve_text"></textarea> </div> <div> 送信内容 <input type="text" id="send_text" value="test"> <button type="button" id="send" disabled>送信</button> </div> </form> <script> install encoding-japanese --save const UUID_UART_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e' const UUID_TX_CHAR_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e' const UUID_RX_CHAR_CHARACTERISTIC = '6e400003-b5a3-f393-e0a9-e50e24dcca9e' let gatt = null let tx = null let rx = null const update = connected => { document.getElementById('connect').textContent = connected ? '切断' : '接続' document.getElementById('send').disabled = !connected } const send = text => rx.writeValue(new TextEncoder().encode(text + '\n')) document.getElementById('connect').addEventListener('click', e => { if(!(navigator.bluetooth && navigator.bluetooth.requestDevice)) { alert('WebBluetooth に未対応のブラウザです。') return } if (document.getElementById('connect').textContent == '接続') { navigator.bluetooth.requestDevice({ filters: [ { services: [UUID_UART_SERVICE] }, { namePrefix: 'BBC micro:bit' } ] }).then(device => { gatt = device.gatt return gatt.connect() }).then(server => server.getPrimaryService(UUID_UART_SERVICE) ).then(service => Promise.all([ service.getCharacteristic(UUID_TX_CHAR_CHARACTERISTIC), service.getCharacteristic(UUID_RX_CHAR_CHARACTERISTIC)]) ).then(characteristics => { tx = characteristics[0] tx.startNotifications() tx.addEventListener('characteristicvaluechanged', e => { const Encoding = require('encoding-japanese'); let text = new TextDecoder().decode(e.target.value) text = Encoding.convert(text, 'UTF-16', 'UTF-8') document.getElementById('recieve_text').value = text + document.getElementById('recieve_text').value }) rx = characteristics[1] update(true) }).catch(function(err) { alert(err) }) } else { gatt.disconnect() update(false) } }) document.getElementById('send').addEventListener('click', e => { send(document.getElementById('send_text').value) }) </script> ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up