|
本帖最后由 cj52 于 2019-4-19 00:06 編輯
前段時(shí)間在知乎上看到有用Arduino做機(jī)械臂的,自己也做了一個(gè)來(lái)玩玩。
基本原理很簡(jiǎn)單,就是電位器(藍(lán)白可調(diào)電阻)來(lái)控制舵機(jī)。
制作2個(gè)機(jī)械臂,從機(jī)械臂的關(guān)節(jié)處用電位器接合,主機(jī)械臂用舵機(jī),將電位器的電壓與舵機(jī)的角度相映射就能讓舵機(jī)與電位器同步運(yùn)作。
學(xué)習(xí)的具體內(nèi)容見(jiàn)代碼,基本上就是記錄學(xué)習(xí)過(guò)程中的幾個(gè)主要?jiǎng)幼,然后根?jù)這些主要?jiǎng)幼鱽?lái)模糊推測(cè)大動(dòng)作之間的小動(dòng)作。
制作出來(lái)的實(shí)物圖如下:
IMG_20190411_080243.jpg (3.25 MB, 下載次數(shù): 204)
下載附件
2019-4-15 18:01 上傳
視頻效果自取鏈接:https://pan.baidu.com/s/1gRzXL1DkdWBaYyxTWxKEyA 提取碼:g9su
https://pan.baidu.com/s/1ngaNVAzMBjx2wjF1jojfbw 提取碼:2vh6
https://pan.baidu.com/s/1vqZn4FpYyzftkw7iwNzFrA 提取碼:cndx
第二個(gè)視頻中主機(jī)械臂出現(xiàn)突變是因?yàn)閺臋C(jī)械臂的電位器接觸不良。
*******************************************************************************
Arduino源程序如下:
#include <Servo.h>
Servo servo_0; //定義4個(gè)舵機(jī)
Servo servo_1;
Servo servo_2;
Servo servo_3;
int sensorPin0 = A0; //電位器阻值輸入口
int sensorPin1 = A1;
int sensorPin2 = A2;
int sensorPin3 = A3;
int SensVal_0;
int SensVal_1;
int SensVal_2;
int SensVal_3;
boolean playmode = false; //設(shè)置運(yùn)行模式,初始化為學(xué)習(xí)
float angle0[30];// 存儲(chǔ)底座舵機(jī)動(dòng)作的數(shù)組,最多存30個(gè)
float angle1[30];//手臂舵機(jī)角度數(shù)組
float angle2[30];//手掌舵機(jī)角度數(shù)組
float angle3[30];//夾子舵機(jī)角度數(shù)組
float dif[4],temp[4];// 差分值與中間數(shù)組
int i,j,k,stepsMax,num=0,key_value,num1=0,del;
void setup() {
// put your setup code here, to run once:
pinMode(4, INPUT); // 鍵盤(pán)輸入口
servo_0.attach(6); // 連接舵機(jī)
servo_1.attach(9);
servo_2.attach(10);
servo_3.attach(11);
Serial.begin(115200);
}
void loop()
{
// put your main code here, to run repeatedly:
if(playmode == false) //學(xué)習(xí)模式
{
SensVal_1 = analogRead(sensorPin1); //讀取電位器阻值
//Serial.println(SensVal_1);
SensVal_1 = map(SensVal_1, 0, 1024, 500, 2500);//將電位器阻值與舵機(jī)角度映射,實(shí)現(xiàn)兩個(gè)機(jī)械臂的同步
SensVal_0 = analogRead(sensorPin0);
//Serial.println(SensVal_0);
SensVal_0 = map(SensVal_0, 0, 1024, 500, 2500);
SensVal_2 = analogRead(sensorPin2);
//Serial.println(SensVal_2);
SensVal_2 = map(SensVal_2, 0, 1024, 500, 2500);
SensVal_3 = analogRead(sensorPin3);
//Serial.println(SensVal_3);
SensVal_3 = map(SensVal_3, 0, 1024, 500, 2500);
servo_0.writeMicroseconds(SensVal_0); //控制主機(jī)械臂跟隨從機(jī)械臂運(yùn)行
servo_1.writeMicroseconds(SensVal_1);
servo_2.writeMicroseconds(SensVal_2);
servo_3.writeMicroseconds(SensVal_3);
}
else //運(yùn)行模式
{
for(i=0;i<num;i++)
{
temp[0]=angle0; //暫存當(dāng)前動(dòng)作角度值
temp[1]=angle1;
temp[2]=angle2;
temp[3]=angle3;
j=i+1; //指向下一個(gè)動(dòng)作
if(j==num) j=0;
dif[0] = abs(angle0[j]-angle0); //下一動(dòng)作與當(dāng)前動(dòng)作做差分
dif[1] = abs(angle1[j]-angle1);
dif[2] = abs(angle2[j]-angle2);
dif[3] = abs(angle3[j]-angle3);
stepsMax = max(dif[0],dif[1]); //找出最大差分值
stepsMax = max(stepsMax,dif[2]);
stepsMax = max(stepsMax,dif[3]);
//將兩個(gè)動(dòng)作分為最大差分值個(gè)小動(dòng)作,即用每個(gè)舵機(jī)的差分值除以最大差分值
if (angle0[j] < angle0) dif[0] = 0-dif[0]/stepsMax; else dif[0] = dif[0]/stepsMax;
if (angle1[j] < angle1) dif[1] = 0-dif[1]/stepsMax; else dif[1] = dif[1]/stepsMax;
if (angle2[j] < angle2) dif[2] = 0-dif[2]/stepsMax; else dif[2] = dif[2]/stepsMax;
if (angle3[j] < angle3) dif[3] = 0-dif[3]/stepsMax; else dif[3] = dif[3]/stepsMax;
for(k=0;k<stepsMax;k++) // 運(yùn)行至下一大動(dòng)作
{
//Serial.println("stepin");
angle0 += dif[0]; //運(yùn)行到下一小動(dòng)作
angle1 += dif[1];
angle2 += dif[2];
angle3 += dif[3];
servo_0.writeMicroseconds(angle0);
servo_1.writeMicroseconds(angle1);
servo_2.writeMicroseconds(angle2);
servo_3.writeMicroseconds(angle3);
delay(1);
}
//Serial.println("stepout");
angle0=temp[0]; //返回暫存的動(dòng)作值
angle1=temp[1];
angle2=temp[2];
angle3=temp[3];
}
}
//Serial.println(digitalRead(4));
Button(); //按鍵檢測(cè)
}
void Button() //按鍵檢測(cè)
{
if (digitalRead(4) == true)
{
delay(20); //消抖
if (digitalRead(4) == true)
{
key_value = 1;
delay(1000);
if(digitalRead(4) == true) key_value = 2; //長(zhǎng)按進(jìn)入運(yùn)行模式
}
}
if ((key_value == 1)) // 記錄舵機(jī)當(dāng)前位置
{
angle0[num1]=SensVal_0;
angle1[num1]=SensVal_1;
angle2[num1]=SensVal_2;
angle3[num1]=SensVal_3;
num1++; //指針加1
key_value = 0;
playmode = false;
}
else if (key_value == 2)
{
num = num1; //取出動(dòng)作的總數(shù)
num1=0; //為下一次學(xué)習(xí)做準(zhǔn)備
playmode = true; //運(yùn)行模式
key_value = 0;
}
}
|
評(píng)分
-
查看全部評(píng)分
|