最近更新于 2024-05-05 14:19
简介
舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统,通过 PWM 可以控制舵机转动到指定的角度。
演示用的舵机都是 180° 的
测试环境
- 硬件(系统):树莓派 cm4 (官方64位系统 Debian 11)
- 编译器 GNU gcc 10.2.1
- WiringPi 库
- 舵机 MG996R x 1 (演示 PWM 舵机控制使用)
- 舵机 TS90A x 2 (演示手柄控制云台)
- PCF 8591 数模转换模块
- 手柄
GPIO 布局图
使用 BCM 编号
舵机使用演示
(1)接线
舵机有三条线,红线为正极,可 3.3V,也可 5V,建议 5V 动力更强;棕线接 GND;黄线接 PWM 控制,这里演示我就接 BCM 17。
(2)源码示例
#include "wiringPi.h" #include "softPwm.h" #define PIN 17 // BCM 17 int main() { wiringPiSetupGpio(); // 初始化 GPIO,按 BCM 编号使用 pinMode(PIN, OUTPUT); // 设置引脚为输出 softPwmCreate(PIN, 15, 200); // 20ms 周期,初始高电平占比 1.5ms,居中 delay(1000); // 延时 1 s,给予时间足够时间给舵机转动 softPwmWrite(PIN, 5); // 转动到 -90° delay(2000); softPwmWrite(PIN, 25); // 转动到 90° delay(1000); softPwmStop(PIN); // 关闭 PWM }
首先舵机会转动到中间 0° 位置,然后向右转到 -90° 位置,然后向左转到 90°位置
编译时 gcc 要加参数 -lwiringPi 进行链接
手柄控制
(1)接线
下面左右转动的舵机 PWM 接 BCM 17,上面上下摆动的舵机接 BCM 18。
PCF 8591 对树莓派接口就是 IIC,GND、VCC、SCL、SDA 分别对应就行,PCF 8591 插了跳线帽的话,全部拔掉,另外树莓派设置记得打开 I2C
手柄 GND、VCC 对着接到树莓派就行,然后 PCF 8591 的 AIN0、AIN1 分别接手柄 X、Y,手柄还有一根 SW 线,那是手柄可以下按,有一个按钮,这里不使用就不接线。
(2)源码示例
#include "wiringPi.h" #include "softPwm.h" #include "pcf8591.h" #include <math.h> #define PIN1 17 // BCM 17 #define PIN2 18 // BCM 18 #define PCF 64 // PCF8591 起始地址 #define AIN0 PCF #define AIN1 PCF+1 /** * @brief 控制舵机 * pcf8591 读值范围为 0~255,125 时手柄居中(实际居中时不一定是 125,可能有偏差) * 然后要将手柄的读值转换为舵机转动角度,对应这里 5~25(0°~180°) * (25 - 5)/ 256 = 0.78125 * 所以手柄值 dir 与舵机转动角度控制值 ang 的关系为 ang = 5 + 0.78125 * dir * * @param pin 舵机 PWM 引脚 * @param op 0~255, 对应 */ void steer(int pin, int dir) { int ang = 5 + (int)round(0.078125 * dir); // 四舍五入取整 softPwmWrite(pin, ang); } int main() { // 初始化 wiringPiSetupGpio(); pcf8591Setup(PCF, 0x48); // AIN0、AIN1 分别对应 PCF+0、PCF+1,0x48为模块自己的 I2C 地址 pinMode(PIN1, OUTPUT); pinMode(PIN2, OUTPUT); softPwmCreate(PIN1, 15, 200); // 居中 0° softPwmCreate(PIN2, 15, 200); delay(1000); while (1) { int x = analogRead(AIN0); // 读手柄值 int y = analogRead(AIN1); steer(PIN1, x); steer(PIN2, y); delay(10); } }
编译时要链接 wiringPi 库和数学库,加参数 -lwiringPi -lm
树莓派使用舵机