使用Arduino控制机械臂
一. 硬件设备
- 1x DFRdunio UNO Rev3
- 1x Prototyping Shield For Arduino
- 1x USB线 AtoB方口
- 1x DFLG6DOF 6自由度机械臂
二. 控制机械臂
机械臂的实现实质上就是舵机+支架,那么对机械臂的控制本质上就是对舵机的控制,对于6自由度机械臂有六台舵机,每个都是180°范围旋转的。
快速实现(使用Arduino的Servo库)
函数 | 说明 |
---|---|
attach() | 参数为接口引脚号,联系Servo对象与引脚输入 |
write() | 参数为角度,范围在0°~180°,用于控制舵机旋转到一定的角度 |
read() | 读取舵机的角度,输出在串口 |
detach() | 使舵机与接口分离 |
通过如下代码即可快速实现对某一舵机的往返运动
#include <Servo.h>
Servo myservo;
int pos;
void setup()
{
myservo.attach(0);
}
void loop()
{
//舵机运动
for(pos = 0; pos < 180; pos += 1)
{
myservo.write(pos0);
delay(10);
}
delay(1000);
//舵机归位
for(pos = 180; pos > 0; pos -= 1)
{
myservo.write(pos);
delay(10);
}
delay(1000);
}
几个注意点:
- 在运行机械臂之前应该对舵机进行逐个校准,了解每个舵机指定的每个角度大概在什么地方,每个舵机所对应的同一角度很可能不指向同一方向,这个问题由很多原因导致,可能是舵机的机械原因,也可能是在安装机械臂过程中造成的安装角度不一致的原因。
- 不能过分运用write()函数,如下代码:
按道理舵机应该先运动到180°位置,再运动到0°位置,实现往复运动,但根据我的验证,write()函数的触发似乎还要判断步长对于我的舵机,如果步长过大,它就不会运行到指定位置,所以这里我的代码上是通过步长1°逐次实现的。write(180); delay(1000); write(0); delay(1000);
- 当受到外界阻力作用时,舵机可能会停止响应,这点很坑。。。也是制约机械臂性能很大的一部分因素。几个场景:
①由于采取1步长,导致机械臂启停频率较高,每次启停都意味着对阻力的震动会产生,由于机械臂结构单薄,造成震动的传导异常迅速,机械臂支撑不起,经常会受到其他舵机震动的联动导致角度过载,导致舵机停止响应;
②舵机初始角度距离期望运行角度差距过大则不会去响应运行,这其实就是注意点2;
③舵机经常会在一开始不响应。。。需要人为手推一下。
机械臂三自由度抓取运动示例:
#include <Servo.h>
Servo myservo0;
Servo myservo1;
Servo myservo2; // create servo object to control a servo
Servo myservo3;
int pos0,pos1,pos2,pos3 = 0;
void setup()
{
myservo0.attach(0);
myservo1.attach(1);
myservo2.attach(2); // attaches the servo on pin 9 to the servo object
myservo3.attach(3);
}
void loop()
{
// myservo4.writeMicroseconds(0);
// delay(10000);
//取物流程
//底座运动
for(pos0 = 0; pos0 < 90; pos0+= 1)
{
myservo0.write(pos0);
delay(10);
}
delay(1000);
//第一舵机运动
for(pos1 = 0; pos1 < 10; pos1+= 1)
{
myservo1.write(pos1);
delay(10);
}
delay(1000);
//第二舵机运动
for(pos2 = 30; pos2 < 150; pos2 += 1)
{
myservo2.write(pos2);
delay(10);
}
delay(1000);
//爪夹运动
for(pos3 = 180;pos3 > 0; pos3 -=1)
{
myservo3.write(pos3);
delay(10);
}
delay(1000);
//爪夹夹紧
for(pos3 = 0; pos3 < 180; pos3 += 1)
{
myservo3.write(pos3);
delay(10);
}
delay(1000);
//第二舵机归位
for(pos2 = 150; pos2 > 30; pos2 -= 1)
{
myservo2.write(pos2);
delay(10);
}
delay(1000);
//第一舵机归位
for(pos1 = 10; pos1 > 0; pos1-= 1)
{
myservo1.write(pos1);
delay(10);
}
delay(1000);
//底座归位
for(pos0 = 90; pos0 > 0; pos0-= 1)
{
myservo0.write(pos0);
delay(10);
}
delay(1000);
}
效果还行,但是机械臂时常需要手动防倒。。。可能还是机械臂太便宜了。。。。
手动实现,不通过库函数
待学习…