国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

做網(wǎng)站 需要多少錢(qián)邯鄲seo營(yíng)銷(xiāo)

做網(wǎng)站 需要多少錢(qián),邯鄲seo營(yíng)銷(xiāo),上海平臺(tái)網(wǎng)站制作公司哪家好,特種作業(yè)操作證查詢(xún)?nèi)肟诓樵?xún)重要的內(nèi)容寫(xiě)在前面: 該系列是以u(píng)p主太極創(chuàng)客的零基礎(chǔ)入門(mén)學(xué)用Arduino教程為基礎(chǔ)制作的學(xué)習(xí)筆記。個(gè)人把這個(gè)教程學(xué)完之后,整體感覺(jué)是很好的,如果有條件的可以先學(xué)習(xí)一些相關(guān)課程,學(xué)起來(lái)會(huì)更加輕松,相關(guān)課程有數(shù)字電路…

重要的內(nèi)容寫(xiě)在前面:

  1. 該系列是以u(píng)p主太極創(chuàng)客的零基礎(chǔ)入門(mén)學(xué)用Arduino教程為基礎(chǔ)制作的學(xué)習(xí)筆記。
  2. 個(gè)人把這個(gè)教程學(xué)完之后,整體感覺(jué)是很好的,如果有條件的可以先學(xué)習(xí)一些相關(guān)課程,學(xué)起來(lái)會(huì)更加輕松,相關(guān)課程有數(shù)字電路(強(qiáng)烈推薦先學(xué)數(shù)電,不然可能會(huì)有一些地方理解起來(lái)很困難)、模擬電路等,然后就是C++(注意C++是必學(xué)的)。
  3. 文章中的代碼都是跟著老師邊學(xué)邊敲的,不過(guò)比起老師的版本我還把注釋寫(xiě)得詳細(xì)了些,并且個(gè)人認(rèn)為重要的地方都有詳細(xì)的分析。
  4. 一些函數(shù)的介紹有參考太極創(chuàng)客官網(wǎng)給出的中文翻譯,為了便于現(xiàn)查現(xiàn)用,把個(gè)人認(rèn)為重要的部分粘貼了過(guò)來(lái)并做了一些修改。
  5. 如有錯(cuò)漏歡迎指正。

視頻鏈接:2-1 MeArm項(xiàng)目概述_嗶哩嗶哩_bilibili

太極創(chuàng)客官網(wǎng):太極創(chuàng)客 – Arduino, ESP8266物聯(lián)網(wǎng)的應(yīng)用、開(kāi)發(fā)和學(xué)習(xí)資料

四、開(kāi)發(fā)機(jī)械臂程序

1、準(zhǔn)備工作

(1)電路部分按下圖所示連接即可。

(2)連接完成后將下面的初始化調(diào)整程序下載到開(kāi)發(fā)板中,讓舵機(jī)轉(zhuǎn)軸轉(zhuǎn)到規(guī)定的初始位置。

#include <Servo.h> Servo base, rArm, fArm, claw ; ?//建立4個(gè)舵機(jī)對(duì)象void setup() 
{ base.attach(11); ? ? // base 伺服舵機(jī)連接引腳11 舵機(jī)代號(hào)'b'rArm.attach(10); ? ? // rArm 伺服舵機(jī)連接引腳10 舵機(jī)代號(hào)'r'fArm.attach(9); ? ? ?// fArm 伺服舵機(jī)連接引腳9 ?舵機(jī)代號(hào)'f'claw.attach(6); ? ? ?// claw 伺服舵機(jī)連接引腳6 ?舵機(jī)代號(hào)'c'Serial.begin(9600);
} 
void loop() 
{ base.write(90); // 將base(底盤(pán))舵機(jī)設(shè)置為初始位置delay(100);rArm.write(90); // 將rArm(后臂)舵機(jī)設(shè)置為初始位置delay(100);fArm.write(90); // 將fArm(前臂)舵機(jī)設(shè)置為初始位置delay(100);claw.write(90); // 將claw(鉗子)舵機(jī)設(shè)置為初始位置delay(3000); 
} 

(3)將4個(gè)MeArm舵機(jī)搖臂按以下示意圖裝配到舵機(jī)上。在MeArm機(jī)械臂安裝過(guò)程中不要讓調(diào)整好的舵機(jī)搖臂轉(zhuǎn)動(dòng),如不小心轉(zhuǎn)動(dòng)了已經(jīng)調(diào)整好的舵機(jī)搖臂,需要將搖臂恢復(fù)圖示狀態(tài)或使用MeArm舵機(jī)初始化調(diào)整程序再次對(duì)舵機(jī)進(jìn)行初始化調(diào)整。

(4)根據(jù)圖紙或說(shuō)明書(shū)或視頻教程安裝機(jī)械臂,安裝完畢后查看電路連接是否出現(xiàn)問(wèn)題(比如正負(fù)極短接、舵機(jī)引線(xiàn)接錯(cuò)、舵機(jī)未與Arduino共地等問(wèn)題),然后再運(yùn)行調(diào)試程序,看看機(jī)械臂會(huì)不會(huì)產(chǎn)生異動(dòng)或者異響,及時(shí)調(diào)整舵機(jī)搖臂的位置或者更換有問(wèn)題的舵機(jī)。

2、通過(guò)串口控制機(jī)械臂(一步到位)

(1)連接完成后將下面的程序下載到開(kāi)發(fā)板中。

