使用PCA9685控制多个舵机

todolist
在这里插入图片描述要单独去找舵机的两个极值的大小,然后去该前文的映射的初始值
在这里插入图片描述
在这里插入图片描述

把角度值打印出来
在这里插入图片描述

0.准备

0.1.硬件设备

0.2.软件安装

1.安装好Arduino IDE
可以前往Arduino官网下载安装,支持windows、macos、linux系统;
在这里插入图片描述2.在Arduino IDE内配置相关的库(也可以到Adafruit PWM Servo Driver Library代码库中下载源码,但是要自己配置路径,所以不推荐 )
在Arduino IDE中依次打开:工具(Tools)-库管理(Library manager)然后搜索Adafruit PWM Servo Driver Library然后选择最新的版本安装就行;
请添加图片描述然后打开Adafruit PWM Servo Driver Library自带的一个案例
在Arduino IDE中依次打开:文件(File)-案例(Example)- Adafruit PWM Servo Driver Library - servo
这个案例也是我们要展示的第一个案例,利用PCA9685,控制八个舵机,并让他们依次完成正转和反转的运动;
请添加图片描述

0.3.硬件连接

请按照如下图实物图所示连接板子
请添加图片描述
请添加图片描述

0.单独使用arduino控制舵机转动

舵机0~180°来回转动。

#include <Servo.h>            //加载文件库
int pos = 0;
Servo myservo;
 
void setup()
{
    
    
  myservo.attach(9, 500, 2500);          //修正脉冲宽度
}
 
void loop()
{
    
    
  for (pos = 0; pos <= 180; pos += 1) {
    
           //pos+=1等价于pos=pos+1
    myservo.write(pos);
    delay(15);					
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    
    
    myservo.write(pos);
    delay(15); 					
  }
}

在这里插入图片描述

舵机单独在一个度数,例如90度

#include <Servo.h> //引入lib
 
Servo myservo;  // 创建一个伺服电机对象
 
char inByte = 0; //串口接收的数据
int angle = 90;  //角度值
String temp = "";//临时字符变量,又或者说是缓存用的吧
 
void setup() 
{
    
    
  myservo.attach(9);    //定义舵机的引脚为9,舵机只能是10,或者9引脚
  Serial.begin(9600);  //设置波特率
}
 
 
void loop() 
{
    
    
  while (Serial.available() > 0) //判断串口是否有数据
  {
    
    
    inByte = Serial.read();//读取数据,串口一次只能读1个字符
    temp += inByte;//把读到的字符存进临时变量里面缓存,
                   //再继续判断串口还有没有数据,知道把所有数据都读取出来
   }
 
   if(temp != "")   //判断临时变量是否为空
   {
    
    
    angle = temp.toInt();    //把变量字符串类型转成整型
    Serial.println(angle);  //输出数据到串口上,以便观察
   }
  temp = "";//请看临时变量
  myservo.write(angle);  //控制舵机转动相应的角度。
  delay(100);//延时100毫秒
}

在这里插入图片描述

1.使用一块PCA9685,控制一个舵机转动

1.1实物演示过程:

请添加图片描述

1.2代码:


#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN  125 
#define SERVOMAX  575 
uint8_t servonum = 0;
void setup() {
    
    
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");
  pwm.begin();
  pwm.setPWMFreq(60); 
}
void loop() {
    
    
  for( int angle =0; angle<181; angle +=20){
    
    
    delay(500);
    pwm.setPWM(0, 0, angleToPulse(angle) );
  }
  delay(1000);
}
int angleToPulse(int ang){
    
    
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);
   Serial.print("Angle: ");Serial.print(ang);
   Serial.print(" pulse: ");Serial.println(pulse);
   return pulse;
}

 

1.3带注释代码:


