แขนหุ่นยนต์พิสูจน์ตัวเองว่ามีประโยชน์และมีประสิทธิผลมากขึ้นในการใช้งานจำนวนมากซึ่งจำเป็นต้องมีความเร็วความถูกต้องและปลอดภัย แต่สำหรับฉันสิ่งที่มากกว่าสิ่งเหล่านี้ดูดีเมื่อพวกเขาทำงาน ฉันมีความปรารถนาเสมอสำหรับแขนหุ่นยนต์ที่สามารถช่วยฉันด้วยงานประจำวันของฉันเช่นเดียวกับ Dum-E และ Dum-U ที่โทนี่ใช้ในห้องทดลองของเขา ทั้งสองบอทสามารถมองเห็นได้ช่วยให้เขาขณะที่สร้างชุดคนเหล็กหรือถ่ายทำผลงานของเขาโดยใช้กล้องวิดีโอ จริงๆแล้ว Dum-E ช่วยชีวิตเขาได้อีกครั้ง ....... และนี่คือที่ที่ฉันอยากจะหยุดเพราะนี่ไม่ใช่แฟนเพจ นอกเหนือจากโลกสมมุติแล้วยังมีแขนหุ่นยนต์ที่ทำจาก Fanuc, Kuka, Denso, ABB, Yaskawa เป็นต้นแขนหุ่นยนต์เหล่านี้ใช้ในสายการผลิตของรถยนต์เหมืองแร่อุตสาหกรรมเคมีและสถานที่อื่น ๆ อีกมากมาย 
ดังนั้นในการกวดวิชานี้เราจะไปสร้างของเราเองแขนหุ่นยนต์ด้วยความช่วยเหลือของ Arduino และ MG995 Servo มอเตอร์ หุ่นยนต์จะมีทั้งหมด 4 องศาอิสระ (DOF) ไม่รวมกริปเปอร์และสามารถควบคุมด้วยโพเทนชิออมิเตอร์ นอกเหนือจากนั้นเรายังจะตั้งโปรแกรมให้มีคุณลักษณะบันทึกและเล่นเพื่อให้เราสามารถบันทึกการเคลื่อนไหวและขอให้หุ่นยนต์ทำซ้ำได้หลายครั้งตามที่เราต้องการ ฟังดูดี !!! เพื่อช่วยให้เริ่มต้นสร้าง ....

จำเป็นต้องใช้วัสดุ

  • Arduino Nano
  • 5 เซอร์โวมอเตอร์ MG-995
  • 5 มิเตอร์
  • คณะกรรมการ Perf
  • Servo horns
  • ถั่วและสกรู

หมายเหตุ : ร่างกายของแขนหุ่นยนต์เป็นเครื่องพิมพ์แบบ 3D อย่างสมบูรณ์ หากคุณมีเครื่องพิมพ์คุณสามารถพิมพ์ได้โดยใช้ไฟล์ออกแบบที่กำหนด Else ใช้แบบจำลอง 3 มิติที่จัดเตรียมไว้และใช้ชิ้นส่วนของคุณโดยใช้ไม้หรือคริลิค หากคุณไม่ได้มีอะไรแล้วคุณก็สามารถใช้กระดาษแข็งที่จะสร้างง่ายแขนหุ่นยนต์

การพิมพ์ 3D และการประกอบแขนหุ่นยนต์

ส่วนที่ใช้เวลาส่วนใหญ่ในการสร้างหุ่นยนต์แขนนี้ก็คือการสร้างร่างกายของตัวเอง ตอนแรกผมเริ่มต้นด้วยการออกแบบร่างกายโดยใช้ Solidworks แต่ภายหลังตระหนักว่ามีการออกแบบที่น่ากลัวหลายอย่างพร้อมใช้งานบนThingiverseและไม่จำเป็นต้องคิดค้นล้อใหม่อีก ดังนั้นฉันจึงผ่านการออกแบบและพบว่าRobotic Arm V2.0 โดย Ashingจะทำงานได้ดีกับมอเตอร์เซอร์โว MG995 ของเราและตรงกับวัตถุประสงค์ของเรา
ไปที่หน้า Thingiverse (ลิงค์ข้างต้น) และดาวน์โหลดไฟล์โมเดล มีทั้งหมด 14 ส่วนที่ต้องพิมพ์และไฟล์ STLสำหรับไฟล์ทั้งหมดสามารถดาวน์โหลดได้จากหน้า Thingiverse ฉันใช้ซอฟต์แวร์ Cura 3.2.1 จาก Ultimaker เพื่อตัดไฟล์ STL และเครื่องพิมพ์ TEVO tarantula 3D ของฉันเพื่อพิมพ์ หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับเครื่องพิมพ์ 3D และวิธีการทำงานคุณสามารถอ่านบทความนี้ในคู่มือเริ่มต้นในการเริ่มต้นด้วยการพิมพ์ 3D
ชิ้นส่วนการพิมพ์ 3D ของแขนหุ่นยนต์ที่ใช้ Cura

