espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.71k stars 7.3k forks source link

MCPWM: both low level at complementary pwm's with dead time. #12237

Closed IhorNehrutsa closed 1 year ago

IhorNehrutsa commented 1 year ago

Answers checklist.

General issue report

I try to use MCPWM in 2MCPWM/4IN full H-Bridge driver for brushed DC motor in MicroPython/ESP32/MCPWM: Add motor control MCPWM driver.

I use Dead Time Configurations for Classical PWM Waveforms Active High Complementary mode

I need five output states for half-bridge image

N MCPWM1 MCPWM1
N S1 S2
--- -------- --------
1 PWM _PWM
2 _PWM PWM
3 0 0
4 1 0
5 0 1

where:

MCPWM1 - High side left aka S1 and Low side left aka S2

MCPWM2 - High side right aka S3 and Low side right aka S4

PWM and _PWM are complementary pwm's at MCPWMx

I can set states 1 an 2 by mcpwm_comparator_set_compare_value(). I can set states 4 an 5 by mcpwm_generator_set_force_level(). But I can not set state 3 with mcpwm_generator_set_force_level(). I need both output MCPWMx in LOW level.

DC5V~27V 5A DC Motor Driver Board Module Reversible Speed Control "H" Bridge PWM Signal Controller

Thanks.

I saw that @suda-morris is MCPWM developer.

suda-morris commented 1 year ago

Hi @IhorNehrutsa

Please related commit: https://github.com/espressif/esp-idf/commit/5680d28b0e09bb700be494e3fbf2c5e92da63a85

IhorNehrutsa commented 1 year ago

I saw the commit and Note at https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/mcpwm.html#_CPPv431mcpwm_generator_set_force_level18mcpwm_gen_handle_tib that

Note

The force level set by this function can be inverted by GPIO matrix or dead-time module. 
So the level set here doesn’t equal to the final output level.

but I can find how to set S1 and S2 to low.

suda-morris commented 1 year ago

because there's an extra inversion introduced by the deadtime, so when you call mcpwm_generator_set_force_level to set the force level, you probably need to invert the level in software again. e.g. if you mcpwm_generator_set_force_level(gen, 0, true) but see a high level output, then try mcpwm_generator_set_force_level(gen, 1, true) instead.

Same situation in this example: https://github.com/espressif/esp-idf/blob/master/examples/peripherals/mcpwm/mcpwm_bldc_hall_control/main/mcpwm_bldc_hall_control_example_main.c#L109-L111

IhorNehrutsa commented 1 year ago

https://github.com/IhorNehrutsa/micropython/blob/985b385c50574b965549a99218c712880224c511/ports/esp32/esp32_mcpwm.c#L366-L386

I try both: lines L369 and L370

STATIC void esp32_mcpwm_motor_off_off(esp32_mcpwm_obj_t *self)
{
    check_esp_err(mcpwm_generator_set_force_level(self->gena, 0, true));
//  check_esp_err(mcpwm_generator_set_force_level(self->genb, 0, true)); // ???
    check_esp_err(mcpwm_generator_set_force_level(self->genb, 1, true)); // ???
}

but genb output allways 1.

suda-morris commented 1 year ago

hi @IhorNehrutsa I think we get your point now. The reason why you always get a high level on Generator A is that, the generator B is derived from Generator A by the dead time module. So you lost the control of the generator B.

something like this:

flowchart LR
    Generator_A --> Generator-Action-Setting-A --> Dead-time-A --> output_A
    Generator-Action-Setting-A --> Dead-time-B --> output_B

A way to walk through is:

flowchart LR
    Generator_A --> Generator-Action-Setting-A --> Dead-time-A --> output_A
    Generator_B --> Generator-Action-Setting-B --> Dead-time-B --> output_B

You can refer to this example for configuring the MCPWM generators and dead time independently.

IhorNehrutsa commented 1 year ago

@suda-morris Solved. Thank you very much.