【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
作为消费类电子,遇到的电机一般有两种,一种是舵机,一种是步进电机。舵机不复杂,就是给它一定的pwm波形,它就会旋转一定的角度。通常来说,占空比越大,旋转的角度就越大;占空比越小,角度也就越小。而步进电机则稍有不同,舵机本身旋转角度是有限制的,但是步进电机是可以一直转动的。通过交叉不停的给予信号,电机就可以一直旋转下去。

1、准备步进电机和驱动板
通常为了驱动步进电机,我们需要一个单独的驱动板,比如uln2003。有了这个驱动板,我们就可以用简单的gpio信号来驱动步进电机了。步进电机如字面意思所示,就是给予一定的信号,就旋转一定的角度。不过由于内部除了电机之外,还有减速器,所以实际转动速度并不快。
2、独立电源
**实际使用的时候,步进电机驱动板一定要添加单独的5v电源,这一点是很多同学容易忘记的地方。**电机启动电流较大,实际使用的时候,pc的usb口提供不了那么大的电流,所以一般来说,需要给步进电机独立的5v电源。
3、连接线
连线还是比较简单的。在uln2003驱动板子上面,有四个连续的pin,在esp32上面找四个gpio,连接到这四个pin上即可。不失一般性,这四个pin可以是d13、d12、d14、d27。电机连接的部分,一般来说,是直接插上去的,接口本身是防反插的。还有一个电源正负,找一个独立电源连接下即可。注意,连接的时候,一定要注意正负。
4、利用ai编写代码
步进电机+uln2003的组合,是一个非常经典的组合,因此用ai来编写代码也是非常合适的。比如说,我们可以这样告诉ai工具,"用esp32的d13、12、14、27编写一个步进电机的驱动程序,驱动板子是uln2003",这样就可以看到对应的代码了。
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
// ULN2003 Stepper Motor Pins
#define IN1_PIN 13 // D13
#define IN2_PIN 12 // D12
#define IN3_PIN 14 // D14
#define IN4_PIN 27 // D27
// Full-step sequence (8 steps)
const uint8_t step_sequence[8][4] = {
{1, 0, 0, 0}, // A
{1, 1, 0, 0}, // AB
{0, 1, 0, 0}, // B
{0, 1, 1, 0}, // BC
{0, 0, 1, 0}, // C
{0, 0, 1, 1}, // CD
{0, 0, 0, 1}, // D
{1, 0, 0, 1} // DA
};
const gpio_num_t step_pins[4] = {IN1_PIN, IN2_PIN, IN3_PIN, IN4_PIN};
void set_step(uint8_t step)
{
for (int i = 0; i < 4; i++)
{
gpio_set_level(step_pins[i], step_sequence[step][i]);
}
}
void release_motor(void)
{
for (int i = 0; i < 4; i++)
{
gpio_set_level(step_pins[i], 0);
}
}
void rotate_cw(int steps, int delay_ms)
{
static int current_step = 0;
for (int i = 0; i < steps; i++)
{
current_step = (current_step + 1) % 8;
set_step(current_step);
vTaskDelay(delay_ms / portTICK_PERIOD_MS);
}
release_motor();
}
void rotate_ccw(int steps, int delay_ms)
{
static int current_step = 0;
for (int i = 0; i < steps; i++)
{
current_step = (current_step - 1 + 8) % 8;
set_step(current_step);
vTaskDelay(delay_ms / portTICK_PERIOD_MS);
}
release_motor();
}
void stepper_init(void)
{
gpio_config_t io_conf;
io_conf.pin_bit_mask = (1ULL << IN1_PIN) | (1ULL << IN2_PIN) |
(1ULL << IN3_PIN) | (1ULL << IN4_PIN);
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.intr_type = GPIO_INTR_DISABLE;
gpio_config(&io_conf);
release_motor();
}
void app_main(void)
{
printf("ULN2003 Stepper Motor Driver\n");
printf("Pins: IN1=%d, IN2=%d, IN3=%d, IN4=%d\n", IN1_PIN, IN2_PIN, IN3_PIN, IN4_PIN);
printf("Note: ULN2003 requires external 5V power!\n");
stepper_init();
while (1)
{
printf("Rotate Clockwise (Fast)...\n");
rotate_cw(512, 10); // Fast rotation: 10ms delay per step
vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("Rotate Counterclockwise (Fast)...\n");
rotate_ccw(512, 10);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
5、编译、调试
这部分基本上遵照esp32一般的调试逻辑即可。实际执行的时候,会发现uln2003上面的板子一直在闪烁,然后休息一会,继续闪烁,再休息一会。其中led灯闪烁的时候,会发现电机也确实是在旋转的。这和我们预想的一致。如果过程当中发现问题,要及时进行断电处理。
另外和继电器一样,本身esp32只是发出控制信号而已,所以外部电机必须加上独立电源才能正常工作。