kopia lustrzana https://github.com/espressif/esp-idf
mcpwm: updated brushed dc example
rodzic
0f0bd29f8f
commit
768af636a6
|
@ -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.
|
||||
|
|
|
@ -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 ".")
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue