2018年5月11日金曜日

ESP32 LEDCのちょっとめんどくさい話


ledcはESP32のLED用高精度PWM機能です。通常のPWMだけでなく、ledc_set_fade_with_timeとledc_fade_startを使えば自動的に指定秒数でfadeしてくれて大変便利。

使い方はだいたいこんな感じです。

// こんな感じでパラメータを設定して
//
ledc_channel_config_t ledc_channel[LEDC_TEST_CH_NUM] = {
{
.channel = LEDC_CHANNEL_0,
.duty = 0,
.gpio_num = LED_GPIO_Red,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_sel = LEDC_TIMER_0
},
{
.channel = LEDC_CHANNEL_1,
.duty = 0,
.gpio_num = LED_GPIO_Green,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_sel = LEDC_TIMER_0
},
{
.channel = LEDC_CHANNEL_2,
.duty = 0,
.gpio_num = LED_GPIO_Blue,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_sel = LEDC_TIMER_0
}
};
// こんな初期化ルーチンを呼び出して、
//
void init_ledc(ledc_channel_config_t *ledc_channel) {
int ch;
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_10_BIT, // resolution of PWM duty
.freq_hz = 5000, // frequency of PWM signal
.speed_mode = LEDC_HIGH_SPEED_MODE, // timer mode
.timer_num = LEDC_TIMER_0 // timer index
};
ledc_timer_config(&ledc_timer);
for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
ledc_channel_config(&ledc_channel[ch]);
}
ledc_fade_func_install(0);
}
以上で準備OK、あとはdutyに変化後の値、BlinkDurationに変化秒数を設定すれば、勝手に変化してくれます。
for (int ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
ledc_set_fade_with_time(ledc_channel[ch].speed_mode,
ledc_channel[ch].channel, duty, BlinkDuration);
ledc_fade_start(ledc_channel[ch].speed_mode,
ledc_channel[ch].channel, LEDC_FADE_NO_WAIT);
}


なのですが、逆論理のLED(HIGHで消灯、LOWで点灯する回路)でちょっとハマりました。

通常消灯は
    ledc_set_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, 0);
    ledc_update_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel);
で良いのですが、逆なので、
    ledc_set_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, 1023);
    ledc_update_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel);
と書いてみたらほんのり点灯してます。細い細いパルスが出てるのですね。

1023を1024に書き換えたら治りました。

じゃあ、ってんで、fadeを
    ledc_set_fade_with_time(ledc_channel[ch].speed_mode,
                                ledc_channel[ch].channel, 1024, BlinkDuration);
    ledc_fade_start(ledc_channel[ch].speed_mode,
                                ledc_channel[ch].channel, LEDC_FADE_NO_WAIT);
にしてみたら…StackOverflowくらいましたw 【追記2018年9月7日:esp-idf 3.2では治っています。1024でもエラーにならずきっちり消灯します!】

しょうがないので、fadeは1023を使いましたけども…細いパルスが残っているのか完全には消えてくれません。演出で処理しますけども…やぁねぇ。

写真は、Kickstarterで入手したハンダ付け作業治具PCBite 2.0を使って基板を空中に浮かせている図。さすがに製品を晒すわけにはいかないのでダミーです。ケースなしでテストしているとショートの危険性があるけど、テープで止めたり剥がしたりするのも煩雑…ってんで、基板の端をバネ付きのクリップで挟んで磁石で灰皿に張り付いています。とても便利です。

クリップだけ追加注文しておけばよかったなぁ。SwitchScienceさんで扱ってくれないからし。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。