#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40 通过这种方式调用,它使用默认地址0x40通过这种方式调用,它使用默认地址0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
// 你也可以调用它与不同的地址,你想Adafruit_PWMServoDriver pwm= Adafruit_PWMServoDriver(0x41);
// 根据您的伺服制造,脉冲宽度最小和最大可能会有所不同,您希望这些尽可能小/大,而不击中最大范围的硬停止。
// 你将不得不调整他们作为必要的配合你的伺服!
#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096) 这是“最小”脉冲长度计数(4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)这是“大”脉冲长度计数(4096)
// our servo # counter 我们的伺服计数器
uint8_t servonum = 0;
void setup() {
    
    
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");
  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates 模拟伺服运行在~ 60hz更新
  //yield();
}

void loop() {
    
    
  for( int angle =0; angle<181; angle +=20){
    
    
    delay(500);
    pwm.setPWM(0, 0, angleToPulse(angle) );
  }
  delay(1000);
}
/*
 * angleToPulse(int ang)
 * gets angle in degree and returns the pulse width
 * also prints the value on seial monitor
 */
int angleToPulse(int ang){
    
    
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max  映射角度0到180伺服min和伺服max
   Serial.print("Angle: ");Serial.print(ang);
   Serial.print(" pulse: ");Serial.println(pulse);
   return pulse;
}

 

1.4另外一种实现代码

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)
// our servo # counter
uint8_t servonum = 0;
void setup() {
    
    
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");

  pwm.begin();
  
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

  //yield();
}

void loop() {
    
    

    pwm.setPWM(0, 0, 125 );
  delay(500);
    pwm.setPWM(0, 0, 255 );
  delay(500);
    pwm.setPWM(0, 0, 450 );
  delay(500);
    pwm.setPWM(0, 0, 575 );
  delay(500); 

}

2.使用一块PCA9685,控制十六个舵机,实现十六个舵机的依次转动

2.1实物演示过程:

请添加图片描述

2.2代码:

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN  150 
#define SERVOMAX  600 
#define USMIN  600 
#define USMAX  2400 
#define SERVO_FREQ 50 
uint8_t servonum = 0;
void setup() {
    
    
  Serial.begin(9600);
  Serial.println("8 channel Servo test!");
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ); 
  delay(10);
}
void setServoPulse(uint8_t n, double pulse) {
    
    
  double pulselength;
  pulselength = 1000000;   
  pulselength /= SERVO_FREQ;   
  Serial.print(pulselength); Serial.println(" us per period"); 
  pulselength /= 4096;  
  Serial.print(pulselength); Serial.println(" us per bit"); 
  pulse *= 1000000;  
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}
void loop() {
    
    
  Serial.println(servonum);
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    
    
    pwm.setPWM(servonum, 0, pulselen);
  }
  delay(500);
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    
    
    pwm.setPWM(servonum, 0, pulselen);
  }
  delay(500);
  for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
    
    
    pwm.writeMicroseconds(servonum, microsec);
  }

  delay(500);
  for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
    
    
    pwm.writeMicroseconds(servonum, microsec);
  }
  delay(500);
  servonum++;
  if (servonum > 7) servonum = 0; 
}

2.3带注释的代码:


