マイコンチェッカーではmbedとパソコンをUSBで接続し、シリアル通信にてデータのやり取りを行います。そこで使用するシリアル通信のやり取り方法を考えます。
使用するmbedはNUCLEO-L152RE
まず初めに使用するmbedについてです。今回は「NUCLEO-L152RE」を使用します。
他のでもいいのですが、色々な事情により「NUCLEO-L152RE」にしました。例えば、シリアル通信のポートが5個ある、デジタルIOが沢山ある、アナログ入出力があるといったことです。
通信速度
さて、mbed(NUCLEO-L152RE)とパソコン間で色々とシリアル通信の速度を試したところ、私の環境では「230400[bps]」が限界でした。これよりも速くするとデータが壊れてしまうので、使い物になりませんでした。
通信速度が230400[bps]の場合、通信時間はどの程度になるのでしょうか。あくまで理論値で細かいところは省いて計算をしてみます。
230400[bps]とは、1秒間に230400ビットのデータをやり取りできるということですね。ビットではわかりにくいのでバイトにしてみましょう。
230400 / 8 = 28800
1秒間に28800バイトのデータ通信が可能ということです。結構早いものですね、1ミリ秒で約28バイト送信できるってことです。
通信フロー
パソコンから指示を出し、mbed(NUCLEO-L152RE)が処理を行います。簡単な指示の流れは以下の通りです。
- パソコンからmbedへデジタル入力の値を取得する指示を送信
- mbedはパソコンから受けた指示にしたがい、デジタル入力の値を取得する
- mbedはパソコンへ取得したデジタル入力の値を送信する
デジタル入力の値が変更したので、mbedからパソコンへ報告する、ということは行いません。あくまでパソコンが問い合わせたときに、その状態を送るだけです。
これは双方向でそれぞれデータのやり取りを行うと、動作が複雑になるからです。
例えば、パソコン側からデジタルIOを入力から出力に変えろと指示が来たのに、、その一瞬手前で入力値が変わったので、mbedからパソコンへ値変わったよ、と報告を出し、その後、出力に変わったよ、と報告を上げる。といったように複雑な動きになることがあります。
この場合、パソコンとしては1個ずつ処理を行えば問題ないのですが、さて、通信異常が発生したらどうしましょうか。もう考えるのが嫌になります。
ということで、パソコンからの指示でmbed(NUCLEO-L152RE)が動く、これが単純でバグを作りこみにくい構造だと思います。
通信伝文仕様
通信伝文の仕様についてですが、中身を考えることも重要なのですが、伝文の長さを固定にするのか、可変にするのかが非常に重要です。
どういうことかといいますと、伝文の長さを例えば30バイトに固定する、というのが固定ですね。この場合、常に30バイト使用するのであれば最適なのですが、命令により必要なデータサイズが違う場合、先頭には意味あるデータを入れ、後半の使用しない部分には0などを入れて送信する必要があります。
命令自体は10バイトしかないけど、必ず30バイト送信する、という形になります。データサイズは1番大きなサイズに合わせる必要があるため、構造によっては非常に無駄なデータを毎回送ることになります。
続いて、データサイズが可変の場合、先ほどの固定とは違い必要なデータのみを送ることができます。10バイトの命令であれば10バイト、30バイトの命令であれば30バイトといった感じです。ただし伝文のサイズがわからないので、伝文自体に伝文サイズを入れる必要があります。
(ここでは説明しませんが、作り方によっては伝文サイズは不要にできます)
さて、ここまでの内容だと可変長の方がいいんじゃないかな、と感じる方が多いと思います。しかし、可変長には可変長の課題が出てきます。最も大きな課題はプログラムが複雑になりやすいことです。伝文のサイズを調べ、どこに何が入っているかということを解析する必要があります。また、データの受信完了がわからないので受信タイムアウトなどの処理が必要になります。
では、1度まとめてみましょう。
固定長のメリット
- プログラムが簡単
- プログラムが少なくて済む
- 受信完了のタイムアウトを不要にできるので、無駄な待ちはなくせる
- 送受信時間が一定になる
固定長のデメリット
- 全ての命令が同じ伝文サイズになるので、状況によっては無駄が生まれる
可変長のメリット
- 伝文サイズを必要最小限にすることができる
- 伝文によって通信時間を短縮できる(伝文が短くなるから)
可変長のデメリット
- プログラムが複雑になる
- 受信完了のタイムアウト時間の待ちが必要になる
- 作り方によるが、伝文に伝文サイズを入れる必要がある(中身もすべて可変長の場合は必要)
結局どうしたの?
今回は可変長にしました。なぜかといいますと、mbed(NUCLEO-L152RE)からシリアル通信を4個行うことにしたからです。1つのシリアルポートへは20バイト前後を最大値とする予定なので、4個だと80バイトになります。しかし、常にシリアル通信を行う予定はないので、80バイト無駄にやり取りするのは嫌だなと考え、可変長にしました。
しかし、後から考えると固定長にしておいた方がよかったと少し後悔しています。なぜかといいますと、プログラムが複雑になってしまったためです。今回の環境ではC#で作成しているWindowsアプリと、C++で作成しているmbed、それぞれに同じ内容のプログラムを作らなくてはいけません。ただでさえ2種類のプログラムを作成しなくてはいけないのに、複雑な構造のプログラムとなると・・・非常に面倒でした。
通信伝文の中身について
通信伝文の中身はそれほど難しいものではありません。
デジタルIOの場合はlong型(4バイト)のデータを1つ用意し、ビット演算を行います。各ビットとIOピンを割り振り0と1で処理します。
mbedから行うシリアル通信は4ポート使い、可変長に対応しているため状況により変わりますが、予定では最大送信サイズが20バイト×4ポートで80バイト、最大受信サイズが21バイト×4ポートで84バイトです。
アナログ入力は2バイト×4ポートで8バイト、アナログ出力はmbed(NUCLEO-L152RE)では1ポートしか使えないので2バイトです。(色々と設定を変えてやれば2ポート使用可能なのですが、今回は使用しません)
まとめ
パソコンとmbed(NUCLEO-L152RE)での通信の場合、どちらも高速に処理が行えるので可変長の通信伝文にしました。
ちなみに伝文の最大サイズは約100バイトになるので、230400[bps]の場合は4[ms]以下になります。応答の時間も考えると単純に2倍してやればいいので、8[ms]くらいです。実際にはIO取得の時間などもあるので、ざっくり10[ms]くらいが1セットの通信にかかる時間です。(注:あくまでかなりざっくりした計算ですよ)
さて、通信伝文を可変長にしたものの、最大通信時間を考えると可変長にする必要なかったな、というのが本音です。ただ可変長のプログラムを作ってみたかったんです。
更新履歴
版 | 更新日 | 説明 |
新規作成 | 2017/8/31 |