LEDC Fade PWM *Phase*
LEDC Fade PWM *Phase*
Hello!
The LEDC peripheral allows changing / "fading" the duty cycle of the generated PWM over time. This is done by having the hardware add to or subtract from the register (LEDC_DUTY_HSCH) that sets when the PWM signal is latched low.
Is it possible to similarly fade the PWM phase? This could be done via a similar mechanism that incremented or decremented the LEDC_HPOINT_HSCH register. This could be useful for dimming AC devices as described here. Because TRIAC only turns off at zero crossing, we must control when output is latched high to dim AC.
I'm assuming the answer here is that this isn't supported by the hardware but thought I might ask anyway just in case.
I'm working on code that performs the fading of PWM phase in zero crossing interrupt (by altering as an alternative. I'll see how well this performs and report back. I'm assuming there will be timing jitter here but perhaps it will be fast enough for our purposes.
Thanks!
-c
The LEDC peripheral allows changing / "fading" the duty cycle of the generated PWM over time. This is done by having the hardware add to or subtract from the register (LEDC_DUTY_HSCH) that sets when the PWM signal is latched low.
Is it possible to similarly fade the PWM phase? This could be done via a similar mechanism that incremented or decremented the LEDC_HPOINT_HSCH register. This could be useful for dimming AC devices as described here. Because TRIAC only turns off at zero crossing, we must control when output is latched high to dim AC.
I'm assuming the answer here is that this isn't supported by the hardware but thought I might ask anyway just in case.
I'm working on code that performs the fading of PWM phase in zero crossing interrupt (by altering as an alternative. I'll see how well this performs and report back. I'm assuming there will be timing jitter here but perhaps it will be fast enough for our purposes.
Thanks!
-c
Last edited by cmason on Fri Dec 30, 2016 8:17 pm, edited 1 time in total.
Re: LEDC Fade PWM *Phase*
Hi cmason,
You are correct that there is no hardware feature similar to the fade feature (LEDC_DUTY_INC_HSCH, etc.) that manipulates LEDC_HPOINT_HSCHn.
However, you can possibly implement the phase change in software. The LEDC_HS_TIMERx_OVF_INT will fire each time the counter overflows. If you can always keep the HPOINT register value high enough that the ISR always runs before the output latches on again, then you can manipulate the HPOINT value each time the counter loops (this will limit your maximum duty cycle, however, as the output is only ever on for the counter range HPOINT...HPOINT+DUTY).
To do this reliably, you'll need to allocate a high priority interrupt that runs from IRAM (ESP_INTR_FLAG_IRAM). Interrupt priority levels 4 and above need their handlers implemented in assembler, which is a bit fiddly, but the benefit is much improved interrupt latency and jitter (see esp_intr_alloc.h for more details). Ideally you will have hardware that can handle the situation where the ISR fails to run and the output turns high at the wrong time, but with sufficient testing you can shoudl be able to work around that in software if you have to.
You are correct that there is no hardware feature similar to the fade feature (LEDC_DUTY_INC_HSCH, etc.) that manipulates LEDC_HPOINT_HSCHn.
However, you can possibly implement the phase change in software. The LEDC_HS_TIMERx_OVF_INT will fire each time the counter overflows. If you can always keep the HPOINT register value high enough that the ISR always runs before the output latches on again, then you can manipulate the HPOINT value each time the counter loops (this will limit your maximum duty cycle, however, as the output is only ever on for the counter range HPOINT...HPOINT+DUTY).
To do this reliably, you'll need to allocate a high priority interrupt that runs from IRAM (ESP_INTR_FLAG_IRAM). Interrupt priority levels 4 and above need their handlers implemented in assembler, which is a bit fiddly, but the benefit is much improved interrupt latency and jitter (see esp_intr_alloc.h for more details). Ideally you will have hardware that can handle the situation where the ISR fails to run and the output turns high at the wrong time, but with sufficient testing you can shoudl be able to work around that in software if you have to.
Re: LEDC Fade PWM *Phase*
The other option may be to use the RMT feature, which can generate arbitrary pulse trains rather than simple PWM.
- martinayotte
- Posts: 141
- Joined: Fri Nov 13, 2015 4:27 pm
Re: LEDC Fade PWM *Phase*
You probably means TRIAC, not MOSFET.cmason wrote: Because MOSFET only turns off at zero crossing, we must control when output is latched high to dim AC.
Re: LEDC Fade PWM *Phase*
Yes, thanks, corrected.You probably means TRIAC, not MOSFET.
-c
Re: LEDC Fade PWM *Phase*
Hi Angus,
I implemented this using the zero-crossing interrupt and it works, most of the time. I'm using zero crossing interrupt (based on external GPIO input from zero-crossing detection circuit) instead of suggested timer reset interrupt because I need to reset the LEDC timer at the zero crossing point anyway.
Here's a video of it working. Oscilloscope traces are as follows, from top:
* Cyan: Zero Crossing Output from dimmer hardware (trigger).
* Purple: interrupt duration as measured via LED GPIO 5 output. Typically < 10us pulse width.
* Yellow: Channel 0 PWM output.
* Blue: Channel 2 PWM output.
A lot of the time, it works great, very steady fades.
Very randomly, however, I'll see periods where it seems like the LEDC hardware isn't responding to my requests to update the hpoint value. The PWM output continues, and in correct phase with 60hz AC (so timer resets are happening), and the interrupt seems to continue running (based on purple oscilloscope trace), but the relative PWM phase doesn't change with updates to the hpoint register. This will continue for a number of seconds and then it will be fine for a while. Here's an example of this on video.
I've tried a number of things including:
* reversing the order of resetting the timer vs updating the hpoint value,
* adding nops or memw instructions around the register updates.
It seems like this may happen more when the hardware (Sparkfun ESP 32 "Thing") is warmed up. It gets hot enough to be painful to the touch. I may experiment with a small heat sink.
Any hints for trying to debug this?
Code is here.
Thanks!
-c
I implemented this using the zero-crossing interrupt and it works, most of the time. I'm using zero crossing interrupt (based on external GPIO input from zero-crossing detection circuit) instead of suggested timer reset interrupt because I need to reset the LEDC timer at the zero crossing point anyway.
Here's a video of it working. Oscilloscope traces are as follows, from top:
* Cyan: Zero Crossing Output from dimmer hardware (trigger).
* Purple: interrupt duration as measured via LED GPIO 5 output. Typically < 10us pulse width.
* Yellow: Channel 0 PWM output.
* Blue: Channel 2 PWM output.
A lot of the time, it works great, very steady fades.
Very randomly, however, I'll see periods where it seems like the LEDC hardware isn't responding to my requests to update the hpoint value. The PWM output continues, and in correct phase with 60hz AC (so timer resets are happening), and the interrupt seems to continue running (based on purple oscilloscope trace), but the relative PWM phase doesn't change with updates to the hpoint register. This will continue for a number of seconds and then it will be fine for a while. Here's an example of this on video.
I've tried a number of things including:
* reversing the order of resetting the timer vs updating the hpoint value,
* adding nops or memw instructions around the register updates.
It seems like this may happen more when the hardware (Sparkfun ESP 32 "Thing") is warmed up. It gets hot enough to be painful to the touch. I may experiment with a small heat sink.
Any hints for trying to debug this?
Code is here.
Thanks!
-c
-
- Posts: 9757
- Joined: Thu Nov 26, 2015 4:08 am
Re: LEDC Fade PWM *Phase*
Fyi, the ESP32 isn't supposed to get hot enough to be painful, and I've never seen that happen. Are you sure all voltages you feed into it are in range, and no weird currents are running anywhere? Do you have a schematic of the thing somewhere?
Re: LEDC Fade PWM *Phase*
On the subject of ESP32 getting hot ... I was working with a chap last week who couldn't get his ESP32 working ... his model was a Sparkfun ESP32 Thing ... and he was reporting that it was getting hot too. He has written to Sparkfun to seek guidance. I mention this merely as a data point ... I have nothing further to add ... but if something happens that is "unexpected", good to see if it is "one off" or a pattern.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: LEDC Fade PWM *Phase*
Sparkfun ESP 32 Thing Schematic is here.ESP_Sprite wrote:Fyi, the ESP32 isn't supposed to get hot enough to be painful, and I've never seen that happen. Are you sure all voltages you feed into it are in range, and no weird currents are running anywhere? Do you have a schematic of the thing somewhere?
I'm seeing about 46 C max using a non-contact thermometer held ~10 cm above the ESP chip after my code has been running (successfully) for perhaps 30 mins.
I'm seeing only about 2.5 mA current draw from the dimmer board which is being fed 3.3V from the Thing and getting back about 2.8V on the zero crossing pin. But I am seeing max 3.9 V *output* from GPIOs (dotted line below)? This might just be noise/ringing?
Thanks,
-c
Re: LEDC Fade PWM *Phase*
Just in case,
Are ch[1..4] and sync compatible with 3.3 volt, If the board is powered with 5.0 volts, it needs level shifters.
Are ch[1..4] and sync compatible with 3.3 volt, If the board is powered with 5.0 volts, it needs level shifters.
Yes Frida is my watchdog!
Who is online
Users browsing this forum: Majestic-12 [Bot] and 312 guests