תוכן עניינים:

בקרת תנועה גימבל: 12 שלבים
בקרת תנועה גימבל: 12 שלבים

וִידֵאוֹ: בקרת תנועה גימבל: 12 שלבים

וִידֵאוֹ: בקרת תנועה גימבל: 12 שלבים
וִידֵאוֹ: איך מחליפים קצה מרובע של ניסאן MT3000 או מוט בקרה 2024, נוֹבֶמבֶּר
Anonim
Image
Image

שלום לכולם, שמי הארג'י נגי. כרגע אני סטודנט שנה שני לומד הנדסת אלקטרוניקה ותקשורת מהמכון הטכנולוגי Pranveer Singh, קאנפור (UP). יש לי עניין רב ברובוטיקה, ארדואינו, בינה מלאכותית ואלקטרוניקה אנלוגית.

המילה "gimbal" מוגדרת כתמיכה מסתובבת המאפשרת סיבוב של כל אובייקט בציר יחיד. אז גימבל בעל שלושה צירים מאפשר לכל אובייקט המותקן על הגמבל להיות בלתי תלוי בתנועתו של האוחז בגמבל. הג'ימבל מכתיב את תנועת האובייקט, לא את הנושא אותו.

הוא מורכב משלושה מנועי סרוו MG996R לשליטה בעלת 3 צירים, ובסיס שעליו יוצבו חיישן MPU6050, הארדואינו והסוללה. הוא משמש לשמירה על יציבות המצלמה ללא רעידות. גימבל בעל 3 צירים מבטיח שתנועת המצלמה תתייצב גם אם זה שמחזיק אותה עולה ויורד, שמאלה וימינה, מלפנים ומאחור. לזה אנו מתייחסים לייצוב פיה, גובה וגלגול.

שלב 1: רשימת רכיבים

רשימת הרכיבים הם:

1) ארדואינו אונו

2) סוללת 8V, 1.5 אמפר להפעלת Arduino Uno

3) 7805 ווסת מתח Ic או שאתה יכול להשתמש במכונת כף

4) MPU 6050

5) 3*(מנועי MG995 SERVO)

6) חוטי מגשר

ציוד אחר:

1) מלחם

2) אקדח דבק

3) מכונת מקדחה

4) פחית אוכל

במקום להשתמש ב- breadborad יש לי שימוש בלוח פרפר קטן מותאם אישית לחיבור אוטובוס חיובי ושלילי

שלב 2: הרכבה

הרכבה
הרכבה
הרכבה
הרכבה

לוח קצף, לוח קצף או לוח קצף בעל נייר הינו חומר קל משקל וחתוך בקלות המשמש להרכבת מנוע סרוו וייצור דגמי קנה מידה.

ראשית הכנתי סוגריים בצורת L להרכבת מנוע סרוו בעזרת לוח קצף.

שלב 3:

תמונה
תמונה

הרכבת הג'ימבל הייתה די קלה. התחלתי בהתקנת סרוו Yaw, חיישן MPU 6050 ומתג ON-OFF. בעזרת ברגים ואומים הדקתי אותו לבסיס

שלב 4: לאחר מכן, באותה שיטה אבטחתי את סרוו הגלילים. החלקים נועדו במיוחד להתאמה נוחה של סרווסי MG995

לאחר מכן, באותה שיטה אבטחתי את סרוו הגלילים. החלקים נועדו במיוחד להתאמה נוחה של סרוו MG995
לאחר מכן, באותה שיטה אבטחתי את סרוו הגלילים. החלקים נועדו במיוחד להתאמה נוחה של סרוו MG995

שלב 5: לאחר מכן, באותה שיטה אבטחתי את סרוו הגלילים. החלקים נועדו במיוחד להתאמה נוחה של סרוו MG995

