ESP-WROOM-02を使ってみる


Arduino-IDEを使ったESP-WROOM-02へのスケッチ書き込み方法は、あちこちで紹介されていますので
今更私が紹介することは何もないです。
こちらこちらに 詳し く紹介されています。
特にこちらの ページの回路図はきれいで非常に参考になりました。

上記のページではGPIO_2をPullUpしています。
GPIO_2のPullUpについては悩みました。
こ ちらのページの「Boot Messages and Modes」には、以下のコメントが記載されています。
note: - GPIO2 is used as TX output and the internal Pullup is enabled on boot.

また、こ ちらこ ちらのページの結線図ではGPIO_2はN/Cとなっています。

その後の調査で、ESP8266はGPIO_0、GPIO_2、GPIO_15の3つの値(0/1)の組み合わせでboot modeを決定することが分かりました。
こちらに その組み合わせの詳細が公開されています。

UARTからスケッチを書き込むとき(UART Download Mode)は、
GPIO_0=GND
GPIO_2=PullUp
GPIO_15=PullDown
EN=PullUp
RST=PullUp
にします。

こ ちらにESP-WROOM-02のデータシートが公開されています。
GPIO_2は内部でPullUpされているようですが、外部抵抗を使ってPullUpした方が安定しました。
また、GPIO_0はPullDownではなくGNDにした方が安定して書き込みができます。
しばらくPullDownを試してみましたが、書き込めるモジュールと書き込めないモジュールが有りました。
GNDにすることで全てのモジュールで安定して書き込めるようになりました。
さらに3.3VとGNDの間に、10uFと0.1uF(100nF)のパスコンを挟んだ方が安定します。

GPIO_0をGND(UART Download Mode)にしてスケッチを書き込んだ後は、GPIO_0をPullUp(Flash Boot Mode)に変更してからリセットするとスケッチが起動します。



ESP-13とESP-WROOM-02はピンコンパチですが、製造者が違います。
ESP-13:ShenZhen AI-thinker CO.,LTD
ESP-WROOM-02:Espressif Inc(Espressif IncはESP8266EXチップの製造元)
こ ちらに公開されているスケッチを使って、両者のチップ情報を取り出してみました。
ESP-WROOM-02にはFlashが2MBの物と4MBの物が有ります。
見ただけでは区別がつかないので、チップ情報を取り出さないと分かりません。

ESP-13
Core Version = 2_5_2
CPU Frequency = 80 MHz
SDK version = 2.2.1(cfd48f3)
Boot version = 7
Boot Mode = 1
Flash Chip IDE Size = 2097152 byte
Flash Chip Real Size = 2097152 byte
Flash Frequency = 40000000 Hz
Flash Chip Mode = DOUT
Free Heap Size = 51456
Free Sketch Size = 233472
Sketch Size = 269168


ESP-WROOM-02(4MBytes Version)
Core Version = 2_5_2
CPU Frequency = 80 MHz
SDK version = 2.2.1(cfd48f3)
Boot version = 6
Boot Mode = 1
Flash Chip IDE Size = 4194304 byte
Flash Chip Real Size = 4194304 byte
Flash Frequency = 40000000 Hz
Flash Chip Mode = DOUT
Free Heap Size = 50528
Free Sketch Size = 233472
Sketch Size = 269168


ESP-WROOM-02(2MBytes Version)
Core Version = 2_5_2
CPU Frequency = 80 MHz
SDK version = 2.2.1(cfd48f3)
Boot version = 7
Boot Mode = 1
Flash Chip IDE Size = 2097152 byte
Flash Chip Real Size = 2097152 byte
Flash Frequency = 40000000 Hz
Flash Chip Mode = DOUT
Free Heap Size = 50536
Free Sketch Size = 233472
Sketch Size = 269168



ESP-WROOM-02U(2MBytes Version)
Core Version = 2_5_2
CPU Frequency = 80 MHz
SDK version = 2.2.1(cfd48f3)
Boot version = 7
Boot Mode = 1
Flash Chip IDE Size = 2097152 byte
Flash Chip Real Size = 2097152 byte
Flash Frequency = 40000000 Hz
Flash Chip Mode = DOUT
Free Heap Size = 51456
Free Sketch Size = 233472
Sketch Size = 269168

全く同じ条件で書き込んだのにFree Heap Sizeが微妙に違っています。



ESP-WROOM-02をブレッドボードで使う場合は、ピッチ変換基盤が必要になります。
今回、ピッチ変換基盤にはAITENDOの製品を使いましたが、AITENDOの製品は、パターン付きとパターンなしの2種類あります。
左がパターン付き、右がパターンなしですが、表面は同じです。


パターン付きの変換基盤は、裏面にチップ抵抗用の回路が作られています。


パターン付きの基盤は1206サイズのチップ抵抗(10KΩ)を使うことで、ENとRSTをPullUpすることができます。
またパターンをショートすることで、以下のようにすることができます。
IO15-GND:GPIO15はGND
IO2-3V3:GPIO2は3.3V
IO0-GND:GPIO0はGND
IO0-3V3:GPIO0は3.3V
こちらで チップ抵抗を使った写真が公開されていますが、GPIO0は固定せずに使っています。
GPIO0を固定してしまうと、ブートモードを切り替えることができなくなります。



AITENDOの変換基盤は幅が大きく、片側5穴のブレットボードでは、右側に余白レーンが無く、仮組することができません。


ブレッドボード上で仮組するためには、サンハヤトの片側6穴のブレッドボード(Model SAD-101)を使う必要が有ります。


