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

וואלאס - רובוט אוטונומי עשה זאת בעצמך - חלק 5 - הוסף IMU: 9 שלבים
וואלאס - רובוט אוטונומי עשה זאת בעצמך - חלק 5 - הוסף IMU: 9 שלבים

וִידֵאוֹ: וואלאס - רובוט אוטונומי עשה זאת בעצמך - חלק 5 - הוסף IMU: 9 שלבים

וִידֵאוֹ: וואלאס - רובוט אוטונומי עשה זאת בעצמך - חלק 5 - הוסף IMU: 9 שלבים
וִידֵאוֹ: מדריך הפעלת רובוט מכונית APP CODING CAR ROBOT 2024, נוֹבֶמבֶּר
Anonim
Image
Image

אנו ממשיכים יחד עם וואלאס. השם וואלאס הגיע מתערובת של "Wall-E", ומפרויקט קודם (זיהוי קולי), ובשימוש בכלי השירות "espeak" זה נשמע מעט בריטי. וכמו שרת או משרת. וזו המטרה הסופית: שהפרויקט הזה יהפוך למשהו שימושי. כך "וואלאס".

וואלאס יכול להסתובב, הוא יכול להימנע ממכשולים באמצעות חיישני מרחק IR (לאחרונה, איכשהו הם טיגנו (?) (צריך לבדוק את זה כשיהיה לי הזדמנות), יש לו גם כמה חיישני מרחק אקוסטיים (שלושה מהם הלכו רע באותו זמן) זמן, יחד עם מרחיב MCP23017), ולבסוף, ניתן לזהות שינויים בזרם המוטורי כדי לדעת מתי הוא נתקל במשהו.

בנוסף לחיישנים, וואלאס "זוכר" את 100 המהלכים, ויש לו ניתוח ראשוני תוך שימוש בהיסטוריית התנועה.

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

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

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

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

על ריצוף וללכת ישר, זו לא הייתה בעיה. זה מופיע על שטיחים. בחרתי להרחיק את וואלאס מהשטיח לאחר שהמסלולים שלו היו מלוכלכים (הם מרימים לכלוך קלים במיוחד).

הבעיה האמיתית היא כאשר מסתובבים על ריצוף.

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

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

ולכן ההסבר לעיל הניע את המדריך הזה.

בהתחלה, רציתי להימנע או לדחות את הכנסת יחידת חישה לתנועה (IMU), מכיוון שהם A) מסובכים, B) רועשים, C) שגיאות עלולות להיווצר לאורך זמן וכו 'וכו'. כי יכולנו להצליח מאוד על ידי קפיצה לחיישני לייזר IR בזמן הטיסה. ואנחנו יכולים - באמצעות לייזרים נוכל לדעת אם הרובוט הסתובב או לא, על ידי מעקב אחר שינויי המרחק.

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

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

נראה לי שקפיצה לשימוש בחיישני הלייזר ToF תיקח אותי לשלב הבא של התוכנה; כלומר SLAM (לוקליזציה ומיפוי סימולטני). עדיין לא הייתי מוכן ללכת לשם.

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