לאחר מכן, באותה שיטה אבטחתי את סרוו הגלילים. החלקים נועדו במיוחד להתאמה נוחה של סרוו MG995
לאחר מכן, באותה שיטה אבטחתי את סרוו הגלילים. החלקים נועדו במיוחד להתאמה נוחה של סרוו MG995

שלב 6: חיבורים

חיבורים
חיבורים

בתרשים המעגלים אתה יכול להשתמש בממיר באק או בווסת מתח 7805 להמרת 8V ל -5 V. המיקרו -בקר שניתן לו דיאגרמת המעגל הוא Arduino Nano אתה יכול גם להשתמש ב- Arduino Uno, Arduino Mega.

סיכות SCL ו- SDA של MPU 6050 מחוברות לסיכה A5 ו- A4 אנלוגי של Arduino. (סיכת SCL ו- SDA עשויה להשתנות, עיין בנתוני הנתונים של סיכות SCl ו- SDA עבור מיקרו -בקר אחר)

שלב 7: חיבור עם IC רגולטור מתח 7805

חיבור עם IC ווסת מתח 7805
חיבור עם IC ווסת מתח 7805

תרשים מעגלים זה מיועד לחיבור של רגולטור המתח 7805, חבר את סוללת 8V ב Vin ותקבל מתח יציאה של 5v.

שלב 8: קידוד

עליך לכלול את הספריות הבאות:

1) #include לחץ כאן להורדת קובץ zip

2) #include לחץ כאן כדי להוריד קובץ zip

לאחר הורדת קובץ ה- zip, הוסף ספריית zip בסקיצה של ארדואינו

עבור קוד

