Arduinoに接続したデバイスとのデータのやり取りにはいろいろな方法があります。
その通信方法には大きくシリアル通信とパラレル通信に分けられます。
シリアル通信に比べパラレル通信では一度に多くのデータを送ることができますが、複数の配線(信号線)が必要となってきます。
以前、シリアル通信の1つであるI2C通信についてご紹介しました。
LCDモジュールに文字を表示させる作例としてパラレル通信とシリアル通信で試してみました。
I2C通信でのやり取りでは2本の信号線(SCL/SDA)のみでArduinoとLCDモジュールを接続しデータのやり取りにより文字を表示させる事が出来ましたが、パラレル通信で同様なことを行うためには非常に多くの信号線が必要となってきます。
Arduinoボードで使えるI/Oピン(入出力端子)には数に限りがあります。
これまでArduino入門編記事ではArduino Unoを中心に使ってきました。
Arduino Unoで言うとI/Oピンとして使える端子はデジタルピンがD0~D13までの14本、アナログピンがA0~A5までの6本使えるので合計20本程しかありません。
サーボモーターやセンサー、モジュールなど接続したり、また他のデバイスと接続するとなると多くの信号線が必要となるパラレル通信では大変となります。
そのため現在ではシリアル通信が主流になるようです。
シリアル通信でよく使われるものには、I2C通信・UART通信・SPI通信の3つがあげられます。
この3つはArduinoでもよく使われる通信方式となります。
I2C通信の基本に関しては上記記事をご覧下さい。
そして今回は、シリアル通信の1つであるUART通信についてご紹介したいと思います。
Arduinoを使っていると一番よく使われる通信方式だと思います。
これまでのArduino入門編記事をご覧の方でUART通信なんて使ったことないよ!と思われる方もいらっしゃるかと思いますが、Arduinoを使っていると普段意識することなくこのUARTでのやり取りを使っています。
Arduinoのスケッチの書き込みはPCとArduinoをUSBケーブルを接続して行いますが、まさしくあれがUART(シリアル通信)によるやり取りとなります。
また、デバッグなどでスケッチで使われている変数の値をシリアルモニタに表示させたりすることがありますが、このやり取りもUART通信により行われています。
今回はシリアル通信の1つであるUART通信の基本を見ていきたいと思います。
目次
UARTシリアル通信の基礎知識!Arduino間でのデータのやり取りなどをやってみる!
UART通信とは?
冒頭でもお話しましたが、シリアル通信の中でよく使われるものとしてUART通信・I2C通信・SPI通信の3つがあります。
Arduinoでも使うことが多い通信方式です。
SPI通信に関してはArduino入門編記事としてまだご紹介出来ていませんが、I2C通信に関してはこちらの記事を参考にして下さい。
UART(ユーアート)は「Universal Asynchronous Receiver/Transmitter」の略となり、I2C通信やSPI通信とは異なり非同期式のシリアル通信となります。
I2C通信にはSCL、SPI通信にはSCKというクロック用の信号ラインがあり同期させながらデータのやり取りを行っています。(同期式シリアル通信)
UART通信ではこのクロック信号がなく、そのためI2CやSPIと比べて仕組みが単純で比較的扱いやすくなっています。
UART通信ではこのクロック用の信号ラインがなく、2つの信号線を使って通信を行います。
UART通信で使われる信号線は、データ送信用の信号線としてTXD(またはTX:Transmitter)とデータ受信用の信号線としてRXD(またはRX:Receiver)の2つの信号線を使ってデータのやり取り(通信)が行われます。
UART通信で使われる信号線
UART通信では、TXとRXの2つの信号線を使って通信を行います。
- TX(Transmitter):データ送信用の信号線
- RX(Receiver):データ受信用の信号線
Arduino Unoを見るとデジタルピンD0にRX・D1にはTXとボードに記載されていますが、これがUART通信で使われる端子となります。
Arduino Unoの心臓部であるマイコンチップATmega328Pの2番ピン(RXD)・3番ピン(TXD)とD0端子・D1端子は直接繋がっています。
またこの2つの端子は、USB-シリアル変換を行うATmega16U2チップにも繋がっています。
そのため、PCとArduinoをUSB端子で接続してスケッチの書き込みやシリアルモニタを使うことが出来るようになっています。
UARTによるやり取りですね!
デジタルピンD0とD1は、通常のデジタル入出力端子として使われるほか、UART通信で使う専用端子にもなっているということです。
このD0端子やD1端子にモジュールやデバイスなど何かしら接続された状態でスケッチの書き込みを行おうとすると書き込みエラーが出ることがありますが、そのためなんですね!
Arduinoを使い始めたばかりの頃は、使っていてこの書き込みエラーによく遭遇しました。
使うデジタルピンに余裕がある場合、D0・D1端子を使わないのはそのためです!
このようにUART通信で使われる信号線TXとRXはArduinoではマイコンチップとハードウェア的に接続されているため、これを『ハードウェアシリアル』と呼びます。
Arduino Unoの場合、UART通信で使える端子がD0(RX)とD1(TX)の1系統しかハードウェアシリアルが用意されていません。
UART通信ではI2CやSPIでの接続のようにマスターやスレーブといった関係がなく1対1でのやり取りとなるためこれでは複数のデバイスとのやり取りが出来ません。
そのため、他のデジタルピンをRX・TXに割り当ててソフトウェア的にUARTでの接続を可能にするライブラリがArduinoには標準で用意されています。
これはソフトウェアによりUART通信を可能にしているので『ソフトウェアシリアル』といいます。(後述します)
UARTでの接続方法
UART通信の概要が分かったところで、その接続方法です。
UART通信では、データ送信用としてTX・データ受信用としてRXの2つの信号線でやり取りを行う通信方式です。
I2C通信やSPI通信のようなクロック信号がなく、またマスターやスレーブといった関係もなく1対1でのやり取りとなる接続関係となります。
そのため接続は非常にシンプルとなります。
Arduinoと対応デバイスとの接続例です。
データ送信用のTXラインを対となる受信ラインRXに接続する形となります。
矢印はデータの向きを示しています。
送信したデータを送るラインと受信するラインでやり取りするという事ですね。
接続はTXをRX、RXをTXに接続するだけなので簡単です!
Arduino | 接続機器 |
TX(送信) | RX(受信) |
RX(受信) | TX(送信) |
【テスト①】2台のArduinoを同期させてみる
UART通信について基本的な部分が分かったところで、いくつか試してみたいと思います。
まず接続した2台のArduinoを同期させてみます。
接続はこのようになります。
TXをRX、RXをTXに接続するだけなので簡単ですね。
仮に送信側Arduino・受信側Arduinoとしておきます。
テスト用の簡単なスケッチを作ってみました。
送信側のLED点灯タイミングを受信側に送りLEDの点灯を同期させるというものとなります。
オンボードLED(D13)を点灯させています。
(送信側Arduinoスケッチ)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // Arduino入門編㉖ UART通信について! // https://burariweb.info // LED点灯テスト①(送信側スケッチ) const int LED_PIN = 13; void setup(){ Serial.begin(9600); // シリアル通信の開始(ボーレート9600bps) pinMode(LED_PIN, OUTPUT); } void loop(){ digitalWrite(LED_PIN, HIGH); Serial.write('1'); // "1"を送信 delay(500); digitalWrite(LED_PIN, LOW); Serial.write('0'); // "0"を送信 delay(500); } |
(受信側Arduinoスケッチ)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // Arduino入門編㉖ UART通信について! // https://burariweb.info // LED点灯テスト①(受信側スケッチ) const int LED_PIN = 13; void setup(){ Serial.begin(9600); // シリアル通信の開始(ボーレート9600bps) pinMode(LED_PIN, OUTPUT); } void loop(){ while(Serial.available() > 0){ // 入力された文字が何バイトか調べその回数分繰り返す int val = Serial.read(); // 1バイト分のデータを読み取る if(val == '1'){ // "1"ならLEDを点灯,"0"ならLEDを消灯 digitalWrite(LED_PIN, HIGH); } else if(val == '0'){ digitalWrite(LED_PIN, LOW); } } } |
先述のようにハードウェアシリアルでは、D0ピンD1ピンに接続された状態ではスケッチの書き込みを上手く行うことが出来ません!
オンボードLED(D13)が同じタイミングで点灯しているのが確認出来ると思います。
スケッチ解説
シリアル通信の開始。
9 | Serial.begin(9600); // シリアル通信の開始(ボーレート9600bps) |
シリアルポートにバイナリデータを出力(送信)する。
17 | Serial.write('1'); // "1"を送信 |
データを受信したかどうかの確認。
16 | while(Serial.available() > 0){ // 入力された文字が何バイトか調べその回数分繰り返す |
受信したデータの読み込み
17 | int val = Serial.read(); // 1バイト分のデータを読み取る |
詳しくは以前ご紹介したシリアルモニタの使い方が参考になると思います。
スケッチを見ると分かりますが、送信側からのデータ(“1” or “0”)により受信側のLEDをON/OFFさせるだけの単純なものとなります。
試しに送信側(RX)と受信側(TX)のデータライン(青ケーブル)を外してみて下さい。
ケーブルを外してもLEDの点灯は変わりません。
つまりデータの向きとして片方向でのやり取りしか行われていないということですね。
【テスト②】Arduino間双方向でやり取りを行う
上記の例では、送信側ArduinoのTXから送られたデータを受信側ArduinoのRXで受け取るといったやり取りが行われていることが分かりました。
それでは、上記の接続にタクトスイッチを追加して一方のArduinoに接続されたスイッチが押されると他のArduinoのLEDが点灯する双方向でのやり取りをやってみます。
接続およびスケッチは共通となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | // Arduino入門編㉖ UART通信について! // https://burariweb.info // LED点灯テスト② const int LED_PIN = 13; const int SW_PIN = 8; void setup(){ Serial.begin(9600); // シリアル通信の開始(ボーレート9600bps) pinMode(LED_PIN, OUTPUT); pinMode(SW_PIN, INPUT_PULLUP); // スイッチに接続したピンをプルアップ digitalWrite(LED_PIN, LOW); } void loop(){ while(Serial.available() > 0){ int val = Serial.read(); // 受信したデータを読み込む if(val == '1'){ // "1"ならLEDを消灯、"0"ならLEDを点灯 digitalWrite(LED_PIN, LOW); } else if(val == '0'){ digitalWrite(LED_PIN, HIGH); } } int SW = digitalRead(SW_PIN); // スイッチの状態を判定 if(SW == HIGH){ // "HIGH"なら”1”を送信 Serial.write('1'); } else if(SW == LOW){ // "LOW"なら"0"を送信 Serial.write('0'); } delay(100); } |
タクトスイッチのON/OFF判定はプルアップさせて使用しているので「HIGH(“1”)」でLEDが消灯、「LOW(“0”)」で点灯します。
プルアップ・プルダウンに関してはこちらの記事を参考にして下さい。
書き込みが上手く出来ずエラーが発生します。
双方向でのデータのやり取りが行われているのが確認できます。
UART対応デバイス使用例
UART通信について理解できたと思います。
UART通信は、SPI通信やI2C通信などと同様にArduinoではよく使われる通信方式となります。
実際の作例としてはこのような使い方ができます。
こちらは以前製作した4足歩行ロボットにUARTでの接続で使えるBluetoothモジュール(HC-05やHC-06)を組み込んで動かしています。
PCのシリアルモニタに入力した値(コマンド)をBluetoothモジュールと接続したArduinoに送信し動きを制御するというものとなります。
PCからBluetoothモジュールにデータを送り、BluetoothモジュールはUART(TX/RX)によりArduinoにデータを引き渡すということですね。
電子工作的にはこのような作例を紹介した方が楽しいですよね!
コントローラーを使って製作物を自在に動かす・・・なかなか楽しいものです!
【テスト③】ソフトウェアシリアルによる接続
最後にソフトウェアシリアルについても少し触れておきます。
ArduinoでUART通信に使えるデジタルピンD0(RX)とD1(TX)はハードウェアシリアルでの接続だということは先に説明しました。
Arduino Unoではこのハードウェアシリアルは1系統(D0:RX,D1:TX)しかありません。
I2C通信やSPI通信のようにマスターに対して複数のスレーブ端末を接続出来るわけではなく、1対1の接続関係にあるのがUART通信の特徴となります。
それでは複数の端末(デバイス)を使いたい場合はどうしたらいいのか?
Arduinoには複数のUARTデバイスを接続する場合、専用ライブラリを使用することにより空いているデジタルピンをTX/RXに割り当ててソフトウェア的にUART接続を可能にする事が出来ます。
これまでやってきたハードウェアシリアルではD0(RX)・D1(TX)端子に何かしらデバイスが接続された状態ではスケッチを書き込む際にエラーが出てしまいましたよね!
ソフトウェアシリアルでは他のデジタルピンを選ぶことによりそれらを回避することも出来ます。
ソフトウェアシリアルでは『SoftwareSerial』というライブラリを使います。
Arduino IDEに標準で入っているライブラリとなります。
SoftwareSerialの使い方は、通常のシリアル通信とほぼ同じです。
詳しくはArduino公式リファレンスをご覧ください!
先程のスケッチをソフトウェアシリアルを使ったものに書き換えてみます。
RXをD2、TXをD3に割り当てました。
これでD0/D1が空いた状態なのでスケッチの書き込みも通常通り行えます。
また複数接続する場合にも使えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // Arduino入門編㉖ UART通信について! // https://burariweb.info // ソフトウェアシリアルを使う! #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // RX,TXの割り当て const int LED_PIN = 13; const int SW_PIN = 8; void setup(){ Serial.begin(9600); mySerial.begin(9600); // ソフトウェアシリアル通信の開始(ボーレート9600bps) pinMode(LED_PIN, OUTPUT); pinMode(SW_PIN, INPUT_PULLUP); // スイッチに接続したピンをプルアップ digitalWrite(LED_PIN, LOW); } void loop(){ while(mySerial.available()>0){ int val = mySerial.read(); // 受信したデータを読み込む if(val == '1'){ // "1"ならLEDを消灯、"0"ならLEDを点灯 digitalWrite(LED_PIN, LOW); } else if(val == '0'){ digitalWrite(LED_PIN, HIGH); } } int SW = digitalRead(SW_PIN); // スイッチの状態を判定 if(SW == HIGH){ // "HIGH"なら”1”を送信 mySerial.write('1'); } else if(SW == LOW){ // "LOW"なら"0"を送信 mySerial.write('0'); } delay(100); } |
スケッチ解説
通常のシリアル通信とほぼ同じですが、異なる部分だけ見ておきます。
まずライブラリのインクルードです。
他のライブラリを使うときと同様にSoftwareSerialライブラリをインクルードしておきます。
5 | #include <SoftwareSerial.h> |
ハードウェアシリアルではD0がRX・D1がTXと決められていましたが、ソフトウェアシリアル(SoftwareSerial)では使いたいピンを任意に選ぶことが出来ます。
こちらでは、RXをD2・TXをD3に設定しmySerialという名前にしています。
6 | SoftwareSerial mySerial(2, 3); // RX,TXの割り当て |
ソフトウェアシリアルでの通信を開始します。
Serial.begin(9600)が残っていますが、このスケッチではハードウェアシリアルでのやり取りは行っていないのでこの行は書かなくても問題ありません。
13 14 | Serial.begin(9600); mySerial.begin(9600); // ソフトウェアシリアル通信の開始(ボーレート9600bps) |
あとはソフトウェアシリアルで設定したRX・TXラインを使いデータの送信及び受信をさせています。
ソフトウェアシリアルを使っている以外は先程のスケッチ内容と同じです。
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | while(mySerial.available()>0){ int val = mySerial.read(); // 受信したデータを読み込む if(val == '1'){ // "1"ならLEDを消灯、"0"ならLEDを点灯 digitalWrite(LED_PIN, LOW); } else if(val == '0'){ digitalWrite(LED_PIN, HIGH); } } int SW = digitalRead(SW_PIN); // スイッチの状態を判定 if(SW == HIGH){ // "HIGH"なら”1”を送信 mySerial.write('1'); } else if(SW == LOW){ // "LOW"なら"0"を送信 mySerial.write('0'); } |
今回のポイント
- UART通信では、TX(送信)とRX(受信)の2つの信号ラインでやり取りを行う
- データのやり取りは1対1での接続(TX→RX・RX←TX)となる
- ハードウェアシリアルではD0(RX)・D1(TX)ピンが使われる
- ソフトウェアシリアルにより任意のデジタルピンにTX/RXを割り当てることが出来る
【追記】Bluetoothモジュールを使って無線通信をしてみる!
UARTによるやり取りは信号線が2本(送信:TX/受信:RX)のみの接続で出来るので比較的簡単に使うことが出来ます。
上記動画の4足歩行ロボットくんにはシリアルでのやり取りが出来るBluetoothモジュールを組み込んでPCをコントローラーとして動かしています。
HC-05というBluetoothモジュールを使っていますが、専用ライブラリなど必要とせず今回ご紹介したような通常のシリアルでのやり取りで使える便利なモジュールとなります。
UART通信でのやり取りが出来れば、いろいろと応用が出来そうですね!
【追記】複数Arduino間でのシリアル通信による制御をやってみました
Arduinoのシリアル通信(UART)や電源供給方法に関してよくお問い合わせ頂くことから、複数Arduinoを接続した簡単な制御テストをやってみました。
あわせて読んで頂ければと思います!
この投稿をInstagramで見る
またシリアルでのやり取りはマイコンボードではよく使われる通信方式となり、無線機能を持たないArduinoへのモジュールの接続にも使われます。
上記Bluetoothモジュールを接続したり、Wi-Fiモジュールの接続でも使われるので参考になればと思います。
この投稿をInstagramで見る
今回使ったパーツ
Arduino UNO
Arduinoはオープンソースのハードウェアなので正規品以外にも互換品が多数販売されています。
互換品でも正規品と比べて特に問題なく使用でき安価なためArduino学習用としていいと思います。
Elegoo製のArduinoボードは、互換ボードの中でも非常にクオリティーが高いのでおすすめです!
Arduino スターターキット
これからArduino学習を進めていくにあたりArduino UNO(互換品)やブレッドボード、ジャンパーピンなどがセットになったスターターキットが販売されています。
私はGeekcreit製のスターターキットを使っていますが、ELEGOO製のものは国内Amazonなどでも購入可能で人気があるようです。(セット内容はほぼ同じです!)
そしてELEGOOのサイトからスターターキット用サンプルスケッチのダウンロードも可能です。(Geekcreitのキットでも使えます)
参考 チュートリアルダウンロードELEGOO基本的にこれからこのセットで出来るものから紹介していこうと考えていますが、かなり多くのことが出来ます。
電子工作を始めるにはまずブレッドボードやジャンパーピン、メインとなるArduino UNOやサーボ、LEDなどの基本的なパーツがないと実際に動かすことが出来ませんが、個々にパーツを購入して回路を組んでとなるとかなりの手間がかかります。
スターターキットがあればArduinoの初歩的なことはかなりの数こなすことが出来るのでオススメです!
そこからスキルアップに伴い個別でセンサーやモジュールなど必要なものを増やしていくのがいいと思います。
今回使ったタクトスイッチなど基本的なパーツは全て揃っています。
最後に!
UARTでの接続は、シンプルで非常に簡単でしたね!
UART通信は、I2C通信やSPI通信と同様にArduinoではよく使われる通信方式になります。
その雰囲気や概要が分かったところで今回はこの辺で・・・
[…] […]