# 4.电机控制之速度控制实验 你好,我是小鱼。前面说到通过控制对应的IO上的PWM占空比即可完成对电机速度的控制。 关于PWM的介绍在ROS2硬件控制篇的舵机控制中已经介绍过了,所以我们知道通过改变PWM的占空比可以实现对输出电压的大小调节。占空比越大,输出电压越高;占空比越小,输出电压越低。 接着我们通过一个实验来验证下 ## 一、新建工程 新建`example22_motor_speed_control` ![image-20230228020753916](4.%E7%94%B5%E6%9C%BA%E6%8E%A7%E5%88%B6%E4%B9%8B%E9%80%9F%E5%BA%A6%E6%8E%A7%E5%88%B6%E5%AE%9E%E9%AA%8C/imgs/image-20230228020753916.png) ## 二、编写代码 程序的基本思路是,通过检测按键输入来改变占空比的大小,从而控制电机的转速。按下按键后,每次增加0.1的占空比,当占空比达到1.0时,重新从0开始计数。在loop函数中,通过控制AIN1引脚的高低电平来实现PWM信号的输出,从而控制电机的速度。 ```c++ /** * @file main.cpp * @author fishros@foxmail.com * @brief 电机速度控制 * @version 0.1 * @date 2022-12-19 * * @copyright Copyright (c) 2022 * */ #include #define AIN1 23 // 电机驱动模块AIN1引脚 #define AIN2 22 // 电机驱动模块AIN2引脚 #define KEY 0 // 按键引脚 #define CYCLE 10 // 定义PWM信号的周期长度,单位为ms float duty = 0.0; // 定义占空比变量,并初始化为0.0 void setup() { Serial.begin(115200); // 初始化串口通信 pinMode(KEY, INPUT); // 设置按键引脚为输入模式 pinMode(AIN1, OUTPUT); // 设置AIN1引脚为输出模式 pinMode(AIN2, OUTPUT); // 设置AIN2引脚为输出模式 digitalWrite(AIN2, LOW);// 设置AIN2引脚为低电平,控制电机转向 } void loop() { // 检测按键是否按下 if (digitalRead(KEY) == LOW) { delay(50); // 延迟50ms,以防止误触 // 确认按键已经按下 if (digitalRead(KEY) == LOW) { // 等待按键松开,避免连续按下 while (digitalRead(0) == LOW) ; // 每次增加0.1的占空比,当占空比达到1.0时,重新从0开始计数 duty = duty + 0.1; if (duty > 1.0) duty = 0; } } // 输出PWM信号控制电机转速 digitalWrite(AIN1, HIGH); // 将AIN1引脚设置为高电平 delay(CYCLE * duty); // 延迟一段时间,时间长度由占空比决定 digitalWrite(AIN1, LOW); // 将AIN1引脚设置为低电平 delay(CYCLE * (1 - duty)); // 延迟一段时间,时间长度由占空比决定 } ``` ## 三、测试 将代码下载到主控板上,点击BOOT按键,观察电机转速。 ![motor_speed_cotrol](4.%E7%94%B5%E6%9C%BA%E6%8E%A7%E5%88%B6%E4%B9%8B%E9%80%9F%E5%BA%A6%E6%8E%A7%E5%88%B6%E5%AE%9E%E9%AA%8C/imgs/motor_speed_cotrol.gif) ## 四、总结 本节我们通过简单的一个实验学习了如何通过PWM调节电机的PWM,但有一点需要注意,程序中使用了delay函数来控制PWM信号的占空比,这种方法在简单的应用场景下是可行的,但是在需要更高精度的控制场景下可能会产生问题。为了实现更高精度的PWM控制,我们可以采用ESP32的电机PWM控制单元,下一节我们就尝试使用这一开源库实现更精细化的控制。