/*

DIY Gimbal - קוד הדרכה Arduino MPU6050 מבוסס על הדוגמה MPU6050_DMP6 מספריית i2cdevlib מאת ג'ף רווברג: https://github.com/jrowberg/i2cdevlib */// I2Cdev ו- MPU6050 חייבים להיות מותקנים כספריות, או אחרת.cpp/ קבצי.h // לשני הכיתות חייבים להיות בנתיב הכלול של הפרויקט שלך #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" // #include "MPU6050.h" // אין צורך אם משתמשים בקובץ כולל MotionApps / / נדרשת ספריית Wire Arduino אם יישום I2Cdev I2CDEV_ARDUINO_WIRE // משמש ב- I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #כולל "Wire.h" #endif #include // כתובת ברירת מחדל I2C היא כתובת I2C ספציפית עבר כפרמטר כאן // AD0 נמוך = 0x68 (ברירת מחדל עבור פריצת SparkFun ולוח הערכה של InvenSense) // AD0 גבוה = 0x69 MPU6050 mpu; // MPU6050 mpu (0x69); // <- שימוש לגובה AD0 // הגדר את 3 מנועי הסרוו סרוו סרוו 0; סרוו סרוו 1; סרוו סרוו 2; צף נכון; int j = 0; #define OUTPUT_READABLE_YAWPITCHROLL #define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards bool blinkState = false; // MPU control/status vars bool dmpReady = false; // set true אם DMP init הצליח uint8_t mpuIntStatus; // מחזיק בתור סטטוס בפסיקה ממשית מ- MPU uint8_t devStatus; // סטטוס החזרה לאחר כל פעולת מכשיר (0 = הצלחה,! 0 = שגיאה) uint16_t packetSize; // גודל מנות DMP צפוי (ברירת המחדל היא 42 בתים) uint16_t fifoCount; // ספירת כל הבייטים הנמצאים כעת ב- FIFO uint8_t fifoBuffer [64]; // מאגר אחסון FIFO // כיוון/תנועה vars Quaternion q; // [w, x, y, z] מיכל רבעוני VectorInt16 aa; // [x, y, z] מדידות חיישן accel VectorInt16 aaReal; // [x, y, z] מדידות חיישן אקסל ללא כבידה VectorInt16 aaWorld; // [x, y, z] מדידות חיישן אקסל מסגרת עולמית מסגרת עולמית VectorFloat gravity; // [x, y, z] euler float float float [3]; // [psi, theta, phi] צף מיכל זווית אוילר ypr [3]; // [yaw, pitch, roll] מיכל yaw/pitch/roll ו- gravity // מבנה מנות לדגמת קומקום של InvenSense uint8_t teapotPacket [14] = {'$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\ r', '\ n'}; // ================================================= ===================== תכונת איתור הפרעות === // ====================== ========================================== בול נדיף mpuInterrupt = false; // מציין אם סיכת ההפרעה של MPU הפכה לחלל חלל dmpDataReady () {mpuInterrupt = true; } // ================================================ ================= //=== הגדרה ראשונית === // ====================== ============================================ הגדרת בטל () {// הצטרף לאוטובוס I2C (ספריית I2Cdev לא עושה זאת באופן אוטומטי) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin (); Wire.setClock (400000); // שעון I2C של 400kHz. הגיבו על שורה זו אם יש לכם קשיי הידור #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire:: setup (400, true); #endif // לאתחל תקשורת טורית // (115200 נבחר מכיוון שהיא נדרשת עבור פלט הדגמת קומקום, אבל זה // באמת תלוי בך בהתאם לפרויקט שלך) Serial.begin (38400); בעוד (! סדרתי); // חכו לספירה של לאונרדו, אחרים ממשיכים מיד // אתחול המכשיר //Serial.println(F("Initializing התקני I2C … ")); mpu.initialize (); pinMode (INTERRUPT_PIN, INPUT); devStatus = mpu.dmpInitialize (); // ספקו כאן קיזוזי גירו משלכם, בקנה מידה לרגישות מינימלית mpu.setXGyroOffset (17); mpu.setYGyroOffset (-69); mpu.setZGyroOffset (27); mpu.setZAccelOffset (1551); // 1688 ברירת המחדל של היצרן עבור שבב הבדיקה שלי // ודא שהוא עבד (מחזיר 0 אם כן) אם (devStatus == 0) {// הפעל את ה- DMP, כעת כשהוא מוכן // Serial.println (F ("הפעלת DMP… ")); mpu.setDMPEnabled (true); attachInterrupt (digitalPinToInterrupt (INTERRUPT_PIN), dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); // הגדר את הדגל Ready DMP שלנו כך שפונקציית הלולאה () הראשית תדע שזה בסדר להשתמש בו //Serial.println(F("DMP מוכן! מחכה להפסקה ראשונה … ")); dmpReady = true; // קבל את גודל חבילת DMP הצפויה להשוואה מאוחר יותר packetSize = mpu.dmpGetFIFOPacketSize (); } אחר {// שגיאה! // 1 = טעינת הזיכרון הראשונית נכשלה // 2 = עדכוני תצורת DMP נכשלו // (אם הוא עומד להישבר, בדרך כלל הקוד יהיה 1) // Serial.print (F ("אתחול DMP נכשל (קוד")); //Serial.print(devStatus); //Serial.println (F (")")); } // הגדר את הסיכות שאליהן מחוברים 3 מנועי הסרוו servo0.attach (10); servo1.attach (9); servo2.attach (8); } // ================================================ ====================== LOOP תכנית עיקרית === // ===================== ============================================ לולאת ריק () { / / אם התכנות נכשל, אל תנסה לעשות דבר אם (! dmpReady) תחזור; // המתן להפרעה MPU או למנות נוספות זמינות בזמן (! mpuInterrupt && fifoCount <packetSize) {if (mpuInterrupt && fifoCount