אפשר לחשוב על שכבות בדבר כזה:

  1. מסגרת פיזית של רובוט / בסיס מבני מכני
  2. מערכת הנעה בסיסית (פטל, רובוקלאו, מנועים, כבלים וכו ', תוכנות בסיסיות, מונעות מקלדת)
  3. מעגלים חיוניים לתמיכה בחיישנים (מחוון מתח דו כיווני, מרחיב יציאות, E-Stop, חלוקת חשמל וכו ')
  4. חיישני הימנעות ממכשולים (אקוסטי, IR)
  5. מיקום ותנועה חיוניים, בסיסיים - זיהוי (מד תאוצה, ג'ירו, מגנטומטר, מקודדים מוטוריים, מקודדי גלגלים)

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

הרשימה לעיל יכולה להיות ממופה פחות או יותר לשכבות הרעיוניות הללו בתוכנה.

  • SLAM (לוקליזציה ומיפוי סימולטני)
  • שליטה ומודעות לתנועה, סיבוב
  • הימנעות מכשולים בסיסית
  • בקרה וגילוי נתוני חיישן
  • תנועה חיונית קדימה, אחורה, שמאלה וימינה, להאיץ, להאט, לעצור

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

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

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

יש "קונפליקט" או "מתח" מסוים בין שני רעיונות או כיוונים מתחרים.

האחד הוא מה שהייתי מכנה "plug-n-play" כדי לפתור את הבעיה A.

השני הוא עשה זאת בעצמך (עשה זאת בעצמך). וייתכן שזו אפילו לא התווית הטובה ביותר לרעיון אחר זה.

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

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

  1. אם נחליט ללכת בדרך plug-n-play, אנו מיד קופצים (בהתאם לתקציב) לדברים כמו הלייזרים המסתובבים העליונים המותקנים למעלה, או מצלמת עומק השדה, או לייזרים ToF, ו- IMU (נושא זה ניתן להדרכה).
  2. אם אנחנו, לעומת זאת, רוצים ללכת במסלול השני, אולי ננסה לחלץ כל פיסת מידע אפשרית מתוך כמה חיישנים אקוסטיים או חיישני IR, או ללא חיישנים כלל - אנחנו פשוט משתמשים בניטור זרם מנוע (בליטה)

מה אפשר להגיד על מספר 1 מול מספר 2? דבר אחד יהיה שלמדנו הרבה יותר על ידי ביצוע מס '2. המגבלות שיש רק חיישנים אקוסטיים לעבודה, מאלצים אותנו לחשוב על הרבה יותר נושאים.

מצד שני, אם אנחנו מרוכזים מדי בעשיית דברים דרך מס '2, יתכן שאנחנו מבזבזים זמן, כי אנחנו מבקשים יותר ממה שצריך מחיישנים אקוסטיים.

עוד רעיון או רעיון אחד לחשוב עליו: איזה תערובת של חומרה ותוכנה עונה בצורה הטובה ביותר על השאלות של "איך לעשות", ואיזה תערובת של תוכנה (וחומרה?) עונה על השאלה "מה", "מתי", "איפה". כי "איך לעשות" היא בדרך כלל שאלה ברמה נמוכה יותר ש"מה "," מתי "ו"איפה" תלויים בכדי לקבל תשובה.

בכל מקרה, כל האמור לעיל היה רק משהו שצריך לחשוב עליו.

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

לכן זה מורה - IMU.

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

שלב 1: חיישן ה- IMU

חיישן ה- IMU
חיישן ה- IMU
חיישן ה- IMU
חיישן ה- IMU

ולכן החיישן הבא שלנו להוסיף לוואלאס הוא ה- IMU. לאחר מחקר, הסתפקתי ב- MPU6050. אבל אז בתקופה זו, MPU9050 (ואפילו לאחרונה, MPU9250) נראה כמו רעיון טוב עוד יותר.

המקור שלי הוא אמזון (בארה ב). אז הזמנתי שניים מהם.

מה שקיבלתי למעשה (נראה שאין שליטה על זה; זה מה שאני לא אוהב באמזון) היו שני MPU92/65. אני תוהה קצת לגבי הייעוד. תסתכל על התמונות; נראה כי זהו כינוי "משפחתי". בכל מקרה, זה מה שאני תקוע איתו.

הוספתו פשוטה מאוד -קבל לוח פרוטו עם מסילות חיבור, הלחם את החיישן ללוח, הוסף בלוק מסוף בורג בן 10 פינים (את שלי קיבלתי מפולו).

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

המשמעות הייתה גם שימוש בכמה ברגים/אגוזים מניילון.

אני הולך להשתמש בפרוטוקול I2C. נקווה שאורך החוט הכולל לא יהיה גרוע מדי.

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

שלב 2: הדברים לא תמיד נקיים, קלים

בעת כתיבת שורות אלה לא נראה שיש הרבה מקוון עבור ה- MPU-92/65 המסוים הזה. מה שיש, ממש כמו ברוב החיישנים, נראה דוגמאות לשימוש בארדואינו.

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

אני מניח שהמדריכים האלה דומים יותר לבלוג מאשר A-B-C ישר, 1-2-3 "ככה אתה עושה את זה".

שלב 3: בדיקה ראשונית

בדיקה ראשונית
בדיקה ראשונית
בדיקה ראשונית
בדיקה ראשונית

מהתמונות בשלב הקודם, החוטים האדומים והשחורים שעוברים לחיישנים הם כמובן VCC (5V) ו- GND. החוטים הירוקים והצהובים הם חיבורי I2C.

אם ביצעת פרויקטים אחרים של I2C, או שעקבת אחרי סדרות אלה, אז אתה כבר יודע על "i2cdetect", וזה הצעד הראשון לדעת אם הפטל יכול לראות את החיישן החדש.

כפי שאתה יכול לראות מהתמונות בשלב זה, הניסיון הראשון שלנו לא הצליח. ה- IMU אינו מופיע (אמור להיות מזהה המכשיר 0x68).

עם זאת, החדשות הטובות הן שאוטובוס I2C פועל. אנו אכן רואים מכשיר אחד 0x20 והוא מרחיב היציאות MCP23017 (אחראי כיום על החיישנים האקוסטיים HCSR04).

זה לא קל לראות בתמונה, אבל חיברתי את אותם חוטים בצבע ירוק וצהוב מה- IMU ל- MCP23017 (ראה משמאל למטה בתמונה)

נצטרך לבצע פתרון בעיות.

שלב 4: פתרון בעיות

Image
Image
פתרון תקלות
פתרון תקלות
פתרון תקלות
פתרון תקלות

באמצעות הגדרת ההמשכיות על מד מתח (זה עם הטון הגבוה), בדקתי חיבורי VCC (5V), GND, SDA ו- SCL. אלה היו טובים.

הניסיון הבא היה לנתק את MCP23017 מאוטובוס I2C, ולהשאיר רק את MPU-92/65 באוטובוס. זה לא הועיל - "i2cdetect" לא הראה אז מכשירים.

אז, לאחר מכן, הסרתי את החיישן ממוט טוטם וחיברתי אותו מחדש לאוטובוס הדו-כיווני 5V-3V; כלומר, ישר אל הפטל. (חוטים קצרים יותר?).

וגם וואלה. הפעם יש הצלחה. אנו רואים 0x68 מופיע באמצעות "i2cdetect".

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

הערה: זה לא היה משנה אם ADO מקורקע או לא. יכול להיות שיש נגדים משולבים ומורדים על הלוח. אותו הדבר אולי נכון לגבי FSYNC.

לאחר מכן, חיברתי מחדש את ה- MCP23017. אז עכשיו יש לנו שני מכשירים באוטובוס I2C. (ראו תמונה). מצליח, כעת אנו רואים הן 0x20 והן 0x68 עם i2cdetect.

הסרטונים נכנסים קצת יותר למה שקרה במהלך פתרון הבעיות.

שלב 5: קריאת נתוני החיישן

Image
Image
קריאת נתוני החיישן
קריאת נתוני החיישן
קריאת נתוני החיישן
קריאת נתוני החיישן

גישות שונות

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

  1. נסה קצת תכנות בסיסי
  2. עיין בכמה תיעודים מקוונים על רישומים
  3. תסתכל על דוגמאות ו / או קוד של אחרים

מדוע גישות אלו? למה לא פשוט לחפש ספרייה או קוד קיים?

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

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

לדוגמה, לאחר שבדקתי קוד C ++ עבור MPU9250 ב- github, הבנתי שזה מכריח אותי להשתמש בהפרעות, מה שאני עדיין לא רוצה לעשות.

כמו כן, הוא מגיע עם דברים נוספים כמו כיול; שוב, משהו שעדיין לא מעניין אותי.

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

רישומים

בעת כתיבת שורות אלה, נראה כי אין הרבה זמינות בחיישן זה. למעשה, אם תסתכל על התמונות המצורפות למדריך זה ותסתכל מקרוב על הכתובות על השבבים בפועל, זה גורם לי לתהות אם זה לא נקישה. אני לא מתייחס למה שאני רואה לשום דבר מ- Invense. בלי קשר, בחרתי להסתכל על פרטי הרישום של הדגמים שמצאתי: MPU-6050 ו- MPU-9250.

בשני המקרים הדברים הבאים זהים לשניהם. ובתור התחלה, אנו מניחים שזה יהיה אותו הדבר גם עבור MPU-92/65 זה.

59 עד 64 - מדידות מד תאוצה

65, 66 - מדידות טמפרטורה 67 עד 72 - מדידות גירוסקופ 73 עד 96 - נתוני חיישן חיצוניים

הערה: נראה כי ל- MPU-6050 אין מגנטומטר, ואילו ל- MPU-9250 (ואנו מניחים שגם).

עוד מידע מעניין, בתקווה שימושי, שנלקח מתוך מסמך הרישום:

מידע על מגנטומטר:

מזהה מגנטומטר: 0x48 רושמים 00 עד 09: 00H WIA 0 1 0 0 1 0 0 0 01H INFO INFO7 INFO6 INFO5 INFO4 INFO3 INFO2 INFO1 INFO0 02H ST1 0 0 0 0 0 0 DOR DRDY 03H HXL HX7 HX6 HX5 HX4 HX3 HX2 HX0 HX0 HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HYH HY15 HY14 HY13 HYH HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ ST2 0 0 0 BITM HOFL 0 0 0 פירוט המשמעות של כל רגיסטר: HXL [7: 0]: נתוני מדידה של ציר ה- X נמוכים יותר ב- 8bit HXH [15: 8]: נתוני מדידת ציר ה- X גבוהים יותר ב- 8bit HYL [7: 0]: נתוני מדידה של ציר Y נמוכים יותר 8 ביט HYH [15: 8]: נתוני מדידה של ציר Y גבוהים יותר 8 סיביות HZL [7: 0]: נתוני מדידה של ציר Z נמוכים יותר 8 סיביות HZH [15: 8]: נתוני מדידה של ציר Z גבוהים יותר 8 ביט

תִכנוּת

פיסת מידע נוספת ממסמכי הרישום היא שנראה שיש רק כמאה אוגרים בערך. אז טקטיקה אחת יכולה להיות כתיבת תוכנית פשוטה שניגשת למכשיר (0x68) ומנסה לקרוא סדרת רישומים ברצף, ללא כל התייחסות למשמעותם, רק כדי לראות אילו נתונים ניתן לראות.

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

הרעיון הוא שכנראה נוכל לחסל כל רישומים שנראים שאין להם נתונים (אפסים או FF?) או שהם לעולם אינם משתנים, ונוכל להתמקד גם באלו שכן משתנים.

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

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

אני אוהב להשתמש בספריית wiringPi כמה שאפשר. יש לו תמיכה ב- I2C.

ריצה ראשונה:

/********************************************************************************

* לבנות: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * להפעלה: sudo./first.test.mpu9265 * * התוכנית הזו רק פלטת טווח של (אפשרי) מאגרים מה- MCP23017, * ולאחר מכן מה- MPU9265 (או כל MPU אחר בכתובת 0x68) * * השתמשתי בו כדי לאמת אם אפשר לקרוא אפילו מהחיישן, מכיוון שכבר * היה לי ביטחון ב- MCP23017. ***************************************** ***************************/ #include #include #include #include #include int main (int argc, char ** argv) {puts ("בוא נראה מה יש ל- MCP23017 @ 0x20 להגיד:"); errno = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "אין אפשרות לפתוח מכשיר wiringPi I2C: %s / n", strerror (errno)); החזרה 1; } עבור (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); עיכוב (10); } לשים (""); puts ("בוא נראה מה יש ל- MPU9265 @ 0x20 להגיד:"); errno = 0; int deviceId2 = 0x68; int fd2 = wiringPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "לא ניתן לפתוח מכשיר wiringPi I2C: %s / n", strerror (errno)); החזרה 1; } עבור (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); עיכוב (10); } לשים (""); החזר 0; }

הריצה השנייה:

/********************************************************************************

* לבנות: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * להפעלה: sudo./second.test.mpu9265 * * תוכנית זו יוצאת את מספר הרישום לצד הערך הנקרא. * * זה הופך את זה שימושי לצנרת (להפנות) את הפלט לקובץ, ולאחר מכן * ניתן לבצע מספר ריצות להשוואה. זה עשוי לתת תובנה מסוימת לגבי * אילו רשומות חשובות וכיצד הנתונים עשויים להתנהג. ***************************************** **************************/ #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x20", strlen ("0x20"))) {deviceId = 0x20; } אחרת אם (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } אחרת אם (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } puts ("בוא נראה מה יש ל- MPU9265 @ 0x20 להגיד:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "לא ניתן לפתוח מכשיר wiringPi I2C: %s / n", strerror (errno)); החזרה 1; } עבור (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); עיכוב (10); } החזר 0; }

ההרצה השלישית:

/********************************************************************************

* לבנות: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * להפעלה: sudo./third.test.mpu9265 * * תוכנית זו היא תוצאה של התוכנית השנייה. הוא קורא רק מתוך * הרשמים שהצביעו על הבדל בין ריצה אחת לאחרת.***************************************** **************************/ #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } אחרת אם (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } puts ("בוא נראה מה יש ל- MPU9265 @ 0x20 להגיד:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "לא ניתן לפתוח מכשיר wiringPi I2C: %s / n", strerror (errno)); החזרה 1; } עבור (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); עיכוב (10); } עבור (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); עיכוב (10); } עבור (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); עיכוב (10); } עבור (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); עיכוב (10); } החזר 0; }

אז מה למדנו עד כה? תמונת הטבלה עם אזורים מודגשים צבעוניים מצביעה על כך שנראה כי הפלט תואם את קבוצות הרישומים הראשונות.

התוצאות עד כה יכולות ליצור שאלות חדשות.

שאלה: מדוע יש רק תוצאת רישום אחת לקבוצה "החיצונית"?

שאלה: מה הם כל אותם רישומים לא ידועים "??????"

שאלה: מכיוון שהתוכנית אינה מונעת הפרעות, האם היא ביקשה נתונים איטיים מדי? מהיר מידי?

שאלה: האם נוכל להשפיע על התוצאות על ידי ניסיון דברים עם החיישן עצמו בזמן שהוא פועל?

שלב 6: בואו נתעמק יותר בקריאות / נתונים

אני חושב שהשלב הבא לפני כל דבר אחר הוא לשפר את התוכנית ל:

  • היו גמישים בכמה עיכוב הלולאה (אלפיות השנייה)
  • היו גמישים בכמה הקריאות לתת ממוצע פועל לרשם

(נאלצתי לצרף את התוכנית כקובץ. נראה שזו הייתה בעיה בהכנסתה לכאן. "Four.test.mpu9265.c")

להלן ריצה באמצעות 10 הקריאות האחרונות בממוצע, בלולאה של 10ms:

sudo./fourth.test.mpu9265 0x68 10 10

61:255 0 255 0 255 0 255 0 0 0: 102 62:204 112 140 164 148 156 188 248 88 228: 167 63:189 188 189 187 189 188 188 188 188 189: 188 64: 60 40 16 96 208 132 116 252 172 36: 112 65: 7 7 7 7 7 7 7 7 7 7: 7 66:224 224 224 240 160 208 224 208 144 96: 195 67: 0 0 0 0 0 0 0 0 0 0: 0 68:215 228 226 228 203 221 239 208 214 187: 216 69: 0 255 0 255 255 0 255 0 0 0: 102 70:242 43 253 239 239 45 206 28 247 207: 174 71: 0 255 255 0 255 255 255 255 255 255: 204 72: 51 199 19 214 11 223 21 236 193 8: 117 73: 0 0 0 0 0 0 0 0 0 0: 0 111: 46 149 91 199 215 46 142 2 233 199: 132 112: 0 0 0 0 0 0 0 0 0 0: 0 189:255 0 255 0 255 0 0 255 0 255: 127 190: 76 36 240 36 100 0 164 164 152 244: 121 191:188 188 188 188 187 188 187 189 187 189: 187 192: 8 48 48 196 96 220 144 0 76 40: 87 193: 7 7 7 7 7 8 7 7 7 7: 7 194:208 224 144 240 176 240 224 208 240 224: 212 195: 0 0 0 0 0 0 0 0 0 0: 0 196:243 184 233 200 225 192 189 242 188 203: 209 197:255 0 0 0 255 0 255 0 0 255: 102 198:223 39 247 43 245 22 255 221 0 6: 130 199: 0 255 255 255 0 255 255 255 255 0: 178 200:231 225 251 1 252 20 211 216 218 16: 164 201: 0 0 0 0 0 0 0 0 0 0: 0 239: 21 138 196 87 26 89 16 245 187 144: 114 240: 0 0 0 0 0 0 0 0 0 0: 0

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

נראה שהרשמים 61, 69, 71, 189, 197 ו- 199 הם בינארי בלבד, או שהם מוכנים / לא מוכנים, או שהם הבייט הגבוה של ערך 16 סיביות (שלילי?).

תצפיות מעניינות נוספות:

  • רושמים 65, 193 - יציב מאוד ואותו ערך
  • רשום 63, 191 - יציב מאוד ואותו ערך
  • רשימות 73, 112, 195, 201, 240 - הכל באפס

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

רשום 65 - טמפרטורה

רשום 193 - ??????

רשום 63 - מד תאוצה

רשום 191 - ??????

רישום 73 - חיצוני

הרשמה 112 והלאה - ??????

ובכן, עדיין יש לנו אלמונים, אך למדנו משהו שימושי.

מרשם 65 (טמפרטורה) ורשום 63 (מד תאוצה) שניהם היו יציבים מאוד. זה משהו שהיינו מצפים לו. לא נגעתי בחיישן; הוא לא זז, פרט לרעידות מקריות, כשהרובוט מונח על אותו שולחן כמו המחשב שלי.

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

שלב 7: אנו מסוגלים להשפיע על הטמפרטורה והאצה

בשלבים הקודמים צמצמנו לפחות מרשם אחד לטמפרטורה, ואחד להאצה.

עם הגרסה הבאה של התוכנית ("5th.test.mpu9265.c"), אנו יכולים למעשה לראות שינוי של שני הרשמים. אנא צפה בסרטונים.

עוד חפירה

אם נחזור לאחור ונתבונן בפרטי הרישום, אנו רואים שיש:

  • שלוש יציאות 16 סיביות לג'ירוסקופ
  • שלוש יציאות 16 ביט למד תאוצה
  • שלוש יציאות 16 ביט למגנטומטר
  • פלט אחד של 16 סיביות לטמפרטורה

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

אז בואו ננסה יותר מאותה גישה, אך הפעם נקרא 16 סיביות במקום 8.

כנראה שנצטרך לעשות משהו כמו להלן. בואו נשתמש בטמפרטורה כדוגמה, מכיוון שהיא רק פלט 16 ביט.

// להשיג מתאר קובץ fd …

int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8 (fd, tempRegHi); int loByte = wiringPiI2CReadReg8 (fd, tempRegLo); int result = hiByte << 8; // הכנס את סדר 8 הביטים לחלק העליון של תוצאה של ערך 16 סיביות | = loByte; // הוסף כעת סדר 8 סיביות, ותניב מספר שלם של 16 סיביות // הדפס מספר זה או השתמש בפונקציית הגרף האופקי לתצוגה מלפני

מהשלבים הקודמים שלנו ראינו שרשם 65 די יציב בסלע, בעוד שרשם 66 רועש מאוד. מאחר ש- 65 הוא בית הסדר היי, ו -66 הסדר הנמוך, זה הגיוני.

לקריאה, אנו יכולים לקחת את הנתונים של הרשמים 65 כפי שהם, אך אנו יכולים למדוד את הערכים של הרשומה של 66.

או שנוכל רק לממוצע את כל התוצאה.

תסתכל על הסרטון האחרון של החלק הזה; הוא מדגים קריאת כל ערך הטמפרטורה של 16 סיביות. הקוד הוא "sixth.test.mpu9265.c"

שלב 8: מד התאוצה והג'ירוסקופ

Image
Image

הסרטונים לקטע זה מציגים תפוקה ממד התאוצה והג'ירוסקופ, באמצעות תוכנית בדיקה "seventh.test.mpu9265.c". קוד זה יכול לקרוא 1, 2 או 3 זוגות בתים רצופים (hi and lo bytes) ולהמיר את הערכים לערך יחיד של 16 סיביות. כך, אנו יכולים לקרוא כל ציר יחיד, או שנוכל לקרוא שניים מהם יחד (וזה מסכם את השינויים), או שנוכל לקרוא את כל השלושה (וזה מסכם את השינויים).

כדי לחזור על השלב הזה, על ההוראה הזו, אני רק מחפש לענות על שאלה פשוטה: "האם הרובוט הסתובב/מסתובב?". אני לא מחפש שום ערך מדויק, כגון האם הוא מסתובב 90 מעלות. זה יגיע מאוחר יותר כשנגיע לביצוע SLAM, אך זה לא נדרש למניעת מכשולים פשוטים ותנועה אקראית.

שלב 9: (עבודה בתהליך) המגנומטר

בעת שימוש בכלי i2cdetect, MPU9265 מופיע כ- 0x68 בטבלה:

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

יש צורך בשלבים נוספים לקריאה מחלק המגנומטר של ה- IMU.

מתוך מסמך ה- PDF של מאגרי Invesense:

רישומים 37 עד 39 - I2C SLAVE 0 CONTROL

  • רישום 37 - I2C_SLV0_ADDR
  • רישום 38 - I2C_SLV0_REG
  • רישום 39 - I2C_SLV0_CTRL

מוּמלָץ: