ESP32のLEDCについて調べてみた。 [ESP32]
某SNSで、LEDCで16チャネル分のPWM出力した時、チャネル8以降でDutyを0に設定してもLOWにならない!と言う話があって、ちょっとLEDCについて調べてみた。
なので以下の様なコードを書いてお確かめ。
ESP32_LEDC_TEST.ino
led.h
led.c
チャネル0のみ1000HzでDuty=50%の波形を出力してみると以下の波形となった。
次に全16チャネルを出力させてみた。その時のチャネル0の波形が以下である。
お判り頂けたであろうか?PWM周波数が変わってしまっている。
以下はesp32_hal_ledc.cの一部抜粋である。
チャネル0とチャネル1は同一タイマーとなっている、、、ようするにチャネル0とチャネル1間では、後から設定した方が有効となってしまう。そりゃそうだ、、、
またチャネル0からチャネル7までと、チャネル8からチャネル15までで異なるグループとなっている。これはグループ0が80MHzを原振とする高速側のタイマー、グループ1が1MHz?を原振とする低速側のタイマーとなっているようである。
つまりledcで沢山のチャネルを使用する時は、上記事柄に気を付けて使う必要がある。
※低速側タイマーの場合、最大のPWM周波数は312KHz(8bit解像度)くらい?
※高速側タイマーの場合、最大のPWM周波数は312KHz(8bit解像度)くらい?
※え!う~~~~ん、高速は判る、80MHzを256で割れば312KHzだしい。まるでウドンのキツネをつまんでいる様な、、、
※結局グループ0側も、グループ1側も、解像度を2bitにすると20MHzの波形を出力できるのう!なんだったのだろう???
※20MHzにすると、IO18とIO21が出力しない。
さて、件のLOWが出ない件であるが、Duty=0とした時の波形が以下である。
LOWフラット、、、
試しにDuty=100とした時の波形は以下である。
3.3Vフラットに見えるが、立下りのヒゲが出ている、、、
なので以下の様なコードを書いてお確かめ。
ESP32_LEDC_TEST.ino
#include "led.h" #define LED_CH0_PIN 32 #define LED_CH1_PIN 33 #define LED_CH2_PIN 25 #define LED_CH3_PIN 26 #define LED_CH4_PIN 27 #define LED_CH5_PIN 14 #define LED_CH6_PIN 13 #define LED_CH7_PIN 15 #define LED_CH8_PIN 4 #define LED_CH9_PIN 16 #define LED_CH10_PIN 17 #define LED_CH11_PIN 5 #define LED_CH12_PIN 18 #define LED_CH13_PIN 19 #define LED_CH14_PIN 21 #define LED_CH15_PIN 22 #define LED_CH0_FRQ 1000.0 /* hz チャネル0とチャネル1は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH1_FRQ 2000.0 /* hz チャネル0とチャネル1は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH2_FRQ 3000.0 /* hz チャネル2とチャネル3は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH3_FRQ 4000.0 /* hz チャネル2とチャネル3は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH4_FRQ 5000.0 /* hz チャネル4とチャネル5は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH5_FRQ 6000.0 /* hz チャネル4とチャネル5は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH6_FRQ 7000.0 /* hz チャネル6とチャネル7は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH7_FRQ 8000.0 /* hz チャネル6とチャネル7は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH8_FRQ 9000.0 /* hz チャネル8とチャネル9は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH9_FRQ 10000.0 /* hz チャネル8とチャネル9は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH10_FRQ 20000.0 /* hz チャネル10とチャネル11は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH11_FRQ 30000.0 /* hz チャネル10とチャネル11は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH12_FRQ 40000.0 /* hz チャネル12とチャネル13は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH13_FRQ 50000.0 /* hz チャネル12とチャネル13は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH14_FRQ 60000.0 /* hz チャネル14とチャネル15は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH15_FRQ 70000.0 /* hz チャネル14とチャネル15は同一タイマーの為、後から設定した方の周波数になるはず */ #define LED_CH0_RES (8) /* resolution */ #define LED_CH1_RES (8) /* resolution */ #define LED_CH2_RES (8) /* resolution */ #define LED_CH3_RES (8) /* resolution */ #define LED_CH4_RES (8) /* resolution */ #define LED_CH5_RES (8) /* resolution */ #define LED_CH6_RES (8) /* resolution */ #define LED_CH7_RES (8) /* resolution */ #define LED_CH8_RES (8) /* resolution */ #define LED_CH9_RES (8) /* resolution */ #define LED_CH10_RES (8) /* resolution */ #define LED_CH11_RES (8) /* resolution */ #define LED_CH12_RES (8) /* resolution */ #define LED_CH13_RES (8) /* resolution */ #define LED_CH14_RES (8) /* resolution */ #define LED_CH15_RES (8) /* resolution */ #define DUTY( duty,res ) map( duty,0,100,0,(1 << res) - 1 ) led led_0( LED_CH0_PIN, 0 ); led led_1( LED_CH1_PIN, 1 ); led led_2( LED_CH2_PIN, 2 ); led led_3( LED_CH3_PIN, 3 ); led led_4( LED_CH4_PIN, 4 ); led led_5( LED_CH5_PIN, 5 ); led led_6( LED_CH6_PIN, 6 ); led led_7( LED_CH7_PIN, 7 ); led led_8( LED_CH8_PIN, 8 ); led led_9( LED_CH9_PIN, 9 ); led led_10( LED_CH10_PIN, 10 ); led led_11( LED_CH11_PIN, 11 ); led led_12( LED_CH12_PIN, 12 ); led led_13( LED_CH13_PIN, 13 ); led led_14( LED_CH14_PIN, 14 ); led led_15( LED_CH15_PIN, 15 ); void setup() { /* led 0 */ led_0.begin( LED_CH0_FRQ, LED_CH0_RES ); led_0.write( DUTY( 50,LED_CH0_RES) ); /* led 1 */ led_1.begin( LED_CH1_FRQ, LED_CH1_RES ); led_1.write( DUTY( 50,LED_CH1_RES) ); /* led 2 */ led_2.begin( LED_CH2_FRQ, LED_CH2_RES ); led_2.write( DUTY( 50,LED_CH2_RES) ); /* led 3 */ led_3.begin( LED_CH3_FRQ, LED_CH3_RES ); led_3.write( DUTY( 50,LED_CH3_RES) ); /* led 4 */ led_4.begin( LED_CH4_FRQ, LED_CH4_RES ); led_4.write( DUTY( 50,LED_CH4_RES) ); /* led 5 */ led_5.begin( LED_CH5_FRQ, LED_CH5_RES ); led_5.write( DUTY( 50,LED_CH5_RES) ); /* led 6 */ led_6.begin( LED_CH6_FRQ, LED_CH6_RES ); led_6.write( DUTY( 50,LED_CH6_RES) ); /* led 7 */ led_7.begin( LED_CH7_FRQ, LED_CH7_RES ); led_7.write( DUTY( 50,LED_CH7_RES) ); /* led 8 */ led_8.begin( LED_CH8_FRQ, LED_CH8_RES ); led_8.write( DUTY( 50,LED_CH8_RES) ); // led_8.write( 0 ); // led_8.write( 255 ); /* led 9 */ led_9.begin( LED_CH9_FRQ, LED_CH9_RES ); led_9.write( DUTY( 50,LED_CH9_RES) ); /* led 10 */ led_10.begin( LED_CH10_FRQ, LED_CH10_RES ); led_10.write( DUTY( 50,LED_CH10_RES) ); /* led 11 */ led_11.begin( LED_CH11_FRQ, LED_CH11_RES ); led_11.write( DUTY( 50,LED_CH11_RES) ); /* led 12 */ led_12.begin( LED_CH12_FRQ, LED_CH12_RES ); led_12.write( DUTY( 50,LED_CH12_RES) ); /* led 13 */ led_13.begin( LED_CH13_FRQ, LED_CH13_RES ); led_13.write( DUTY( 50,LED_CH13_RES) ); /* led 14 */ led_14.begin( LED_CH14_FRQ, LED_CH14_RES ); led_14.write( DUTY( 50,LED_CH14_RES) ); /* led 15 */ led_15.begin( LED_CH15_FRQ, LED_CH15_RES ); led_15.write( DUTY( 50,LED_CH15_RES) ); } void loop() { }
led.h
/****************************************************************************/ /* led header */ /* Copyright (C) 2018 hamayan All Rights Reserved. */ /****************************************************************************/ #ifndef LED_h #define LED_h #include <Arduino.h> #include <esp32-hal-ledc.h> extern "C" { } class led { private : uint8_t ledPin; uint8_t ledChannel; public : led( uint8_t pin, uint8_t channel ); ~led(); double begin( double freq, uint8_t resolution_bits ); void write( uint32_t duty ); uint32_t read(); double tone( double freq ); double note( note_t note, uint8_t octave ); }; #endif /* LED_h */ /****************************************************************************/ /* Copyright (C) 2018- by hamayan */ /****************************************************************************/
led.c
/****************************************************************************/ /* led source */ /* Copyright (C) 2018 hamayan All Rights Reserved. */ /****************************************************************************/ #include "led.h" /*************************************************************************/ /* constructor,destructor */ /*************************************************************************/ led::led( uint8_t pin, uint8_t channel ) { ledPin = pin; ledChannel = channel; ledcAttachPin( pin, channel ); } led::~led() { ledcDetachPin( ledPin ); } /*************************************************************************/ /* begin */ /*************************************************************************/ double led::begin( double freq, uint8_t resolution_bits ) { return ledcSetup( ledChannel, freq, resolution_bits ); } /*************************************************************************/ /* write (duty) */ /*************************************************************************/ void led::write( uint32_t duty ) { ledcWrite( ledChannel, duty ); } /*************************************************************************/ /* read (duty) */ /*************************************************************************/ uint32_t led::read() { return ledcRead( ledChannel ); } /*************************************************************************/ /* tone */ /*************************************************************************/ double led::tone( double freq ) { return ledcWriteTone( ledChannel, freq ); } /*************************************************************************/ /* note */ /*************************************************************************/ double led::note( note_t note, uint8_t octave ) { return ledcWriteNote( ledChannel, note, octave ); } /****************************************************************************/ /* Copyright (C) 2018- by hamayan */ /****************************************************************************/
チャネル0のみ1000HzでDuty=50%の波形を出力してみると以下の波形となった。
次に全16チャネルを出力させてみた。その時のチャネル0の波形が以下である。
お判り頂けたであろうか?PWM周波数が変わってしまっている。
以下はesp32_hal_ledc.cの一部抜粋である。
/* * LEDC Chan to Group/Channel/Timer Mapping ** ledc: 0 => Group: 0, Channel: 0, Timer: 0 ** ledc: 1 => Group: 0, Channel: 1, Timer: 0 ** ledc: 2 => Group: 0, Channel: 2, Timer: 1 ** ledc: 3 => Group: 0, Channel: 3, Timer: 1 ** ledc: 4 => Group: 0, Channel: 4, Timer: 2 ** ledc: 5 => Group: 0, Channel: 5, Timer: 2 ** ledc: 6 => Group: 0, Channel: 6, Timer: 3 ** ledc: 7 => Group: 0, Channel: 7, Timer: 3 ** ledc: 8 => Group: 1, Channel: 0, Timer: 0 ** ledc: 9 => Group: 1, Channel: 1, Timer: 0 ** ledc: 10 => Group: 1, Channel: 2, Timer: 1 ** ledc: 11 => Group: 1, Channel: 3, Timer: 1 ** ledc: 12 => Group: 1, Channel: 4, Timer: 2 ** ledc: 13 => Group: 1, Channel: 5, Timer: 2 ** ledc: 14 => Group: 1, Channel: 6, Timer: 3 ** ledc: 15 => Group: 1, Channel: 7, Timer: 3 */
チャネル0とチャネル1は同一タイマーとなっている、、、ようするにチャネル0とチャネル1間では、後から設定した方が有効となってしまう。そりゃそうだ、、、
またチャネル0からチャネル7までと、チャネル8からチャネル15までで異なるグループとなっている。これはグループ0が80MHzを原振とする高速側のタイマー、グループ1が1MHz?を原振とする低速側のタイマーとなっているようである。
つまりledcで沢山のチャネルを使用する時は、上記事柄に気を付けて使う必要がある。
※低速側タイマーの場合、最大のPWM周波数は312KHz(8bit解像度)くらい?
※高速側タイマーの場合、最大のPWM周波数は312KHz(8bit解像度)くらい?
※え!う~~~~ん、高速は判る、80MHzを256で割れば312KHzだしい。まるでウドンのキツネをつまんでいる様な、、、
※結局グループ0側も、グループ1側も、解像度を2bitにすると20MHzの波形を出力できるのう!なんだったのだろう???
※20MHzにすると、IO18とIO21が出力しない。
さて、件のLOWが出ない件であるが、Duty=0とした時の波形が以下である。
LOWフラット、、、
試しにDuty=100とした時の波形は以下である。
3.3Vフラットに見えるが、立下りのヒゲが出ている、、、
2018-11-16 11:17
nice!(0)
コメント(0)
コメント 0