mcpwm: updated brushed dc example

This commit is contained in:
morris 2021-01-11 14:26:33 +08:00
parent 0f0bd29f8f
commit 768af636a6
4 changed files with 134 additions and 113 deletions

View File

@ -1,25 +1,68 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
| Supported Targets | ESP32 | ESP32-S3 |
| ----------------- | ----- | -------- |
# MCPWM Brushed DC Motor Example
# MCPWM brushed dc motor control Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example will show you how to use MCPWM module to control brushed dc motor, you need to make connection between ESP32 and motor driver
This code is tested with L298 motor driver, user needs to make changes according to the driver they use
Motor first moves forward, then backward and then stops for 2 Secs each countinuously
This example mainly illustrates how to drive a brushed DC motor by generating two specific PWM signals. We used [L298N](https://www.st.com/content/st_com/en/products/motor-drivers/brushed-dc-motor-drivers/l298.html) as the H-bridge driver to provide the needed voltage and current for brushed DC motor.
## How to Use Example
### Hardware Required
* A development board with any Espressif SoC which features MCPWM peripheral (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for Power supply and programming
* A separate 12V power for brushed DC (the voltage depends on the motor model used in the example)
* A brushed DC motor, e.g. [25GA370](http://www.tronsunmotor.com/data/upload/file/201807/e03b98802b5c5390d6570939def525ba.pdf)
Connection :
```
Power (12V)
^
|
+----------------+ +------------+--------------+ +-------------+
| | | | | |
| GPIO15+------ PWM0A +-+ IN_A +------+ +-------+ OUT_A +------+ Brushed |
| ESP | | H-Bridge | | DC |
| GPIO16+------ PWM0B +-+ IN_B +------+ +-------+ OUT_B +------+ Motor |
| | | | | |
+--------+-------+ +------------+--------------+ +-------------+
| |
+------------------------------------------------->+
|
v
GND
```
### Build and Flash
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Step 1: Pin assignment
* GPIO15 is assigned as the enable/input 1 for motor driver
* GPIO16 is assigned as the enable/input 2 for motor driver
## Example Output
Run the example, you will see the following output log:
## Step 2: Connection
* connect GPIO15 with input 1 of motor driver
* connect GPIO16 with input 2 of motor driver
```
...
I (0) cpu_start: Starting scheduler on APP CPU.
I (350) example: running forward
I (2350) example: running backward
I (4350) example: stop
I (6350) example: running forward
I (8350) example: running backward
I (10350) example: stop
...
```
Motor first moves forward, then backward and then stops for 2 seconds each, continuously.
## Step 3: Initialize MCPWM
* You need to set the frequency and duty cycle of MCPWM timer
* You need to set the MCPWM unit you want to use, and bind the unit with one of the timers
## Troubleshooting
* Make sure your ESP board and H-bridge module have been connected to the same GND panel.
For any technical queries, please open an [issue] (https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@ -1,2 +1,2 @@
idf_component_register(SRCS "mcpwm_brushed_dc_control_example.c"
idf_component_register(SRCS "mcpwm_brushed_dc_example_main.c"
INCLUDE_DIRS ".")

View File

@ -1,95 +0,0 @@
/* brushed dc motor control example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* This example will show you how to use MCPWM module to control brushed dc motor.
* This code is tested with L298 motor driver.
* User may need to make changes according to the motor driver they use.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_attr.h"
#include "driver/mcpwm.h"
#include "soc/mcpwm_periph.h"
#define GPIO_PWM0A_OUT 15 //Set GPIO 15 as PWM0A
#define GPIO_PWM0B_OUT 16 //Set GPIO 16 as PWM0B
static void mcpwm_example_gpio_initialize(void)
{
printf("initializing mcpwm gpio...\n");
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
}
/**
* @brief motor moves in forward direction, with duty cycle = duty %
*/
static void brushed_motor_forward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num , float duty_cycle)
{
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B);
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_A, duty_cycle);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state
}
/**
* @brief motor moves in backward direction, with duty cycle = duty %
*/
static void brushed_motor_backward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num , float duty_cycle)
{
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A);
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_B, duty_cycle);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state
}
/**
* @brief motor stop
*/
static void brushed_motor_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
{
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_A);
mcpwm_set_signal_low(mcpwm_num, timer_num, MCPWM_OPR_B);
}
/**
* @brief Configure MCPWM module for brushed dc motor
*/
static void mcpwm_example_brushed_motor_control(void *arg)
{
//1. mcpwm gpio initialization
mcpwm_example_gpio_initialize();
//2. initial mcpwm configuration
printf("Configuring Initial Parameters of mcpwm...\n");
mcpwm_config_t pwm_config;
pwm_config.frequency = 1000; //frequency = 500Hz,
pwm_config.cmpr_a = 0; //duty cycle of PWMxA = 0
pwm_config.cmpr_b = 0; //duty cycle of PWMxb = 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
while (1) {
brushed_motor_forward(MCPWM_UNIT_0, MCPWM_TIMER_0, 50.0);
vTaskDelay(2000 / portTICK_RATE_MS);
brushed_motor_backward(MCPWM_UNIT_0, MCPWM_TIMER_0, 30.0);
vTaskDelay(2000 / portTICK_RATE_MS);
brushed_motor_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
vTaskDelay(2000 / portTICK_RATE_MS);
}
}
void app_main(void)
{
printf("Testing brushed motor...\n");
xTaskCreate(mcpwm_example_brushed_motor_control, "mcpwm_examlpe_brushed_motor_control", 4096, NULL, 5, NULL);
}

