Skip to content

Commit 6d20aad

Browse files
committed
docs: sg90
1 parent 6024827 commit 6d20aad

File tree

6 files changed

+127
-17
lines changed

6 files changed

+127
-17
lines changed

docs/docs/guide/.obsidian/appearance.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44
"page-width"
55
],
66
"cssTheme": "GitHub Theme",
7-
"accentColor": "#37b94d"
7+
"accentColor": "#37b94d",
8+
"baseFontSizeAction": true,
9+
"baseFontSize": 20
810
}

docs/docs/guide/.obsidian/workspace.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
"state": {
1414
"type": "markdown",
1515
"state": {
16-
"file": "10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
16+
"file": "10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
1717
"mode": "source",
1818
"source": false,
1919
"backlinks": false
2020
},
2121
"icon": "lucide-file",
22-
"title": "28BYJ-48步进电机"
22+
"title": "SG90舵机"
2323
}
2424
}
2525
]
@@ -85,13 +85,13 @@
8585
"state": {
8686
"type": "outline",
8787
"state": {
88-
"file": "10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
88+
"file": "10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
8989
"followCursor": false,
9090
"showSearch": false,
9191
"searchQuery": ""
9292
},
9393
"icon": "lucide-list",
94-
"title": "28BYJ-48步进电机 的大纲"
94+
"title": "SG90舵机 的大纲"
9595
}
9696
}
9797
]
@@ -109,16 +109,19 @@
109109
},
110110
"active": "ba89e06e4ba5dcbd",
111111
"lastOpenFiles": [
112-
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
113112
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
113+
"04.外设学习/4.1-基础外设/4.1.6-LED_PWM/LED_PWM控制.md",
114+
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
115+
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments/Pasted image 20250528152414.png",
116+
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments/Pasted image 20250528152307.png",
117+
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments",
114118
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527165130.png",
115119
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527163637.png",
116120
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527163522.png",
117121
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527162100.png",
118122
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527161829.png",
119123
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments",
120124
"目录.md",
121-
"04.外设学习/4.1-基础外设/4.1.6-LED_PWM/LED_PWM控制.md",
122125
"04.外设学习/4.1-基础外设/4.1.1-GPIO/GPIO入门.md",
123126
"attachments/Templates.md",
124127
"04.外设学习/4.1-基础外设/4.1.4-ADC/ADC模数转换.md",
@@ -134,7 +137,6 @@
134137
"attachments/20250202192226.png",
135138
"01.认识ESP32/1.2-ESP32开发环境搭建/1.环境搭建-Windows.md",
136139
"03.FreeRTOS基础/3.4-FreeRTOS软件定时器/FreeRTOS软件定时器.md",
137-
"00.常见问题及解决方案/attachments/20250506154522.png",
138-
"00.常见问题及解决方案/attachments/Pasted image 20250506154437.png"
140+
"00.常见问题及解决方案/attachments/20250506154522.png"
139141
]
140142
}

