ホーム > カテゴリ > ロボット・電子工作・マイコン >

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なのでレベル変換(FXMA2102PCA9306)を使用して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・ラズパイ等)でユーザー同士で情報を共有して下さい。

関連記事



公開日:2017年04月30日 最終更新日:2017年06月24日
記事NO:02343