/*************************************************** 
  This is an example for our Adafruit 16-channel PWM & Servo driver
  Servo test - this will drive 8 servos, one after the other on the
  first 8 pins of the PCA9685
  这是我们的Adafruit 16通道PWM和伺服驱动器伺服测试的一个例子-这将驱动8个伺服,一个接一个在PCA9685的前8引脚上
  Pick one up today in the adafruit shop! 今天去adafruit店买一个吧
  ------> http://www.adafruit.com/products/815
  These drivers use I2C to communicate, 2 pins are required to  
  interface.
  #这些驱动程序使用I2C进行通信,需要2个引脚进行接口。
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!
  #Adafruit投入了时间和资源来提供这个开放源代码,请通过购买Adafruit的产品来支持Adafruit和开源硬件
  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
  #由Limor Fried/Ladyada为Adafruit Industries编写。BSD许可,以上所有文本必须包含在任何重分发中
 ****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

  // called this way, it uses the default address 0x40 #通过这种方式调用,它使用默认地址0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
  // you can also call it with a different address you want #你也可以用你想要的另一个地址打电话
  //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
  // you can also call it with a different address and I2C interface #你也可以用不同的地址和I2C接口调用它
  //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);
  // Depending on your servo make, the pulse width min and max may vary, you 
  // want these to be as small/large as possible without hitting the hard stop
  // #根据您的伺服制造,脉冲宽度最小和最大可能会有所不同,您希望这些尽可能小/大
  // for max range. You'll have to tweak them as necessary to match the servos you have!
  // #而不击中硬停止最大范围。您必须根据需要调整它们以匹配您拥有的伺服!

#define SERVOMIN  150 // This is the 'minimum' pulse length count (out of 4096) #这是“最小”脉冲长度计数(4096)
#define SERVOMAX  600 // This is the 'maximum' pulse length count (out of 4096) #这是“最大”脉冲长度计数(4096)
#define USMIN  600    // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
                      // #这是基于150最小脉冲的四舍五入的“最小”微秒长度
#define USMAX  2400   // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
                      // #这是基于最大脉冲600的四舍五入的“最大”微秒长度
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates #模拟伺服运行在~50赫兹更新

// our servo # counter #我们的伺服计数器
uint8_t servonum = 0;

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

  pwm.begin();
  /*
   * In theory the internal oscillator (clock) is 25MHz but it really isn't
   * that precise. You can 'calibrate' this by tweaking this number until
   * you get the PWM update frequency you're expecting!
   *  #理论上,内部振荡器(时钟)是25MHz,但它真的没有那么精确。你可以通过调整这个数字“校准”,直到你得到你期待的PWM更新频率!
   * The int.osc. for the PCA9685 chip is a range between about 23-27MHz and
   * is used for calculating things like writeMicroseconds()
   * #int.osc。用于PCA9685芯片的是一个大约23-27MHz的范围,用于计算像写微秒()
   * Analog servos run at ~50 Hz updates, It is importaint to use an
   * oscilloscope in setting the int.osc frequency for the I2C PCA9685 chip.
   *  #模拟伺服运行在~ 50hz更新,这是重要的使用示波器设置int。用于I2C PCA9685芯片的osc频率。
   * 1) Attach the oscilloscope to one of the PWM signal pins and ground on
   *    the I2C PCA9685 chip you are setting the value for.
   *    #将示波器连接到PWM信号引脚中的一个,并接地在I2C PCA9685芯片上,您正在设置的值。
   * 2) Adjust setOscillatorFrequency() until the PWM update frequency is the
   *    expected value (50Hz for most ESCs)
   *    #调整setOscillatorFrequency()直到PWM更新频率为期望值(大多数esc为50Hz)
   * Setting the value here is specific to each individual I2C PCA9685 chip and
   * affects the calculations for the PWM update frequency. 
   *  #此处设置的值针对每个I2C PCA9685芯片,会影响PWM更新频率的计算。
   * Failure to correctly set the int.osc value will cause unexpected PWM results
   *  #未能正确设置int.osc值会导致意想不到的PWM结果
   */
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates #模拟伺服运行在~50赫兹更新

  delay(10);
}

// You can use this function if you'd like to set the pulse length in seconds 
// #如果你想设置以秒为单位的脉冲长度,你可以使用这个函数
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. It's not precise!
// #例如setServoPulse(0,0.001)是~1毫秒的脉冲宽度。它并不精确

void setServoPulse(uint8_t n, double pulse) {
    
    
  double pulselength;
  
  pulselength = 1000000;       // 1,000,000 us per second #每秒1,000,000个单位
  pulselength /= SERVO_FREQ;   // Analog servos run at ~60 Hz updates #模拟伺服运行在~ 60hz更新
  Serial.print(pulselength); Serial.println(" us per period"); 
  pulselength /= 4096;         // 12 bits of resolution #12位分辨率
  Serial.print(pulselength); Serial.println(" us per bit"); 
  pulse *= 1000000;            // convert input seconds to us #将输入秒转换为我们
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}

