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:
Code: mcpwm_dimmer.c Select all
#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);
}