โชคดีที่ไม่มีชิ้นส่วนใดที่มีโครงแขวนมากกว่าจึงไม่จำเป็นต้องสนับสนุน การออกแบบเป็นแบบเรียบง่ายและด้วยเหตุนี้จึงสามารถจัดการได้อย่างง่ายดายด้วยเครื่องพิมพ์ 3D พื้นฐานใด ๆ ประมาณ 4.5 ชั่วโมงหลังจากพิมพ์ชิ้นส่วนทั้งหมดพร้อมที่จะประกอบ คำแนะนำการชุมนุมเป็นอีกครั้งที่ได้อธิบายไว้อย่างเรียบร้อยโดยAshingตัวเองและด้วยเหตุนี้ฉันจะไม่ครอบคลุม
ชิ้นส่วนที่พิมพ์ 3D ของแขนหุ่นยนต์

หนึ่งปลายเล็ก ๆ คือคุณจะต้องทราย / ยื่นขอบของชิ้นส่วนสำหรับมอเตอร์เพื่อให้พอดีกับมอเตอร์ทั้งหมดจะพอดีกับ Vey สบายกับเล็กน้อยแรงทางกล มีความอดทนและใช้แฟ้มเพื่อสร้างห้องพักสำหรับมอเตอร์ถ้าดูเหมือนแน่น คุณต้องใช้สลักเกลียวขนาด 3 มม. จำนวน 20 ตัวเพื่อประกอบหุ่นยนต์ ARM
เมื่อมอเตอร์ติดตั้งให้แน่ใจว่าสามารถหมุนและไปถึงตำแหน่งที่ต้องการได้ก่อนที่จะขันให้แน่น หลังจากติดตั้งเสร็จแล้วคุณสามารถต่อขยายสายไฟของมอเตอร์เซอร์โวทั้งสามเครื่องได้ ฉันใช้สายชายกับหญิงเพื่อขยายและนำไปยังแผงวงจร ตรวจสอบให้แน่ใจว่าคุณใช้สายไฟอย่างถูกต้องเพื่อไม่ให้ลอดเข้ามาในขณะที่ Arm กำลังทำงาน เมื่อประกอบแขนหุ่นยนต์ของฉันขึ้นมาแล้วมองภาพแบบนี้ในภาพด้านล่าง
รวบรวมชิ้นส่วนที่พิมพ์ 3D ทั้งแขนหุ่นยนต์

แผนภูมิวงจรรวม

มอเตอร์เซอร์โว MG995 ทำงานร่วมกับ 5V และคณะกรรมการ Arduino มีตัวควบคุม 5V ด้วย ดังนั้นการสร้างวงจรเป็นเรื่องง่ายมาก เราต้องเชื่อมต่อมอเตอร์เซอร์โว 5 ตัวกับหมุดPWM ของ Arduinoและ 5 โพเทนชิโอมิเตอร์ไปยังหมุดอนาล็อก Arduino เพื่อควบคุมเซอร์โวมอเตอร์ แผนภาพวงจรสำหรับเดียวกันจะได้รับด้านล่าง
 แผนภาพสำหรับการบันทึกและเล่น 3D แขนพิมพ์ด้วย Arduino

สำหรับวงจรนี้ฉันไม่ได้ใช้แหล่งพลังงานภายนอกใด ๆ Arduino ใช้พลังงานจากพอร์ต USB และขา 5 V บนบอร์ดใช้ในการจ่ายพลังงานให้ Potentiometer และ Servo motor ในแขนหุ่นยนต์ของเราในช่วงเวลาใด ๆ ตัวอย่างเช่นมอเตอร์ไฟฟ้าหนึ่งตัวจะเคลื่อนไหวได้เพราะฉะนั้นการบริโภคในปัจจุบันจะน้อยกว่า 150mAซึ่งสามารถมาจากตัวควบคุมแรงดันไฟฟ้าบนกระดานของคณะกรรมการ Arduino ได้
เรามี5 Servo ยนต์และ 5 มิเตอร์จะควบคุมพวกเขาตามลำดับ 5 โพเทนชิโอมิเตอร์เหล่านี้เชื่อมต่อกับหมุดอนาล็อก 5 ตัว A0 ถึง A4 ของบอร์ด Arduino มอเตอร์เซอร์โวถูกควบคุมโดยสัญญาณ PWM ดังนั้นเราจึงต้องเชื่อมต่อกับหมุด PWM ของ Arduino เมื่อ Arduino Nano หมุด D3, D5, D6, D9 และ D11 สนับสนุนเฉพาะ PWM ดังนั้นเราจึงใช้หมุด 5 ตัวแรกสำหรับเซอร์โวมอเตอร์ของเรา ฉันได้ใช้กระดาน perf เพื่อประสานการเชื่อมต่อและคณะกรรมการของฉันดูคล้ายกับด้านล่างนี้เมื่อเสร็จสิ้น ฉันยังได้เพิ่มแจ็คกระบอกเพื่อเปิดใช้งานอุปกรณ์ผ่านแบตเตอรี่หากจำเป็น อย่างไรก็ตามมันเป็นตัวเลือกที่สมบูรณ์
โพเทนชิออมิเตอร์ 5 ตัวเพื่อควบคุมเซอร์โวมอเตอร์ 5 ตัว