void loop() {
    
    
  // Drive each servo one at a time using setPWM() #使用setPWM()一次驱动每个伺服
  Serial.println(servonum);
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    
    
    pwm.setPWM(servonum, 0, pulselen);
  }

  delay(500);
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    
    
    pwm.setPWM(servonum, 0, pulselen);
  }

  delay(500);

  // Drive each servo one at a time using writeMicroseconds(), it's not precise due to calculation rounding!
  // #每次使用writemmicroseconds()驱动每个伺服,由于计算舍入不精确每次使用writemmicroseconds()驱动每个伺服,
  // #由于计算舍入不精确每次使用writemmicroseconds()驱动每个伺服,由于计算舍入不精确
  // The writeMicroseconds() function is used to mimic the Arduino Servo library writeMicroseconds() behavior. 
  // #writeMicroseconds()函数用于模拟Arduino Servo库的writeMicroseconds()行为。
  writeMicroseconds()
  for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
    
    
    pwm.writeMicroseconds(servonum, microsec);
  }

  delay(500);
  for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
    
    
    pwm.writeMicroseconds(servonum, microsec);
  }

  delay(500);

  servonum++;
  if (servonum > 7) servonum = 0; // Testing the first 8 servo channels
}

3.使用一块PCA9685,控制十六个舵机,实现十六个舵机的依次转动请添加图片描述#### 3.1代码

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40 通过这种方式调用,它使用默认地址0x40通过这种方式调用,它使用默认地址0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You’ll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN 125 // this is the ‘minimum’ pulse length count (out of 4096)
#define SERVOMAX 575 // this is the ‘maximum’ pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 0;

void setup() {
Serial.begin(9600);
Serial.println(“16 channel Servo test!”);

pwm.begin();

pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates

//yield();
}

void loop() {

for(int i=0; i<16; i++) //这里就是依次控制从0号到15号舵机
{
for( int angle =0; angle<181; angle +=10){ //舵机角度从零开始每50ms增加10度
delay(50);
pwm.setPWM(i, 0, angleToPulse(angle) );//舵机角度置零
}
}

delay(1000);// wait for 1 second

}

/*
/* angleToPulse(int ang)

  • @brief gets angle in degree and returns the pulse width
  • @param “ang” is integer represending angle from 0 to 180
  • @return returns integer pulse width
  • Usage to use 65 degree: angleToPulse(65);
    */

