SoftwareSerialの「文字化け」や「受信データの破損」対策をする [Arduino/ESP-WROOM-02]
ArduinoからESP-WROOM-02を使用する際のシリアル通信には「HardwareSerial」と「SoftwareSerial」の2種類があります。
HardwareSerialは問題ありません。問題なのはSoftwareSerialです。SoftwareSerialでシリアル通信のbaudrate(ボーレート)が「115200bps」だと必ず受信データが破損して文字化けが発生します。
今回は検証結果と対策をご紹介します。
1. 配線図
今回は検証の為、電源はArduinoの「3.3V」を使用します。ESP-WROOM-02は実行用(Flash Boot Mode)の配線です。
<※本来は「TX/RX」は5Vなのでレベル変換(FXMA2102、PCA9306)を使用して3.3Vにします。(省略)
2. HardwareSerialの検証(115200bps)
スケッチ
ATコマンドでバージョン情報をシリアルモニターへ表示します。
// シリアルバッファを取得する
// ※バッファは最大64バイトなので、時間で繰り返し取得します。
String getSerialBuffer(Stream* mySerial,uint32_t readTime){
char c; String result = ""; uint32_t st = millis();
// readTimeの間、シリアルバッファを読み込む
while ((millis() - st) < readTime) {
while(mySerial->available() > 0){
c = mySerial->read();
if(c == '\0'){
continue;
}
result += c;
}
}
return result;
}
void setup() {
Serial.begin(115200);
delay(10);
// ATコマンドでバージョン情報を取得する
Serial.println("AT+GMR");
String str = getSerialBuffer(&Serial,1000);
// ゴミの削除
str.replace("AT+GMR","");
str.replace("\r\r\n","");
str.replace("\r\nOK","");
Serial.println(str);
}
void loop() {
}
実行結果
ハードウェアシリアルは正常に表示されます。
3. SoftwareSerialの検証1(115200bps)
ATコマンドでバージョン情報をシリアルモニターへ表示します。
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3); // TX, RX
// シリアルバッファを取得する
// ※バッファは最大64バイトなので、時間で繰り返し取得します。
String getSerialBuffer(Stream* mySerial,uint32_t readTime){
char c; String result = ""; uint32_t st = millis();
// readTimeの間、シリアルバッファを読み込む
while ((millis() - st) < readTime) {
while(mySerial->available() > 0){
c = mySerial->read();
if(c == '\0'){
continue;
}
result += c;
}
}
return result;
}
void setup() {
Serial.begin(115200);
mySerial.begin(115200);
// ATコマンドでバージョン情報を取得する
mySerial.println("AT+GMR");
String str = getSerialBuffer(&mySerial,1000);
Serial.println(str);
}
void loop() {
}
実行結果
ハードウェアシリアルの実行結果と見比べてみるとわかりますが、ソフトウェアシリアル(115200bps)の受信データは破損しています。
4. SoftwareSerialの検証2(9600/115200bps)
最初に115200bpsでバージョン情報を表示後、シリアル通信速度を9600bpsに変更してから2回目のバージョン情報をシリアルモニターへ表示します。
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3);
// シリアルバッファを取得する
// ※バッファは最大64バイトなので、時間で繰り返し取得します。
String getSerialBuffer(Stream* mySerial,uint32_t readTime){
char c; String result = ""; uint32_t st = millis();
// readTimeの間、シリアルバッファを読み込む
while ((millis() - st) < readTime) {
while(mySerial->available() > 0){
c = mySerial->read();
if(c == '\0'){
continue;
}
result += c;
}
}
return result;
}
void setup() {
Serial.begin(9600);
mySerial.begin(115200);
delay(10);
// 1回、実行をするとESP-WROOM-02のシリアル通信速度が9600となります。
// 2回目以降は通信速度が115200の「1.」「2.」は実行されませんのでご注意を。
// ※デフォルトの115200に戻すには、USB電源(給電)をはずせばOKです。
// 1. バージョン情報[115200]
mySerial.println("AT+GMR");
Serial.println(getSerialBuffer(&mySerial,1000));
// 2. シリアル通信速度の変更[115200]
// 通信速度 : 9600
// データ : 8bits
// ストップ : 1bit
// パリティ : none
// フロー制御 : none
mySerial.println("AT+UART_CUR=9600,8,1,0,0");
Serial.println(getSerialBuffer(&mySerial,1000));
mySerial.begin(9600);
delay(10);
// 3. バージョン情報[9600]
mySerial.println("AT+GMR");
Serial.println(getSerialBuffer(&mySerial,1000));
}
void loop() {
}
実行結果
115200bpsは「文字化け」が発生して、9600bpsは正常に表示されます。
この事からArduinoからSoftwareSerialでESP-WROOM-02を操作するには「115200bps」を使用してはいけない事となります。
AT+UART_CURのフロー制御について(メモ書き)
ESP8266 AT Instruction Set(ATコマンド)(p18)から抜粋。
| 本文 | 日本語訳 |
|---|---|
| Flow control needs hardware support: MTCK is UART0 CTS and MTDO is UART0 RTS. | フロー制御にはハードウェアサポートが必要:MTCKはUART0 CTS、MTDOはUART0 RTS。 |
ここを見る限り「MTCK = GPIO_13」「MTDO = GPIO_15」のようです。
http://www.esp8266.com/viewtopic.php?p=40512
※但し、Arduinoからは使用する事はできません。ESP-WROOM-02にArduinoスケッチを書き込む場合のようです。
掲示板
ArduinoやRaspberry Piなどの電子工作の掲示板を作成しました。質問やわからない事は電子工作 (Arduino・ラズパイ等)でユーザー同士で情報を共有して下さい。
関連記事
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









