Using MCPWM for AC dimming
Posted: Sat Oct 03, 2020 6:59 am
Hi
I am generating a 100Hz MCPWM signal that is synchronised with the AC signal. Although it works well, when I increase the PWM duty cycle to a point, it starts to glitch.
It seems that this phenomenon occurs when the high side of the PWM gets close to the trigger signal. (See the glitch at t=6s to t=7s)
Does anyone know what causes this?
Thanks.
My code:
I am generating a 100Hz MCPWM signal that is synchronised with the AC signal. Although it works well, when I increase the PWM duty cycle to a point, it starts to glitch.
It seems that this phenomenon occurs when the high side of the PWM gets close to the trigger signal. (See the glitch at t=6s to t=7s)
Does anyone know what causes this?
Thanks.
My code:
- #include <stdio.h>
- #include "string.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "esp_attr.h"
- #include "soc/rtc.h"
- #include "driver/mcpwm.h"
- #include "soc/mcpwm_periph.h"
- #include "esp_task_wdt.h"
- #define GPIO_PWM0A_OUT 19 // Pin output - connect to Triac gate
- #define GPIO_SYNC0_IN 2 // Pin input - connect to ZC circuit
- static void mcpwm_example_gpio_initialize(void)
- {
- printf("initializing mcpwm gpio...\n");
- mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
- mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM_SYNC_0, GPIO_SYNC0_IN); // need to modify esp_rom_gpio_connect_in_signal in components/drivers/mcpwm.c
- gpio_pulldown_en(GPIO_SYNC0_IN); //Enable pull down on SYNC0 signal
- }
- /**
- * @brief Configure whole MCPWM module
- */
- static void mcpwm_example_config(void *arg)
- {
- // mcpwm gpio initialization
- mcpwm_example_gpio_initialize();
- // initialize mcpwm configuration
- printf("Configuring Initial Parameters of mcpwm...\n");
- mcpwm_config_t pwm_config;
- pwm_config.frequency = 100; //frequency = 100Hz , double of AC 50Hz since we drive for two halves of the waveform
- pwm_config.cmpr_a = 0.0;
- pwm_config.counter_mode = MCPWM_DOWN_COUNTER;
- pwm_config.duty_mode = MCPWM_DUTY_MODE_0; // active high
- mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);
- // Syncronization configuration
- mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_SELECT_SYNC0, 850); // % phase offset
- const int MIN_PWM_DUTY = 0;
- const int MAX_PWM_DUTY = 75;
- // vary duty cycle
- float x = 0;
- float delta = .1;
- for(;;)
- {
- if(MAX_PWM_DUTY<x) delta = -.1;
- else if(MIN_PWM_DUTY>x) delta = .1;
- mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM0A, x);
- vTaskDelay(5 / portTICK_PERIOD_MS);
- x+=delta;
- }
- }
- void app_main(void)
- {
- printf("Testing MCPWM for AC dimming...\n");
- xTaskCreate(mcpwm_example_config, "mcpwm_example_config", 4096, NULL, 5, NULL);
- }