Arduinoを使った電子工作を始めるようになり当ブログでも電子工作関連の記事を投稿するようになりました。
そしてすごく感じるのは、電子工作って非常に人気があるようですね!
ArduinoやESP-32など便利なマイコンボードやRaspberry Piの登場が大きく関係しているのでしょうか。
これは国内だけの話ではなく海外でも電子工作ブームみたいなのが起こっているのかな?なんて感じています。
そしてSNSを含めArduino関連の事でよくコメントを頂くようになりましたが、その中で特に多いのがArduinoの電源周りの質問やシリアルでのやり取りについてです。
Arduinoの電源まわりのご質問はブログにもこれまで多く頂いたことから先日記事としてまとめてみました。
次に多いのがArduinoのシリアルでのやり取りについてです。
Arduinoではボードにもよりますが、UnoやNanoなど一般的によく使われるArduinoにはハードウェアシリアルが1系統用意されています。
また複数のデバイスとのやり取りを行いたい場合、ソフトウェアシリアルを使い空いているデジタルピンにRXやTX(UART)をソフトウェア的に割り当てることにより使うことも出来ます。
シリアル通信でのデータのやり取りが出来るようになると、Arduinoで出来ることの幅も広がります。
Arduinoには標準で無線通信機能が搭載されていませんが、例えばBluetoothモジュールを接続すれば無線での通信が可能となります。
またWi-Fi接続をしたい場合では、ESP8266が搭載されたWi-FiシールドやESP-01など小型Wi-Fiモジュールを接続する事により可能となります。
また赤外線(IR)通信を使えばリモコンでArduinoを操作するなんて事も出来ます。
これらはシリアルでの接続でArduinoとデータのやり取りを行いますが、このようにシリアル通信(UART)はマイコンではよく使われる通信方式となりArduinoでも便利に使うことが出来ます。
そしてArduinoに少し慣れてくるとESP-32のマイコンボードも面白くなってきます。
技適が取得された無線通信用のモジュールはArduinoの場合あまりありませんが、よく使われるESP-32のボードで言うとESP-WROOM-32Dなどは技適が取得されたWi-Fi&Bluetoothモジュールが搭載された便利なマイコンボードになるかと思います。
これらはシリアルでのデータのやり取りとなるのでArduinoを使っていろいろとやっているとマイコンボードは違いますがESP-32などでも扱うことが出来るようになると思います。
今回は上記Arduinoのシリアル通信の追記として、複数Arduinoをシリアルで接続しそれらを制御してみたいと思います。
複数Arduino間でシリアル通信をやってみる!
Arduinoを使った1対多数の簡単なシリアル通信をやってみたいと思います。
I2C通信を使っても同様なことは出来ますが、今回はシリアル通信でやってみます。
Arduinoのシリアル通信(UART)に関して詳しくはこちらの記事を参考にして下さい。
手元に余っていたArduino UnoとMega、Leonardoなど合計6台のArduinoボードを接続し、親機にあたるArduinoからデータを送信し、それに繋がった複数の子機Arduinoをシリアル通信で制御しLEDを点灯させてみます。
上記記事を読んで頂ければ接続は簡単です。
シリアル通信(UART)では、2本の信号線を使いデータのやり取りを行います。
送信用のデータラインとなるTXと受信用のデータラインとなるRXの2本です。
- TX:データ送信用
- RX:データ受信用
シリアル通信での接続の基本は、ArduinoのTX(送信)ラインを接続機器のRX(受信)ラインと繋ぎデータを送信するというものとなります。
そして接続機器からのデータは、ArduinoのRX(受信)ラインから受け取ります。
ちょうどTXとRXがクロスした形の接続ですね。
もちろんこれは接続機器がArduinoになっても同様にデータの送受信を行うことが出来るので、Arduino間でのデータ送のやり取りを行うことも可能となります。
今回親機となるArduinoから子機となるその他多数のArduinoに命令を送り制御する形で各ArduinoのLEDを点灯させてみたいと思います。。
それぞれハードウェアシリアルで接続します。
ArduinoはMegaのように複数のハードウェアシリアルポートが搭載されたボードもありますが、大抵のボードは1系統のみ用意されています。
Arduino Unoの場合、ボードに書かれているRX(デジタルピンD0)、TX(D1)がそれにあたります。(ボードによってシリアルピンの位置は異なります)
通常の接続はこのようになります。
今回親機Arduinoから複数の子機Arduinoに命令を送り制御するという片方向でのやり取りで行ってみます。
親機Arduinoの送信(TX)を複数の子機Arduinoの受信(RX)に接続するということです。
シリアルでの接続は非常に簡単です。
親機ArduinoのTXをブレッドボードを使い各子機ArduinoのRXに接続するだけです。
今回子機側からはデータの送信は行わないので、上記図の子機(受信側Arduino)のTX→親機(送信側Arduino)のRXの青ラインは不要となります。
折角なので電源供給も親機Arduinoからすべて供給させてみます。
Arduinoにはどのボードにも[5V端子]が付いています。
この[5V端子]はボードのレギュレータを通して5Vを作り出しているので、安定した電圧を外部に供給する事が出来ます。
Arduinoの電源供給方法に関してはこちらの記事も参考にして下さい。
親機Arduinoの[5V端子][GND端子]をそれぞれ子機Arduinoの同端子に接続すれば、全ての子機Arduinoの電源を親機Arduinoから供給する事が出来ます。(電源供給はどのArduinoからでも行なえます)
接続は以上です。
親機Arduino | 子機Arduino | |
シリアル端子 | TX | 子機① RX |
子機② RX | ||
子機③ RX | ||
子機・・・・・ | ||
電源 | 5V端子 | 同様に各子機Arduinoの5V端子に接続 |
GND端子 | 同様に各子機ArduinoのGND端子に接続 |
それでは簡単なスケッチでテストしてみます。
親機から1~6までの数字を送信し、対応した番号のArduinoに繋げたオンボードLEDが点灯するというものです。(1は親機自身となります)
まず親機となるArduino用のスケッチです。
今回接続するArduinoの合計台数は6台なので、変数Board_Totalの数を6としています。
接続するArduinoの数に応じて数値を変えて下さい。
【親機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 26 27 28 29 30 31 32 | // 複数Arduino間のシリアル通信(親機Arduino用スケッチ) // https://burariweb.info int Board_Total = 6; // 親Arduinoを含め接続するArduinoの数 int tim = 200; void setup(){ Serial.begin(9600); // シリアル通信の開始(親機・子機Arduinoでボーレードを合わせる) pinMode(LED_BUILTIN, OUTPUT); // ビルトインLED(D13) } void loop(){ for(int i=1; i<=Board_Total; i++){ if(i == 1){ digitalWrite(LED_BUILTIN, HIGH); // 数字が1なら親機ArduinoのLEDを点灯 delay(tim); digitalWrite(LED_BUILTIN, LOW); } else { Serial.write(i); // 子機Arduinoに数字を送信 delay(tim); } } tim = tim -10; if(tim < 60){ tim = 60; } } |
次に子機Arduino用のスケッチです。
それぞれ子機Arduinoに次のスケッチを書き込みます。
その際に変数Board_Noの値をそれぞれのボードで変えて下さい。
親機Arduinoは1とするので、子機Arduinoは2,3,4・・・のように各子機番号を割り振ります。
【子機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 26 | // 複数Arduino間のシリアル通信(子機Arduino用スケッチ) // https://burariweb.info int Board_No =2; // 子機の番号の割り振り void setup(){ Serial1.begin(9600); // シリアル通信の開始(親機・子機Arduinoでボーレードを合わせる) pinMode(LED_BUILTIN, OUTPUT); } void loop(){ while(Serial1.available()){ // 受信データを確認する byte Signal = (byte)Serial1.read(); // 受信データを読み取る Serial1.println(Signal); if(Signal == Board_No){ // 受信データが自分の番号なのか確認 digitalWrite(LED_BUILTIN, HIGH); // LEDを点灯 } else{ digitalWrite(LED_BUILTIN, LOW); //LEDを消灯 } } } |
今回ハードウェアシリアルでのやり取りなので、ArduinoのTX/RX端子に接続された状態だと書き込みエラーが発生する場合があります。
配線する前に各Arduinoにスケッチを書き込んでおくか、書き込むArduinoのTX/RX端子に繋がれたケーブルを一旦外してからスケッチの書き込みを行って下さい!
スケッチの書き込みが完了し配線の接続も出来たら、親Arduinoに通電します。(子機Arduinoの通電でもOKです)
順番に各ArduinoのオンボードLEDが点灯すれば成功です!
下記動画では分かりやすくするためにD13にLEDを繋げています。
この投稿をInstagramで見る
簡単なテストですが、シリアルでのやり取りで他のArduinoを制御する事が出来ましたね!
補足
上記動画では数種類のArduinoボードを使ってハードウェアシリアルでの接続でデータのやり取りを行っています。
そしてArduinoのシリアルポートはボードによって少し仕様が異なっています。
例えばArduino MegaではD0(RX)/D1(TX)以外にも3系統のハードウェアシリアル端子(Serial/Serial1/Serial2/Serial3)が搭載されています。
また上記動画では手前の黄色いボードはArduino Leonardo互換ボードとなりますが、Leonardoに搭載されているATmega32U4チップはUSB機能を内蔵しているため、他のボードに搭載されているシリアル通信用のチップが搭載されていません。
そのためシリアルピンの取り扱いが少し異なり、上記スケッチのシリアルに関係する部分「Serial.begin()、Serial.available()、 Serial.read()」のSerialをSerial1に書き換える必要があります。
もしLeonardoのボードを使う場合、スケッチをそのように修正して下さい!
また、Arduino公式サイトにも各Arduinoボードのシリアルピンについて書かれています。
他のマイコンボードと違いArduinoの場合、ボードが変わってもシリアル以外の他の項目もある程度仕様が統一されていて使いやすい印象を受けますが、ボードによって微妙に異なる部分もあるので公式サイトをいろいろと眺めていると発見があると思います。
最後に!
以前Arduinoのシリアル通信の記事に書いたものの追記として簡単なテストをやってみました。
Arduinoの電源供給方法やシリアルでのやり取りについてよく質問やコメント頂くことから簡単なテストでやってみたのですが、Leonardのシリアルのとり方などArduinoのボードによって微妙に仕様が異なる部分も気付き個人的になるほどとなることが多く勉強になりました。
簡単と思うことでも実際に接続して動かしてみると新たな発見があり楽しいですね!
コメントを残す