WEMOS D1 R1/R2 [ESP8266] + PCA9685 驱动舵机
PCA9685 16-Channel 12-BIT PWM Driver,某些淘宝卖家只是标注了16路舵机驱动模块。
PCA9685上有黄红黑三排针脚(红黑为正负极,黄色为PWM),每排标注0-15,共计16组。每组可以控制一个舵机。
本文以PCA9685代替前述名称。
这里需要注意 SDA和SCL引脚,SDA默认为4,SCL默认为5。
本文以 wemos d1 r1/r2控制,其名称也常带 UNO。外形酷似arduino uno。本质是基于ESP8266,但有5V输出,有
DC
接口,也可以在VIN
供电使用较宽电压供电(如两节3.7V锂电池直接供电),类似arduino uno。
除了Wemos D1 R1与R2外还有D1 开发板 R32基于ESP32均是UNO类型的。理论上均可以使用本文代码,包括ardunio uno。除SDA和SCL针脚不可参考本文其他地方接线也适用。
观察wemos D1 R1开发板上的对应标注的是D4=SDA=D14,D3=SCL=D15。通过wemos D1 R1引脚定义头文件也可知道D4=4,D3=5。
wemos D1 R2开发板也标注了 三处SDA和SCL ,这些是互通的。SDA=D2,SCL=D1。
其它开发板正常情况4和5也是 SDA和SCL引脚。
但是记得WEMOS D1 开发板除D0不支持I2C以外其他引脚均可以,因此用其他引脚也是可以的,需要修改代码。
接线
-
wemos D1 R1/R2 与PCA9685接线
wemos D1 R1/R2引脚 PCA9685引脚 5V V+ 3.3V VCC SDA SDA SCL SCL GND GND -
PCA9685与舵机接线
鄙人使用的SG90舵机,PCA9685上有黄红黑三排针脚,每排0-15,共计16组。每组可以控制一个舵机。
后文提供的代码,是以0号位的三根黄红黑接入SG90舵机为例。
PCA9685引脚 SG90舵机引脚 黄色(PWM) 黄色 红色 (V+) 红色 黑色 (GND) 棕色 -
总体接线
代码
-
需要库 adafruit/Adafruit PWM Servo Driver Library
-
使用arduino IDE
使用arduino IDE可以在库管理 搜索
Adafruit PWM Servo Driver Library
选择 项目 -> 加载库 -> 库管理 打开库管理进行搜索
或者按 Ctrl + Shift + I 打开库管理进行搜索
-
使用platformio(基于Vscode或者clion)
在
platformio.ini
添加以下内容:lib_deps = adafruit/Adafruit PWM Servo Driver Library@^2.4.0
-
-
代码内容
根据自己接入的舵机是[0-15]具体哪一通道需要修改loop中调用
pwm.setPWM
传参的第一个参数。本例子是先正转到上限,回正再反转到上限。设置了上限下限和中间值的点。可以根据实际情况调节上下限。
此处for循环是逐步设置角度,使得稍微丝滑一些,不用循环也是可以的。#include <Adafruit_PWMServoDriver.h> #include <Wire.h> Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); #define SERVOUP 150 //上限 #define SERVOMID 375 // 中间值 #define SERVODOWN 600 // 下限 void setup() { Serial.begin(115200); Serial.println("channel [0] Servo test!"); pwm.begin(); pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates } void loop() { Serial.println("off "); for (uint16_t pulselen = SERVOMID; pulselen < SERVODOWN; pulselen++) { // 舵机接在 第n组针脚上,则是 pwm.setPWM(n, 0, pulselen); pwm.setPWM(0, 0, pulselen); } delay(500); for (uint16_t pulselen = SERVODOWN; pulselen > SERVOMID; pulselen--) { pwm.setPWM(0, 0, pulselen); } Serial.println("on "); delay(1000); for (uint16_t pulselen = SERVOMID; pulselen > SERVOUP; pulselen--) { pwm.setPWM(0, 0, pulselen); } delay(500); for (uint16_t pulselen = SERVOUP; pulselen < SERVOMID; pulselen++) { pwm.setPWM(0, 0, pulselen); } delay(3000); }
-
重设SDA SCL
若不希望使用默认I2C引脚,同时其他引脚也支持I2C,可以参照当前方法重设I2C引脚。
读源码可知,调用 TwoWire 的pins函数重设sda /scl引脚
void TwoWire::pins(int sda, int scl) { default_sda_pin = sda; default_scl_pin = scl; }
Adafruit_PWMServoDriver 重设sda scl引脚部分示例,此处只给出了setup函数
#include <Adafruit_PWMServoDriver.h> #include <Wire.h> TwoWire wire = TwoWire(); Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(PCA9685_I2C_ADDRESS, wire); void setup() { Serial.begin(115200); while (!Serial) { } Serial.println("servoArm start!"); wire.pins(D11, D10); pwm.begin(); pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates } // 其它内容省略