ถ้าคุณเป็นคนใหม่อย่างสมบูรณ์กับเซอร์โวมอเตอร์และอาร์บูดิโนคุณควรอ่านข้อมูลพื้นฐานเกี่ยวกับเซอร์โวมอเตอร์และการควบคุมเซอร์โวกับ Arduinoก่อนที่คุณจะดำเนินโครงการต่อไป

Arduino สำหรับแขนหุ่นยนต์

ตอนนี้ส่วนที่สนุกคือการเขียนโปรแกรม Arduino เพื่อให้ผู้ใช้สามารถบันทึกการเคลื่อนไหวโดยใช้ POT แล้วเล่นเมื่อจำเป็น การทำเช่นนี้เราต้องตั้งโปรแกรม Arduino ไว้สองโหมด เมื่อเป็นโหมดบันทึกและอื่น ๆ ที่เป็นโหมดการเล่น ผู้ใช้สามารถสลับระหว่างสองโหมดโดยใช้จอแสดงผลแบบอนุกรม โปรแกรมที่สมบูรณ์จะทำเช่นเดียวกันสามารถพบได้ที่ด้านล่างของหน้านี้คุณสามารถใช้โปรแกรมตามที่มันเป็น แต่ด้านล่างนี้ฉันได้อธิบายโปรแกรมด้วยตัวอย่างขนาดเล็กเพื่อให้คุณเข้าใจ
เช่นเคยเราเริ่มต้นโปรแกรมโดยการเพิ่มไฟล์ส่วนหัวที่ต้องการ ที่นี่ไฟล์ส่วนหัวServo.hถูกใช้เพื่อควบคุมเซอร์โวมอเตอร์ เรามีเซอร์โวมอเตอร์ 5 ตัวและด้วยเหตุนี้ 5 ชิ้นจึงถูกประกาศให้มอเตอร์แต่ละชื่อ เรายังเริ่มต้นตัวแปรที่เราจะใช้ใน progam ฉันได้ประกาศให้ทุกคนเป็นสากล แต่คุณสามารถเปลี่ยนขอบเขตหากคุณสนใจในการเพิ่มประสิทธิภาพของโปรแกรม เราได้ประกาศอาร์เรย์ที่เรียกว่าsaved_dataซึ่งชื่อรัฐจะบันทึกการเคลื่อนไหวที่บันทึกไว้ทั้งหมดของ ARM หุ่นยนต์
#include <Servo.h> // ไฟล์ส่วนหัวของ Servo

// ประกาศวัตถุสำหรับ Servo Servo Servo Servo 5 
ตัว; 
Servo Servo_1; 
เซอร์โวเซอร์โว 2; 
Servo Servo_3; 
Servo Gripper;

// ประกาศเกี่ยวกับตัวแปรสากล
int S0_pos, S1_pos, S2_pos, S3_pos, G_pos; 
int P_S0_pos, P_S1_pos, P_S2_pos, P_S3_pos, P_G_pos; 
int C_S0_pos, C_S1_pos, C_S2_pos, C_S3_pos, C_G_pos; 
int POT_0, POT_1, POT_2, POT_3, POT_4;

int saved_data [700]; // อาร์เรย์สำหรับบันทึกข้อมูลที่บันทึกไว้

int array_index = 0; 
ถ่านเข้า = 0;

int action_pos; 
int action_servo;

ภายในฟังก์ชั่นการตั้งค่าโมฆะเราจะเริ่มการสื่อสารแบบอนุกรมที่ความเร็ว 9600 baud rate นอกจากนี้เรายังระบุขาที่มอเตอร์เซอร์โวติดอยู่ด้วย ที่นี่ในกรณีของเราเราได้ใช้หมุด 3,5,6,9 และ 10 ซึ่งระบุโดยใช้ฟังก์ชันattach เนื่องจากฟังก์ชั่นการตั้งค่าทำงานระหว่างเริ่มต้นเราสามารถใช้มันเพื่อตั้งแขนหุ่นยนต์ของเราในตำแหน่งเริ่มต้น ดังนั้นฉันได้ hardcoded ตำแหน่งค่าสำหรับทั้งห้ามอเตอร์ ค่าที่เข้ารหัสแบบ hardcoded เหล่านี้สามารถเปลี่ยนแปลงได้ตามความต้องการของคุณในภายหลัง เมื่อสิ้นสุดฟังก์ชันการตั้งค่าเราจะพิมพ์บรรทัดอนุกรมเพื่อขอให้ผู้ใช้กด R หรือ P เพื่อดำเนินการที่สอดคล้องกัน
การตั้งค่าเป็นโมฆะ () { 
Serial.begin (9600); // การตรวจสอบ Serial Debugging

// ถอดหมุดที่ Servo Motors เชื่อมต่อกับ
Servo_0.attach (3); 
Servo_1.attach (5) 
Servo_2.attach (6); 
Servo_3.attach (9); 
Gripper.attach (10);

// เขียนเซอร์โวมอเตอร์ลงในตำแหน่งเริ่ม
ต้น Servo_0.write (70); 
Servo_1.write (100); 
Servo_2.write (110); 
Servo_3.write (10); 
Gripper.write (10);

Serial.println ("กด" R "เพื่อบันทึกและ" P "เพื่อเล่น"); // ให้ผู้ใช้เป็นผู้ใช้
}

