LED controller PWM timer compare values
LED controller PWM timer compare values
Hello,
As I've seen it, the LED controller sets up PWM signals on up to 8 output channels. All channels turn on at the beginning of the shared PWM period, so all simultaneously, and then turn off when their individual compare value has been reached in the internal timer.
Is there a way to turn on channels at different times, or compare values? Or at least invert the output so that a channel isn't on during the time from LOW to CMP, but from CMP to HIGH.
I'd like to distribute the channel on-times more evenly to even the load on the PSU and have a less flickering light. One of my main scenarios is a dual-white (CCT) lighting that combines cold and warm white with 2 channels. When the light is on at maximum single brightness (100% of one channel), it doesn't flicker at all. But if it's distributed over two colours, it starts flickering again. This can be avoided if both colours (channels) simply alternate instead of partially overlap. Then it's never dark, just the colour changes very quickly according to the desired colour temperature.
I can achieve the output inverting on AVR MCUs with a flag and it works very well. But I'm using an ESP32 for a bigger application with more channels.
As I've seen it, the LED controller sets up PWM signals on up to 8 output channels. All channels turn on at the beginning of the shared PWM period, so all simultaneously, and then turn off when their individual compare value has been reached in the internal timer.
Is there a way to turn on channels at different times, or compare values? Or at least invert the output so that a channel isn't on during the time from LOW to CMP, but from CMP to HIGH.
I'd like to distribute the channel on-times more evenly to even the load on the PSU and have a less flickering light. One of my main scenarios is a dual-white (CCT) lighting that combines cold and warm white with 2 channels. When the light is on at maximum single brightness (100% of one channel), it doesn't flicker at all. But if it's distributed over two colours, it starts flickering again. This can be avoided if both colours (channels) simply alternate instead of partially overlap. Then it's never dark, just the colour changes very quickly according to the desired colour temperature.
I can achieve the output inverting on AVR MCUs with a flag and it works very well. But I'm using an ESP32 for a bigger application with more channels.
Re: LED controller PWM timer compare values
Just checking, have you read through this ?
https://docs.espressif.com/projects/esp ... ntrol-ledc
https://docs.espressif.com/projects/esp ... ntrol-ledc
Re: LED controller PWM timer compare values
For what it's worth, you can invert the GPIOs used in the GPIO matrix to get the inversion effect you want. You could also have a look at the MCPWM peripheral; while it has less outputs, it does have phase angle features.
Re: LED controller PWM timer compare values
Yes, I've read that before and looked at it again. Do you have a certain part of that page in mind? Because it doesn't anwer my question.
MCPWM (Motor PWM) has only 3 channels? That's as much as the ATtiny1614 has. I'm using ESP32 for the 8 channels.
So I assume that it's not possible to use custom compare values. But the output inverting is already a good solution. Is it this?
MCPWM (Motor PWM) has only 3 channels? That's as much as the ATtiny1614 has. I'm using ESP32 for the 8 channels.
So I assume that it's not possible to use custom compare values. But the output inverting is already a good solution. Is it this?
Code: Select all
GPIO.func_out_sel_cfg[my_gpio_num].inv_sel = invert ? 1 : 0;Re: LED controller PWM timer compare values
The ESP32 has two MCPWM units, so I think you should get 6 channels. (Which is still less than 8, to be fair.)
Yes, that code would do the trick I think.
Yes, that code would do the trick I think.
Re: LED controller PWM timer compare values
So it does work, but initialisation is not smooth. Depending on the order of instructions, the inverted channels will briefly flash up at boot, or they will remain on, and some are even different than the others.
What can I do to keep all LEDs off at all times during initialisation and use the inverted channels normally later? I will provide corresponding inverted duty values, the initial value should be the maximum so that the pin remains completely off at startup.
Code: Select all
ledc_channel.channel = LEDC_CHANNEL_6;
ledc_channel.gpio_num = LED6_GPIO;
ledc_channel_config(&ledc_channel);
GPIO.func_out_sel_cfg[LED7_GPIO].inv_sel = 1;
ledc_channel.channel = LEDC_CHANNEL_7;
ledc_channel.gpio_num = LED7_GPIO;
ledc_channel_config(&ledc_channel);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, 7, PWM_MAXDUTY);
Re: LED controller PWM timer compare values
This is a version that sets the correct initial state, but the short flash of all inverted channels remains. This may sound small but it feels frightening if a powerful room light does that in the dark.
Code: Select all
// Configure LED timers
ledc_timer_config_t ledc_timer = {
.duty_resolution = PWM_RESOLUTION,
.freq_hz = 2500,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_num = LEDC_TIMER_0,
.clk_cfg = LEDC_AUTO_CLK,
};
ledc_timer_config(&ledc_timer);
// Configure LED channels
ledc_channel_config_t ledc_channel = {
.channel = LEDC_CHANNEL_0,
.duty = 0,
.gpio_num = LED0_GPIO,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.hpoint = 0,
.timer_sel = LEDC_TIMER_0
};
ledc_channel_config(&ledc_channel);
// Other channels...
ledc_channel.channel = LEDC_CHANNEL_6;
ledc_channel.gpio_num = LED6_GPIO;
ledc_channel.duty = 0;
ledc_channel_config(&ledc_channel);
ledc_channel.channel = LEDC_CHANNEL_7;
ledc_channel.gpio_num = LED7_GPIO;
ledc_channel.duty = PWM_MAXDUTY;
ledc_channel_config(&ledc_channel);
GPIO.func_out_sel_cfg[LED7_GPIO].inv_sel = 1;
Re: LED controller PWM timer compare values
You could possibly get around this by initializing all channels to an unused GPIO, starting the LEDC channels (including inverting the ones you need inverted), then manually routing the signals to the correct GPIOs using something like this:
Code: Select all
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
gpio_set_direction(gpio, GPIO_MODE_OUTPUT);
esp_rom_gpio_connect_out_signal(gpio, signal_idx, out_inv, oen_inv);
Re: LED controller PWM timer compare values
Sorry for the long delay, the project was stalled.
Could you please explain how to use the two functions?
I found the header for gpio_hal_iomux_func_sel here but can't figure out what the parameters mean.
I also found the header for esp_rom_gpio_connect_out_signal here but can't figure out what all parameters mean. First is the GPIO, third should probably be true for me. And the others?
Is this stuff documented anywhere or is it hidden internal magic that may change at any time?
And should these functions be called before or after ledc_channel_config? If some before/after, which when?
Could you please explain how to use the two functions?
I found the header for gpio_hal_iomux_func_sel here but can't figure out what the parameters mean.
I also found the header for esp_rom_gpio_connect_out_signal here but can't figure out what all parameters mean. First is the GPIO, third should probably be true for me. And the others?
Is this stuff documented anywhere or is it hidden internal magic that may change at any time?
And should these functions be called before or after ledc_channel_config? If some before/after, which when?
Re: LED controller PWM timer compare values
Okay, so I typed a whole bunch of text here as an answer, which I'll still include as reference below, but then I noticed you can tell the LED driver to invert the channel by setting output_invert to true. I'll still include the answer as it's more generic and works for drivers other than the LEDC:
It sets up the IOMUX for the selected GPIO pin to make it act as a 'standard' GPIO. The IOMUX can be used to route some high-speed signals to the IO pin, but that's not what we want here. ('pin name' is GPIO number here, func is the function selected by the iomux)I found the header for gpio_hal_iomux_func_sel here but can't figure out what the parameters mean.
This sets up the GPIO matrix. First argument is indeed the GPIO. Second one is the signal to route to that GPIO, you can get those from here. (The LEDC driver probably has that setup already, but the function still needs the proper signal as an argument.) Third is if the output needs to be inverted; you want that to be true. Fourth is if the output enable needs to be inverted; that should be false.I also found the header for esp_rom_gpio_connect_out_signal here but can't figure out what all parameters mean. First is the GPIO, third should probably be true for me. And the others?
That API should be stable, as it directly refers to the underlying hardware. You want to call it after configuring the driver, because otherwise the driver will overwrite the settings.Is this stuff documented anywhere or is it hidden internal magic that may change at any time?
And should these functions be called before or after ledc_channel_config? If some before/after, which when?
Who is online
Users browsing this forum: Baidu [Spider], ChatGPT-User, Google [Bot] and 2 guests