①全局變量及包含的頭文件:

#include <Servo.h> ? ? ? ? ? ? ? ?//使用servo庫(kù)
Servo base, fArm, rArm, claw ; ? ?//創(chuàng)建4個(gè)servo對(duì)象
//建立4個(gè)int型變量存儲(chǔ)當(dāng)前電機(jī)角度值,初始角度值為設(shè)備啟動(dòng)后初始狀態(tài)所需要的電機(jī)角度數(shù)值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;
//存儲(chǔ)電機(jī)極限值(const指定該數(shù)值為常量,常量數(shù)值在程序運(yùn)行中不能改變)
const int baseMIN = 0;
const int baseMAX = 180;
const int rArmMIN = 45;
const int rArmMAX = 180;
const int fArmMIN = 35;
const int fArmMAX = 120;
const int clawMIN = 25;
const int clawMAX = 100;

②初始化工作部分:

void setup()
{base.attach(11); ? ? // base 伺服舵機(jī)連接引腳11 舵機(jī)代號(hào)'b'delay(200); ? ? ? ? ?// 穩(wěn)定性等待rArm.attach(10); ? ? // rArm 伺服舵機(jī)連接引腳10 舵機(jī)代號(hào)'r'delay(200); ? ? ? ? ?// 穩(wěn)定性等待fArm.attach(9); ? ? ?// fArm 伺服舵機(jī)連接引腳9 ?舵機(jī)代號(hào)'f'delay(200); ? ? ? ? ?// 穩(wěn)定性等待claw.attach(6); ? ? ?// claw 伺服舵機(jī)連接引腳6 ?舵機(jī)代號(hào)'c'delay(200); ? ? ? ? ?// 穩(wěn)定性等待Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial."); ? 
}

③循環(huán)工作部分:

void loop()
{//使用串口監(jiān)視器輸入電機(jī)指令控制機(jī)械臂電機(jī)if (Serial.available() > 0) { //指令舉例: b45,將底盤(pán)舵機(jī)調(diào)整到45度位置char serialCmd = Serial.read(); ?//獲取串口接收緩存中的一個(gè)字符armDataCmd(serialCmd); ? ? ? ? ? //更改所記錄的“當(dāng)前舵機(jī)角度”}//根據(jù)記錄的當(dāng)前舵機(jī)角度進(jìn)行設(shè)置base.write(basePos);delay(10);fArm.write(fArmPos); delay(10);rArm.write(rArmPos); delay(10);claw.write(clawPos); ?delay(10); ? 
}

④更改所記錄的“當(dāng)前舵機(jī)角度”:

void armDataCmd(char serialCmd)
{Serial.print("serialCmd = ");Serial.print(serialCmd); ?int servoData = Serial.parseInt(); ? //獲取串口接收緩存中的整數(shù)數(shù)據(jù)作為角度值switch(serialCmd) ? ?//根據(jù)命令的第一個(gè)字符判斷需要控制哪個(gè)舵機(jī){case 'b': ?if(servoData > baseMAX) servoData = baseMAX; ?//判斷是否越上界if(servoData < baseMIN) servoData = baseMIN; ?//判斷是否越下界basePos = servoData; ?//更改當(dāng)前舵機(jī)角度Serial.print(" ?Set base servo value: ");Serial.println(servoData);break;case 'c': ?if(servoData > clawMAX) servoData = clawMAX; ?//判斷是否越上界if(servoData < clawMIN) servoData = clawMIN; ?//判斷是否越下界clawPos = servoData; ?//更改當(dāng)前舵機(jī)角度Serial.print(" ?Set claw servo value: ");Serial.println(servoData);break;case 'f': ?if(servoData > fArmMAX) servoData = fArmMAX; ?//判斷是否越上界if(servoData < fArmMIN) servoData = fArmMIN; ?//判斷是否越下界fArmPos = servoData; ?//更改當(dāng)前舵機(jī)角度Serial.print(" ?Set fArm servo value: ");Serial.println(servoData);break;case 'r': ?if(servoData > rArmMAX) servoData = rArmMAX; ?//判斷是否越上界if(servoData < rArmMIN) servoData = rArmMIN; ?//判斷是否越下界rArmPos = servoData; ?//更改當(dāng)前舵機(jī)角度Serial.print(" ?Set rArm servo value: ");Serial.println(servoData);break;case 'o': ?reportStatus();break;default:Serial.println(" Unknown Command.");} ?
}
void reportStatus()
{Serial.println("");Serial.println("");Serial.println("++++++ Robot-Arm Status Report +++++");Serial.print("Claw Position: clawPos = "); Serial.println(claw.read());Serial.print("Base Position: basePos = "); Serial.println(base.read());Serial.print("Rear ?Arm Position: rArmPos = "); Serial.println(rArm.read());Serial.print("Front Arm Position: fArmPos = "); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++++++++++++");Serial.println("");
}

(2)然后進(jìn)行人工調(diào)試。

①通過(guò)串口助手向Arduino發(fā)送內(nèi)容“b45”,機(jī)械臂的base舵機(jī)搖臂將立刻旋轉(zhuǎn)至45°的位置,同理可調(diào)試其它3個(gè)舵機(jī)。

