Page 1 of 1

ESP32 MCPWM Input Capture Problem

Posted: Thu Jul 05, 2018 2:20 am
by steve.kim
I am testing the input capture function contained within MCPWM.
I am testing an example source MCPWM(mcpwm_basic_config_example.c).
In order to know the frequency values entered in CAP 0,
the remainder has been disabled and only the pwm0 and Capture0 functions have been enabled.

*Test content
1. I entered a frequency of 2 kHz into the CAP 0 pin.
2. The output results are output alternately between 500us and 9500us, rather than continuously output to 500us as shown below.
3. Also, if I input the input frequency to 20 kHz, the value will be output strangely. I think it's almost impossible to measure.

* Questions
1. Is the example source working normally?
2. Doesn't it work normally with high frequency inputs?
If so, what are the measurable frequency limits?
(I would like to measure up to 200kHz)

* Mainly Function Setting
static void disp_captured_signal(void *arg)
{
uint32_t *current_cap_value = (uint32_t *)malloc(sizeof(CAP_SIG_NUM));
uint32_t *previous_cap_value = (uint32_t *)malloc(sizeof(CAP_SIG_NUM));
capture evt;

while (1) {
xQueueReceive(cap_queue, &evt, portMAX_DELAY);

if (evt.sel_cap_signal == MCPWM_SELECT_CAP0) {
current_cap_value[0] = evt.capture_signal - previous_cap_value[0];
previous_cap_value[0] = evt.capture_signal;
//How was the fomula made?
current_cap_value[0] = (current_cap_value[0] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
printf("%d us \n", current_cap_value[0]);
}
}
}

static void IRAM_ATTR isr_handler()
{
uint32_t mcpwm_intr_status;
capture evt;
mcpwm_intr_status = MCPWM[MCPWM_UNIT_0]->int_st.val; //Read interrupt status
if (mcpwm_intr_status & CAP0_INT_EN) {
evt.capture_signal = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP0);
evt.sel_cap_signal = MCPWM_SELECT_CAP0;
xQueueSendFromISR(cap_queue, &evt, NULL);
}
MCPWM[MCPWM_UNIT_0]->int_clr.val = mcpwm_intr_status;
}

static void mcpwm_example_config(void *arg)
{
//1. mcpwm gpio initialization
mcpwm_example_gpio_initialize();

//2. initialize mcpwm configuration
printf("Configuring Initial Parameters of mcpwm...\n");
mcpwm_config_t pwm_config;
pwm_config.frequency = 2000; //frequency = 1000Hz
pwm_config.cmpr_a = 50.0; //duty cycle of PWMxA = 50.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);
mcpwm_capture_enable(MCPWM_UNIT_0, MCPWM_SELECT_CAP0, MCPWM_POS_EDGE, 0);
MCPWM[MCPWM_UNIT_0]->int_ena.val = CAP0_INT_EN; //Enable interrupt on CAP0, CAP1 and CAP2 signal
mcpwm_isr_register(MCPWM_UNIT_0, isr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); //Set ISR Handler

vTaskDelete(NULL);
}

Output Result:
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
500 us
9500 us
.
.
.

Re: ESP32 MCPWM Input Capture Problem

Posted: Wed Sep 05, 2018 1:57 am
by holopaul
Hi,

I think i'm getting the same results as you did. Have you find a solutions for this?

Re: ESP32 MCPWM Input Capture Problem

Posted: Sat Dec 22, 2018 5:47 pm
by Milan991
Hi,

I have the same problem. Is there any update on this?

@steve.kim Have you created issue on ESP-IDF githbub repo with same question?

Re: ESP32 MCPWM Input Capture Problem

Posted: Fri Dec 28, 2018 10:46 am
by ESP_houwenxiang
Milan991 wrote:
Sat Dec 22, 2018 5:47 pm
Hi,

I have the same problem. Is there any update on this?

@steve.kim Have you created issue on ESP-IDF githbub repo with same question?
Hi,
The default scheduling time for our task is 100 milliseconds. However, the frequency of the interrupt is too high (depending on the frequency of the signal), the queue is very easy full. So `xQueueSendFromISR` will fail. This means you will miss several measurements. but the counter of CAP0 is always increasing. `period = current measure - last measure ` get a wrong result.

Re: ESP32 MCPWM Input Capture Problem

Posted: Fri Dec 28, 2018 10:51 am
by ESP_houwenxiang
You can calculate the time between two adjacent triggers in the interrupt, then turn off the interrupt. Because you don't need to measure the frequency of the signal all the time. re-enable the interrupt when you want to measure the signal.

Re: ESP32 MCPWM Input Capture Problem

Posted: Thu Jan 17, 2019 8:21 pm
by Milan991
Hi @ESP_houwenxiang,

I've managed to capture distance between rising edges of 125 us, after increasing frequency even further i could not get lower than this value. Is this the limit of capture mode?

Thank you very much for explanation, it had helped me a lot.

Re: ESP32 MCPWM Input Capture Problem

Posted: Sat Jul 10, 2021 3:57 am
by CityLark
Dude I have the same question. why 125us? the timer frequency capture uses is 8khz? why it's not 80M as same as the apb clock 8khz is totally not enough for a coder capture!

Re: ESP32 MCPWM Input Capture Problem

Posted: Sat Jul 10, 2021 7:59 am
by CityLark
dude! I've solved this problem
0e7fc16e3569522c4051c93399fdaf7.png
0e7fc16e3569522c4051c93399fdaf7.png (11.68 KiB) Viewed 5625 times
!!!

It's because those calculations in the example code uses integer division so the detail of the number is discarded, use some float calculations and It will be smooth as you wish