---
# System prepended metadata

title: ゼミナールB

---

# ゼミナールB
# プロジェクト１
マイクロコントローラとPC間で情報のやり取りを無線でできるようにする。

# 無線通信の方法を選ぶ
一、micro:bitの無線通信についてWebページで調べる。
　その結果、micro:bitには二つの無線通信機能があることを知った。
　一つ目はBluetooth Low Energy（BLE）である。
　二つ目はCPUのなかにある独自の無線機能である。
 
二、無線通信の方法を選ぶ
 ここでBLEを使って、無線通信を実現したいと考えている。
 
# micro:bitの設定
三、Bluetoothを利用してPCとの接続
　Bluetoothを使って、PCとの接続方法を調べた。その結果、micro:bitとPC両方の設定が必要であることを知った。
　ここで、まずmicro:bit側の設定を行いたいと思う。
 
**１、micro:bitのBluetooth機能の設定**
 　micro:bitの無線通信機能は二つあるが、それらを同時に使うことはできない。
  何の設定も入れない状態だとBluetooth機能がoffの状態である。
  
  ここで、まずはCPUの無線機能をoffにして、Bluetooth機能をonにする。
![](https://i.imgur.com/ddDwBji.png)
![](https://i.imgur.com/SxuIILv.png)
![](https://i.imgur.com/RcqtRVm.jpg)
![](https://i.imgur.com/tTdK04v.png)
これで、Bluetooth機能がonになった。

この後、文字列の受信送信ができるように、micro:bitの初期設定を行う。
![](https://i.imgur.com/2FnOna6.jpg)


ブロックは作って、ダウンロードし、実行する。


![](https://i.imgur.com/kS1ZIRk.jpg)

このように、点灯すれば、micro:bit側の準備が完了となる。



# PCの設定

**２、PCの設定**
  PCでは「Web Bluetooth API」を作成し、micro:bit との通信を実現する。
  今回はPCからmicro:bitにメッセージを送ったり、micro:bitのメッセージを受信したりするためにUART RXとUART TX両方のポートを使用する。
  
  PC側の設定では、htmlファイルを作成し、それをChromeで開いてmicro:bitと無線通信して、情報を受けたり、送ったりする。
  
  
  htmlファイルは自力で作れたら、ここに貼り付ける。
  
 　......
  
  htmlファイルの作成ができたら、右クリックで開き方法を選択する。
　
![](https://i.imgur.com/fg0x4TV.png)

  このように、Chromeを選択し、開いたらこの様なページが出てくる。
  
  ![](https://i.imgur.com/2sQtyOT.png)

　ここで接続を押して、自分の持っているmicro:bitとペアする。
 
 ペアができたら、micro:bitの表情は無表情から笑顔になる。
 
 ![](https://i.imgur.com/VOBZGKs.jpg)
この様に、笑顔になったら、micro:bitとPCの接続が完了し、無線通信ができるようになった。

# 動いてみる
まずはAを押したら、この様になる。
![](https://i.imgur.com/EyCClkT.png)


次に、Bを押してみる。
![](https://i.imgur.com/Xfms6u4.png)

最後に、ABを同時に押してみる。
![](https://i.imgur.com/w369xCB.png)

この様に、ボタンを押したことで、自分の設定したように文字をPCに送ることができる。


逆に、送信する内容を決めて、micro:bitにて表示することもできる。

![](https://i.imgur.com/mVb8lyg.png)

今は最大19文字のアルファベットしか送信できない。
それ以上送信する場合、反応がしなくなる。

promiseについて

# 漢字機能を追加
 漢字の表示方法について、調べてみた。
 
　得た情報が少ない。けど、拡張機能のところに、カタカナという機能があることを知った。
 それを追加すると
 ![](https://i.imgur.com/OFI0zIO.png)
が出てくる。
 ![](https://i.imgur.com/SUQX2af.png)
 この様に作って、実行が可能になる。

 実行してみたら、半角のカタカナ文字しか出力できないことがわかった。
 
 本題に戻る。
　
 もしかしたら、プログラムをそのまま実行すると、表示できるんじゃないのかなー

やってみて

![](https://i.imgur.com/ND7QEGc.png)
文字化けが出た。

原因を探してみる。



受信内容<textarea id="recieve_text"   ></textarea>

この行を書き換えたら表示できるかも

結局、色々調べて変えてみたが、できなかった。

よくよく考えると

![](https://i.imgur.com/FnxUp3t.png)

このブロックでは、アルファベットした送れないかもしれない。

日本語の文を送る時に文字化けが起きた。

ここでやり方を変えてみる。
![](https://i.imgur.com/YiasGk2.png)
この様にやるのは一番簡単だけど、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 = '私'
```

その結果

![](https://i.imgur.com/aQDDgBC.png)

正しく表示できる。


ここからわかることは、その文に問題があると判断した。
問題あるというか、文字への変換ができない。

ここで、以下のように直してみた。

# プログラムを改善してみる(2)
前回先生のアドバイスを受けて、この様にプログラムを書き換えて、色々実行してみる。


```
let y= new TextEncoder().encode('私'); 
let text=new TextDecoder().decode(e.target.value)
console.log(e.target.value);
console.log(y);
```



「私」という文字を符号なし８ビット整数の配列に転換してみた。

その結果、
![](https://i.imgur.com/BzOAG8j.png)
になった。

また、「私」と受け取ったはずのe.target.valueも変換して、調べてみる。

その結果、
![](https://i.imgur.com/PzKwjr2.png)
なぜか、謎の「193」が得られた。

正しく転換できるabcにして、結果を見てみる。
![](https://i.imgur.com/Ace0tIw.png)

ブロックをこの様に作って、実行する。
その結果、

![](https://i.imgur.com/XdHaqJ9.png)
となった。
半角のabcにした場合、両方同じ結果が得たことがわかる。
連続しているabcであるため、結果も97、98、99といった連続の数字になった。

漢字がだめなら、全角の数字を入れてみる。

![](https://i.imgur.com/K2R0WZ5.png)
```
let y= new TextEncoder().encode('１２３'); 
let text=new TextDecoder().decode(e.target.value)
console.log(e.target.value);
console.log(y);
```
この様に、ブロックの中身を書き換えて、実行してみる。

やはり、正しく表示できない。ここから、日本語ばかりでなく、全角文字は全部出力不可とわかった。

では、console.logした結果を見てみる。
![](https://i.imgur.com/Lq7xQ70.png)

このような結果になった。

やはり、e.target.valueの結果はおかしい。

ここまで、わかったのはプログラムに問題がなくて、microbitから文字列を受け取った時点で問題が生じたことである。

ここで文字コード表を調べる。

![](https://i.imgur.com/G39JCuX.png)
この表にある１２３を転換してみると、下正しく表示したのはUTF8に当てはまることがわかった。

上はどちらとも当てはまらないが、UTF16の後ろの１ビットとは当てはまる。

ここで推測だが、もしかしたら、後ろの１ビットだけ受け取ったじゃないのかな。

この推測を確かめるのは、先ほどの「私」をみる。

193だけ受け取った。これは16進数のC1である。
表を調べてみると
![](https://i.imgur.com/0INiJIj.png)
UTF16であることと、後ろの１ビットだけ受け取ったことがわかる。

さっきの推測も確かめられた。

次からはmicrobit側の改善をする。

microbit側に問題があるとわかって、改善してみる。
以下のように、microbit側のプログラム書き換える。
 bluetooth.uartWriteString(0xE7A781)
直接書き換えて、これで表示できるかを確かめる
その結果、エラーが出た。


#  最終回

今までやったことから、最後の１Bだけ送信される。
全角２文字を字数に渡すと、２文字の最後の１Bだけ送信できる。


これを利用して、工夫すると、表示したい文字列が表示できるようになると考えている。

例えば、「私」を送信したい場合、79C1を分けて送信する。
79とC1に分ける。
ここで、文字列表を調べて、XX79とXXC1の文字を使って、この２文字を送信する。

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>
```
