mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
mcpwm: updated brushed dc example
This commit is contained in:
@@ -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 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.
|
||||||
|
|
||||||
This code is tested with L298 motor driver, user needs to make changes according to the driver they use
|
## How to Use Example
|
||||||
|
|
||||||
Motor first moves forward, then backward and then stops for 2 Secs each countinuously
|
### 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
|
## Example Output
|
||||||
* GPIO15 is assigned as the enable/input 1 for motor driver
|
|
||||||
* GPIO16 is assigned as the enable/input 2 for motor driver
|
|
||||||
|
|
||||||
|
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
|
## Troubleshooting
|
||||||
* 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
|
* 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.
|
||||||
|
@@ -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 ".")
|
INCLUDE_DIRS ".")
|
||||||
|
@@ -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);
|
|
||||||
}
|
|
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user