M5Stackでも使えるデバイス間通信 5種について調査してみた

##はじめに
マイコンやその周辺機器などで扱う、デバイス間通信についてまとめました。
筆者は、M5Stackについて勉強中でもあるので少し関連付けて解説します。

##目次
- はじめに
- 目次
- UDP/TCP 
- Serial
    - SPI
    - I2C
    - UART
- おわりに
- 参考リンク

##UDP (User Datagram Protocol) / TCP (Transmission Control Protocol)
UDPとTCPはWi-Fiや有線LANを使って利用できる通信方式です。
両者は、簡単に言えばスピード重視のUDP、正確さ重視のTCPといった風で、
どちらが優秀というわけではなく、単に用途・目的によって使い分けようという感じです。

この違いはどこから生まれるのでしょうか。
TCPではUDPに対して、データを受信できなかった場合にデータを送り直してもらうという機能が追加されています。Transmission（送信）をControlする機能というわけですね。これがあることによって通信の信頼性が保証されますが、逆を言えば通信速度が低下するということでもあります。

なので、例えば動画のストリーミングだと、データがある程度欠けていても問題ない、それよりも通信速度が欲しい！となるので、より速いUDPのほうが採用されやすくなります。まとめると、

- Wi-Fiや有線LANで使える。
- UDP: 速いけど信頼性はない
- TCP: 信頼性はあるけど速くない

といった感じです。

##Serial通信について
シリアル通信は、1つの伝送路を使って1bitずつデータを送るやり方です。反対にパラレル通信というのもあり、こちらは複数の信号線で同期して一度にたくさんデータを送るやり方です。以前はパラレル通信のほうが速いというメリットがありましたが、同期しなきゃいけない制約だったり、単純に通信速度が向上したおかげでシリアル通信も早くなりました。(最近のUSBとかすごい速いですよね)

それにシリアル通信のほうが同期も簡単で扱いやすいので組み込みではシリアル通信普及しています。

次は、具体的にマイコンなどで使われるシリアル通信について見ていきましょう。

##SPI (Serial Peripheral Interface)
SPIは、名前のPeripheral（周辺）にもあるように、マイコンとその周辺機器とシリアル通信ができます。特徴は、4本の信号線を使って複数のデバイスと同期式の通信ができることです。利点としては、I2C（後で出てくる）と比べて配線は増るものの速い通信が可能になっています。

ここでの同期式とは、あくまでもクロック信号に同期しているという意味でパラレル通信の同期とは区別されます。
同期について詳しく知りたい人は調歩同期と調べてみてください。

####信号線
SPI通信には4つの信号線が用意されていて、それぞれ名前がついています。なので、同じ線で結ばれているポートは同じ名前になっています。

- SIMO(Slave In Master Out): マスタモードなら出力、スレーブモードなら入力
- SOMI(Slave Out Master In): マスタモードなら入力、スレーブモードなら出力、、親切な名前だね！
- SCLK(Serial Clock): マスタからスレーブにクロックを出力する同期のための線
- SS(Slave Select): 複数のスレーブ機器を繋げる場合に、通信したいスレーブ機器のSS端子をLOWして使う。スレーブ機器が単一の場合は省略可能。

見てわかる通りSOMIを除いてマスタ→スレーブとなっていますね。

![SPI接続例_GFDL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556756/2fdfe533-5b73-3078-d7fe-b40e1d11d873.png)

補足: ここで出てくるマスタ/スレーブというのは制御する側/される側という意味で、語源が主人/奴隷なので違う言葉を使おうという動きもあります。

####通信の流れ
SPIは同期式ということで、通信の流れはざっくりと以下の感じ。

1. 通信したいスレーブ機器のSSをLowに
2. SCLKでクロックを出力
3. SCLKに同期してSIMOとSOMIでデータを相互転送

これで、SPIのことがなんとなく分かりました。
もっと詳しく知りたい方は、極性とかモードとかを調べてみてください。

##I2C (Inter-Integrated Circuit)
IC間の通信を担い、マイコンとその周辺機器の通信でよく使われます。アイツーシーとよく呼ばれていますが、正式にはアイスクエアドシーらしいです。

I2Cの利点は、たった2つの信号線で、相手を指定して複数の機器と通信できることです。製造コストが低く、通信速度よりもコストダウンを優先するときに適しています。

####信号線
利点にもある通り、用意されている信号線は次の2つのみです。これもSPIのように、同じ信号線で繋がっているポート同じ名前になります。

- SDA (Serial Data): データ用の信号線
- SCL (Serial Clock): クロック用の信号線

![I2C接続例_GFLD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556756/d2f05b76-1302-20bb-8aa0-98a7cf6e5a1a.png)

SDAとSCLはプルアップする必要があり、プルアップ抵抗は製品によって決まっている場合があります。