docs/docs/guide/10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
> [!TIP] 🚀 ESP32 模块驱动案例 | 轻松驱动28BYJ-48步进电机
55
> - 💡 **碎碎念**😎:本节将介绍ESP-IDF环境下驱动28BYJ-48步进电机的原理和相关代码编写。
66
> - 📺 **视频教程**:🚧 *开发中*
7-
> - 💾 **示例代码**🚧 *开发中*
8-
>
7+
> - 💾 **示例代码**[ESP32-Guide/code/10.practice/common_modules/28byj-48](https://github.com/DuRuofu/ESP32-Guide/tree/main/code/10.practice/common_modules/28byj-48)
8+
99

1010
## 一、介绍
1111

@@ -20,10 +20,7 @@
2020

2121
28BYJ-48 可以使用以下驱动方式:
2222

23-
单四相(Wave Drive):每次只激活一个线圈,最低功耗,但扭矩最小
24-
25-
26-
23+
- 单四相(Wave Drive):每次只激活一个线圈,最低功耗,但扭矩最小
2724
- 双四相(Full Step):每次激活两个线圈,扭矩较大
2825
- 八拍细分(Half Step):交替激活单个和两个线圈,运动最平稳,精度最高(推荐)
2926

@@ -64,6 +61,8 @@ ULN2003是一种新型的七路高耐压、大电流达林顿晶体管驱动IC
6461
6562
## 三、示例
6663

64+
下面的代码实现一个简单的八拍细分的控制逻辑:
65+
6766
```c
6867
#include <stdio.h>
6968
#include "freertos/FreeRTOS.h"

docs/docs/guide/10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,136 @@
33
> [!TIP] 🚀 ESP32 模块驱动案例 | 驱动SG90舵机
44
> - 💡 **碎碎念**😎:本节将介绍使用ESP32驱动SG90舵机
55
> - 📺 **视频教程**:🚧 *开发中*
6-
> - 💾 **示例代码**🚧 *开发中*
6+
> - 💾 **示例代码**[ESP32-Guide/code/10.practice/common_modules/sg90](https://github.com/DuRuofu/ESP32-Guide/tree/main/code/10.practice/common_modules/sg90)
77
>
88
99
## 一、介绍
1010

1111
### 1.1 SG90 舵机简介
1212

13+
SG90 是一种常见的小型舵机,重量轻、体积小、性价比高,广泛应用于遥控模型、机器人、智能车、机械臂等项目中。其内部包含一个小型电机、齿轮减速系统、位置反馈电位器以及控制电路。SG90 通常具有 180° 的旋转范围(部分版本可能限制在 0~120°),通过控制输入的 PWM 信号即可实现精确的角度控制。
14+
15+
![](attachments/Pasted%20image%2020250528152307.png)
16+
17+
其引脚定义如下:
18+
19+
![](attachments/Pasted%20image%2020250528152414.png)
20+
21+
红色:VCC / 棕色:GND / 橙色:信号线
1322

1423
### 1.2 PWM 控制原理
1524

25+
SG90 是通过 PWM(Pulse Width Modulation,脉宽调制)信号来控制的。PWM 信号的周期通常为 20ms(即 50Hz 频率),其中关键的是“高电平脉宽”,也称为占空时间。这个脉宽决定了舵机转动的角度。
1626

27+
- 控制信号为周期性方波,周期固定为 20ms;
28+
- 高电平时间(脉宽)通常在 0.5ms ~ 2.5ms 之间;
29+
- 舵机会根据该脉宽转动到相应角度的位置;
30+
- 舵机会持续对该信号进行采样,保持在设定角度上。
1731

1832
### 1.3 舵机角度与脉宽关系
1933

34+
SG90 舵机的角度和 PWM 脉宽呈线性关系。典型的对应关系如下:
2035

36+
| 脉宽(ms) | 对应角度(°) |
37+
| ------ | -------- |
38+
| 0.5 ms | 0°(最左) |
39+
| 1.0 ms | 45° |
40+
| 1.5 ms | 90°(中位) |
41+
| 2.0 ms | 135° |
42+
| 2.5 ms | 180°(最右) |
2143

2244
## 二、使用
2345

46+
驱动 SG90 舵机通常使用 PWM 信号,而 ESP32 提供了灵活的 LEDC(LED Control)外设,可以非常方便地输出稳定的 PWM 信号,适合控制舵机这类需要特定周期和脉宽的外设。
2447

48+
LEDC 外设支持以下功能:
2549

26-
## 三、示例
50+
- 高精度定时(可配置频率和占空比)
51+
- 多通道支持
52+
- 高速与低速模式
53+
54+
对于 SG90 舵机,建议配置:
2755

56+
- PWM 频率:50Hz(周期 20ms)
57+
- 占空比范围:对应脉宽为 0.5ms ~ 2.5ms,占整个周期的 2.5% ~ 12.5%
58+
59+
## 三、示例
2860

61+
```c
62+
#include <stdio.h>
63+
#include "driver/ledc.h"
64+
#include "freertos/FreeRTOS.h"
65+
#include "freertos/task.h"
66+
#include "esp_err.h"
67+
68+
#define LEDC_TIMER LEDC_TIMER_0
69+
#define LEDC_MODE LEDC_LOW_SPEED_MODE
70+
#define LEDC_OUTPUT_IO (2) // 控制舵机的GPIO口
71+
#define LEDC_CHANNEL LEDC_CHANNEL_0
72+
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 13位分辨率 -> 8192
73+
#define LEDC_FREQUENCY (50) // 舵机需要 50Hz 周期 (20ms)
74+
75+
// 占空比计算:
76+
// 13位分辨率,满周期 = 8192(即 100%)
77+
// 对应脉宽范围 0.5ms ~ 2.5ms -> 占周期的 2.5% ~ 12.5%
78+
#define SERVO_MIN_DUTY_US 500 // 0.5ms
79+
#define SERVO_MAX_DUTY_US 2500 // 2.5ms
80+
#define SERVO_PERIOD_US 20000 // 20ms = 50Hz
81+
82+
static void ledc_init(void)
83+
{
84+
ledc_timer_config_t ledc_timer = {
85+
.speed_mode = LEDC_MODE,
86+
.duty_resolution = LEDC_DUTY_RES,
87+
.timer_num = LEDC_TIMER,
88+
.freq_hz = LEDC_FREQUENCY,
89+
.clk_cfg = LEDC_AUTO_CLK};
90+
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
91+
92+
ledc_channel_config_t ledc_channel = {
93+
.speed_mode = LEDC_MODE,
94+
.channel = LEDC_CHANNEL,
95+
.timer_sel = LEDC_TIMER,
96+
.intr_type = LEDC_INTR_DISABLE,
97+
.gpio_num = LEDC_OUTPUT_IO,
98+
.duty = 0,
99+
.hpoint = 0};
100+
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
101+
}
102+
103+
// 设置舵机角度(0~180)
104+
void set_servo_angle(uint8_t angle)
105+
{
106+
if (angle > 180)
107+
angle = 180;
108+
109+
uint32_t pulse_width_us = SERVO_MIN_DUTY_US +
110+
((SERVO_MAX_DUTY_US - SERVO_MIN_DUTY_US) * angle) / 180;
111+
112+
uint32_t duty = (pulse_width_us * (1 << LEDC_DUTY_RES)) / SERVO_PERIOD_US;
113+
114+
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
115+
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
116+
}
117+
118+
void app_main(void)
119+
{
120+
ledc_init();
121+
122+
// 依次转动 0° → 90° → 180°
123+
set_servo_angle(0);
124+
vTaskDelay(pdMS_TO_TICKS(1000));
125+
126+
set_servo_angle(90);
127+
vTaskDelay(pdMS_TO_TICKS(1000));
128+
129+
set_servo_angle(180);
130+
vTaskDelay(pdMS_TO_TICKS(1000));
131+
while (1)
132+
{
133+
vTaskDelay(pdMS_TO_TICKS(1000));
134+
}
135+
```
29136
30137
31138
# 参考链接
214 KB
Loading
305 KB
Loading

0 commit comments

Comments
 (0)