= 1024) {

// אפס כדי שנוכל להמשיך לנקות mpu.resetFIFO (); fifoCount = mpu.getFIFOCount (); Serial.println (F ("הצפת FIFO!")); // אחרת, בדוק אם נתוני DMP מוכנים להפריע (זה אמור לקרות בתדירות גבוהה)} אחרת אם (mpuIntStatus & _BV (MPU6050_INTERRUPT_DMP_INT_BIT)) {// המתן לאורך הנתונים הזמין הנכון, אמור להיות המתנה קצרה מאוד בזמן (חבילה זמינה של fifoCount 1 / / (זה מאפשר לנו מיד לקרוא יותר מבלי לחכות להפסקה) fifoCount -= packetSize; // קבל ערכי Yaw, Pitch and Roll #ifdef OUTPUT_READABLE_YAWPITCHROLL mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& mgrp, &;.dmpGetYawPitchRoll (ypr, & q, & gravity); // ערכי Yaw, Pitch, Roll - רדיאנים לדרגות ypr [0] = ypr [0] * 180 / M_PI; ypr [1] = ypr [1] * 180 / M_PI; ypr [2] = ypr [2] * 180 / M_PI; // דלג על 300 קריאות (תהליך כיול עצמי) אם (j <= 300) {correct = ypr [0]; // Yaw מתחיל בערך אקראי, אז אנחנו ללכוד את הערך האחרון אחרי 300 קריאות j ++;} // אחרי 300 קריאות אחרת {ypr [0] = ypr [0] - נכון; // הגדר את Yaw ל- 0 deg - הפחת את הערך Yaw האקראי האחרון מהערך הנוכחי כדי להפוך את יו 0 מעלות es // מפה את הערכים של חיישן MPU6050 מ -90 עד 90 לערכים המתאימים לבקרת סרוו מ 0 עד 180 int servo0Value = map (ypr [0], -90, 90, 0, 180); int servo1Value = map (ypr [1], -90, 90, 0, 180); int servo2Value = map (ypr [2], -90, 90, 180, 0); // שלוט בסרוווס בהתאם לכיוון servo0.write (servo0Value) בכיוון MPU6050; servo1.write (servo1Value); servo2.write (servo2Value); } #endif}}

לבסוף באמצעות פונקציית הכתיבה, אנו שולחים ערכים אלה לסרוווס כאותות שליטה. כמובן שאתה יכול להשבית את סרוו Yaw אם אתה רוצה ייצוב פשוט לציר ה- X וה- Y, ולהשתמש בפלטפורמה זו כגימבל מצלמה

שלב 9: כאשר כל הרכיבים מחוברים, מראהו דומה לתמונה זו

כאשר כל הרכיבים מחוברים, מראהו דומה לתמונה זו
כאשר כל הרכיבים מחוברים, מראהו דומה לתמונה זו

שלב 10: הכנס כעת את כל חומרי הבסיס לתוך פחית המזון

כעת הכנס את כל חומרי הבסיס לפחית המזון
כעת הכנס את כל חומרי הבסיס לפחית המזון

שלב 11: כאשר כל החוטים והרכיבים מונחים בתוך מזון יכול לאחר מכן להדביק אקדח דבק בבסיס לוח הקצף

כאשר כל החוטים והרכיבים ממוקמים בתוך מזון יכול לאחר מכן להדביק אקדח דבק בבסיס לוח הקצף
כאשר כל החוטים והרכיבים ממוקמים בתוך מזון יכול לאחר מכן להדביק אקדח דבק בבסיס לוח הקצף

שלב 12: סיכום

שים לב שזה רחוק מלהיות מצלמה טובה. התנועות אינן חלקות מכיוון שהסרווואים הללו אינם מיועדים למטרה כזו. מכנסי מצלמות אמיתיים משתמשים במנוע BLDC מסוג מיוחד לקבלת תנועות חלקות. לכן, שקול את הפרויקט הזה רק למטרות חינוכיות.

זה הכל בשביל ההדרכה הזו, אני מקווה שנהניתם ולמדתם משהו חדש. אל תהסס לשאול כל שאלה בקטע ההערות למטה ואל תשכח לבדוק את אוספי הפרויקטים שלי

מוּמלָץ: