Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
LED_PWMの実験(ESP-WROOM-32)

概要

Arduino core for the ESP32を使った、ESP-WROOM-32開発ボードのLED_PWMの実験です。LEDの明るさを制御します。

Arduino core for the ESP32には、現時点(2018/1/6)では、analogWrite()tone()が実装されていないようです。ただし、PWMを行うための、ledcXXX()という関数群が用意されています。これらの関数群の使い方を調べて、LEDの明るさを制御する実験を行いました。

あくまで、実験ベースなので、間違いが含まれている可能性が高いので注意してください。「おそらく」などの言葉がちりばめられています。

Arduino core for the ESP32のインストールのページはこちら。

実験

ESP32には、LED_PWMという、主にLEDの明るさを制御するためのPWMが実装されています。もちろん、LEDの明るさ以外の用途にも利用可能です。

利用可能なピン

アナログ機能を持ったピンは、ESP32 DatasheetArduino core for the ESP32によると、以下のピンのようです。ただし、GPIO34~GPIO39の6ピンは、入力専用のピンなので、LED_PWMに利用できないようです(LED_PWMを設定するledcAttachPin()という関数の中でpinMode(pin, OUTPUT)を呼び出していて、この呼び出しが失敗するため)。

アナログピン番号 GPIO番号 アナログピン番号 GPIO番号
A0 36(利用不可) A12 2
A3 39(利用不可) A13 15
A4 32 A14 13
A5 33 A15 12
A6 34(利用不可) A16 14
A7 35(利用不可) A17 27
A10 4 A18 25
A11 0 A19 26

LED_PWMの使い方

以下のAPIを呼び出すことにより、利用することができます。

  1. ledcSetup()
  2. ledcAttachPin()
  3. ledcWrite()

ledcAttachPin()とledcSetup()を呼び出す順序はおそらく関係ありません。

他にも、以下のAPIが用意されています。

  1. ledcWriteTone()
  2. ledcWriteNote()
  3. ledcRead()
  4. ledcReadFreq()
  5. ledcDetachPin()

ledcSetup()

チャネルの設定を行います。

double ledcSetup(uint8_t chan, double freq, uint8_t bit_num) という形式です。実際に設定された周波数を返します。

chanは、ledcAttachPin()で設定したチャネルです。

freqは、(おそらく)タイマの周波数です。タイマは、高速チャネル、低速チャネルとも4つあり、チャネル0と1、2と3、…のペアで共有していると思われます。

bit_numは、(おそらく)ledcWrite()で指定可能な、dutyのビット長です。

リファレンス形式のドキュメントはこちら

ledcAttachPin()

指定したピンを、LED_PWMで利用できるようにします。

void ledcAttachPin(uint8_t pin, uint8_t chan)  という形式です。

pinは、上の表の、アナログピン番号もしくはGPIO番号です。pins_arduino.hで、static const uint8_t A0 = 36;のように定義されているので、どちらの値を利用しても大丈夫です。

chanは、ピンに割り当てるチャネルで、0~15の値を指定します。以下の説明は、少し怪しいですが、0~7と8~15とでは、利用するハードウェアの特性が異なっており、前者は高速チャネル、後者は低速チャネルと思われます。

リファレンス形式のドキュメントはこちら

ledcWrite()

PWM出力を行います。analogWrite()の代用ができます。

void ledcWrite(uint8_t chan, uint32_t duty) という形式です。

chanは、ledcAttachPin()で設定したチャネルです。

dutyは、PWMのデューティー比です。ledcSetup()で指定したbit_num長まで指定可能です。実際には、ビット長のチェックは行っていないようなので、bit_num長を超える数値も設定できます。この場合の動作はよくわかりませんでした。また、dutyを格納するレジスタは、24ビット長で、下位4ビットは小数を表すため、実際には最大で20ビットまでではないかと思います(dutyをレジスタに設定する際、4ビット左シフトしています)。

リファレンス形式のドキュメントはこちら

ledcWriteTone()

指定した周波数を、デューティ比50%で出力します。tone()の代用ができます。

double ledcWriteTone(uint8_t chan, double freq) という形式です。実際に設定された周波数を返します。

chanは、ledcAttachPin()で設定したチャネルです。

freqは、出力したい周波数です。

スピーカーやオシロスコープを持っていないので、机上検討結果です。

ledcWriteNote()

指定した音階を出力します。

double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave) という形式です。実際に設定された周波数を返します。

chanは、ledcAttachPin()で設定したチャネルです。

noteは、音階で、以下の通りです。

出力 出力
NOTE_C NOTE_Fs ファ#
NOTE_Cs ド# NOTE_G
NOTE_D NOTE_Gs ソ#
NOTE_Eb ミ♭ NOTE_A
NOTE_E NOTE_Bb シ♭
NOTE_F ファ NOTE_B

octaveは、オクターブを指定します。0から8までを指定可能です。

例えば、NOTE_Aは、7040が設定されていて、実際の周波数は、noteFreq = (double)noteFrequencyBase[note] / (double)(1 << (8-octave)) という式で計算されています。このため、ledcWriteNote(0, NOTE_A, 4)とすると、440Hzが出力されるはずです。スピーカーやオシロスコープを持っていないので、机上検討結果です。

ledcRead()

現在設定されているdutyを返します。

uint32_t ledcRead(uint8_t chan) という形式です。
chanは、ledcAttachPin()で設定したチャネルです。

ledcReadFreq()

現在設定されている周波数を返します。

double ledcReadFreq(uint8_t chan) という形式です。
chanは、ledcAttachPin()で設定したチャネルです。

ledcDetachPin()

ピンとチャネルの結びつきを解除します。

void ledcAttachPin(uint8_t pin, uint8_t chan) という形式です。
pinは、ピン番号です。

chanは、ledcAttachPin()で設定したチャネルです。

スケッチ例

A18ピンにLEDを接続して、暗→明→暗→明→…を繰り返します。

const int ledPin = A18;

void setup() {
  // put your setup code here, to run once:
  ledcSetup(0, 12800, 8);
  ledcAttachPin(ledPin, 0);}

void loop() {
  // put your main code here, to run repeatedly:
  static uint8_t brightness = 0;
  static int diff = 1;

  ledcWrite(0, brightness);

  if (brightness == 0) {
    diff = 1;
  } else if (brightness == 255) {
    diff = -1;
  }

  brightness += diff;
  delay(10);
}

参考文献

ESP32 Datasheet
ESP32 Technical Reference Manual

バージョン

Arduino 1.8.4/Arduino core for the ESP32/ESP-WROOM-32



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2018 garretlab all rights reserved.
inserted by FC2 system