②通過(guò)串口助手向Arduino發(fā)送內(nèi)容“b200”,由于200°超出base舵機(jī)的上界180°,機(jī)械臂的base舵機(jī)搖臂將立刻旋轉(zhuǎn)至上界180°的位置,同理可調(diào)試其它3個(gè)舵機(jī)的上下界。(需要注意的是,上下界指的是機(jī)械臂舵機(jī)能達(dá)到的不損壞機(jī)械臂時(shí)的最大/小角度,這個(gè)角度可以對(duì)四個(gè)舵機(jī)分別進(jìn)行調(diào)試而得出,每個(gè)機(jī)械臂的舵機(jī)旋轉(zhuǎn)上下界可能略有差異,但只要每個(gè)舵機(jī)都經(jīng)過(guò)正確的初始化調(diào)整,差異應(yīng)該是很小的)

3、通過(guò)串口控制機(jī)械臂(有緩慢轉(zhuǎn)動(dòng)的過(guò)程)

(1)在上例中,通過(guò)Arduino直接控制舵機(jī)旋轉(zhuǎn),會(huì)發(fā)現(xiàn)舵機(jī)搖臂旋轉(zhuǎn)的速度非???#xff0c;然而現(xiàn)實(shí)中大多自動(dòng)工作的機(jī)械臂都是緩慢轉(zhuǎn)動(dòng)的,如果每一個(gè)動(dòng)作都是“一氣呵成”,這將增加非常多不必要的麻煩與危險(xiǎn),為了讓機(jī)械臂緩慢轉(zhuǎn)動(dòng),可以將一次大幅度的轉(zhuǎn)動(dòng)分成若干次小幅度的轉(zhuǎn)動(dòng)完成,每次小幅度轉(zhuǎn)動(dòng)間隔一定的時(shí)間,這樣即可實(shí)現(xiàn)機(jī)械臂的緩慢轉(zhuǎn)動(dòng)。

(2)連接完成后將下面的初始化調(diào)整程序下載到開(kāi)發(fā)板中,然后進(jìn)行人工調(diào)試。

①全局變量及包含的頭文件:

#include <Servo.h> ? ? ? ? ? ? ? ?//使用servo庫(kù)
Servo base, fArm, rArm, claw ; ? ?//創(chuàng)建4個(gè)servo對(duì)象
//建立4個(gè)int型變量存儲(chǔ)當(dāng)前電機(jī)角度值,初始角度值為設(shè)備啟動(dòng)后初始狀態(tài)所需要的電機(jī)角度數(shù)值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;
//存儲(chǔ)電機(jī)極限值(const指定該數(shù)值為常量,常量數(shù)值在程序運(yùn)行中不能改變)
const int baseMIN = 0;
const int baseMAX = 180;
const int rArmMIN = 45;
const int rArmMAX = 180;
const int fArmMIN = 35;
const int fArmMAX = 120;
const int clawMIN = 25;
const int clawMAX = 100;

②初始化工作部分:

void setup()
{base.attach(11); ? ? //base 伺服舵機(jī)連接引腳11 舵機(jī)代號(hào)'b'delay(200); ? ? ? ? ?//穩(wěn)定性等待rArm.attach(10); ? ? //rArm 伺服舵機(jī)連接引腳10 舵機(jī)代號(hào)'r'delay(200); ? ? ? ? ?//穩(wěn)定性等待fArm.attach(9); ? ? ?//fArm 伺服舵機(jī)連接引腳9 ?舵機(jī)代號(hào)'f'delay(200); ? ? ? ? ?//穩(wěn)定性等待claw.attach(6); ? ? ?//claw 伺服舵機(jī)連接引腳6 ?舵機(jī)代號(hào)'c'delay(200); ? ? ? ? ?//穩(wěn)定性等待Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial."); ? 
}

③循環(huán)工作部分:

void loop()
{//使用串口監(jiān)視器輸入電機(jī)指令控制機(jī)械臂電機(jī)if (Serial.available() > 0) { //指令舉例: b45,將底盤(pán)舵機(jī)調(diào)整到45度位置char serialCmd = Serial.read(); ?//獲取串口接收緩存中的一個(gè)字符armDataCmd(serialCmd); ? ? ? ? ? //更改所記錄的“當(dāng)前舵機(jī)角度”}//根據(jù)記錄的當(dāng)前舵機(jī)角度進(jìn)行設(shè)置base.write(basePos);delay(10);fArm.write(fArmPos); delay(10);rArm.write(rArmPos); delay(10);claw.write(clawPos); ?delay(10); ? 
}

④更改所記錄的“當(dāng)前舵機(jī)角度”:(reportStatus函數(shù)的實(shí)現(xiàn)沿用上例即可)