ฉันได้กำหนดฟังก์ชันที่เรียกว่าRead_POTซึ่งจะอ่านค่าแอนะล็อกทั้งหมด 5 โพเทนชิออมิเตอร์และแม็ปกับค่าตำแหน่งเซอร์โว ดังที่เราทราบ Arduino มี ADC 8 บิตซึ่งทำให้เราได้ผลลัพธ์จาก 0-1023 แต่ค่าตำแหน่งของเซอร์โวมอเตอร์มีตั้งแต่ 0-180 นอกจากนี้เนื่องจากมอเตอร์เซอร์โวเหล่านี้ไม่ค่อยแม่นยำมากไม่ปลอดภัยที่จะขับไปที่ปลายสุด 0 หรือ 180 ปลายดังนั้นเราจึงกำหนดให้ 10-170 เป็นขีด จำกัด ของเรา เราใช้ฟังก์ชันแผนที่เพื่อแปลง 0-1023 เป็น 10-170 สำหรับมอเตอร์ทั้งห้าดังที่แสดงด้านล่าง
void Read_POT () / / ฟังก์ชั่นเพื่ออ่านรูปแบบค่าอะนาล็อก POT และแม็ปไปยังค่า Servo 
{ 
   POT_0 = analogRead (A0); POT_1 = analogRead (A1); POT_2 = analogRead (A2); POT_3 = analogRead (A3); POT_4 = อะนาล็อกRead (A4); // อ่านค่าแบบอะนาล็อกจากทั้ง 5 POT 
   S0_pos = map (POT_0,0,1024,10,170); / / แผนที่สำหรับ servo ที่ 1 (ฐานมอเตอร์) 
   S1_pos = แผนที่ (POT_1,0,1024,10,170); // แผนที่สำหรับ servo ที่ 2 (มอเตอร์สะโพก) 
   S2_pos = แผนที่ (POT_2,0,1024,10,170); // แผนที่สำหรับ Servo ที่ 3 (มอเตอร์ไหล่) 
   S3_pos = แผนที่ (POT_3,0,1024,10,170); / / แผนที่สำหรับเซอร์โว 4 (คอยนต์) 
   G_pos = แผนที่ (POT_4,0,1024,10,170); / / แผนที่สำหรับเซอร์โว 5 (Gripper motor) 
}

รหัสโหมดการบันทึก

ในโหมดการบันทึกผู้ใช้ต้องควบคุมบอทโดยใช้โพเทนชิพมิเตอร์ แต่ละ POT สอดคล้องกับมอเตอร์แต่ละตัวเนื่องจากหม้อมีความหลากหลายเราควรบันทึกตำแหน่งของมอเตอร์และหมายเลขมอเตอร์ภายในอาร์เรย์saved_data ลองดูวิธีการที่จะทำได้โดยใช้ฟังก์ชั่นRecord

ขจัดปัญหา Jitter กับ Servo
เมื่อทำงานกับเซอร์โวมอเตอร์เหล่านี้ปัญหาทั่วไปที่ทุกคนอาจเจอคือมอเตอร์อาจกระวนกระวายใจขณะทำงาน มีปัญหามากมายสำหรับปัญหานี้อันดับแรกคุณต้องแยกแยะว่าปัญหาเกิดจากวงจรควบคุมของมอเตอร์หรือมีค่าตำแหน่งที่เขียนลงในเซอร์โวมอเตอร์ ในกรณีของฉันฉันใช้จอแสดงผลแบบอนุกรมและพบว่าค่าของservo_posไม่ได้ซ้ายคงที่และบางครั้งกระวนกระวายใจขึ้น / ลงสุ่ม
ดังนั้นผมจึงตั้งโปรแกรม Arduino ในการอ่านค่า POT สองครั้งและเปรียบเทียบค่าทั้ง ค่าจะได้รับตามค่าที่ถูกต้องเฉพาะเมื่อค่าทั้งสองมีค่าเท่ากันค่าจะถูกยกเลิก Thankfully นี้แก้ไขปัญหากระวนกระวายใจสำหรับฉัน ตรวจสอบให้แน่ใจว่า POT ติดตั้งอย่างแน่นหนา (I soldered) ให้กับขาอะนาล็อกของ Arduino การสูญเสียการเชื่อมต่อใด ๆ จะทำให้เกิดความกระวนกระวายใจ ตัวแปรP_x_posถูกใช้เพื่อบันทึกค่าเก่าแล้วจึงอ่านและแมปค่าx_posโดยใช้ฟังก์ชันRead_POT ที่กล่าวมาข้างต้น
Read_POT (); // อ่านค่า POT สำหรับครั้งที่ 1 
// บันทึกใน varibale เพื่อเปรียบเทียบในภายหลัง
   P_S0_pos = S0_pos; 
   P_S1_pos = S1_pos; 
   P_S2_pos = S2_pos; 
   P_S3_pos = S3_pos; 
   P_G_pos = G_pos; 
