Page 1 of 1

Using MCPWM for AC dimming

Posted: Sat Oct 03, 2020 6:59 am
by ytan86
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:
  1.  
  2. #include <stdio.h>
  3. #include "string.h"
  4. #include "freertos/FreeRTOS.h"
  5. #include "freertos/task.h"
  6. #include "freertos/queue.h"
  7. #include "esp_attr.h"
  8. #include "soc/rtc.h"
  9. #include "driver/mcpwm.h"
  10. #include "soc/mcpwm_periph.h"
  11. #include "esp_task_wdt.h"
  12.  
  13.  
  14. #define GPIO_PWM0A_OUT 19   // Pin output - connect to Triac gate
  15. #define GPIO_SYNC0_IN   2   // Pin input - connect to ZC circuit
  16.  
  17. static void mcpwm_example_gpio_initialize(void)
  18. {
  19.     printf("initializing mcpwm gpio...\n");
  20.     mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
  21.     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
  22.     gpio_pulldown_en(GPIO_SYNC0_IN);   //Enable pull down on SYNC0  signal
  23. }
  24.  
  25. /**
  26.  * @brief Configure whole MCPWM module
  27.  */
  28. static void mcpwm_example_config(void *arg)
  29. {
  30.     // mcpwm gpio initialization
  31.     mcpwm_example_gpio_initialize();
  32.  
  33.     // initialize mcpwm configuration
  34.     printf("Configuring Initial Parameters of mcpwm...\n");
  35.     mcpwm_config_t pwm_config;
  36.     pwm_config.frequency = 100;    //frequency = 100Hz , double of AC 50Hz since we drive for two halves of the waveform
  37.     pwm_config.cmpr_a = 0.0;      
  38.     pwm_config.counter_mode = MCPWM_DOWN_COUNTER;
  39.     pwm_config.duty_mode = MCPWM_DUTY_MODE_0; // active high
  40.     mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);  
  41.  
  42.     // Syncronization configuration
  43.     mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_SELECT_SYNC0, 850); // % phase offset
  44.    
  45.     const int MIN_PWM_DUTY = 0;
  46.     const int MAX_PWM_DUTY = 75;
  47.  
  48.     // vary duty cycle
  49.     float x = 0;
  50.     float delta = .1;
  51.     for(;;)
  52.     {
  53.         if(MAX_PWM_DUTY<x) delta = -.1;
  54.         else if(MIN_PWM_DUTY>x) delta = .1;
  55.        
  56.         mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM0A, x);
  57.        
  58.         vTaskDelay(5 / portTICK_PERIOD_MS);            
  59.         x+=delta;
  60.     }
  61. }
  62.  
  63. void app_main(void)
  64. {
  65.     printf("Testing MCPWM for AC dimming...\n");
  66.     xTaskCreate(mcpwm_example_config, "mcpwm_example_config", 4096, NULL, 5, NULL);
  67. }
  68.