2019年8月28日水曜日

ArduinoでWiFi接続してみる

ArduinoでWiFiを活用するのであれば、Arduino YúnやらESP8266、ESP32などのマイコンボードを使えば全く問題ない。むしろ手間もかからず、目的を達成する速度も向上するので効率も良くなる。

ただし、それらデバイスではGPIOの数は限られてしまう。
例えば、Arduino MegaのGPIO数が必要で、WiFiにも接続したい場合を想定すると、何かしらの手立てでWiFiモジュールと接続するしかない。

って事で、WiFiシールドを調べて見ると、販売終了、技適未取得、高額な商品のいずれかになる。
Switch Scienceでは、ESP-WROOM-02を搭載したWiFiシールドが比較的安価で販売されているが、同様な構成でESP-WROOM-02を使用した記事を見かけたので、そちらを試してみる事に。

前回の"ESP-WROOM-02のATモードでWiFI接続"は、このための準備。
配線も、Switch ScienceのWiFiシールドの回路図を参考にして(パクって)いたりする。

とりあえず、Arduino UNOと接続。
UARTの5V、3.3Vレベル変換には、秋月電子通商の4ビット双方向ロジックレベル変換モジュールを使用。
Arduio側のソフトウェアUARTのピンは、WiFiシールドと異なりTXD=D11、RXD=D10を指定。
※WiFiシールドでは、TXD=D2、RXD=D4

ArduinoとESP-WROOM-02間で通信させてみます。
使用するのは、Arduino IDEに付属するサンプルスケッチ。
(ArduinoIDE 1.8.9 : "ファイル" - "スケッチ例" - "SoftwareSerial" - "SoftwareSerialExample.ino")

スケッチの内容を見て行きます。
#include <SoftwareSerial.h>
SoftwareSerialライブラリをインクルード。
SoftwareSerialでは、最大115200 bpsでの通信が可能となります。
SoftwareSerialオブジェクトに紐づく関数は以下。
  • SoftwareSerial()
  • available()
  • begin()
  • isListening()
  • overflow()
  • peek()
  • read()
  • print()
  • println()
  • listen()
  • write()
SoftwareSerialオブジェクトのインスタンスを作成。
SoftwareSerial mySerial(10, 11); // RX, TX

SoftwareSerial(rxPin, txPin, inverse_logic)

説明

SoftwareSerialは、SoftwareSerialオブジェクトのインスタンスを作成するために使用されます。このオブジェクトの名前は、次の例のように指定する必要があります。inverse_logic引数はオプションであり、デフォルトはfalseです。動作の詳細については、以下を参照してください。複数のSoftwareSerialオブジェクトを作成できますが、特定の時点でアクティブにできるのは1つだけです。

通信を有効にするには、SoftwareSerial.begin()を呼び出す必要があります。

パラメータ

rxPin: シリアルデータを受信するピン

txPin: シリアルデータを送信するピン

inverse_logic: 着信ビットの意味を反転するために使用されます(デフォルトは通常のロジックです)。設定されている場合、SoftwareSerialはRxピンのLOW(通常ピンの0ボルト)を1ビット(アイドル状態)として、HIGH(通常ピンの5ボルト)を0ビットとして扱います。また、Txピンへの書き込み方法にも影響します。デフォルト値はfalseです。

Warning: Arduinoが処理できる範囲外のシリアルデータを出力するデバイスを接続しないでください。通常、5Vで動作するボードでは0Vから5V、3.3Vで動作するボードでは0Vから3.3Vです。

#include <SoftwareSerial.h>

const byte rxPin = 2;
const byte txPin = 3;

// 新しいシリアルオブジェクトを設定します
SoftwareSerial mySerial (rxPin, txPin);
void setup() {
	// シリアル通信を開き、ポートの開放を待ちます:
	Serial.begin(57600);
	while (!Serial) {
		; // シリアルポートが接続されるのを待ちます。 ネイティブUSBポートでのみ必要
	}


	Serial.println("Goodnight moon!");

	// ソフトウェアシリアルポートのデータレートを設定する
	mySerial.begin(4800);
	mySerial.println("Hello, world?");
}
Serial.beginは、チュートリアルでも出てくるArduinoとPC間のシリアル通信の速度を設定するものです。
mySerial.beginも対象が異なるだけで基本的に同じ目的で使用します。
異なる点は、ソフトウェアでシリアル通信を実装しているため最大ボーレートが115200に限定される事でしょうか。
ESP-WROOM-02のATモードでのボーレートは、115200bpsが標準で設定されていますが、Arduinoで安定する9600bpsに変更し、スケッチも

	Serial.begin(9600);

	mySerial.begin(9600);
の様に書き換えておく。ArduinoとPC間のボーレートは、元のままでも問題なく動作するのですが、気分的に書き換えています。 Serial.println、mySerial.printlnは、共にシリアルのデータ表示を行います。 ここでの一連の流れは、Arduino - PC間で指定のボーレートでのシリアル通信を設定、Serial(シリアルモニタ)に対して"Goodnight moon!"の表示指示を行い、Arduino - ESP-WROOM-02間で指定のボーレートでのシリアル通信を設定、mySerial(ESP-WROOM-02)に対して"Hello, world?"の表示指示を行う処理を表しています。
void loop() { // 繰り返し実行
	if (mySerial.available()) {
		Serial.write(mySerial.read());
	}
	if (Serial.available()) {
		mySerial.write(Serial.read());
	}
}
mySerial.available()、Serial.available()のavailable()は、どちらも(ソフトウェア)シリアルポートからの読み取りに使用できるバイト数(文字)を取得します。これは、すでに受信され、シリアル受信バッファーに保存されているデータです。

write()、read()も同様にSerial、SoftwareSerialで同じ機能で動作します。

write()は、ソフトウェアシリアルポートに対してデータを送信します。
戻り値は、送信したバイト数 (byte) 。

read()は、受信データを読み込みます。
SoftwareSerialでは、listen()で選択されたポートのみでしか受信できません。
戻り値は、Serialの場合は、読み込みデータの最初の1byte。SoftwareSerialの場合は、読み込んだ文字列。
どちらもデータがない場合には-1となります。

動作としては、mySerial、Serialどちらかに送信されたデータがあれば、相互にデータを交換します。

では、実際に動かしてみましょう。

修正したスケッチを別名で保存してArduinoへ書き込みを行い、改行を"CRおよびLF"、シリアルモニタを"9600bps"に設定すると、以下の様な表示が確認できます。
Goodnight moon!
Hello, world?
 
ERROR

"ERROR"は、mySerialに表示指示を出した"Hello, world?"によるものなので気にしなくて大丈夫です。
続けて、ATとタイプして送信すると、
Goodnight moon!
Hello, world?
 
ERROR
AT

OK

となれば通信がArduinoを"介して"ESP-WROOM-02をATモードで操作出来る事が確認出来たわけです。

ATモードで独自にWIFI設定するなら"ESP-WROOM-02のATモードでWiFI接続"を参照。

ここまでは、ArduinoとESP-WROOM-02が連携した動作になっていません。あくまで繋がってるだけですね。ここから先は、"ITEADLIB_Arduino_WeeESP8266"を導入してゴニョゴニョして行くの良さげです。ただ、もう少し違う方法を探ってみたいと考えているのですが、長くなるので今回は、ここまで。

あ、ちなみにUSBのみの給電だと心もとないので、ACアダプタの使用は必須かも。

0 件のコメント:

コメントを投稿