18
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UARTを利用してESP32とシリアル通信する

Last updated at Posted at 2020-07-12

Goal

  • UART通信を利用してESP32とWindows間で通信してみる
  • USB to TTL変換ケーブルを使ってみる

利用した開発ボード

ESP32-DevKitC ESP-WROOM-32開発ボード
http://akizukidenshi.com/catalog/g/gM-11819/

UART通信って?

ちょっと調べたら以下のような感じらしい。

  • 1対1の接続
  • 基本は信号線が2本
    • TX(TXD):送信
    • RX(RXD):受信
  • 接続機器同士はクロスで接続する
    • TX -> RX
    • RX <- TX
  • 信号線の電圧には5vと3.3Vの2種類ある。通信機器同士は同じ電圧で利用しないと最悪壊れる
  • 信頼性を高めるためフロー制御が必要な場合は以下の信号線も利用する
    • RTS(Request to Send)
    • CTS(Clear to Send)
  • 通信速度(ボーレート)を接続機器間で合わせる必要がある

パソコン側の準備

今回はこちらを購入してみました。USBで仮想COMポートを作成してUART通信できるようになります。

DSD TECH SH-U09C USB - TTLシリアルアダプター + FTDI FT232RLチップ Windows 10 8 7 Mac OS X対応
https://www.amazon.co.jp/gp/product/B07BBPX8B8/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

シリアルアダプターの準備設定

USBなのでとりあえずUSBポートに刺してみました。おお、自動でドライバ入れてくれました!この辺りはさすがwindowsですね!

image.png

image.png

プロバイダーがFTDI(シリアル変換チップのメーカー)となっているので問題なさそうな予感です!このまま行こう:relaxed:

シリアル通信のターミナルソフト

Teratermを使います。SSH接続以外で使うのは初めてですね:v:

ESP32側の準備

Arduino UNOでのシリアル通信用の接続方法を調べる

まずは情報の多いArduinoについて調べました。するとArdunoではUARTで利用できるピンがデフォルトでは決まっているようです。例えばArduino UNOであれば下記のとおり 01 となります。これはUNOの基盤にも TX -> 1 RX <- 0 とわかりやすく書いてありますね。

image.png

なお :point_up: ページには大切なことが書かれていましたが横道にそれますので引用欄にて1

また、上記サイトには書かれていませんが、通常のGPIOピンをUART通信に利用できるソフトウェアシリアルも利用可能なようです。このあたりは下記のサイトが非常に参考になりました。

https://asukiaaa.blogspot.com/2019/03/arduino.html
https://shizenkarasuzon.hatenablog.com/entry/2018/09/10/093648

用語をいったんまとめる

  • ハードウェアシリアル
    • ハードウェアで持つ機能を用いてシリアル通信する。これらで利用するピンが「デフォルトで決まっているピン
  • ソフトウェアシリアル
    • ソフトウェア上でシリアル通信する。基本的にどのピンでも割り当てることが可能

ESP32への接続について

ESP32用のライブラリを直接見てみると下記のとおり3系統使えることがわかります。これらはハードウェアシリアルとのこと2です。

変数名 RXピン(default) TXピン(default)
Serial 3 1
Serial1 9 10
Serial2 16 17

なおGPIOのマッピングは下記のとおりですので、この通り繋いでみます。

image.png

ハードウェアシリアルを試す

UART0 で接続

動作確認用にLEDを入れているので下記のような感じになりました。

185DF9DF-2E20-46C8-9EDB-CB5BB4D2EA91.jpeg

UART0を利用する
int LED = 18;
int count = 0;

void setup() {
  pinMode(LED, OUTPUT);

  Serial.begin(115200);
}

