舵机+16路舵机驱动板+Arduino UNO机械臂测试代码解析

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了舵机+16路舵机驱动板+Arduino UNO机械臂测试代码解析相关的知识,希望对你有一定的参考价值。

舵机+16路舵机驱动板+Arduino UNO机械臂测试代码解析

  • 程序源码:
// the setup function runs once when you press reset or power the board
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver servo_pmw;//实例化舵机库结构体对象
int j = 0;
String comdata = "";
int numdata[6] = { 0 }, SERVO_PIN[6] = { 0, 1, 2, 3, 4, 5 }, mark = 0;
 
void setup() {
    pinMode(13, OUTPUT);
    Serial.begin(9600);
    servo_pmw.begin();
    servo_pmw.setPWMFreq(50);
    servo_xiaozun();
    delay(1000);
    servo_dakai();
}
 
// the loop function runs over and over again until power down or reset
void loop() {
    zhuaqu();
}
 
//抓取动作
void zhuaqu()
{
    servo_pmw.setPWM(0, 0, 307);
    delay(1000);
    servo_pmw.setPWM(4, 0, 150);
    delay(1000);
    servo_pmw.setPWM(1, 0, 152);
    delay(1000);
    servo_pmw.setPWM(2, 0, 204);
    delay(1000);
    servo_pmw.setPWM(4, 0, 210);
    delay(1000);
    servo_pmw.setPWM(2, 0, 250);
    delay(1000);
    servo_pmw.setPWM(1, 0, 260);
    delay(1000);
    servo_pmw.setPWM(0, 0, 104);
    delay(1000);
    servo_pmw.setPWM(1, 0, 155);
    delay(1000);
    servo_pmw.setPWM(2, 0, 204);
    delay(1000);
    servo_pmw.setPWM(4, 0, 150);
    delay(1000);
    servo_pmw.setPWM(2, 0, 250);
    delay(1000);
    servo_pmw.setPWM(1, 0, 260);
    delay(10000);
}
 
//底座舵机最大旋转范围
void cs0()
{
    servo_pmw.setPWM(0, 0, 70);
    delay(5000);
    servo_pmw.setPWM(0, 0, 408);
    delay(5000);
}
 
//摇臂1最大可旋转范围
void cs1()
{
    servo_pmw.setPWM(1, 0, 307);
    delay(5000);
    servo_pmw.setPWM(1, 0, 204);
    delay(5000);
}
//摇臂2最大可旋转范围
void cs2()
{
    servo_pmw.setPWM(2, 0, 320);
    delay(5000);
    servo_pmw.setPWM(2, 0, 130);
    delay(5000);
}
 
//旋转臂最大可旋转范围
void cs3()
{
    servo_pmw.setPWM(3, 0, 120);
    delay(3000);
    servo_pmw.setPWM(3, 0, 370);
    delay(3000);
}
//夹持最大可张开范围
void cs4()
{
    servo_pmw.setPWM(4, 0, 210);  //关闭
    delay(3000);
    servo_pmw.setPWM(4, 0, 150);  //打开
    delay(3000);
}
 
//启动缩回机械臂
void servo_xiaozun()
{
    servo_pmw.setPWM(0, 0, 307);
    delay(500);
    servo_pmw.setPWM(1, 0, 307);
    delay(500);
    servo_pmw.setPWM(2, 0, 90);
    delay(500);
    servo_pmw.setPWM(3, 0, 120);
    delay(500);
    servo_pmw.setPWM(4, 0, 200);
    delay(500);
}
 
//启动伸展机械臂
void servo_dakai()
{
    servo_pmw.setPWM(0, 0, 204);
    delay(500);
    servo_pmw.setPWM(1, 0, 204);
    delay(500);
    servo_pmw.setPWM(2, 0, 330);
    delay(500);
    servo_pmw.setPWM(3, 0, 130);
    delay(500);
    servo_pmw.setPWM(4, 0, 150);
    delay(500);
}
 
//调试用
void servo_0()
{
    servo_pmw.setPWM(0, 0, 103);
    servo_pmw.setPWM(1, 0, 103);
    servo_pmw.setPWM(2, 0, 103);
    servo_pmw.setPWM(3, 0, 103);
    servo_pmw.setPWM(4, 0, 103);
}
 
//调试用
void servo_300()
{
    servo_pmw.setPWM(0, 0, 408);
    servo_pmw.setPWM(1, 0, 408);
    servo_pmw.setPWM(2, 0, 408);
    servo_pmw.setPWM(3, 0, 408);
    servo_pmw.setPWM(4, 0, 408);
}
 
 
//调试用
void serial_read()
{
    while (Serial.available() > 0)
    {//读取串口信息
        comdata += char(Serial.read());//接收并存储串口收到的字符串数据
        //Serial.read()每次只能读一个字节,所以需要累加读取
        //Serial.readString()将字符从串行缓冲区读取到字符串中。如果超时(默认超时时间为 1000 毫秒),该功能将终止
        //Serial.setTimeout()设置最大毫秒以等待串行数据。它默认为 1000 毫秒.
        delay(2);
        mark = 1;//接收到数据设置的标志位
    }
 
    if (mark == 1)
    {//标志位成立执行以下语句
        Serial.println(comdata);
        Serial.println(comdata.length());
        for (int i = 0; i < comdata.length(); i++)
        {
            if (comdata[i] == ',')
            {
                j++;
            }
            else
            {
                numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
                //将ASCII值转换为整数值
            }
            comdata = String("");//清空接收到的数据,等待下一次数据接收存放。
            mark = 0;//将标志位置零
        }
        for (int i = 0; i < 6; i++)
        {
            Serial.print(SERVO_PIN[i]);
            Serial.print("---");
            Serial.println(numdata[i]);
            servo_pmw.setPWM(SERVO_PIN[i], 0, numdata[i]);
            numdata[i] = 0;//清空接收到的数据,等待下一次数据接收存放。
        }
    }
}
涉及到的函数
  • Serial.read()

从串口的缓冲区取出并读取一个Byte的数据,比如有设备通过串口向Arduino发送数据了,我们就可以用Serial.read()来读取发送的数据。

  • Serial.available()

返回串口缓冲区中当前剩余的字符个数。一般用这个函数来判断串口的缓冲区有无数据,当Serial.available()>0时,说明串口接收到了数据,可以读取;

  • comdata[i] - '0',字符转整形数据类型的方法。

上述示例代码中的comdata[i] 是String(数据类型)组成的数字字符,0,1,2,3,4,5,6,7,8,9, 减去字符 0 的 ASCII 值, 正好变成 整型量 (int) 0,1,2,3,4,5,6,7,8,9,
0-9对应的ASCII码:
在这里插入图片描述

以上是关于舵机+16路舵机驱动板+Arduino UNO机械臂测试代码解析的主要内容,如果未能解决你的问题,请参考以下文章

Arduino控制16路PWM舵机驱动板(PCA9685)

Proteus仿真Arduino UNO +PCA9685 16路舵机控制

arduino驱动16路舵机

Arduino机械臂的板子是店家改过的我初学者看不懂求助大佬

Arduino UNO舵机仿真实验

Arduino机械臂的板子是店家改过的我初学者看不懂求助大佬