ESP32のGPIO出力について

概要

ESP32の出力に関してかんたんにまとめてみました。digitalWrite()、ledcWrite()、dacWrite()を対象とします。

動作電圧に関して

ESP32は3.0Vから3.6Vまでの電圧で動作させることができます。昔はもう少し低電圧で動作が可能でしたが、無線を利用時に不安定になるので、最低電圧が上がっていった経緯があります。

データシートPower supply voltageの項目を見ると、3.0Vから3.6Vまでで、推奨が3.3Vになっています。本解説では3.3Vで動かした場合の数値で説明を行います。

出力の種類について

ESP32では以下の3種類の出力があります。

デジタル出力 digitalWrite()

デジタル出力は一番シンプルな出力です。LOWの場合には0V、HIGHの場合には3.3Vの電圧を出力します。

LOWの場合には0Vを出力するよりは、外部からの電気を吸い込む動きになります。LOWを出力すると内部でGNDに接続するイメージで利用してください。

ESP32の場合GPIOから出力した場合、あまり電流を流せないですが、外部電源からGPIOに接続してLOW出力することで、より多くの電流を吸い込む方向で流すことが可能です。

また、厳密にはESP32内部での電圧低下などもありますので、データシートによるとLOWのときにはLow-level output voltageが0.1×VDDとありますので0Vから0.33V、HIGHのときにはHigh-level output voltageが0.8×VDDで、2.64Vから3.3Vが出力されます。

実際のところLOWはほぼ0Vで、HIGHも3.0V以下が出力されることは少なく、3.0V以下になった場合には入力電源が足りていない可能性が高いです。

他の出力でも出力電圧は同様にぶれますが、説明が複雑になるのでLOWで0V、HIGHで3.3Vとして説明を続けます。

PWM出力 ledcWrite()

少しわかりにくいパルス幅変調出力です。デジタル出力はLOWかHIGHの2種類でしたが、PWM出力は、擬似的に出力量を制御することができます。

上記の図の場合8分割したスロットのうち、4つだけHIGHの出力をしています。周期的に出力されていますので、LEDなどの点灯に利用した場合には50%の明るさで光ります。

上記が8分の2の出力です。この場合には25%の点灯になります。

PWM出力をする前に、PWMの初期化を行う必要があります。上記は16スロットに分割した例です。スロット数を増やすことで、より細かい粒度で出力を調整することができます。

もう一つ設定しないといけないのが、1スロットの時間です。時間を倍にすると上記のように横幅が広がります。

時間の設定は内部タイマーで行います。一定クロックが経過したら、カウントアップする設定になっており、スロット単位で出力をLOWとHIGHを切り替えています。

CPUクロックを下げることで、PWMの最高クロックも下がってしまうので注意してください。標準的な設定では12kHz(12000)で、1サイクルは256スロット(8ビット)に設定することが多いようです。

通信用のクロック周波数などを作成する場合には上記の設定が重要になり、HIGHとLOWを繰り返すため、スロットを2スロット(1ビット)に設定し、希望するクロック数で動かしたりします。それ以外のLEDの明るさ制御などは、それほど細かい設定を気にしなくても利用できます。

  pinMode(PIN, OUTPUT);
  ledcSetup(PWMCH, 12000, 8);
  ledcAttachPin(PIN, PWMCH);

上記の場合には8ビットで256スロットあるので、出力なしの0から、すべてのスロットがHIGHになっている256までの出力となります。

上記がオシロスコープで測定した図です。左から0%、50%、100%と出力を変えながら実験したときのデータになります。

アナログ出力 dacWrite()

PWM出力は擬似的な出力制御でしたが、アナログ出力は出力電圧を直接することができます。

上記が0%、50%、100%出力をオシロスコープで確認したときのデータです。PWMは主にLEDの明るさ制御ですが、アナログ出力は主にスピーカーを鳴らす場合に利用することが多いです。

dacWrite()は0から255までを指定することができ、0が0Vで255が3.3V出力になります。PWMの場合には256が最高値でしたが、dacWrite()では255が最高値なので注意してください。

スピーカー出力の場合には、無音が128で、上下に波形が出る形になりますが、初期化前の0から無音状態の128に急に出力を変更したときにノイズが乗るので注意しましょう。諦めるか、徐々に数字をあげて128にしてから再生することでノイズ低減が可能です。

ピンモード

Arduinoではすべてのピンを利用前に初期化する必要があります。初期化し忘れても動くことがおおいですが、ピンによって起動時に設定されているモードが違うので、すべてのピンを初期化してから使うようにしたほうが安全です。

OUTPUT

  pinMode(PIN, OUTPUT);

一番標準的な出力で、基本的にはこれを出力しておけば問題ありません。入力の場合にはアナログとデジタル出力でモードが違いますが、出力はOUTPUTで問題ありません。

デジタル出力やPWM出力の場合、LOWの場合にはGNDに接続して、外部から電気を吸い込み、HIGHの場合には3.3Vを出力します。アナログ出力の場合には0はデジタル出力やPWM出力のLOWと同じですが、1-255までは任意の電圧を出力します。

OUTPUT_OPEN_DRAIN

  pinMode(PIN, OUTPUT_OPEN_DRAIN);

オープンドレイン出力モードです。デジタル出力とPWM出力のモードになります。LOWのときにはGNDに接続して外部からの電気を吸い込む動きで変わらないですが、HIGHのときには3.3Vを出力するのではなく、ハイインピーダンスという、なにも接続されていない状態になります。

これはLOWのときに電気を吸い込む動きだけを行いたい場合、HIGHで3.3Vを出力してもその電力は無駄になるので、出力しないモードです。

ピン一覧

GPIO種類デジタル出力PWM出力アナログ出力
GPIO0I/O×
GPIO1I/O×
GPIO2I/O×
GPIO3I/O×
GPIO4I/O×
GPIO5I/O×
GPIO6I/O×
GPIO7I/O×
GPIO8I/O×
GPIO9I/O×
GPIO10I/O×
GPIO11I/O×
GPIO12I/O×
GPIO13I/O×
GPIO14I/O×
GPIO15I/O×
GPIO16I/O×
GPIO17I/O×
GPIO18I/O×
GPIO19I/O×
GPIO21I/O×
GPIO22I/O×
GPIO23I/O×
GPIO25I/O
GPIO26I/O
GPIO27I/O×
GPIO32I/O×
GPIO33I/O×
GPIO34I×××
GPIO35I×××
GPIO36I×××
GPIO37I×××
GPIO38I×××
GPIO39I×××

GPIO34以降は入力専用のため、出力には一切利用できません。

アナログ出力はGPIO25とGPIO26でのみ利用が可能です。

PWMは最大16チャンネルまでのサポートのため、同時に利用できるのは16個までです。

関連情報

まとめ

出力はPWMとオープンドレインがちょっと難しいですが、入力に比べればシンプルです。

上記に入力についても書いたので、合わせて読んでもらえればと思います。

コメント