void twinkle(){
  if ((count % 2) == 1) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

void loop() {
  Serial.print("count = ");
  Serial.println(count);
  twinkle();
  delay(1000);

  count++;
}

特に問題なく動きました。ArduinoIDEのシリアルモニタでも見れていますね!(COM3はESP32とUSB接続しているポートです)

image.png

UART1 で接続

ちょっと事前に調べてみると、何やらUART1はそのままでは利用できないような記述がたくさん。下記サイトに解決方法が記載ありました。

どうやら、GPIOのうち使えないピンがあるみたいですね。下記に詳細が記載ありました。

参考にしたサイトをもとにちょっと試してみます。

UART1を利用する

int LED = 18;
int count = 0;
int RX_PIN = 22;
int TX_PIN = 23;

void setup() {
  pinMode(LED, OUTPUT);
  Serial1.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
}

void twinkle(){
  if ((count % 2) == 1) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

void loop() {
  Serial1.print("count = ");
  Serial1.println(count);
  twinkle();
  delay(1000);

  count++;
}

うまくいきました!

image.png

UART2 で接続

うまくいくだろうから割愛。
ただ、UART2はUART0, UART1と異なりシステムから予約されていないので、シリアル通信をするならUART2を使ったほうがよさそうです。

ソフトウェアシリアルで接続

:rotating_light: 結論を先に。結果、利用できませんでした :rotating_light:

ソフトウェアシリアルは利用できないと参考サイトには記載がありましたが、UART1 の接続で汎用のGPIOを利用できた時点でソフトウェアシリアルなことをやっているような気がしたので同じ戦略でやってみます。

UART3を作ってみた(注:動きません)
int LED = 18;
int count = 0;
int RX_PIN = 22;
int TX_PIN = 23;

HardwareSerial Serial3(3);

void setup() {
  pinMode(LED, OUTPUT);
  Serial3.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
}

void twinkle(){
  if ((count % 2) == 1) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

void loop() {
  Serial3.print("count = ");
  Serial3.println(count);
  twinkle();
  delay(1000);

  count++;
}

結果だめでした:sob:UART1 など用意されているものはUARTコントローラときちんと接続されているのでしょうね。ちなみに下記も試しましたが駄目でした。
includeの位置がおかしいのはご愛嬌ということで。

ソフトウェアシリアルを使ってみた(注:動きません)
int LED = 18;
int count = 0;
int RX_PIN = 22;
int TX_PIN = 23;

#include <SoftwareSerial.h>
SoftwareSerial mySerial(RX_PIN, TX_PIN);

void setup() {
  pinMode(LED, OUTPUT);
  mySerial.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
}

void twinkle(){
  if ((count % 2) == 1) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

void loop() {
  mySerial.print("count = ");
  mySerial.println(count);
  twinkle();
  delay(1000);

  count++;
}

image.png

下記フォルダに SoftwareSerial.h もないので別途どなたか作ってらっしゃるライブラリを使うしかなさそうです。
https://github.com/espressif/arduino-esp32/tree/master/cores/esp32

確認していませんが、下記とか使えそうな気がします(無責任)

今回のはまりどころ

  • UART接続時の各端末はクロスで接続すること(当たり前だわな…)

    • USBSBとESP32を接続する場合
      • USBのTXをESP32のRX(に割り当てたピン)へ
      • USBのRXをESP32のTX(に割り当てたピン)へ
  • ESP32について

    • Bootボタン長押しでアップロードする(すっかり忘れてた)
    • リセットボタン(EN)を押さないと新しいプログラムが反映されない
      • USB接続後の初回起動時だけはENボタンを押さずに反映されたので気づくのに時間がかかった…

感想

  • 何も考えずに接続して動かす前にきちんとマニュアルを読もう
  • シリアルモニターが使えるようになったのでデバッグが楽になった!
  • シリアル通信できることでできることが格段と広がるので次が楽しみ!
  1. Arduino(やESP32)へのプログラムの転送時に、RX/TXピンに何らかの線が接続されているとアップロードに失敗する原因となると記載あるので、アップロード時にはピンを外すことを忘れないようにしましょう。

  2. "The ESP32 chip has three UART controllers (UART0, UART1, and UART2) that feature an identical set of registers for ease of programming and flexibility." https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html

18
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?