int angleToPulse(int ang){
int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
Serial.print("Angle: “);Serial.print(ang);
Serial.print(” pulse: ");Serial.println(pulse);
return pulse;
}
`

4.使用一块PCA9685,控制十六个舵机,实现十六个舵机的同时转动

/*
 * Original sourse: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
 * 
 * This is the Arduino code PAC6985 16 channel servo controller
 * watch the video for details (V1) and demo http://youtu.be/y8X9X10Tn1k
 *  This code is #3 for V2 Video Watch the video :
 *  I have got 3 codes as follow:https://youtu.be/bal2STaoQ1M
 *  
   #1-Arduino Code to run one by one all servos from 0 to 180°   
   #2-Arduino Code to control specific servos with specific angle
   #3-Arduino Code to run 2 or all servos at together
   
 * Written/updated by Ahmad Shamshiri for Robojax Video channel www.Robojax.com
 * Date: Dec 16, 2017, in Ajax, Ontario, Canada
 * Permission granted to share this code given that this
 * note is kept with the code.
 
  * Watch video for this code: 
 * 
 * Related Videos
V5 video of PCA9685 32 Servo with ESP32 with WiFi https://youtu.be/bvqfv-FrrLM
V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
V3 video of PCA9685 how to control 32 Servo motors https://youtu.be/6P21wG7N6t4
V2 Video of PCA9685 3 different ways to control Servo motors: https://youtu.be/bal2STaoQ1M
V1 Video introduction to PCA9685 to control 16 Servo  https://youtu.be/y8X9X10Tn1k

 * Disclaimer: this code is "AS IS" and for educational purpose only.
 * this code has been downloaded from http://robojax.com/learn/arduino/
 
 * Get this code and other Arduino codes from Robojax.com
Learn Arduino step by step in structured course with all material, wiring diagram and library
all in once place. Purchase My course on Udemy.com http://robojax.com/L/?id=62

****************************
Get early access to my videos via Patreon and have  your name mentioned at end of very 
videos I publish on YouTube here: http://robojax.com/L/?id=63 (watch until end of this video to list of my Patrons)
****************************

or make donation using PayPal http://robojax.com/L/?id=64

 *  * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been download from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
// Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 0;

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

  pwm.begin();
  
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

  //yield();
}

// the code inside loop() has been updated by Robojax
void loop() {
    
    

    //watch video for details: https://youtu.be/bal2STaoQ1M
    for( int angle =0; angle<181; angle +=10){
    
    
      delay(50);
      for(int i=0; i<16; i++)
        {
    
          
          pwm.setPWM(i, 0, angleToPulse(angle) );
        }
    }
 

  
// robojax PCA9865 16 channel Servo control
  delay(1000);
 
}

/*
 * angleToPulse(int ang)
 * gets angle in degree and returns the pulse width
 * also prints the value on seial monitor
 * written by Ahmad Shamshiri for Robojax, Robojax.com
 */
int angleToPulse(int ang){
    
    
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max 
   Serial.print("Angle: ");Serial.print(ang);
   Serial.print(" pulse: ");Serial.println(pulse);
   return pulse;
}

5.使用一块PCA9685,控制三十二个舵机,实现三十二个舵机的同时转动

 /*
 * Original sourse: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
 * 
 * This is the Arduino code PCA6985 16 channel servo controller
 * to control 32 Servo Motors
 * This is V3 Video on PCA9685: https://youtu.be/6P21wG7N6t4
 * 
 * watch the video for details (V1) and demo http://youtu.be/y8X9X10Tn1k
 * Watch Video V2 :https://youtu.be/bal2STaoQ1M
 *  
   
 * Written/updated by Ahmad Shamshiri for Robojax Video channel www.Robojax.com
 * Date: Dec 15, 2019, in Ajax, Ontario, Canada

 * Watch video for this code: 
 * 
 * Related Videos
V5 video of PCA9685 32 Servo with ESP32 with WiFi https://youtu.be/bvqfv-FrrLM
V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
V3 video of PCA9685 how to control 32 Servo motors https://youtu.be/6P21wG7N6t4
V2 Video of PCA9685 3 different ways to control Servo motors: https://youtu.be/bal2STaoQ1M
V1 Video introduction to PCA9685 to control 16 Servo  https://youtu.be/y8X9X10Tn1k
 * Disclaimer: this code is "AS IS" and for educational purpose only.
 * this code has been downloaded from http://robojax.com/learn/arduino/
 
 * Get this code and other Arduino codes from Robojax.com
Learn Arduino step by step in structured course with all material, wiring diagram and library
all in once place. Purchase My course on Udemy.com http://robojax.com/L/?id=62

****************************
Get early access to my videos via Patreon and have  your name mentioned at end of very 
videos I publish on YouTube here: http://robojax.com/L/?id=63 (watch until end of this video to list of my Patrons)
****************************

or make donation using PayPal http://robojax.com/L/?id=64

 *  * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been download from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
// Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)


int servoNumber = 0;

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

  board1.begin();
  board2.begin();  
  board1.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
  board2.setPWMFreq(60);
  //yield();
}

// the code inside loop() has been updated by Robojax
void loop() {
    
    


    for( int angle =0; angle<181; angle +=10){
    
    
      for(int i=0; i<16; i++)
        {
    
          
            board2.setPWM(i, 0, angleToPulse(angle) );
            board1.setPWM(i, 0, angleToPulse(angle) );
        }
    }
  
// robojax PCA9865 16 channel Servo control
  delay(100);
 
}

/*
 * angleToPulse(int ang)
 * gets angle in degree and returns the pulse width
 * also prints the value on seial monitor
 * written by Ahmad Nejrabi for Robojax, Robojax.com
 */
int angleToPulse(int ang){
    
    
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max 
   Serial.print("Angle: ");Serial.print(ang);
   Serial.print(" pulse: ");Serial.println(pulse);
   return pulse;
}
 

参考:http://robojax.com/learn/arduino/

猜你喜欢

转载自blog.csdn.net/qq_44649945/article/details/127831203