Before submitting a new issue, please follow the checklist and try to find the answer.
git rev-parse --short HEAD to get the commit id.): i dont have any idea how to get that in arduinoI used mcpwm example inside arduino and it worked perfectly until I changed the frequency below 15 Hz and output is weird I got different frequencies I set it to 1 and then output got 58 Hz I changed it to 15 then it got 815 Hz .
I need frequency 1 and 2 Hz how can i solve this problem( I used MCPWM_UNIT_0, MCPWM0 both channel A and B)
//Detailed problem description goes here.
PWM frequency must be 1 Hz
PWM is something near 60 Hz
// It helps if you attach a picture of your setup/wiring here.
no need wiring
// the code should be wrapped in the ```cpp tag so that it will be displayed better.
#include "driver/mcpwm.h"
#include "esp_log.h"
#define GPIO_PWM0A_OUT 13 //Set GPIO 19 as PWM0A
#define GPIO_PWM0B_OUT 12 //Set GPIO 18 as PWM0B
void setup() {
// put your setup code here, to run once:
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
mcpwm_config_t pwm_config;
pwm_config.frequency = 1; //frequency = 1000Hz
pwm_config.cmpr_a = 50.0; //duty cycle of PWMxA = 60.0%
pwm_config.cmpr_b = 50.0; //duty cycle of PWMxb = 50.0%
pwm_config.counter_mode = MCPWM_UP_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_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, MCPWM_DUTY_MODE_0);
mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, MCPWM_DUTY_MODE_1);
mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
}
void loop() {
// put your main code here, to run repeatedly:
}
no debug produced since module is working but if you need i can provide you
i think the program is very minimal
build folder (note this may contain all the code details and symbols of your project.)You will have to change hardcoded prescale values because tick is 1mhz and period register is 16 bit so 1mhz/65535 = 15hz.
@negativekelvin Thank for your quick reply. How can I change hardcoded prescale value in arduino ?
Which file do i have to change?
You can't so you will have to make your own version of mcpwm_set_frequency function
@negativekelvin you were totally right. i created a folder inside arduino library and put mcpwm.c and mcpwm.h in that folder then changed the name of these two files to MCPWM1.c and MCPWM1.h then in .c file i changed #include "driver/mcpwm.h "#include "MCPWM1.h" and
everything now working like a charm
Maybe keep this open because the driver should either dynamically calculate prescale values or let the user change them and report an error if it cannot produce the requested frequency.
Also related https://github.com/espressif/esp-idf/issues/1101
Hi,
I tried to do the same to generate the frequency of 1Hz but I could not clearly understand where should I have to add the:
I was not also able to find the mcpwm.c file in neither my arduino library nor in my ESP32 library. When I add them into my code and also just copied the mcpwm.h code to my ESP32 libraries nothing changes and the frequency is still 60Hz instead of 1 Hz.
@mehdina94rm
You can find this two register MCPWM[mcpwm_num]->clk_cfg.prescale and MCPWM[mcpwm_num]->timer[timer_num].period.prescale, both these two register is used to configure the clock divider. MCPWM_CLK_PRESCL is used set to set the register clk_cfg.prescale, and the TIMER_CLK_PRESCALE is used to set the register period.prescale.
Thanks for your comment, I have changed my code to configure the clock divider but nothing happens when I upload this code in my ESP32:
void setup() {
// put your setup code here, to run once:
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
mcpwm_config_t pwm_config;
pwm_config.frequency = 1; //frequency = 1000Hz
pwm_config.cmpr_a = 30.0; //duty cycle of PWMxA = 60.0%
pwm_config.cmpr_b = 50.0; //duty cycle of PWMxb = 50.0%
pwm_config.counter_mode = MCPWM_UP_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_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, MCPWM_DUTY_MODE_0);
delay(5000);
mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, MCPWM_DUTY_MODE_1);
mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
}
void loop() {
// put your main code here, to run repeatedly:
}
You have to do it as stated above, copy from here https://github.com/espressif/esp-idf/blob/v3.2/components/driver/mcpwm.c
Hello, mcpwm_set_frequency function overrides MCPWM[mcpwm_num]->clk_cfg.prescale and MCPWM[mcpwm_num]->timer[timer_num].period.prescale, can that function calculate values of prescale inside it??? Like ledc.
This is a very good function to control an AC motor (frequency converters works around 0-320Hz).