KOZOS上で超音波センサのデータを周期的にPCへ送信してみた (設計編)

# 1. 今回のやりたいこと
今回は、「周期的に超音波センサのデータを取得し、bluetoothを使ってPCにそのデータを送信する」ということをしたいです。システムと言ってよいかわかりませんが、今回作るシステムを距離測定システムと呼ぶこととします。

今回のしたいことにおいて、設計編と実装編に分けて記事を書く予定です。まずは設計編から書いていきます。

# 2. 環境
* 使用ボード：nucleo l4r5zi
    * Cortex-M4搭載、2MBのFlash、640KのSRAM、USB OTG
* 開発環境：Atollic TrueSTUDIO® for STM32, Built on Eclipse Neon.1a.(Version: 9.3.0 )
* 対象OS：KOZOS※
※下記書籍で紹介されているOSになります。ソースコードも展開されています。
[12ステップで作る 組込みOS自作入門](http://kozos.jp/books/makeos/)
* 超音波センサ： HC-SR04 
* BlueTooth通信モジュール：HC-06

# 3. 前提
nucleo l4r5ziにKOZOSをポーティングしています。さらに指定した時間sleepする関数：kz_tsleep、超音波センサからデータを取得するタスクを追加実装いたしました。詳細について、下記記事に記載しておりますので、興味ある方は見ていただけると嬉しいです。
[KOZOSをnucleo l4r5ziにポーティングしてみた](https://qiita.com/hcuymitoh/items/31fc2e54ae9fb72c9230)
[KOZOSにdly_tskと同じ機能のサービスコールを実装してみた](https://qiita.com/hcuymitoh/items/5b0aa1245710d0f84777)
[KOZOS上で超音波センサのデータを周期的に取得してみた](https://qiita.com/hcuymitoh/items/e905dff59f34466c5f5a)

# 4. BlueTooth通信モジュール : HC-06

### 4.1 HC-06とは
今回はBlueTooth通信モジュールとしてHC-06を使用します。
* 表
![HC-06_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/fc76c2a5-a28c-836b-9c3f-4d99b5137243.jpeg)
* 裏
![HC-06__.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/79c7323f-1969-122c-d16a-3f46d6de8072.jpeg)

HC-06は、UART通信でデータのやり取りを行います。HC-06に電源を入れると、ペアリングされていない状態であれば、ATモードで動作します。ATモードは、コマンドを受け付ける状態であり、HC-06の設定を確認したり変更することができます。例えば、"AT"と送信すると"OK"と帰ってきます。これをすることで接続ができていることを確認できます。

### 4.2 接続状態の確認方法
今回、BlueToothモジュールを使用するということで、PCとBlueToothの接続状態を管理したいと考えています。HC-06には、上記の写真の通り、RXD、TXD、GND、VCCしかピンがはんだ付けされていません。（裏の写真のSTATE、WAKEUPにピンがはんだ付けされていますが、もともとははんだ付けされていませんでした）どのように接続状態を判断すればよいかを色々調べたところ、STATEのpinがその判断に使えることがわかりました。実際に、電圧計でSTATE pinを測定したところ、PCと接続が切れた状態では0.0 ~ 2.0v、接続状態では3.3v固定になっていました。ちなみに、WAKEUP pinは接続時でも接続がきれた状態でも0.0vでした。

今回は、STATE pinをマイコン側でGPIO入力に設定したピンに接続し、そのpinの状態を確認することで接続状態を判別します。
nucleo l4r5ziとは下記のように接続しています。
![ボード_HC06接続.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/1e2aa67a-30f9-4722-a630-9febedceb9f8.png)



# 5. 距離測定システム
### 5.1 仕様
仕様は下記の通りとします。
* PCから"measure start"のコマンドを受信すると、1s周期で超音波センサのデータを取得し、PCへBlueTooth経由でそのデータを送信する
* PCから"measure stop"のコマンドを受信すると、超音波センサのデータの取得を停止する


### 5.2 全体像
今回作成するシステムの全体像を下記に示します。
![Qiita_全体像.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/5347eae3-0577-e186-18ce-c5a726978692.png)


PCには、HC-06と通信するためのBlueToothアダプタを挿しています。

### 5.3 機能設計

今回の仕様を満たすための機能は下記の通りになります。
* __システム制御機能__
システム全体の制御を行います。各機能では、それぞれの機能間でデータの送受信を行うことはせず、必ずシステム制御機能を介してデータの送受信を行うようにします。システム制御機能には、各機能間のデータの送受信制御に加えて、各機能から要求された周期的に発生させてほしいイベントを発生させる機能も持たせることとします。これは、今回の"超音波センサのデータを1s周期で取得する"という仕様を実現するための機能になります。

* __超音波センサ制御機能__
超音波センサの初期化を行い、超音波センサからデータを1s周期で取得します。

* __BlueTooth送信機能__
PCとBlueToothの接続状態を管理し、データをBlueTooth経由でPCへ送信します。

* __コンソール機能__
PCからのコマンドを解析し、受信したコマンドに対応した処理を行います。

機能の関連図を下記に示します。
矢印は、データの通信を表しています。
![機能間レンズ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/355ee392-7d96-ba17-c1d7-825ef6d56bcb.png)

コンソール、BlueToothはともにUSARTを使用するため、USARTドライバが必要になります。
超音波センサは、GPIOを使用して制御するためGPIOドライバが必要になります。
これらについては、サンプルとして提供されているドライバを使用することとします。

今回は、KOZOS上で動かすということなので、各機能をタスクを使用して実現したいと思います。
タスク間の通信にはメッセージを使用します。

次章から、各機能の詳細について説明していきます。

#### 5.3.1 システム制御機能
システム制御機能の状態遷移図を下記に示します。
![CTL_状態遷移図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/91da2161-b1d7-4636-773f-353405b8745d.png)


* __メッセージの入出力__
    * __入力__
        * __システム初期化メッセージ__
        本機能に対して、システム初期化メッセージを送信することで各機能が動作し始めます。
        * __データ送信要求メッセージ (from 超音波センサ制御機能)__
        データの送信要求を受け付けます。
        
    * __出力__
        * __初期化要求メッセージ (to 各機能)__
        各機能に、初期化要求メッセージを送信します。 
        * __データ送信要求メッセージ (to BlueTooth送信機能)__
        送信要求のあったデータをBlueTooth送信機能に送信します。

#### 5.3.2 超音波センサ制御機能
超音波センサ制御機能の状態遷移図を下記に示します。
![US_状態遷移図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/d1bb7674-30a7-a169-8002-aaf2833dc3f7.png)

* __メッセージの入出力__
    * __入力__
        * __初期化要求メッセージ (from システム制御機能)__
        システム制御機能から初期化要求メッセージを受信すると、本機能の初期化を実施します。
        * __データ取得開始メッセージ (from コンソール機能)__
        本メッセージを受信すると、システム制御へ1s周期でデータ取得メッセージを送信してもらうように要求します。
        * __データ取得メッセージ (from システム制御機能)__
        本メッセージを受信すると、超音波センサのデータを取得します。
        * __データ取得停止メッセージ (from コンソール機能)__
        本メッセージを受信すると、超音波センサのデータ取得を停止します。
    * __出力__
        * __データ送信要求メッセージ (to BlueTooth送信機能)__
        各機能に、初期化要求メッセージを送信します。 


#### 5.3.3 BlueTooth送信機能
BlueTooth送信機能を、PCとBlueToothの接続状態を管理する機能とデータ送信機能の2つに分けます。

##### 5.3.3.1 接続状態管理機能
接続状態管理機能は、一定間隔でPCとBlueToothの接続状態を確認します。
特に状態はなく、「4.2 接続状態の確認方法」に記載の通り、一定間隔でSTATE pinに接続されているGPIOの状態を確認し、Highであればデータ送信機能に、接続済みメッセージを送信します。Lowであれば、非接続メッセージを送信します。

* __メッセージの入出力__
    * __入力__
        特になし
    * __出力__
        * __接続済みメッセージ (to データ送信機能)__
        PCとBlueToothが接続されている場合、BlueToothのデータ送信機能へ、本メッセージを送信します。
        * __非接続メッセージ (to データ送信機能)__
        PCとBlueToothが接続されていない場合、BlueToothのデータ送信機能へ、本メッセージを送信します。

##### 5.3.3.2 データ送信機能

データ送信機能の状態遷移図を下記に示します。
![BT_状態遷移図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/a72c8847-5844-e7a7-fb0f-03fb2cfb9622.png)


* __メッセージの入出力__
    * __入力__
        * __初期化要求メッセージ (from システム制御機能)__
        システム制御機能から初期化要求メッセージを受信すると、本機能の初期化を実施します。
        * __接続済みメッセージ (from 接続状態管理機能)__
        本メッセージを受信すると、接続済み状態に遷移します。
        * __非接続メッセージ (from 接続状態管理機能)__
        本メッセージを受信すると、非接続状態に遷移します。
        * __データ送信要求メッセージ (from システム制御機能)__
        本メッセージを受信したときの挙動は、非接続状態、接続済み状態で変わります。
        非接続状態の場合は、データは捨てず内部にためておきます。
        接続状態の場合は、USARTドライバを使用して、BlueTooth経由でPCへデータを送信します。
    * __出力__
        特になし

#### 5.3.4 コンソール機能
コーンソール機能は、サンプルとして提供されている状態のまま使用するため、詳細は割愛します。
PCからのコマンドをUSARTドライバを介して受信した際に、そのコマンドに応じた処理を行います。

### 5.4 シーケンス図
シーケンス図を下記に示します。
![Qiita_シーケンス図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/3d145a62-b7c6-092b-811a-0eb7524a6ae1.png)

# 6. 最後に
設計編は以上となります。
実装編は、また近々記載いたしますので少々お待ちください。

本件について、何か不明点・アドバイスがあればコメントしていただけると嬉しいです。