ESP32 - Slow program then goes faster

Hello,

I am having issues with my program. Basically when I first compile and download to the board (ESP -WROOM - 32) the program iteself runs slowly. Not only on the plotter (which runs at 921600), but I also checked with an oscilloscope the PWM outputs. After a while (around one hours ?) the program picks up speed and runs smootly.
The program I'm running generates 6 PMWs for a full Hbridge control of an induction motor.

#include "arduino.h"
#include "driver/mcpwm.h"
#include "soc/mcpwm_reg.h"
#include "soc/mcpwm_struct.h"

  int fref = 50 ;                        // frequency
  int tref = 2000;                       // ramp time
  int Vn = 230;                          // motor nominal voltage
  int Vmin = 10;                         // minumum voltage scalar ref
  int Valfa;                             // first voltage component 
  int Vbeta;                             // second voltage component
  bool run = 1;                          // system run
  int Gain = 9;                          // gain first compnent
  float Tc = 20E-6;                      // sample integration
  float Tau = 0.05;                      // const integration
  int f = 25;                            // normal freq
  float f_1, f_2;                        // alfa beta components
  float t = 0;                           // actual time elpsed
  float DutyVU, DutyVV, DutyVW;          // PWM duty cycle for each phase
  
#define GPIO_PWM0A_OUT 13  //High side FET PHASE1
#define GPIO_PWM0B_OUT 14  //Low Side FET PHASE1
#define GPIO_PWM1A_OUT 27  //High side FET PHASE2
#define GPIO_PWM1B_OUT 26  //Low Side FET PHASE2
#define GPIO_PWM2A_OUT 32  //High side FET PHASE3
#define GPIO_PWM2B_OUT 25  //Low Side FET PHASE3
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {

  Serial.begin(921600);
}
void MCPWM_SetUP(){

    //Set up the MCPWM to create complimentary PWM with a set dead time on rising edges
    mcpwm_group_set_resolution(MCPWM_UNIT_0, 10000000);
    mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_0, 10000000);
    mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_1, 10000000);  
    mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_2, 10000000);  

  //Config structure for timers
  mcpwm_config_t pwm_config;
    pwm_config.frequency = 4000;         //switching freq 4000Hz
    pwm_config.cmpr_a = 0;
    pwm_config.cmpr_b = 0;
    pwm_config.counter_mode = MCPWM_UP_DOWN_COUNTER;
    pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
   
    //Timer initialization
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);  
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_config); 
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_2, &pwm_config); 

    //Timer sync
    mcpwm_set_timer_sync_output(MCPWM_UNIT_0, MCPWM_TIMER_0,MCPWM_SWSYNC_SOURCE_TEP);   
    mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_0,MCPWM_SELECT_TIMER0_SYNC, 0);            //timer 0 has 0 degree shift
    mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_1,MCPWM_SELECT_TIMER0_SYNC, 0);            //timer 1 has 0 degree shift
    mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_2,MCPWM_SELECT_TIMER0_SYNC, 0);            //timer 2 has 0 degree shift
 
    //Deadtime 
    mcpwm_deadtime_enable(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE,20,0);
    mcpwm_deadtime_enable(MCPWM_UNIT_0,MCPWM_TIMER_1,MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE,20,0);
    mcpwm_deadtime_enable(MCPWM_UNIT_0,MCPWM_TIMER_2,MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE,20,0);
 
    //PWM starts operating using the set PWM Duty value
    mcpwm_set_duty(MCPWM_UNIT_0,MCPWM_TIMER_0,MCPWM_GEN_A,DutyVU);
    mcpwm_set_duty(MCPWM_UNIT_0,MCPWM_TIMER_1,MCPWM_GEN_A,DutyVV);
    mcpwm_set_duty(MCPWM_UNIT_0,MCPWM_TIMER_2,MCPWM_GEN_A,DutyVW);

    //Firing 
    mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM0A,GPIO_PWM0A_OUT);   // Phase 1 H
    mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM0B,GPIO_PWM0B_OUT);   // Phase 1 L

    mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM1A,GPIO_PWM1A_OUT);   // Phase 2 H
    mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM1B,GPIO_PWM1B_OUT);   // Phase 2 L

    mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM2A,GPIO_PWM2A_OUT);   // Phase 3 H
    mcpwm_gpio_init(MCPWM_UNIT_0,MCPWM2B,GPIO_PWM2B_OUT);   // Phase 3 L
  
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Main control
void loop() {

MCPWM_SetUP();
delay(10);

if (run == 1) {                       //ramp setup - to check

   if (t<tref) {
    t = t+1;
    f = map(t,0,tref,0,fref);
    delay(1000);
   }
   else {
    t = tref;
    f = map(t,0,tref,0,fref);
   }
   
  f=50;   //TEST! TO REMOVE
  f < 60;                                                        // max freq
  f_1 = (f * Gain + Vmin);                                       //first component scalar
  f_2 = ( Tc * f_1 + Tau * f_2 ) / ( Tau + Tc ) ;                //integration scalar
             
  if (f_2>2*PI) {                                                //upper wrapping limit 2PI 
    f_2=0;                                                       //upper wrapping limit 2PI
  }           
           
  Valfa = f_1*(cos(f_2));                                        //Valfa bi domain
  Vbeta = f_1*(sin(f_2));                                        //Vbeta bi domain

  float V1 = Valfa;                                              //inverse clarke s1
  float V2 = (-0.5 * Valfa) + (sqrt(3)/2) * Vbeta;               //inverse clarke s2
  float V3 = (-0.5 * Valfa) - (sqrt(3)/2) * Vbeta;               //inverse clarke s3

  float V1Map = map(V1,(-f_1),(f_1),0,Vn);                       //sinusodial scaling V1
  float V2Map = map(V2,(-f_1),(f_1),0,Vn);                       //sinusodial scaling V2
  float V3Map = map(V3,(-f_1),(f_1),0,Vn);                       //sinusodial scaling V3

  //// Duty = (period - A) / Period
  DutyVU = (V1Map/Vn)*100;                                       //Duty cycle PWM U
  DutyVV = (V2Map/Vn)*100;                                       //Duty cycle PWM V
  DutyVW = (V3Map/Vn)*100;                                       //Duty cycle PWM W

  Serial.println(f);
  Serial.print(" ");
  Serial.print(DutyVU);
  Serial.print(" ");
  Serial.print(DutyVV);
  Serial.print(" ");
  Serial.print(f);
  Serial.println();


//if (f == 0) {
//  run = 0;

}
}

The code might not be perfect and I was wondering if the problem was due to the code itself or HW related.

Thanks

Could the "around one hours" be 2000 seconds instead?

1 Like

Well.. that was it...
I tought that by forcing the f value two line later, that value would not be taken in account.

My bad I guess.

Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.