Page 1 of 1

Strange behavior when changing dutycycle at up down counter

Posted: Thu Oct 10, 2019 2:47 am
by AndreMP
Hi dear,

I´m using 2 mcpwm with up and down counter and could make 2 symmetric complementary wave forms with deadtime, this is ok!
But how to change the duty cycle to affect the up and down cycle?

I try to create a interrupt at the start of timer and change the dutyCycle before it start.
But it's only changing at the down part of duty cycle.

I tried with TEP,TEZ isr interrupt events and had the same results.
The TEP interrupt (in yellow, occur when it goes up or down) activate a change of duty cycle that occur before High PWM (blue), but it only work after the middle at the down part of timer. The code call a sequence of 4 cycles of 20% and 4 cycles of 60%.
20191009_194937c.jpg
TEPExample
20191009_194937c.jpg (69.19 KiB) Viewed 2667 times
It have high frequency but with pwm_config.frequency = 30 has the same result.
I tried to put the mcpwm_set_duty at the interrupt, but gave this exception:
Guru Meditation Error: Core 0 panic'ed (Coprocessor exception)

This is a simplified version to test the code, and was called from arduino setup() with
xTaskCreatePinnedToCore(loopPWM, "loopPWM", 8192, NULL, 1, NULL, 0);
I could create the full example on GitHub if it helps.

Code: Select all

#include <MotorPWM.h>
#include <driver/mcpwm.h>
#include <Arduino.h>
#include <soc/mcpwm_struct.h>

static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
float acelteste = 0;
bool mudou=false;
uint8_t stg1=0;
uint32_t mcpwm_intr_status;
bool ltest = 0;

static void IRAM_ATTR isr_handler(void *arg){
	mcpwm_intr_status = MCPWM[MCPWM_UNIT_0]->int_st.val;
	if(mcpwm_intr_status > 0){
		digitalWrite(17, ltest);
		mudou = true;     
	}
	MCPWM[MCPWM_UNIT_0]->int_clr.val = mcpwm_intr_status;
}
mcpwm_config_t pwm_config;

void setupPWM(){
    mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 16);
	pinMode(17, OUTPUT);//to debug isr call
    pwm_config.frequency = 30000;//15Khz * 2 for up down counter
    pwm_config.cmpr_a = 0;       //% duty cycle of PWMxA
    pwm_config.cmpr_b = 0;       //% duty cycle of PWMxb
    pwm_config.counter_mode = MCPWM_UP_DOWN_COUNTER;
    pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);   //Configure PWM0A & PWM0B with above settings	

    MCPWM[MCPWM_UNIT_0]->int_ena.timer0_tep_int_ena = true;//A PWM timer 0 TEP event will trigger this interrupt
    mcpwm_isr_register(MCPWM_UNIT_0, isr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL);  //Set ISR Handler	
}

void loopPWM(void*z)
{	
	disableCore0WDT();//Feeding wdt was not working
	delay(500);
    setupPWM();
	Serial.printf("\nloop2() em core: %d", xPortGetCoreID());
	delay(500);
	Serial.printf("start!");
	delay(500);
	while (1)
	{
		delayMicroseconds(0); //to isr can be called
	  	if(mudou){
			mudou = false;
			mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, (acelteste));				  
			stg1++;
			if(stg1 <= 4)
				acelteste = 20;
			else
				if(stg1 <= 8)
					acelteste = 60;
			if(stg1 == 8)
				stg1 = 0;				  
			ltest = !ltest;
		}
	}
}

Re: Strange behavior when changing dutycycle at up down counter

Posted: Thu Oct 10, 2019 11:49 pm
by AndreMP
This topic can be closed.

I change de duty cycle mode to 1 and the blue line do what I expected.

Then I figure out that this is the behavior when you have a up an down counter.
The complementary channel must have this behavior to the other channel fit in the remaining space.