(RB-13K111)6自由度機(jī)械臂Arduino版
目錄 |
產(chǎn)品概述
機(jī)械手臂目前在機(jī)械人技術(shù)領(lǐng)域中得到廣泛的應(yīng)用,在工業(yè)制造、醫(yī)學(xué)治療、娛樂服務(wù)、教學(xué)應(yīng)用、軍事以及太空探索等領(lǐng)域都能見到它的身影。雖然大家經(jīng)常在電影或者電視中見過,似曾想過擁有一臺(tái)屬于自己的機(jī)械臂,因其功能針對性強(qiáng)和高額的售價(jià),使我們望而卻步?,F(xiàn)在你不必?fù)?dān)心這個(gè)問題了,AS-6D0F鋁合金機(jī)械臂套件,可以實(shí)現(xiàn)你的機(jī)器人夢想。此版說明書主要介紹如何利用4個(gè)大按鈕模塊與Arduino Uno控制器之間的通訊直接控制六自由度機(jī)械臂并且在LCD2004液晶屏上實(shí)時(shí)顯示監(jiān)控到的信息,此說明書還介紹Arduino Uno控制器與LCD2004液晶屏及大按鍵之間的接線和調(diào)試過程,按照此說明書的步驟一步一步的組裝完成后,給其上電,通過4個(gè)大按鈕模塊就可以輕松實(shí)現(xiàn)對六自由度機(jī)械臂的控制。
主控器技術(shù)參數(shù)
- 主控器:Carduino UNO R3
- 微處理器:ATmega328
- Flash 內(nèi)存:32 KB (ATmega328 其中0.5 KB 用于引導(dǎo)程序)
- 工作電壓:5V
- 輸入電壓:接上USB 時(shí)無須外部供電或外部7V~12V DC 輸入
- 輸出電壓:5V DC 輸出和3.3V DC 輸出和外部電源輸入
- 時(shí)鐘頻率:16 MHz
- 輸入電壓:7-12V(推薦)
- 輸入電壓:6-20V(限制)
- 支持USB 接口協(xié)議及供電(不需外接電源)
- 支持ISP 下載功能
- 數(shù)字I/O 端口:14(6 個(gè)PWM 輸出口)
- 模擬輸入端口:6
- 直流電流:40mA(I/O 端口)
- 直流電流:50mA(3.3V 端口)
- EEPROM:1 KB (ATmega328)
- SRAM:2 KB (ATmega328)
- 尺寸:75x55x15mm
零件列表
安裝連線
步驟1:如圖所示,CarDuino Uno 控制器與傳感器擴(kuò)展板連接,并通過 USB 連接線給 Carduino UNO 上傳例子程序。
步驟2:如圖所示,將按壓式大按鈕模塊與傳感器擴(kuò)展板 V5.0 的模擬接口連接。
將 4 個(gè)大按鈕模塊分別接到傳感器擴(kuò)展板 v5.0 的 4 個(gè)模擬口A0、A1、A2、A3,作為機(jī)械臂的控制按鍵,功能如下:
- A0被按下時(shí),舵機(jī)號(hào)從上至下選中
- A1被按下時(shí),舵機(jī)號(hào)從下至上選中
- A2被按下時(shí),舵機(jī)順時(shí)針轉(zhuǎn)
- A3被按下時(shí),舵機(jī)逆時(shí)針轉(zhuǎn)
步驟3:如下圖所示,將 RB-150MG 與傳感器擴(kuò)展板 V5.0 連接,依次連接底盤到夾持器舵機(jī)。
- 將底盤到夾持器的舵機(jī)順次連接到傳感器擴(kuò)展板的 6 個(gè)數(shù)字口 D4(底盤舵機(jī))D5、D6、D7、D8、D9(夾持器舵機(jī))。
步驟4 如圖所示:將 IIC LCD2004 液晶顯示屏與傳感器擴(kuò)展板連接,IIC LCD2004液晶顯示屏接到傳感器擴(kuò)展板 v5.0 的 IIC 接口,連接時(shí)需要注意紅色對應(yīng)“+”,黑色對應(yīng)“-”
步驟5 圖下圖所示:給機(jī)械臂電控部分進(jìn)行供電。
- 取下傳感器擴(kuò)展板 v5.0 的跳線帽,使用開關(guān)電源(5V 給傳感器擴(kuò)展板 v5.0 供電,12V 給 CarDuino Uno 控制器供電),紅色接 VCC,黑色接 GND(注意區(qū)分正負(fù)極)。
步驟6 完成以上步驟后,機(jī)械臂所有電控及供電就全部安裝完成,接下來回頭檢查一下各個(gè)部分的接線,尤其是是否有電源和地接反的情況,如果確定接線無誤,就可以給機(jī)械臂供電了。
例子程序
程序編譯上傳前,需要下載程序使用的庫文件Arduino版機(jī)械臂庫文件下載地址
#include <Servo.h> //調(diào)用一些庫文件 #include <TimedAction.h> #include <SimpleTimer.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> //定義舵機(jī)位置名稱,并編號(hào)。 const int base = 0; const int shoulder = 1; const int elbow = 2; const int wristflex = 3; const int wristrot = 4; const int gripper = 5; const int stdDelay = 20; //舵機(jī)運(yùn)動(dòng)延時(shí)(單位ms) const int maxServos = 6; //舵機(jī)的數(shù)量 const int centerPos = 90; //舵機(jī)中位位置 unsigned long key_millis = 0; unsigned long button_millis = 0; int keyDelay = 100; //定義延時(shí)時(shí)間 int buttonDelay = 50; //定義按鍵延時(shí) int thisServo = base; //定義起始電機(jī) typedef struct{ //數(shù)組框架結(jié)構(gòu) byte neutral; //中位角度 byte minPos; //最小角度 byte maxPos; //最大角度 byte delaySpeed; //延時(shí)時(shí)間 byte curPos; //舵機(jī)當(dāng)前角度 } ServoPos; //結(jié)構(gòu)體名稱 ServoPos servosPos[] = { //對舵機(jī)限位 { 90, 180, 10, stdDelay, 0 }, //中位90,最小角度180,最大角度10,范圍0~180度。 { 90, 180, 10, stdDelay, 0 }, { 90, 180, 60, stdDelay, 0 }, { 90, 170, 50, stdDelay, 0 }, { 90, 180, 10, 10, 0 }, { 90, 125, 55, 5, 0 } }; byte serv = 90; int counter = 0; int curServo = 0; int sMove[] = {0, 90, 0}; int sAttach[] = {0, 0}; LiquidCrystal_I2C lcd(0x27,20,4); //0x27 D7~D0端口開關(guān)設(shè)置0x表示十六進(jìn)制27轉(zhuǎn)換成16進(jìn)制數(shù)是00100111 1代表開,0代表關(guān), 20列,4行,行號(hào)從零算起,第一行行號(hào)0,第二行行號(hào)1. Servo servos[maxServos]; int destServoPos[maxServos]; int currentServoPos[maxServos]; TimedAction servoMove[maxServos] = TimedAction(100, doServoFunc); // 延時(shí),延時(shí)時(shí)間為聲明時(shí)間。 SimpleTimer timer; // For movement tests TimedAction keys = TimedAction(10, keypadFunc); void setup() { //設(shè)置 delay(200); Wire.begin(); lcd.init(); //LCD初始化 lcd.backlight(); //LCD背光燈打開 delay(500); lcd.on(); // LCD開機(jī) setupDisplay(); //調(diào)用子程序,設(shè)置顯示內(nèi)容門,后面有定義。 for(int i=0; i<maxServos; i++) { servos[i].write(servosPos[i].neutral); servosPos[i].curPos = servosPos[i].neutral; servos[i].attach(i+4); destServoPos[i] = centerPos; currentServoPos[i] = centerPos; servoMove[i].disable(); } //timer.setInterval(5000, servoTestFunc); } void loop() { for(int x=0; x<maxServos; x++) { curServo = x; servoMove[x].check(); } //timer.run(); keys.check(); navSwitchFunc(); } void servoTestFunc() { if(counter % 2) { Move(thisServo, servosPos[thisServo].minPos, servosPos[thisServo].delaySpeed); } else Move(thisServo, servosPos[thisServo].maxPos, servosPos[thisServo].delaySpeed); counter++; } void writeServo() { int servoNum = sMove[0]; if(servoNum >=0 && servoNum <= maxServos) { destServoPos[servoNum] = sMove[1]; servoMove[servoNum].enable(); servoMove[servoNum].setInterval(sMove[2]); } } void setServoAttach() { int servo = 1; // sAttach[0] int mode = 2; // sAttach[1] if(servo >= 0 && servo <= maxServos) { if (mode == 1) servos[servo].attach(servo+4); else servos[servo].detach(); } } void doServoFunc() { int x = curServo; if(destServoPos[x] == currentServoPos[x]) servoMove[x].disable(); if(destServoPos[x] > currentServoPos[x]) currentServoPos[x]++; else currentServoPos[x]--; servosPos[x].curPos = constrain(currentServoPos[x], servosPos[x].maxPos, servosPos[x].minPos); currentServoPos[x] = servosPos[x].curPos; servos[x].write(currentServoPos[x]); jointPos(x, currentServoPos[x]); } void Move(int servoNum, int servoPosition, int delayTime) { //舵機(jī)驅(qū)動(dòng)指令 sMove[0] = servoNum; //所驅(qū)動(dòng)舵機(jī)號(hào) sMove[1] = servoPosition; //舵機(jī)的目標(biāo)位置 sMove[2] = delayTime; //每個(gè)舵機(jī)運(yùn)動(dòng)的延遲時(shí)長 writeServo(); } void Attach(int servoNum, int servoMode) { sAttach[0] = servoNum; sAttach[1] = servoMode; } void navSwitchFunc() { //鍵盤檢測子程序 if (millis() > button_millis + buttonDelay) { button_millis = millis(); if(digitalRead(A0) == LOW) { // 當(dāng)A0引腳低電平 thisServo--; //電機(jī)號(hào)自加1 thisServo = constrain(thisServo, 0, 5); //電機(jī)控制范圍 jointPos(thisServo, servosPos[thisServo].curPos); delay(200); //延時(shí)200毫秒 } if(digitalRead(A1)== LOW) { //當(dāng)A1引腳低電平 thisServo++; //電機(jī)號(hào)自加1 thisServo = constrain(thisServo, 0, 5); //電機(jī)控制范圍 jointPos(thisServo, servosPos[thisServo].curPos); delay(200); //延時(shí)200毫秒 } if(digitalRead(A2) == LOW) { //當(dāng)A2引腳低電平 byte t = thisServo; servosPos[t].curPos--; //電機(jī)角度自減1 servosPos[t].curPos = constrain(servosPos[t].curPos, servosPos[t].maxPos, servosPos[t].minPos); jointPos(t, servosPos[t].curPos); } if(digitalRead(A3) == LOW) { //當(dāng)A3引腳低電平 byte t = thisServo; servosPos[t].curPos++; //電機(jī)角度自減1 servosPos[t].curPos = constrain(servosPos[t].curPos, servosPos[t].maxPos, servosPos[t].minPos); jointPos(t, servosPos[t].curPos); } } } void keypadFunc() { byte keypad = lcd.keypad(); lcd.command(0); if (keypad !=0) { if (millis() > key_millis + keyDelay) { keypress(keypad); key_millis = millis(); } } } void keypress (byte keypad) { //讀取按鍵按下情況。 byte t; lcd.setCursor(15, 1); switch(keypad) { case 1: lcd.print("1"); t = base; servosPos[t].curPos--; break; case 2: lcd.print("2"); t = shoulder; servosPos[t].curPos--; break; case 3: lcd.print("3"); t = elbow; servosPos[t].curPos--; break; case 5: lcd.print("4"); t = base; servosPos[t].curPos++; break; case 6: lcd.print("5"); t = shoulder; servosPos[t].curPos++; break; case 7: lcd.print("6"); t = elbow; servosPos[t].curPos++; break; case 9: lcd.print("7"); t = wristflex; servosPos[t].curPos--; break; case 10: lcd.print("8"); t = wristrot; servosPos[t].curPos--; break; case 11: lcd.print("9"); t = gripper; servosPos[t].curPos--; break; case 13: lcd.print("*"); t = wristflex; servosPos[t].curPos++; break; case 14: lcd.print("0"); t = wristrot; servosPos[t].curPos++; break; case 15: lcd.print("#"); t = gripper; servosPos[t].curPos++; break; } servosPos[t].curPos = constrain(servosPos[t].curPos, servosPos[t].maxPos, servosPos[t].minPos); jointPos(t, servosPos[t].curPos); } void jointPos(byte t, byte pos) { //定義兩個(gè)byte類型的變量,t,pose. lcd.setCursor(6, 1);//電機(jī)所在位置名稱 switch(t) { case base: // 1, 4 lcd.print("bse"); //LCD顯示bse break; case shoulder: // 2, 5 lcd.print("shl"); //LCD顯示shl break; case elbow: // 3, 6 lcd.print("elb"); //LCD顯示elb break; case wristflex: // 7, * lcd.print("wfx"); //LCD顯示wfx break; case wristrot: // 8, 0 lcd.print("wrt"); //LCD顯示wrt break; case gripper: // 9, # lcd.print("grp"); //LCD顯示grp break; } lcd.setCursor(2, 3);// 設(shè)置顯示位置第4行,3列就是說前面空2格。 lcd.print(" you are welcome "); lcd.setCursor(6, 2);//pose后面顯示的角度位置。 lcd.print(pos, DEC); //當(dāng)按鍵按下后顯示角度值。 servos[t].write(pos); } void setupDisplay() { //子程序定義,LCD顯示內(nèi)容,開機(jī)立即顯示。 lcd.clear(); //LCD清屏 lcd.blink_off(); //LCD光標(biāo)閃爍關(guān) lcd.home(); // lcd.setCursor(1, 1); //設(shè)置顯示位置第2行,2列就是說前面空1格。 lcd.print("key: "); //顯示內(nèi)容 “key” lcd.setCursor(4, 0); //設(shè)置顯示位置第一行,5列就是說前面空4格。 lcd.print("alsrobotbase ");//顯示內(nèi)容”alsrobotbase” lcd.setCursor(1, 2); // 設(shè)置顯示位置 lcd.print("Pos: "); //顯示內(nèi)容”Pos” }
電控部分說明書
6自由度機(jī)械臂機(jī)械部分安裝說明
按壓式大按鈕模塊使用說明書
IIC 2004液晶擴(kuò)展板使用說明書
V5.0傳感器擴(kuò)展板使用說明
Arduino UNO入門教程
Arduino UNO 驅(qū)動(dòng)安裝
Arduino UNO 編程參考手冊
產(chǎn)品相關(guān)推薦
產(chǎn)品購買地址
周邊產(chǎn)品推薦
相關(guān)問題解答
arduino六自由機(jī)械臂編譯不成功問題
Arduino UNO R3 可以實(shí)現(xiàn)機(jī)械臂控制嗎?
6自由度機(jī)械臂舵機(jī)容易被拉下來
相關(guān)學(xué)習(xí)資料
AS-6DOF鋁合金機(jī)械臂功能演示之定位抓取
6自由度機(jī)械臂玩兒家測評一
6自由度機(jī)械臂玩兒家測評二
奧松機(jī)器人技術(shù)論壇