####通信の流れ
先程出てきたとおり、I2Cの通信では、スレーブアドレスを指定するという手順が加わっています。I2Cの通信の流れは簡単に書くと、

1. マスタが通信を開始する
2. マスタがスレーブアドレスを指定する
3. マスタがスレーブからデータを送信/受信する
4. マスタが通信を終了する

の4段階となっています。
簡単ですが、これでI2Cの事もなんとなく理解できました。

少しだけ掘り下げると、通信の開始/終了の合図には、SPIのように単に端子をLOWにすればいいのではなく、START Condition/STOP Conditionという様式を使います。又、受信側はデータの受信後、データを正常に受け取ればACK（ACKnowledge）、受信できなければNACK（NotACKnowledge）を返しています。なので、その結果を使ってプログラムを作成できたりするわけです。

## UART (Universal Asynchronous Receiver Transmitter)
非同期式シリアル通信の1つです。非同期式ということはSPIやI2Cと違いクロックを使用しないので、UARTは単純な仕組みになっています。
ちなみに、UARTのA、Asynchronousという単語は、「同期的」を意味するSynchronousの語頭に'a'（無い）を付けて「非同期の」という意味になっています。

####ポート
UARTは信号線ではなくポートに名前がついています。信号線がTXからRXに繋がっているところがSPIやI2Cとは違いますね。

- TX (Transmitter): 送信
- RX (Receiver): 受信


![UART接続例_GFDL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556756/c672e2dc-c3b3-1c27-7807-41c0dfa230d5.png)


本当にシンプルな構成になっていますね。
補足として、TXはTxD、RXはRxDと書かれることもあるようです。

####ボーレート (Baud Rate)
UARTはクロックが存在しないので、通信の速度を合わせるために伝送の速度（ボーレート）を合わせることが必要です。9600bpsや115200bpsなどよく使われる転送レートがいくつかあります。

ちなみにが多いんですけど、Baudは1秒当たりの変調の回数の単位で、bpsとは本来別の単位です。例えば1変調が4bitを表す時なんかを考えれば違いが分かると思います。

#### 通信の流れ
UARTの通信の流れはとても単純です。

1. Start Bit: 電圧レベルをLOWにしてデータの送信開始を知らせる。
2. 8bitのデータをボーレートに合わせて送信する。
3. Stop Bit: 電圧レベルをHIGHにしてデータの送信終了を知らせる。

加えて、データの誤りを検出するためにパリティビットというものが使われることがありますが、基本的にはこれだけです。

M5Stack (Core系)では、CP2102というUARTとUSBの信号を変換するチップが載っています。これによって、UARTをUSB端子で利用できているわけですね。USBというのは、PCの進化に伴って色々な通信をラップするように発展してきました。気になった人は調べてみてくださいね。

##おわりに
ご高覧ありがとうございました。
今回は、今取り組んでいる移動ロボットの作成で通信関係のところで躓いたので、あまりよく分かっていなかったマイコンの通信について調べました。なので、私自身実戦経験があるわけではなく、使いやすさとか感覚的なことは分かりません。
間違い気づいたことなどあれば、ご指摘ください。

以上、初投稿でした。読んでくださりありがとうございました。

使用した画像のライセンスはすべてGFDLとなっています。
以下に参考にしたページのリンクを張っておきます。

##参考リンク集
- UDP/TCP
  - 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 https://wa3.i-3-i.info/word110.html
  - ハートランド・ザ・ワールド https://hldc.co.jp/blog/2019/07/11/2819/
- Serial
    - 全般
        - クチコミ https://www.kumikomi.jp/what-is-the-difference-between-serial-communication-and-parallel-communication/
        - Diatrend Corp https://www.diatrend.com/glossary/knowledge_communication.htm
        - Embedded Technology Lab https://emb.macnica.co.jp/articles/8191/
    - SPI
        - ラピステクノロジー https://www.lapis-tech.com/jp/common/miconlp/tips/2-18-spiとは/
        - 衛星ラボ https://eiseilab.com/spi/
        - ウィキペディア https://ja.wikipedia.org/wiki/I2C
    - I2C
        - 衛星ラボ https://eiseilab.com/i2c/
        - ウィキペディア https://ja.wikipedia.org/wiki/I2C
    - UART
        - 衛星ラボ https://eiseilab.com/uart/
    - M5Stack
        - Lang-ship https://lang-ship.com/blog/work/esp32-asyncudp/
        - M5Stack https://github.com/m5stack/M5-Schematic/blob/master/Core/Basic/M5-Core-Schematic(20171206).pdf
- その他
  - セッション - NTT https://www.ntt.com/bizon/glossary/j-s/session.html
  - マスター/スレーブ方式 - e-Words https://e-words.jp/w/マスター-スレーブ方式.html
  - ボー - ウィキペディア https://ja.wikipedia.org/wiki/ボー
  - バス - e-Words https://e-words.jp/w/バス.html