Arduino uno使用PCA9685模块实现16路舵机控制

PCA9685模块

PCA9685是16路12位PWM信号发生器,可用于控制舵机、led、电机等设备,采用I2C通信。主机只需要I2C接口即可实现16路舵机控制。
PCA9685的I2C地址默认0x40,如果需要改变地址,则需要将板上A0-A5焊通即可对应的bit置1,此时地址为:0x40+A5:A0。这也意味着主机可以通过I2C地址控制64个PCA9685模块,从而实现最大16*64路舵机控制。
PCA9685模块如下图:
Arduino uno使用PCA9685模块实现16路舵机控制_第1张图片

Arduino uno与模块连线

AIN4 ------- SDA
AIN5 ------- SCL
5V -------- VCC
3.3V -------- V+
GND -------- GND
舵机线按照颜色对应接模块0控制口。
V+是舵机电源,试验采用的是9g小舵机,所以也可以用3.3V带动,但是mg995这种大舵机,则需要5V以上才能带动。
VCC是模块的电源,用于PCA9685芯片。
Arduino uno使用PCA9685模块实现16路舵机控制_第2张图片

Adafruit库安装

使用Arduino的好处之一是有丰富的库支持。PC9685模块也有对应的库可以使用,这是一个外部库,由Adafruit提供。

选择工具菜单下的管理库选项

Arduino uno使用PCA9685模块实现16路舵机控制_第3张图片

搜索adafruit pwm

Arduino uno使用PCA9685模块实现16路舵机控制_第4张图片

点击安装

Arduino uno使用PCA9685模块实现16路舵机控制_第5张图片

安装完后,即可在文件下示例里面找到对应的示例

Arduino uno使用PCA9685模块实现16路舵机控制_第6张图片

控制程序

舵机的控制一般需要一个20ms的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度舵机为例,那么对应的控制关系是这样的:
0.5ms————–0度;
1.0ms————45度;
1.5ms————90度;
2.0ms———–135度;
2.5ms———–180度;

PCA9685可以设置更新频率,时基脉冲周期20ms相当于50HZ更新频率。PCA9685采用12位的寄存器来控制PWM占比,对于0.5ms,相当于0.5/204096=102的寄存器值。以此类推如下:
0.5ms————–0度:0.5/20
4096 = 102
1.0ms————45度:1/204096 = 204
1.5ms————90度:1.5/20
4096 = 306
2.0ms———–135度:2/204096 = 408
2.5ms———–180度:2.5/20
4096 =510

但是实际使用的时候,还是有偏差,除了0度以及180度,其他需要乘以0.915系数。最后的寄存器值如下:
0.5ms————–0度:0.5/204096 = 102
1.0ms————45度:1/20
4096 = 204 * 0.915 = 187
1.5ms————90度:1.5/204096 = 306 * 0.915 = 280
2.0ms———–135度:2/20
4096 = 408 * 0.915 = 373
2.5ms———–180度:2.5/20*4096 =510

控制程序使用串口通讯接受指令,实现0/45/90/135/180度,总共5种角度的控制。

#include 
#include 

// 默认地址 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVO_0  102 
#define SERVO_45  187 
#define SERVO_90  280 
#define SERVO_135  373 
#define SERVO_180  510 

// our servo # counter
uint8_t servonum = 0;
char comchar;

void setup() {
  Serial.begin(9600);
  Serial.println("8 channel Servo test!");

  pwm.begin();
  pwm.setPWMFreq(50);  // 50HZ更新频率,相当于20ms的周期

  delay(10);
}

void loop() {
    while(Serial.available()>0){
    comchar = Serial.read();//读串口第一个字节
    switch(comchar)
    {
      case '0':
      pwm.setPWM(0, 0, SERVO_0);
      Serial.write(comchar);
      break;
      case '1':
      pwm.setPWM(0, 0, SERVO_45);
      Serial.write(comchar);
      break;
      case '2':
      pwm.setPWM(0, 0, SERVO_90);
      Serial.write(comchar);
      break;
      case '3':
      pwm.setPWM(0, 0, SERVO_135);
      Serial.write(comchar);
      break;       
      case '4':
      pwm.setPWM(0, 0, SERVO_180);
      Serial.write(comchar);
      break;
      default:
      Serial.write(comchar);
      break;                  
    }
  }
}

效果视频如下:
http://v.douyin.com/y1VBvX/

你可能感兴趣的:(Robot)