0%

在树莓派4B上使用PCA9685控制MG996R伺服电机

raspberry-pi-logo-1920.png

技术原理

PCA9685

PCA9685.png

简介

  • 采用I2C通信,内置了PWM驱动器和一个时钟,不需要不断发送信号占用单片机资源
  • 支持16路PWM输出,每路12位分辨率(4096级),在60Hz的更新率能够达到4us分辨率
  • 内置25MHz晶振,可不连接外部晶振,也可以连接外部晶振,最大50MHz
  • 分为控制电和驱动电两个电源,控制电支持2.3V-5.5V电压,最大耐压值5.5V,逻辑电平3.3V,驱动电支持5V-10V直流电压。

引脚定义

引脚 功能
GND 接地
OE 使能引脚(低电平时使能芯片)
SCL I2C总线控制线
SDA I2C总线数据线
VCC 控制电压,2.3V-5.5V
V+ 驱动电压,5V-10V

!注意:

PCA9685背面.png

V+是给外接设备供电的引脚,在驱动大功率舵机时候通常不使用V+,而是使用外接电源的两个端口。

V+的电压是多少,舵机的电压就是多少。

一定要注意电压范围,不能接入过大电压。

接线

PCA9685连接树莓派GPIO

其中绿色位置的VCC和GND我皆在了4和6上。

PWM与舵机角度的对应关系

PWM

舵机通过输入PWM脉冲信号来进行控制。如上图所示,一个脉冲周期为20ms,高电平为脉冲宽度,这个宽度决定了舵机的旋转角度。

例如180°的MG996R,当高电平宽度为1.5ms时,舵机处于90°位置;当高电平宽度为1ms时,舵机处于0°;2ms时为180°。以此类推,进而可以总结出公式:
$$
舵机旋转1°=\frac{最大脉冲宽度-最小脉冲宽度}{最大角度}
$$

准备工作

打开IIC

raspi-config -> Interfacing Options -> I2C -> enable

安装adafruit

1
sudo pip3 install adafruit-pca9685

测试

.py文件来自:Adafruit_Python_PCA9685/simpletest.py at master · adafruit/Adafruit_Python_PCA9685 (github.com)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Simple demo of of the PCA9685 PWM servo/LED controller library.
# This will move channel 0 from min to max position repeatedly.
# Author: Tony DiCola
# License: Public Domain
from __future__ import division
import time

# Import the PCA9685 module.
import Adafruit_PCA9685


# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)

# Initialise the PCA9685 using the default address (0x40).
pwm = Adafruit_PCA9685.PCA9685()

# Alternatively specify a different address and/or bus:
#pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)

# Configure min and max servo pulse lengths
servo_min = 150 # Min pulse length out of 4096
servo_max = 600 # Max pulse length out of 4096

# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
pulse_length = 1000000 # 1,000,000 us per second
pulse_length //= 60 # 60 Hz
print('{0}us per period'.format(pulse_length))
pulse_length //= 4096 # 12 bits of resolution
print('{0}us per bit'.format(pulse_length))
pulse *= 1000
pulse //= pulse_length
pwm.set_pwm(channel, 0, pulse)

# Set frequency to 60hz, good for servos.
pwm.set_pwm_freq(60)

print('Moving servo on channel 0, press Ctrl-C to quit...')
while True:
# Move servo on channel O between extremes.
pwm.set_pwm(0, 0, servo_min)
time.sleep(1)
pwm.set_pwm(0, 0, servo_max)
time.sleep(1)

问题解决

FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'

原因:配置中没有使能I2C,或者I2C使能失败。

解决:进入配置界面,重新使能I2C。

补充:也可能是设置好之后系统未能响应,重启解决。

参考资料

PCA9685 Data Sheet

MG996R Data Sheet

Raspberry Pi 4 Data Sheet

adafruit/Adafruit_Python_PCA9685: Python code to use the PCA9685 PWM servo/LED controller with a Raspberry Pi or BeagleBone black. (github.com)