View File

@ -0,0 +1,73 @@
/* Brushed DC motor control example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/mcpwm.h"
static const char *TAG = "example";
#define GPIO_PWM0A_OUT (15) //Set GPIO 15 as PWM0A
#define GPIO_PWM0B_OUT (16) //Set GPIO 16 as PWM0B
/**
* @brief motor moves in forward direction, with duty cycle = duty %
*/
static void brushed_motor_forward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, float duty_cycle)
{
ESP_LOGI(TAG, "running forward");
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_HAL_GENERATOR_MODE_FORCE_LOW);
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_A, duty_cycle);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_DUTY_MODE_0);
}
/**
* @brief motor moves in backward direction, with duty cycle = duty %
*/
static void brushed_motor_backward(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, float duty_cycle)
{
ESP_LOGI(TAG, "running backward");
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_HAL_GENERATOR_MODE_FORCE_LOW);
mcpwm_set_duty(mcpwm_num, timer_num, MCPWM_OPR_B, duty_cycle);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_DUTY_MODE_0);
}
static void brushed_motor_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
{
ESP_LOGI(TAG, "stop");
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_A, MCPWM_HAL_GENERATOR_MODE_FORCE_LOW);
mcpwm_set_duty_type(mcpwm_num, timer_num, MCPWM_OPR_B, MCPWM_HAL_GENERATOR_MODE_FORCE_LOW);
}
void app_main(void)
{
// Initialize GPIO
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT);
// MCPWM configuration
mcpwm_config_t pwm_config = {
.frequency = 1000,
.cmpr_a = 0,
.cmpr_b = 0,
.counter_mode = MCPWM_UP_COUNTER,
.duty_mode = MCPWM_DUTY_MODE_0,
};
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);
while (1) {
brushed_motor_forward(MCPWM_UNIT_0, MCPWM_TIMER_0, 50.0);
vTaskDelay(pdMS_TO_TICKS(2000));
brushed_motor_backward(MCPWM_UNIT_0, MCPWM_TIMER_0, 30.0);
vTaskDelay(pdMS_TO_TICKS(2000));
brushed_motor_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
vTaskDelay(pdMS_TO_TICKS(2000));
}
}