ほとんどのUSB-TTL変換チップはチップ本体に5V→3.3VへのVoltage Regulatorを内蔵していて、
3.3Vを出力することができますが、データシートに よると最大電流が100mAなので
スケッチの書き込みはできますが、Wifiを使うスケッチでは実行時に電流不足でクラッシュします。
Wifiを使うスケッチを安定して動かすには、5Vを外部レギュレータなどで3.3Vに変換して、ESPに給電しないと安定して動きません。
USBの5Vを3.3Vに変換するときは、レギュレータ(AMS1117がよく使われます)を慎重に選ぶ必要が有ります。

これはGPIO0(上側の左から2番目)をGNDに落とした状態です。
リセットピン(上側の右から2番目)を一瞬GNDに落とすとスケッチを書き込むことができます。
左下に有るのが5V→3.3Vのレギュレータです。


これはGPIO0をPullUpした状態です。
リセットピンを一瞬GNDに落とすとスケッチを起動することができます。


ブレッドボードパターンのユニバーサルを2枚使って、開発ボードを作りました。
右下のレギュレータ(AMS1117)で5V→3.3Vに変換して給電しています。
1本線の抵抗は0Ω抵抗でジャンパー代わりに多用しています。
これで全てのGPIOを使うことができます。




最近になってこのようなT型の変換基盤も発見しました。
これならば片側5穴のブレッドボードでも仮組することができます


右が千石で見つけた基盤(\180) 左が秋月で見つけた基盤(\80)で、サイズと値段が反比例します。




こちら
にESP-WROOM-02のデータシートが公開されています。
Schematicsを見ると、SoCであるESP8266EXの他に、SPI-Flashメモリー、クリスタル、幾つかの抵抗、コンデンサー、 コイルが内蔵され ていることが分かります。
この構成はESP-WROOM-02に限らず、ESP-01やESP-12など、ESP8266EXを使った全てのモジュールで共通です。



こ ちらのページの「Minimal Hardware Setup for Running only」では、スケッチ実行時の結線は以下の様に書かれています。
VCC VCC(3.3V)
GND GND
GPIO_0 PullUp
GPIO_15 PullDown
CH_PD PullUp

この結線ではスケッチが動いたり、動かなかったり安定しませんでした。
そこでRESETのPullUpを追加したところ、安定して起動するようになりました。
VCC VCC(3.3V)
GND GND
GPIO_0 PullUp
GPIO_15 PullDown
CH_PD PullUp
RESET PullUp

GPIO_0がPullUp、GPIO_15がPullDownであれば、GPIO_2の状態に関係なくFlash Boot Modeで起動します。
スケッチの書き込み時には、GPIO_2はPullUpしておく必要が有りますので、GPIO_2は常にPullUpでも問題ありません。
WeMosやNodeMCUでは、スケッチ書き込み時にUSB-UART変換チップのDTRとRTSを使った、
こ ちらのリセット回路でGPIO_0とRESETのPullUp/PullDownを自動的に切り替えています。
難しい回路ではないので、自分で組み込むことも可能です。

また、電源(特に電流容量)にはかなりシビアで、500mA以上ないと安定してWiFiの接続ができません。
USB-TTL変換モジュールからの3.3V給電ではWiFi接続時に電流不足でクラッシュします。
USBの5Vを3.3Vに変換して使うときは、レギュレータ(AMS1117がよく使われます)を慎重に選ぶ必要が有ります。

GPIOとして実際に使えるのは(Tx/Rxを除いて)以下の9本で す。
・GPIO_0(※)
・GPIO_2(※)
・GPIO_4
・GPIO_5
・GPIO_12
・GPIO_13
・GPIO_14
・GPIO_15(※)
・GPIO_16

以下のスケッチで、これらのピンを使ったLチカが動くことを確認しました。
(※)GPIO_0、GPIO_2、GPIO_15は起動モードの選択ピンとして使われます。
PullUpやPullDownしておく必要がありますが、出力ポートとしては普通に使うことができます。
/*
 * Blink LED with ESP-13
 */

int pins[] = { 0, 2, 4, 5, 12, 13, 14, 15, 16 };
int numpins;

void setup() {
  delay(1000);
  Serial.begin(9600);
  numpins=sizeof(pins)/4;
  Serial.print("Start numpins=");
  Serial.println(numpins);
  for (int i=0;i<numpins;i++) {
    pinMode(pins[i], OUTPUT);
    digitalWrite(pins[i], LOW);
  }
}

void loop() {
  static int pin=0;

  Serial.print("pin=");
  Serial.println(pins[pin]);
  for (int i=0;i<numpins;i++) {
    digitalWrite(pins[i], LOW);
  }
  digitalWrite(pins[pin], HIGH);
  pin++;
  if (pin == numpins) pin=0;
  delay(1000);
}

以下のスケッチで、これらのピンをディジタル入力で使える事を確認しました。
(※)GPIO_0、GPIO_2、GPIO_15は起動モードの選択ピンとして使われます。
PullUpやPullDownしておく必要がありますので、入力ポートとして使う場合は注意する必要があります。
*
 * Digital Read with ESP-13
 */

int pins[] = { 4, 5, 12, 13, 14, 16 };
int numpins;

void setup() {
  delay(1000);
  Serial.begin(9600);
  numpins=sizeof(pins)/4;
  Serial.print("Start numpins=");
  Serial.println(numpins);
  for (int i=0;i<numpins;i++) {
    pinMode(pins[i], INPUT);
  }
}

void loop() {
  static int pin=0;
  int data;

  Serial.print("pin=");
  Serial.print(pins[pin]);
  data=digitalRead(pins[pin]);
  Serial.print(" data=");
  Serial.println(data);
  pin++;
  if (pin == numpins) pin=0;
  delay(1000);
}