void armDataCmd(char serialCmd)
{Serial.print("serialCmd = ");Serial.print(serialCmd); ?int servoData = Serial.parseInt(); ?//獲取串口接收緩存中的整數(shù)數(shù)據(jù)作為角度值int fromPos, toPos;switch(serialCmd) ? //根據(jù)命令的第一個(gè)字符判斷需要控制哪個(gè)舵機(jī){case 'b': ?fromPos = base.read(); ? ?//讀取base舵機(jī)的當(dāng)前角度值toPos = servoData; ? ? ? ?//命令中的角度值作為調(diào)整后角度值if(servoData > baseMAX) servoData = baseMAX; ?//判斷是否越上界if(servoData < baseMIN) servoData = baseMIN; ?//判斷是否越下界if (fromPos <= toPos) //如果“起始角度值”小于“目標(biāo)角度值” ,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i<=toPos; i++){base.write(i);delay(15);}else ? ? ? ? ? ? ? ?//否則“起始角度值”大于“目標(biāo)角度值”,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i>=toPos; i--){base.write(i);delay(15);}basePos = servoData;Serial.print(" ?Set base servo value: ");Serial.println(servoData);break;case 'c':fromPos = claw.read(); ? ?//讀取claw舵機(jī)的當(dāng)前角度值toPos = servoData; ? ? ? ?//命令中的角度值作為調(diào)整后角度值if(servoData > clawMAX) servoData = clawMAX; ?//判斷是否越上界if(servoData < clawMIN) servoData = clawMIN; ?//判斷是否越下界if (fromPos <= toPos) //如果“起始角度值”小于“目標(biāo)角度值” ,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i<=toPos; i++){claw.write(i);delay(15);}else ? ? ? ? ? ? ? ?//否則“起始角度值”大于“目標(biāo)角度值”,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i>=toPos; i--){claw.write(i);delay(15);}clawPos = servoData;Serial.print(" ?Set claw servo value: ");Serial.println(servoData);break; ?case 'f': ?fromPos = fArm.read(); ? ?//讀取fArm舵機(jī)的當(dāng)前角度值toPos = servoData; ? ? ? ?//命令中的角度值作為調(diào)整后角度值if(servoData > fArmMAX) servoData = fArmMAX; ?//判斷是否越上界if(servoData < fArmMIN) servoData = fArmMIN; ?//判斷是否越下界if (fromPos <= toPos) //如果“起始角度值”小于“目標(biāo)角度值” ,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i<=toPos; i++){fArm.write(i);delay(15);}else ? ? ? ? ? ? ? ?//否則“起始角度值”大于“目標(biāo)角度值”,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i>=toPos; i--){fArm.write(i);delay(15);}fArmPos = servoData;Serial.print(" ?Set fArm servo value: ");Serial.println(servoData);break;case 'r': ?fromPos = rArm.read(); ? ?//讀取rArm舵機(jī)的當(dāng)前角度值toPos = servoData; ? ? ? ?//命令中的角度值作為調(diào)整后角度值if(servoData > rArmMAX) servoData = rArmMAX; ?//判斷是否越上界if(servoData < rArmMIN) servoData = rArmMIN; ?//判斷是否越下界if (fromPos <= toPos) //如果“起始角度值”小于“目標(biāo)角度值” ,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i<=toPos; i++){rArm.write(i);delay(15);}else ? ? ? ? ? ? ? ?//否則“起始角度值”大于“目標(biāo)角度值”,每15ms向目標(biāo)轉(zhuǎn)動(dòng)1°for (int i=fromPos; i>=toPos; i--){rArm.write(i);delay(15);}rArmPos = servoData;Serial.print(" ?Set rArm servo value: ");Serial.println(servoData);break;case 'o': reportStatus();break;default: Serial.println(" Unknown Command.");} ?
}

(3)然后進(jìn)行人工調(diào)試。

①通過(guò)串口助手向Arduino發(fā)送內(nèi)容“b45”,機(jī)械臂的base舵機(jī)搖臂將緩慢地旋轉(zhuǎn)至45°的位置,同理可調(diào)試其它3個(gè)舵機(jī)。

②通過(guò)串口助手向Arduino發(fā)送內(nèi)容“b200”,由于200°超出base舵機(jī)的上界180°,機(jī)械臂的base舵機(jī)搖臂將緩慢地旋轉(zhuǎn)至180°的位置,同理可調(diào)試其它3個(gè)舵機(jī)的上下界。(需要注意的是,每個(gè)機(jī)械臂的舵機(jī)旋轉(zhuǎn)上下界可能略有差異,但只要每個(gè)舵機(jī)都經(jīng)過(guò)正確的初始化調(diào)整,差異應(yīng)該是很小的)

4、通過(guò)串口控制機(jī)械臂(有設(shè)置快捷指令)

(1)電路連接完成后將下面的程序下載到開(kāi)發(fā)板中。

①全局變量及包含的頭文件:

#include <Servo.h> ? ? ? ? ? ? ? ?//使用servo庫(kù)
Servo base, fArm, rArm, claw ; ? ?//創(chuàng)建4個(gè)servo對(duì)象//存儲(chǔ)電機(jī)極限值(const指定該數(shù)值為常量,常量數(shù)值在程序運(yùn)行中不能改變)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;int DSD = 15; //Default Servo Delay (默認(rèn)電機(jī)運(yùn)動(dòng)延遲時(shí)間)
//此變量用于控制電機(jī)運(yùn)行速度,增大此變量數(shù)值將降低電機(jī)運(yùn)行速度,從而控制機(jī)械臂動(dòng)作速度

②初始化工作部分:

void setup()
{base.attach(11); ? ? //base 伺服舵機(jī)連接引腳11 舵機(jī)代號(hào)'b'delay(200); ? ? ? ? ?//穩(wěn)定性等待rArm.attach(10); ? ? //rArm 伺服舵機(jī)連接引腳10 舵機(jī)代號(hào)'r'delay(200); ? ? ? ? ?//穩(wěn)定性等待fArm.attach(9); ? ? ?//fArm 伺服舵機(jī)連接引腳9 ?舵機(jī)代號(hào)'f'delay(200); ? ? ? ? ?//穩(wěn)定性等待claw.attach(6); ? ? ?//claw 伺服舵機(jī)連接引腳6 ?舵機(jī)代號(hào)'c'delay(200); ? ? ? ? ?//穩(wěn)定性等待base.write(90); delay(10); ? ? //base 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待fArm.write(90); delay(10); ? ? //fArm 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待rArm.write(90); delay(10); ? ? //rArm 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待claw.write(90); delay(10);  ? ?//claw 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial"); ? 
}

