mirror of
https://github.com/DuRuofu/ESP32-Guide.git
synced 2026-02-06 07:02:01 +08:00
docs: sg90
This commit is contained in:
4
docs/docs/guide/.obsidian/appearance.json
vendored
4
docs/docs/guide/.obsidian/appearance.json
vendored
@@ -4,5 +4,7 @@
|
||||
"page-width"
|
||||
],
|
||||
"cssTheme": "GitHub Theme",
|
||||
"accentColor": "#37b94d"
|
||||
"accentColor": "#37b94d",
|
||||
"baseFontSizeAction": true,
|
||||
"baseFontSize": 20
|
||||
}
|
||||
18
docs/docs/guide/.obsidian/workspace.json
vendored
18
docs/docs/guide/.obsidian/workspace.json
vendored
@@ -13,13 +13,13 @@
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"mode": "source",
|
||||
"source": false,
|
||||
"backlinks": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "28BYJ-48步进电机"
|
||||
"title": "SG90舵机"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -85,13 +85,13 @@
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "28BYJ-48步进电机 的大纲"
|
||||
"title": "SG90舵机 的大纲"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -109,8 +109,12 @@
|
||||
},
|
||||
"active": "ba89e06e4ba5dcbd",
|
||||
"lastOpenFiles": [
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.6-LED_PWM/LED_PWM控制.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments/Pasted image 20250528152414.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments/Pasted image 20250528152307.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527165130.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527163637.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527163522.png",
|
||||
@@ -118,7 +122,6 @@
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527161829.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments",
|
||||
"目录.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.6-LED_PWM/LED_PWM控制.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.1-GPIO/GPIO入门.md",
|
||||
"attachments/Templates.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.4-ADC/ADC模数转换.md",
|
||||
@@ -134,7 +137,6 @@
|
||||
"attachments/20250202192226.png",
|
||||
"01.认识ESP32/1.2-ESP32开发环境搭建/1.环境搭建-Windows.md",
|
||||
"03.FreeRTOS基础/3.4-FreeRTOS软件定时器/FreeRTOS软件定时器.md",
|
||||
"00.常见问题及解决方案/attachments/20250506154522.png",
|
||||
"00.常见问题及解决方案/attachments/Pasted image 20250506154437.png"
|
||||
"00.常见问题及解决方案/attachments/20250506154522.png"
|
||||
]
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
> [!TIP] 🚀 ESP32 模块驱动案例 | 轻松驱动28BYJ-48步进电机
|
||||
> - 💡 **碎碎念**😎:本节将介绍ESP-IDF环境下驱动28BYJ-48步进电机的原理和相关代码编写。
|
||||
> - 📺 **视频教程**:🚧 *开发中*
|
||||
> - 💾 **示例代码**:🚧 *开发中*
|
||||
>
|
||||
> - 💾 **示例代码**:[ESP32-Guide/code/10.practice/common_modules/28byj-48](https://github.com/DuRuofu/ESP32-Guide/tree/main/code/10.practice/common_modules/28byj-48)
|
||||
|
||||
|
||||
## 一、介绍
|
||||
|
||||
@@ -20,10 +20,7 @@
|
||||
|
||||
28BYJ-48 可以使用以下驱动方式:
|
||||
|
||||
单四相(Wave Drive):每次只激活一个线圈,最低功耗,但扭矩最小
|
||||
|
||||
|
||||
|
||||
- 单四相(Wave Drive):每次只激活一个线圈,最低功耗,但扭矩最小
|
||||
- 双四相(Full Step):每次激活两个线圈,扭矩较大
|
||||
- 八拍细分(Half Step):交替激活单个和两个线圈,运动最平稳,精度最高(推荐)
|
||||
|
||||
@@ -64,6 +61,8 @@ ULN2003是一种新型的七路高耐压、大电流达林顿晶体管驱动IC
|
||||
|
||||
## 三、示例
|
||||
|
||||
下面的代码实现一个简单的八拍细分的控制逻辑:
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
@@ -3,29 +3,136 @@
|
||||
> [!TIP] 🚀 ESP32 模块驱动案例 | 驱动SG90舵机
|
||||
> - 💡 **碎碎念**😎:本节将介绍使用ESP32驱动SG90舵机
|
||||
> - 📺 **视频教程**:🚧 *开发中*
|
||||
> - 💾 **示例代码**:🚧 *开发中*
|
||||
> - 💾 **示例代码**:[ESP32-Guide/code/10.practice/common_modules/sg90](https://github.com/DuRuofu/ESP32-Guide/tree/main/code/10.practice/common_modules/sg90)
|
||||
>
|
||||
|
||||
## 一、介绍
|
||||
|
||||
### 1.1 SG90 舵机简介
|
||||
|
||||
SG90 是一种常见的小型舵机,重量轻、体积小、性价比高,广泛应用于遥控模型、机器人、智能车、机械臂等项目中。其内部包含一个小型电机、齿轮减速系统、位置反馈电位器以及控制电路。SG90 通常具有 180° 的旋转范围(部分版本可能限制在 0~120°),通过控制输入的 PWM 信号即可实现精确的角度控制。
|
||||
|
||||

|
||||
|
||||
其引脚定义如下:
|
||||
|
||||

|
||||
|
||||
红色:VCC / 棕色:GND / 橙色:信号线
|
||||
|
||||
### 1.2 PWM 控制原理
|
||||
|
||||
SG90 是通过 PWM(Pulse Width Modulation,脉宽调制)信号来控制的。PWM 信号的周期通常为 20ms(即 50Hz 频率),其中关键的是“高电平脉宽”,也称为占空时间。这个脉宽决定了舵机转动的角度。
|
||||
|
||||
- 控制信号为周期性方波,周期固定为 20ms;
|
||||
- 高电平时间(脉宽)通常在 0.5ms ~ 2.5ms 之间;
|
||||
- 舵机会根据该脉宽转动到相应角度的位置;
|
||||
- 舵机会持续对该信号进行采样,保持在设定角度上。
|
||||
|
||||
### 1.3 舵机角度与脉宽关系
|
||||
|
||||
SG90 舵机的角度和 PWM 脉宽呈线性关系。典型的对应关系如下:
|
||||
|
||||
| 脉宽(ms) | 对应角度(°) |
|
||||
| ------ | -------- |
|
||||
| 0.5 ms | 0°(最左) |
|
||||
| 1.0 ms | 45° |
|
||||
| 1.5 ms | 90°(中位) |
|
||||
| 2.0 ms | 135° |
|
||||
| 2.5 ms | 180°(最右) |
|
||||
|
||||
## 二、使用
|
||||
|
||||
驱动 SG90 舵机通常使用 PWM 信号,而 ESP32 提供了灵活的 LEDC(LED Control)外设,可以非常方便地输出稳定的 PWM 信号,适合控制舵机这类需要特定周期和脉宽的外设。
|
||||
|
||||
LEDC 外设支持以下功能:
|
||||
|
||||
- 高精度定时(可配置频率和占空比)
|
||||
- 多通道支持
|
||||
- 高速与低速模式
|
||||
|
||||
对于 SG90 舵机,建议配置:
|
||||
|
||||
- PWM 频率:50Hz(周期 20ms)
|
||||
- 占空比范围:对应脉宽为 0.5ms ~ 2.5ms,占整个周期的 2.5% ~ 12.5%
|
||||
|
||||
## 三、示例
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "driver/ledc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#define LEDC_TIMER LEDC_TIMER_0
|
||||
#define LEDC_MODE LEDC_LOW_SPEED_MODE
|
||||
#define LEDC_OUTPUT_IO (2) // 控制舵机的GPIO口
|
||||
#define LEDC_CHANNEL LEDC_CHANNEL_0
|
||||
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 13位分辨率 -> 8192
|
||||
#define LEDC_FREQUENCY (50) // 舵机需要 50Hz 周期 (20ms)
|
||||
|
||||
// 占空比计算:
|
||||
// 13位分辨率,满周期 = 8192(即 100%)
|
||||
// 对应脉宽范围 0.5ms ~ 2.5ms -> 占周期的 2.5% ~ 12.5%
|
||||
#define SERVO_MIN_DUTY_US 500 // 0.5ms
|
||||
#define SERVO_MAX_DUTY_US 2500 // 2.5ms
|
||||
#define SERVO_PERIOD_US 20000 // 20ms = 50Hz
|
||||
|
||||
static void ledc_init(void)
|
||||
{
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = LEDC_MODE,
|
||||
.duty_resolution = LEDC_DUTY_RES,
|
||||
.timer_num = LEDC_TIMER,
|
||||
.freq_hz = LEDC_FREQUENCY,
|
||||
.clk_cfg = LEDC_AUTO_CLK};
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.speed_mode = LEDC_MODE,
|
||||
.channel = LEDC_CHANNEL,
|
||||
.timer_sel = LEDC_TIMER,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = LEDC_OUTPUT_IO,
|
||||
.duty = 0,
|
||||
.hpoint = 0};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
}
|
||||
|
||||
// 设置舵机角度(0~180)
|
||||
void set_servo_angle(uint8_t angle)
|
||||
{
|
||||
if (angle > 180)
|
||||
angle = 180;
|
||||
|
||||
uint32_t pulse_width_us = SERVO_MIN_DUTY_US +
|
||||
((SERVO_MAX_DUTY_US - SERVO_MIN_DUTY_US) * angle) / 180;
|
||||
|
||||
uint32_t duty = (pulse_width_us * (1 << LEDC_DUTY_RES)) / SERVO_PERIOD_US;
|
||||
|
||||
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
|
||||
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ledc_init();
|
||||
|
||||
// 依次转动 0° → 90° → 180°
|
||||
set_servo_angle(0);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
set_servo_angle(90);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
set_servo_angle(180);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
while (1)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# 参考链接
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 214 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
Reference in New Issue
Block a user