Read_POT (); // อ่านค่า POT เป็นครั้งที่ 2

ตอนนี้เราจะต้องควบคุมตำแหน่งของเซอร์โวมอเตอร์ถ้าค่าที่ถูกต้อง นอกจากนี้หลังจากการควบคุมเราต้องบันทึกหมายเลขมอเตอร์และตำแหน่งมอเตอร์ในอาร์เรย์ เราสามารถใช้สองอาร์เรย์ที่แตกต่างกันหนึ่งสำหรับหมายเลขมอเตอร์และอื่น ๆ สำหรับตำแหน่งของมัน แต่เพื่อประหยัดหน่วยความจำและความซับซ้อนฉันได้รวมทั้งของพวกเขาโดยการเพิ่มค่าความแตกต่างกับค่า pos ก่อนที่จะบันทึกในอาร์เรย์
   ถ้า (P_S0_pos == S0_pos) // ถ้าค่าที่ 1 และ 2 เหมือนกัน
   { 
    Servo_0.write (S0_pos); // ควบคุมเซอร์โว
    ถ้า (C_S0_pos! = S0_pos) // ถ้า POT ถูกเปิด    {       saved_data [array_index] = S0_pos + 0; // บันทึกตำแหน่งใหม่ลงในอาร์เรย์ มีการเพิ่มศูนย์สำหรับ zeroth motor (สำหรับวัตถุประสงค์ในการ understading)       array_index ++; // เพิ่มดัชนีอาร์เรย์    }     C_S0_pos = S0_pos; // บันทึกค่าก่อนหน้านี้เพื่อตรวจสอบว่าได้เปิด POT แล้วหรือไม่   }   





   


ค่าความแตกต่างของ Sero_0 คือ 0 และ Servo_1 เท่ากับ 1000 สำหรับ Servo_3 เท่ากับ 3000 และสำหรับ Gripper เป็น 4000 เส้นของรหัสที่มีการเพิ่มความแตกต่างของค่าตำแหน่งและบันทึกลงในอาร์เรย์จะแสดงอยู่ด้านล่าง
saved_data [array_index] = S0_pos + 0; // บันทึกตำแหน่งใหม่ลงในอาร์เรย์ มีการเพิ่มศูนย์สำหรับมอเตอร์ zeroth (เพื่อวัตถุประสงค์ในการ understading) 
saved_data [array_index] = S1_pos + 1000; / / 1000 จะถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 1 เป็น differentiater 
saved_data [array_index] = S2_pos + 2000; // 2000 ถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 2 เป็น differentiater 
saved_data [array_index] = S3_pos + 3000; // 3000 จะถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 3 เป็น differentiater 
saved_data [array_index] = G_pos + 4000; // 4000 จะถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 4 เป็น differentiater

รหัสโหมดการเล่น

หลังจากที่ผู้ใช้มีการบันทึกการเคลื่อนไหวในที่saved_dataเขาสามารถสลับไปยังโหมดการเล่นโดยการป้อน 'P” ในจอแสดงผลแบบอนุกรม ภายในโหมดการเล่นเรามีการเข้าถึงแต่ละองค์ประกอบที่บันทึกไว้ในอาร์เรย์และแบ่งค่าเพื่อให้ได้หมายเลขมอเตอร์และตำแหน่งมอเตอร์และควบคุมตำแหน่งของตนตามลำดับ
เราใช้ลูปforเพื่อนำทางไปยังทุกองค์ประกอบของอาร์เรย์ไม่เกินค่าที่บันทึกไว้ในอาร์เรย์ จากนั้นเราจะใช้ตัวแปรสองตัวคือaction_servoและaction_posเพื่อรับจำนวนเซอร์โวมอเตอร์ที่จะควบคุมและตำแหน่งตามลำดับ เพื่อให้ได้จำนวนเซอร์โวมอเตอร์เราจะหารด้วย 1000 และเพื่อให้ได้ตำแหน่งที่เราต้องใช้ตัวเลขสามตัวสุดท้ายซึ่งสามารถหาได้โดยการใช้โมดูลัส
ตัวอย่างเช่นถ้าค่าที่บันทึกไว้ในอาร์เรย์เป็น 3125 แล้วมันหมายความว่า 3 ยนต์จะต้องมีการย้ายไปยังตำแหน่งของ 125
  สำหรับ (int Play_action = 0; Play_action <array_index; Play_action ++) // นำทางผ่านทุกองค์ประกอบที่บันทึกไว้ในอาร์เรย์
  { 
    action_servo = saved_data [Play_action] / 1000; // charector กำปั้นขององค์ประกอบอาร์เรย์ถูกแยกออกเพื่อทราบจำนวน servo 
    action_pos = saved_data [Play_action]% 1000; / / สาม charectors สุดท้ายขององค์ประกอบอาร์เรย์จะแยกออกเพื่อทราบตำแหน่ง servo

ตอนนี้ทั้งหมดที่เหลือจะทำมันใช้หมายเลขเซอร์โวและย้ายไปยังที่คุ้มค่าที่ได้รับตำแหน่งของเซอร์โว ฉันได้ใช้กรณีเปลี่ยนเพื่อเข้าหมายเลขมอเตอร์เซอร์โวและฟังก์ชั่นเขียนเพื่อย้ายเซอร์โวมอเตอร์ไปยังตำแหน่งนั้น กรณีสวิทซ์จะแสดงอยู่ด้านล่าง
    เปลี่ยน (action_servo) {// ตรวจสอบเซอร์โวมอเตอร์ที่ควรจะควบคุม
      กรณี 0: // ถ้า zeroth motor 
        Servo_0.write (action_pos); 
      ทำลาย;

      กรณีที่ 1: // ถ้าใช้
        Servo_1.write motoric ตัวแรก (action_pos); 
      ทำลาย;

      กรณีที่ 2: // ถ้าใช้
        Servo_2.write เซอร์โว
2 (action_pos);       ทำลาย;

      กรณีที่ 3: // ถ้ามี
        Servo_3.write 
ยนต์ที่สาม (action_pos);       ทำลาย;

      กรณีที่ 4: // ถ้ามอเตอร์
        Gripper.write 
4 ตัว(action_pos);       ทำลาย;

ฟังก์ชันลูปหลัก
ภายในฟังก์ชั่นลูปหลักเราจะต้องตรวจสอบสิ่งที่ผู้ใช้ป้อนผ่านจอแสดงผลแบบอนุกรมและรันโหมดบันทึกของโหมดการเล่นตามลำดับ ตัวแปรขาเข้าใช้เพื่อเก็บค่าของผู้ใช้ หากป้อน 'R' โหมดบันทึกจะเปิดใช้งานและหาก 'P' ถ้ากดโหมด Play จะทำงานโดยถ้าข้อความเงื่อนไขตามที่แสดงด้านล่าง
void loop () {

ถ้า (Serial.available ()> 1) / / ถ้ามี recevied จากจอภาพอนุกรม
{ 
incoming = Serial.read (); 
ถ้า (incoming == 'R') 
Serial.println ("เริ่มบันทึกแขนหุ่นยนต์ ...... "); 
ถ้า (เข้ามา == 'P') 
Serial.println ("การเล่นลำดับบันทึก"); 
}

if (incoming == 'R') // ถ้าผู้ใช้เลือก Record mode 
Record ();

if (incoming == 'P') // หากผู้ใช้เลือก Play Mode 
Play (); 
}

การทำงานของ ARM แบบบันทึกและเล่น

ทำการเชื่อมต่อตามที่แสดงในแผนภาพวงจรและอัปโหลดรหัสที่ระบุด้านล่าง ให้ Arduino Nano ของคุณใช้พอร์ต USB ของคอมพิวเตอร์ของคุณและเปิดจอภาพแบบอนุกรมคุณจะได้รับการต้อนรับด้วยข้อความแนะนำนี้
ส่ง R เพื่อบันทึกการเคลื่อนไหวของ Robotic Arm

ตอนนี้ให้ป้อน R ในจอแสดงผลอนุกรมแล้วกด Enter โปรดทราบว่าควรเลือกบรรทัดล่างของจอภาพแบบอนุกรม Newline เมื่อเข้าสู่บอทจะเข้าสู่โหมดการบันทึกและคุณจะหน้าจอต่อไปนี้
ตำแหน่งการบันทึก Servos ของแขนหุ่นยนต์

ข้อมูลที่แสดงที่นี่สามารถใช้สำหรับการดีบัก ตัวเลขที่เริ่มต้นจากแบบ 69 เป็นตำแหน่งปัจจุบันของเซอร์โวมอเตอร์ 0 ถึงมอเตอร์ 5 ค่าดัชนีจะเป็นขนาดอาร์เรย์ โปรดทราบว่าอาร์เรย์ที่เราใช้อยู่มีจำนวน จำกัด 700 ดังนั้นเราจึงได้บันทึกการเคลื่อนไหวทั้งหมดก่อนที่เราจะเกินขีด จำกัด นั้น หลังจากการบันทึกเสร็จสิ้นเราสามารถใส่ P ในจอมอนิเตอร์แบบอนุกรมและกด Enter และเราจะเข้าสู่โหมด Play และจอภาพอนุกรมจะแสดงข้อมูลต่อไปนี้
ส่ง P เพื่อเล่นการเคลื่อนไหวของ Robotic Arm

ในโหมดการเล่นหุ่นยนต์จะทำซ้ำการเคลื่อนไหวเดียวกันที่ทำในโหมดบันทึกภาพ การเคลื่อนไหวเหล่านี้จะถูกเรียกใช้อีกครั้งและอีกครั้งจนกว่าคุณจะขัดจังหวะผ่านจอแสดงผลแบบอนุกรม การทำงานที่สมบูรณ์สามารถพบได้ที่วิดีโอที่เชื่อมโยงอยู่ด้านล่างของหน้า
หวังว่าคุณจะเข้าใจโครงการนี้และสนุกกับการสร้างโครงการ หากคุณมีปัญหาในการทำให้การทำงานคุณสามารถใช้ส่วนความคิดเห็นด้านล่างหรือฟอรั่มสำหรับความช่วยเหลือทางเทคนิคเพิ่มเติม คุณสามารถใช้บอทนี้และสร้างสิ่งต่างๆขึ้นด้านบนได้ ฉันวางแผนจะให้วิสัยทัศน์โดยใช้ Raspberry Pi และ Open CV และตรวจสอบสิ่งที่สามารถทำได้ ความคิดของคุณคืออะไร? ปล่อยให้พวกเขาอยู่ในส่วนความคิดเห็นและเรายินดีที่จะรับฟังจากคุณ 
รหัส
/ * 
   ARM หุ่นยนต์ที่มีตัวเลือก Record and Play โดยใช้ Arduino 
   Code โดย: B. Aswinth Raj 
   เว็บไซต์: www.circuitdigest.com
   วันที่: 05-08-2018 
* /
#include <Servo.h> // ไฟล์ส่วนหัวของ Servo
// ประกาศวัตถุสำหรับ Servo Servo Servo Servo 5   
ตัว; 
Servo Servo_1; 
เซอร์โวเซอร์โว 2; 
Servo Servo_3; 
Servo Gripper;
// ประกาศเกี่ยวกับตัวแปรสากล  
int S0_pos, S1_pos, S2_pos, S3_pos, G_pos; 
int P_S0_pos, P_S1_pos, P_S2_pos, P_S3_pos, P_G_pos; 
int C_S0_pos, C_S1_pos, C_S2_pos, C_S3_pos, C_G_pos; 
int POT_0, POT_1, POT_2, POT_3, POT_4;
int saved_data [700]; // อาร์เรย์สำหรับบันทึกข้อมูลที่บันทึกไว้
int array_index = 0; 
ถ่านเข้า = 0;
int action_pos; 
int action_servo;
การตั้งค่าเป็นโมฆะ () { 
Serial.begin (9600); // การตรวจสอบ Serial Debugging
// แจ้งหมุดที่ Servo Motors เชื่อมต่อกับ  
Servo_0.attach (3); 
Servo_1.attach (5) 
Servo_2.attach (6); 
Servo_3.attach (9); 
Gripper.attach (10);
// เขียนเซอร์โวมอเตอร์ไปที่ตำแหน่งเริ่มต้น  
Servo_0.write (70); 
Servo_1.write (100); 
Servo_2.write (110); 
Servo_3.write (10); 
Gripper.write (10);
Serial.println ("กด" R "เพื่อบันทึกและ" P "เพื่อเล่น"); // สั่งให้ผู้ใช้  
}
void Read_POT () / / ฟังก์ชั่นเพื่ออ่านรูปแบบค่าอะนาล็อก POT และแม็ปไปยังค่า Servo 

   POT_0 = analogRead (A0); POT_1 = analogRead (A1); POT_2 = analogRead (A2); POT_3 = analogRead (A3); POT_4 = อะนาล็อกRead (A4); // อ่านค่าแบบอะนาล็อกจากทั้ง 5 POT 
   S0_pos = map (POT_0,0,1024,10,170); / / แผนที่สำหรับ servo ที่ 1 (ฐานมอเตอร์) 
   S1_pos = แผนที่ (POT_1,0,1024,10,170); // แผนที่สำหรับ servo ที่ 2 (มอเตอร์สะโพก) 
   S2_pos = แผนที่ (POT_2,0,1024,10,170); // แผนที่สำหรับ Servo ที่ 3 (มอเตอร์ไหล่) 
   S3_pos = แผนที่ (POT_3,0,1024,10,170); / / แผนที่สำหรับเซอร์โว 4 (คอยนต์) 
   G_pos = แผนที่ (POT_4,0,1024,10,170); / / แผนที่สำหรับเซอร์โว 5 (Gripper motor) 
}
void Record () // Function to Record การเคลื่อนไหวของหุ่นยนต์

Read_POT (); // อ่านค่า POT เป็นครั้งแรก
/ / บันทึกไว้ในตัวแปรเพื่อเปรียบเทียบในภายหลัง
   P_S0_pos = S0_pos; 
   P_S1_pos = S1_pos; 
   P_S2_pos = S2_pos; 
   P_S3_pos = S3_pos; 
   P_G_pos = G_pos; 
   
Read_POT (); // อ่านค่า POT เป็นครั้งที่ 2 
  
   if (P_S0_pos == S0_pos) // ถ้าค่าที่ 1 และ 2 เหมือนกัน
   { 
    Servo_0.write (S0_pos); // ควบคุมเซอร์โว
    
    ถ้า (C_S0_pos! = S0_pos) // ถ้า POT ถูกเปิด  
    { 
      saved_data [array_index] = S0_pos + 0; // บันทึกตำแหน่งใหม่ลงในอาร์เรย์ มีการเพิ่มศูนย์สำหรับ zeroth motor (สำหรับวัตถุประสงค์ในการ understading) 
      array_index ++; // เพิ่มดัชนีอาร์เรย์  
    }
    
    C_S0_pos = S0_pos; // บันทึกค่าก่อนหน้านี้เพื่อตรวจสอบว่าได้เปิด POT แล้วหรือไม่  
   }
/ / ในทำนองเดียวกันทำซ้ำสำหรับทั้ง 5 ยนต์เซอร์โว
   ถ้า (P_S1_pos == S1_pos) 
   { 
    Servo_1.write (S1_pos); 
    
    if (C_S1_pos! = S1_pos) 
    { 
      saved_data [array_index] = S1_pos + 1000; / / 1000 ถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 1 เป็น
      array_index ที่แตกต่าง  ++; 
    } 
    
    C_S1_pos = S1_pos; 
   }
   if (P_S2_pos == S2_pos) 
   { 
    Servo_2.write (S2_pos); 
    
    if (C_S2_pos! = S2_pos) 
    { 
      saved_data [array_index] = S2_pos + 2000; // 2000 ถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 2 เป็น
      array_index ที่แตกต่าง  ++; 
    } 
    
    C_S2_pos = S2_pos; 
   }
   if (P_S3_pos == S3_pos) 
   { 
    Servo_3.write (S3_pos); 
    
    if (C_S3_pos! = S3_pos) 
    { 
      saved_data [array_index] = S3_pos + 3000; // 3000 จะถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 3 เป็น
      array_index ที่แตกต่าง  ++; 
    } 
    
    C_S3_pos = S3_pos;   
   }
   if (P_G_pos == G_pos) 
   { 
    Gripper.write (G_pos); 
    
    if (C_G_pos! = G_pos) 
    { 
      saved_data [array_index] = G_pos + 4000; // 4000 จะถูกเพิ่มสำหรับเซอร์โวมอเตอร์ที่ 4 เป็น
      array_index ที่แตกต่าง  ++; 
    } 
    
    C_G_pos = G_pos; 
   } 
   
  // พิมพ์ค่าสำหรับการดีบัก  
  Serial.print (S0_pos); Serial.print (""); Serial.print (S1_pos); Serial.print (""); Serial.print (S2_pos); Serial.print (""); Serial.print (S3_pos); Serial.print (""); Serial.println (G_pos); 
  Serial.print ("Index ="); Serial.println (array_index); 
  ล่าช้า (100); 
}

เป็นโมฆะ () เล่น // functon การเล่นการเคลื่อนไหวที่บันทึกอยู่ในแขนหุ่นยนต์

  สำหรับ (int Play_action = 0; Play_action <array_index; Play_action ++) // นำทางผ่านองค์ประกอบที่บันทึกไว้ทุกในอาร์เรย์  
  { 
    action_servo = saved_data [Play_action] / 1000 // อักขระกำปั้นขององค์ประกอบอาร์เรย์ถูกแยกออกเพื่อทราบจำนวน
    แอ็คชัน action_pos = saved_data [Play_action]% 1000; / / สามตัวสุดท้ายขององค์ประกอบอาร์เรย์ถูกแยกออกเพื่อทราบตำแหน่ง servo 
    เปลี่ยน (action_servo) {// ตรวจสอบเซอร์โวมอเตอร์ที่ควรจะควบคุม  
      กรณี 0: // ถ้า zeroth motor 
        Servo_0.write (action_pos); 
      ทำลาย;
      กรณีที่ 1: // ถ้าใช้
        Servo_1.write motoric ตัวแรก (action_pos); 
      ทำลาย;
      กรณีที่ 2: // ถ้าใช้
        Servo_2.write เซอร์โว(action_pos); 
      ทำลาย;
      กรณีที่ 3: // ถ้ามี
        Servo_3.write ยนต์ที่สาม (action_pos); 
      ทำลาย;
      กรณีที่ 4: // ถ้ามอเตอร์
        Gripper.write 4 ตัว(action_pos); 
      ทำลาย; 
    }
    ล่าช้า (50); 
    
  } 
}

void loop () {
ถ้า (Serial.available ()> 1) / / ถ้าสิ่งที่ได้รับจากการตรวจสอบอนุกรม  

incoming = Serial.read (); 
ถ้า (incoming == 'R') 
Serial.println ("เริ่มบันทึกแขนหุ่นยนต์ ...... "); 
ถ้า (เข้ามา == 'P') 
Serial.println ("การเล่นลำดับบันทึก"); 
}
if (incoming == 'R') // ถ้าผู้ใช้เลือก Record mode 
Record ();
if (incoming == 'P') // หากผู้ใช้เลือก Play Mode  
Play ();
}