③循環(huán)工作部分:

void loop()
{if (Serial.available() > 0) { ?char serialCmd = Serial.read(); ?//獲取指令中的第一個(gè)字符armDataCmd(serialCmd); ? ? ? ? ? //根據(jù)串行指令執(zhí)行相應(yīng)操作}
}void armDataCmd(char serialCmd)
{if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r') ?//如果第一個(gè)字符是舵機(jī)代號(hào){int servoData = Serial.parseInt(); ? ?//獲取指令中的整數(shù)數(shù)據(jù)servoCmd(serialCmd, servoData, DSD); ?//調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù)(參數(shù):舵機(jī)名,目標(biāo)角度,單次延遲時(shí)間)} else {switch(serialCmd){ ? ?case 'o': ?//輸出舵機(jī)狀態(tài)信息reportStatus();break;case 'i': ?//機(jī)械臂初始化armIniPos();break; ? ? default: ? //未知指令反饋Serial.println("Unknown Command.");}} ?
}

④機(jī)械臂舵機(jī)運(yùn)行函數(shù):

void servoCmd(char servoName, int toPos, int servoDelay)
{ ?Servo servo2go; ?//創(chuàng)建servo對(duì)象//串口監(jiān)視器輸出接收指令信息Serial.println("");Serial.print("+Command: Servo ");Serial.print(servoName);Serial.print(" to ");Serial.print(toPos);Serial.print(" at servoDelay value ");Serial.print(servoDelay);Serial.println(".");Serial.println(""); ?int fromPos; //建立變量,存儲(chǔ)電機(jī)起始運(yùn)動(dòng)角度值switch(servoName) ? //根據(jù)命令的第一個(gè)字符判斷需要控制哪個(gè)舵機(jī){case 'b':if(toPos >= baseMin && toPos <= baseMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = base; ? ? ? ?//把對(duì)象base拷貝到servo2gofromPos = base.read(); ?//獲取當(dāng)前base電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: Base Servo Value Out Of Limit!");return;}case 'c':if(toPos >= clawMin && toPos <= clawMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = claw; ? ? ? ?//把對(duì)象claw拷貝到servo2gofromPos = claw.read(); ?//獲取當(dāng)前claw電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: Claw Servo Value Out Of Limit!");return;}case 'f':if(toPos >= fArmMin && toPos <= fArmMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = fArm; ? ? ? ?//把對(duì)象fArm拷貝到servo2gofromPos = fArm.read(); ?//獲取當(dāng)前fArm電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: fArm Servo Value Out Of Limit!");return;}case 'r':if(toPos >= rArmMin && toPos <= rArmMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = rArm; ? ? ? ?//把對(duì)象rArm拷貝到servo2gofromPos = rArm.read(); ?//獲取當(dāng)前rArm電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: rArm Servo Value Out Of Limit!");return;} ?}//通過(guò)對(duì)象servo2go指揮電機(jī)運(yùn)行if (fromPos <= toPos) //如果“起始角度值”小于“目標(biāo)角度值”for (int i=fromPos; i<=toPos; i++){servo2go.write(i);delay(servoDelay);}else ? ? ? ? ? ? ? ? ?//否則“起始角度值”大于“目標(biāo)角度值”for (int i=fromPos; i>=toPos; i--){servo2go.write(i);delay(servoDelay);}
}

⑤報(bào)告舵機(jī)當(dāng)前角度函數(shù):

void reportStatus()
{Serial.println("");Serial.println("");Serial.println("+ Robot-Arm Status Report +");Serial.print("Claw Position: "); Serial.println(claw.read());Serial.print("Base Position: "); Serial.println(base.read());Serial.print("Rear ?Arm Position:"); Serial.println(rArm.read());Serial.print("Front Arm Position:"); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++");Serial.println("");
}

⑥機(jī)械臂重新初始化函數(shù):

void armIniPos()
{Serial.println("+Command: Restore Initial Position.");int robotIniPosArray[4][3] = ? //使用二維數(shù)組存儲(chǔ)4個(gè)舵機(jī)的初始化信息{/* ?舵機(jī)代號(hào) 目標(biāo)角度 單次延遲  */{ ? ?'b', ? ? 90, ? ?DSD},{ ? ?'r', ? ? 90, ? ?DSD},{ ? ?'f', ? ? 90, ? ?DSD},{ ? ?'c', ? ? 90, ? ?DSD} }; ? for (int i = 0; i < 4; i++) ?//調(diào)用4次機(jī)械臂舵機(jī)運(yùn)行函數(shù),分別初始化4個(gè)舵機(jī){servoCmd(robotIniPosArray[i][0], robotIniPosArray[i][1], robotIniPosArray[i][2]);}
}

(2)然后進(jìn)行人工調(diào)試。

①通過(guò)串口助手向Arduino發(fā)送內(nèi)容“b45”,機(jī)械臂的base舵機(jī)搖臂將緩慢地旋轉(zhuǎn)至45°的位置,同理可調(diào)試其它3個(gè)舵機(jī)。

②通過(guò)串口助手向Arduino發(fā)送內(nèi)容“b200”,由于200°超出base舵機(jī)的上界180°,機(jī)械臂的base舵機(jī)不會(huì)有任何動(dòng)作,同時(shí)Arduino通過(guò)串口報(bào)指令有誤,同理可調(diào)試其它3個(gè)舵機(jī)。

③通過(guò)串口助手向Arduino發(fā)送內(nèi)容“o”,Arduino將通過(guò)串口發(fā)送四個(gè)舵機(jī)當(dāng)前的狀態(tài)。

④通過(guò)串口助手向Arduino發(fā)送內(nèi)容“i”,Arduino將控制四個(gè)舵機(jī)恢復(fù)初始狀態(tài)。

5、通過(guò)串口控制機(jī)械臂(設(shè)有手柄控制方式)

(1)電路連接完成后將下面的程序下載到開(kāi)發(fā)板中。

①全局變量及包含的頭文件:

#include <Servo.h> ? ? ? ? ? ? ? ?//使用servo庫(kù)
Servo base, fArm, rArm, claw ; ? ?//創(chuàng)建4個(gè)servo對(duì)象//存儲(chǔ)電機(jī)極限值(const指定該數(shù)值為常量,常量數(shù)值在程序運(yùn)行中不能改變)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;int DSD = 15; //Default Servo Delay (默認(rèn)電機(jī)運(yùn)動(dòng)延遲時(shí)間)
//此變量用于控制電機(jī)運(yùn)行速度,增大此變量數(shù)值將降低電機(jī)運(yùn)行速度,從而控制機(jī)械臂動(dòng)作速度bool mode;        ? //記錄當(dāng)前的模式:mode = 1 —— 指令模式,mode = 0 —— 手柄模式
int moveStep = 3; ?//每一次按下手柄按鍵的舵機(jī)移動(dòng)量(僅適用于手柄模式)

②初始化工作部分:

void setup()
{base.attach(11); ? ? //base 伺服舵機(jī)連接引腳11 舵機(jī)代號(hào)'b'delay(200); ? ? ? ? ?//穩(wěn)定性等待rArm.attach(10); ? ? //rArm 伺服舵機(jī)連接引腳10 舵機(jī)代號(hào)'r'delay(200); ? ? ? ? ?//穩(wěn)定性等待fArm.attach(9); ? ? ?//fArm 伺服舵機(jī)連接引腳9 ?舵機(jī)代號(hào)'f'delay(200); ? ? ? ? ?//穩(wěn)定性等待claw.attach(6); ? ? ?//claw 伺服舵機(jī)連接引腳6 ?舵機(jī)代號(hào)'c'delay(200); ? ? ? ? ?//穩(wěn)定性等待base.write(90); delay(10); ? ? //base 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待fArm.write(90); delay(10); ? ? //fArm 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待rArm.write(90); delay(10); ? ? //rArm 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待claw.write(90); delay(10);  ? ?//claw 伺服舵機(jī)旋轉(zhuǎn)角度初始化+穩(wěn)定性等待Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial"); ? 
}

③循環(huán)工作部分:

void loop()
{if (Serial.available()>0) { ?char serialCmd = Serial.read(); ?//獲取指令中的第一個(gè)字符if(mode == 1) ?//根據(jù)mode判斷現(xiàn)在處于什么模式{armDataCmd(serialCmd); ?//指令模式} else {armJoyCmd(serialCmd); ? //手柄模式}}
}

④指令模式下的處理邏輯:

void armDataCmd(char serialCmd)
{//判斷用戶(hù)是否因搞錯(cuò)模式而輸入錯(cuò)誤的指令信息(即指令模式下輸入手柄按鍵信息)if ( ? serialCmd == 'w' || serialCmd == 's' || serialCmd == 'a' || serialCmd == 'd'|| serialCmd == '5' || serialCmd == '4' || serialCmd == '6' || serialCmd == '8' ){Serial.println("+Warning: Robot in Instruction Mode..."); delay(100);while(Serial.available() > 0) char wrongCommand = Serial.read(); ?//清除串口緩存中的錯(cuò)誤指令return;}  ? ? ? ? ? ? ? if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){int servoData = Serial.parseInt();servoCmd(serialCmd, servoData, DSD); ?//調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù)(參數(shù):舵機(jī)名,目標(biāo)角度,單次延遲)} elseswitch(serialCmd){ ? case 'm': ?  //切換至手柄模式 mode = 0; Serial.println("Command: Switch to Joy-Stick Mode.");break;case 'o': ? ?//輸出舵機(jī)狀態(tài)信息reportStatus();break;case 'i': ? ?//機(jī)械臂初始化armIniPos();break; ?default: ? ? //未知指令反饋Serial.println("Unknown Command.");} ?
}

⑤手柄模式下的處理邏輯:

void armJoyCmd(char serialCmd)
{//判斷用戶(hù)是否因搞錯(cuò)模式而輸入錯(cuò)誤的指令信息(即手柄模式下輸入舵機(jī)指令)if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){Serial.println("+Warning: Robot in Joy-Stick Mode...");delay(100);while(Serial.available()>0) char wrongCommand = Serial.read(); ?//清除串口緩存中的錯(cuò)誤指令return;} int baseJoyPos, rArmJoyPos, fArmJoyPos, clawJoyPos;switch(serialCmd){case 'a': ?//Base向左Serial.println("Received Command: Base Turn Left"); ? ? ? ? ? ? ? ?baseJoyPos = base.read() - moveStep;? //目標(biāo)角度=當(dāng)前角度-單次操作移動(dòng)角度servoCmd('b', baseJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù)?case 'd': ?//Base向右Serial.println("Received Command: Base Turn Right"); ? ? ? ? ? ? ? ?baseJoyPos = base.read() + moveStep;? //目標(biāo)角度=當(dāng)前角度+單次操作移動(dòng)角度servoCmd('b', baseJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ? ? ? ?case 's': ?//rArm向下Serial.println("Received Command: Rear Arm Down"); ? ? ? ? ? ? ? ?rArmJoyPos = rArm.read() + moveStep;? //目標(biāo)角度=當(dāng)前角度+單次操作移動(dòng)角度servoCmd('r', rArmJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ? ? ? ? ? ? ?case 'w': ?//rArm向上Serial.println("Received Command: Rear Arm Up"); ? ? rArmJoyPos = rArm.read() - moveStep;? //目標(biāo)角度=當(dāng)前角度-單次操作移動(dòng)角度servoCmd('r', rArmJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ?case '8': ?//fArm向上Serial.println("Received Command: Front Arm Up"); ? ? ? ?fArmJoyPos = fArm.read() + moveStep;? //目標(biāo)角度=當(dāng)前角度+單次操作移動(dòng)角度servoCmd('f', fArmJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ?case '5': ?//fArm向下Serial.println("Received Command: Front Arm Down"); ? ? ? ?fArmJoyPos = fArm.read() - moveStep;? //目標(biāo)角度=當(dāng)前角度-單次操作移動(dòng)角度servoCmd('f', fArmJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ?case '4': ?//Claw關(guān)閉Serial.println("Received Command: Claw Close Down"); ? ? ? ?clawJoyPos = claw.read() + moveStep;? //目標(biāo)角度=當(dāng)前角度+單次操作移動(dòng)角度servoCmd('c', clawJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ?case '6': ?//Claw打開(kāi)Serial.println("Received Command: Claw Open Up"); ? ? clawJoyPos = claw.read() - moveStep;? //目標(biāo)角度=當(dāng)前角度-單次操作移動(dòng)角度servoCmd('c', clawJoyPos, DSD);break; //調(diào)用機(jī)械臂舵機(jī)運(yùn)行函數(shù) ?case 'm': ? //切換至指令模式 mode = 1; Serial.println("Command: Switch to Instruction Mode.");break;case 'o': ? //輸出舵機(jī)狀態(tài)信息reportStatus();break;case 'i': ? //機(jī)械臂初始化armIniPos();break;default: ? ?//未知指令反饋Serial.println("Unknown Command.");return;} ?
}

⑥報(bào)告舵機(jī)當(dāng)前角度函數(shù):

void reportStatus()
{Serial.println("");Serial.println("");Serial.println("+ Robot-Arm Status Report +");Serial.print("Claw Position: "); Serial.println(claw.read());Serial.print("Base Position: "); Serial.println(base.read());Serial.print("Rear ?Arm Position:"); Serial.println(rArm.read());Serial.print("Front Arm Position:"); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++");Serial.println("");
}

⑦機(jī)械臂重新初始化函數(shù):

void armIniPos()
{Serial.println("+Command: Restore Initial Position.");int robotIniPosArray[4][3] = ? //使用二維數(shù)組存儲(chǔ)4個(gè)舵機(jī)的初始化信息{/* ?舵機(jī)代號(hào) 目標(biāo)角度 單次延遲  */{ ? ?'b', ? ? 90, ? ?DSD},{ ? ?'r', ? ? 90, ? ?DSD},{ ? ?'f', ? ? 90, ? ?DSD},{ ? ?'c', ? ? 90, ? ?DSD} }; ? for (int i = 0; i < 4; i++) ?//調(diào)用4次機(jī)械臂舵機(jī)運(yùn)行函數(shù),分別初始化4個(gè)舵機(jī){servoCmd(robotIniPosArray[i][0], robotIniPosArray[i][1], robotIniPosArray[i][2]);}
}

⑧機(jī)械臂舵機(jī)運(yùn)行函數(shù):

void servoCmd(char servoName, int toPos, int servoDelay)
{ ?Servo servo2go; ?//創(chuàng)建servo對(duì)象//串口監(jiān)視器輸出接收指令信息Serial.println("");Serial.print("+Command: Servo ");Serial.print(servoName);Serial.print(" to ");Serial.print(toPos);Serial.print(" at servoDelay value ");Serial.print(servoDelay);Serial.println(".");Serial.println(""); ?int fromPos; //建立變量,存儲(chǔ)電機(jī)起始運(yùn)動(dòng)角度值switch(servoName){case 'b':if(toPos >= baseMin && toPos <= baseMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = base; ? ? ? ?//把對(duì)象base拷貝到servo2gofromPos = base.read(); ?//獲取當(dāng)前base電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: Base Servo Value Out Of Limit!");return;}case 'c':if(toPos >= clawMin && toPos <= clawMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = claw; ? ? ? ?//把對(duì)象claw拷貝到servo2gofromPos = claw.read(); ?//獲取當(dāng)前claw電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: Claw Servo Value Out Of Limit!");return;}case 'f':if(toPos >= fArmMin && toPos <= fArmMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = fArm; ? ? ? ?//把對(duì)象fArm拷貝到servo2gofromPos = fArm.read(); ?//獲取當(dāng)前fArm電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: fArm Servo Value Out Of Limit!");return;}case 'r':if(toPos >= rArmMin && toPos <= rArmMax){ ?//判斷是否越界,越界就報(bào)錯(cuò)servo2go = rArm; ? ? ? ?//把對(duì)象rArm拷貝到servo2gofromPos = rArm.read(); ?//獲取當(dāng)前rArm電機(jī)角度值用于“電機(jī)運(yùn)動(dòng)起始角度值”break;} else {Serial.println("+Warning: rArm Servo Value Out Of Limit!");return;} ?}//通過(guò)對(duì)象servo2go指揮電機(jī)運(yùn)行if (fromPos <= toPos) //如果“起始角度值”小于“目標(biāo)角度值”for (int i=fromPos; i<=toPos; i++){servo2go.write(i);delay(servoDelay);}else ? ? ? ? ? ? ? ? ?//否則“起始角度值”大于“目標(biāo)角度值”for (int i=fromPos; i>=toPos; i--){servo2go.write(i);delay(servoDelay);}
}

(2)根據(jù)程序注釋進(jìn)行人工調(diào)試。

6、配合HC-06藍(lán)牙模塊控制機(jī)械臂

(1)按照下圖所示將電路連接好。

(2)沿用上例的程序即可,手機(jī)連接上HC-06藍(lán)牙模塊,接著打開(kāi)配套軟件的手柄操作界面,設(shè)置好每個(gè)鍵所對(duì)應(yīng)的指令信息,在機(jī)械臂處于手柄操作模式的前提下對(duì)其進(jìn)行調(diào)試。

http://aloenet.com.cn/news/38468.html

相關(guān)文章:

  • wordpress英文版如何變成中文版網(wǎng)站seo標(biāo)題優(yōu)化技巧
  • 單位網(wǎng)站建設(shè)方案如何優(yōu)化關(guān)鍵詞
  • 北京網(wǎng)站建設(shè)設(shè)計(jì)公司哪家好如何做好關(guān)鍵詞的優(yōu)化
  • 個(gè)人網(wǎng)站展示免費(fèi)的網(wǎng)頁(yè)設(shè)計(jì)成品下載
  • 網(wǎng)站建設(shè)程序結(jié)構(gòu)免費(fèi)推廣的預(yù)期效果
  • wordpress多用戶(hù)后臺(tái)windows10優(yōu)化大師
  • 原來(lái)做網(wǎng)站后來(lái)跑?chē)?guó)外了教育機(jī)構(gòu)排名
  • wordpress站點(diǎn)版權(quán)設(shè)置大數(shù)據(jù)比較好的培訓(xùn)機(jī)構(gòu)
  • 百度站長(zhǎng)平臺(tái)申請(qǐng)?zhí)峤绘溄雍蟬eo服務(wù)
  • 柳州疫情最新通知seo經(jīng)典案例
  • 電子商務(wù)營(yíng)銷(xiāo)模式有哪些長(zhǎng)沙網(wǎng)站seo推廣公司
  • 青浦手機(jī)網(wǎng)站建設(shè)網(wǎng)站推廣排名公司
  • php網(wǎng)站后臺(tái)模板推廣app最快的方法
  • 貴陽(yáng) 網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷(xiāo)主要內(nèi)容
  • 做旅行網(wǎng)站的依據(jù)及意義國(guó)內(nèi)十大搜索引擎網(wǎng)站
  • 福州專(zhuān)業(yè)網(wǎng)站建設(shè)友鏈交易網(wǎng)
  • app小程序開(kāi)發(fā)價(jià)格網(wǎng)站優(yōu)化方式有哪些
  • 無(wú)錫網(wǎng)站建設(shè)制作方案網(wǎng)頁(yè)設(shè)計(jì)制作網(wǎng)站html代碼大全
  • 特效網(wǎng)站大全seo秘籍優(yōu)化課程
  • 哪家做網(wǎng)站便宜營(yíng)銷(xiāo)型網(wǎng)站建站推廣
  • 網(wǎng)站開(kāi)發(fā)數(shù)據(jù)庫(kù)課程設(shè)計(jì)專(zhuān)注于網(wǎng)站營(yíng)銷(xiāo)服務(wù)
  • 做模擬人生類(lèi)的游戲下載網(wǎng)站廣告開(kāi)戶(hù)南京seo
  • 調(diào)查問(wèn)卷在哪個(gè)網(wǎng)站做子域名在線(xiàn)查詢(xún)
  • 志勛網(wǎng)站建設(shè)公司中國(guó)十大外貿(mào)平臺(tái)
  • 建企業(yè)網(wǎng)站怎么做網(wǎng)站自然排名工具
  • 有域名怎樣做網(wǎng)站軟文網(wǎng)站發(fā)布平臺(tái)
  • 9元包郵網(wǎng)站怎么做seo搜索引擎優(yōu)化是什么
  • 網(wǎng)站域名建設(shè)費(fèi)進(jìn)什么科目人工智能培訓(xùn)心得體會(huì)
  • 有域名了怎么做網(wǎng)站百度推廣優(yōu)化公司
  • 新手做網(wǎng)站視頻講解大地seo視頻