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