فهرست مطالب:

والاس - ربات خودکار DIY - قسمت 5 - IMU را اضافه کنید: 9 مرحله
والاس - ربات خودکار DIY - قسمت 5 - IMU را اضافه کنید: 9 مرحله

تصویری: والاس - ربات خودکار DIY - قسمت 5 - IMU را اضافه کنید: 9 مرحله

تصویری: والاس - ربات خودکار DIY - قسمت 5 - IMU را اضافه کنید: 9 مرحله
تصویری: ترکید😱😭 2024, نوامبر
Anonim
Image
Image

ما به همراه والاس پیش می رویم. نام والاس از ترکیبی از "Wall-E" و از یک پروژه قبلی (تشخیص صدا) گرفته شد و در استفاده از ابزار "espeak" کمی انگلیسی به نظر می رسید. و مانند خدمتکار یا ساقی. و این هدف نهایی است: این پروژه به چیزی مفید تبدیل شود. بنابراین "والاس".

والاس می تواند حرکت کند ، می تواند با استفاده از سنسورهای فاصله مادون قرمز از موانع جلوگیری کند (اخیراً ، به نوعی آنها سرخ شده اند؟ زمان ، همراه با یک بسط دهنده MCP23017) ، و در نهایت ، می تواند تغییرات جریان موتور را تشخیص دهد تا بداند چه زمانی به چیزی برخورد کرده است.

والاس علاوه بر سنسورها ، 100 حرکت را "به خاطر می آورد" و با استفاده از تاریخچه حرکات ، تجزیه و تحلیل ابتدایی دارد.

هدف تا کنون برای والاس این است که فقط سعی کند به جلو حرکت کند و بداند چه موقع در یک الگوی تکراری (مانند گوشه ای) گیر کرده است و واقعاً به جلو حرکت نمی کند.

چندین بار برای حرکت و ناوبری پشت سر گذاشته ام و سردرد مداوم در حین چرخش بوده است.

از آنجا که والاس یک ربات ردیابی شده است ، و من می خواستم همه چیز را در نرم افزار ساده تر نگه دارم (برای بعد) ، به منظور چرخاندن ، من فقط او را در حالت محوری/چرخشی قرار می دهم. بنابراین ، چرخه قدرت / وظیفه برابر اما متضاد را برای موتورها اعمال کنید.

مشکلی که پیش آمد به دلیل طراحی پلت فرم ربات Agent 390 است. کمربندهای ردیف تمایل دارند به پهلوها مالیده شوند. و بدتر اینکه یک طرف این کار را بیشتر از طرف دیگر انجام می دهد.

در مورد کفپوش و مستقیم رفتن ، مشکلی ایجاد نکرده است. روی موکت نمایان می شود. من تصمیم گرفتم والاس را بعد از کثیف شدن آهنگ هایش از فرش دور نگه دارم (آنها خیلی راحت کثیفی را جمع می کنند).

مشکل اصلی هنگام چرخش روی کف است.

اگر نرم افزار از چرخه کاری سطح بالا استفاده کند ، کم و بیش به طور مداوم تغییر می کند. با این حال ، در چرخه کم وظیفه ، ممکن است بچرخد یا نباشد. یا ممکن است کمی بچرخد و سپس سرعتش کم شود. به نظر می رسد عمل محوری از طریق نرم افزار غیرقابل کنترل است یا در بهترین حالت بسیار دشوار است.

این مشکل در هنگام ناوبری و حرکت در اطراف یا دور شدن از موانع خود را نشان می دهد. یا می تواند بسیار وحشتناک دور شود ، یا می تواند در تلاش برای انجام شیفت های بسیار کوچک ، بدون حتی حتی حرکت ، گیر کند.

و بنابراین توضیحات فوق انگیزه این دستورالعمل را ایجاد کرد.

در ابتدا ، من می خواستم از یک واحد تشخیص حرکت (IMU) صرف نظر کنم یا آن را به تأخیر بیندازم ، زیرا آنها A) پیچیده ، B) پر سر و صدا ، C) ممکن است خطاها در طول زمان معرفی شوند ، و غیره ، و غیره. می توانیم با پرش به سنسورهای لیزری IR زمان پرواز بسیار خوب عمل کنیم. و ما می توانیم - با استفاده از لیزرها ، با ردیابی تغییرات در فاصله ، بدانیم که ربات می چرخد یا خیر.

در واقع ، ما نیز می توانیم (به نوعی) این کار را اکنون با سنسورهای صوتی انجام دهیم.

با این حال ، همه اینها یک راه بسیار غیرمستقیم و پیچیده برای پاسخ به یک س simpleال ساده است: "آیا ما چرخیده ایم یا نه؟"

به نظرم رسید که استفاده از سنسورهای لیزری ToF مرا به سطح بعدی نرم افزار برساند. یعنی SLAM (بومی سازی و نقشه برداری همزمان). هنوز آمادگی رفتن به آنجا را نداشتم.

انجام یک پروژه ربات به صورت لایه ای خوب است ، لایه های اول (پایین) ساده تر و لایه های دوم (بالا) انتزاعی تر هستند و به مسائل سخت تری می پردازند.

لایه ها را می توان چنین چیزی تصور کرد:

  1. قاب فیزیکی ربات / اساس ساختاری مکانیکی
  2. سیستم رانندگی ابتدایی (تمشک ، Roboclaw ، موتورها ، کابل کشی و غیره ، نرم افزار اصلی ، صفحه کلید)
  3. مدارهای ضروری برای پشتیبانی از سنسورها (تغییر ولتاژ دو جهته ، گسترش دهنده پورت ، توقف الکترونیکی ، توزیع برق و غیره)
  4. سنسورهای اجتناب از موانع (آکوستیک ، IR)
  5. تعیین موقعیت و حرکت اساسی - تشخیص (شتاب سنج ، ژیروسکوپ ، مغناطیس سنج ، رمزگذار موتور ، رمزگذار چرخ)

می توانید لیست خود را تهیه کنید. نکاتی که در مورد این لیست وجود دارد این است که احتمالاً باید این کارها را به ترتیب انجام دهید ، و همچنین اگر مدتی را در هر لایه صرف کنید تا هر کدام به حالت کاری خوب برسند ، بعداً به شما کمک می کند تا همه چیز پیچیده تر شود.

لیست فوق می تواند کم و بیش به این لایه های مفهومی در نرم افزار ترسیم شود.

  • SLAM (بومی سازی و نقشه برداری همزمان)
  • کنترل و آگاهی از حرکت ، چرخش
  • اجتناب از موانع اساسی
  • کنترل و تشخیص داده های حسگر
  • حرکت ضروری رو به جلو ، عقب ، چپ و راست ، سرعت ، آهسته ، توقف

همانطور که مشاهده می کنید ، برای این فهرست ، اولین موارد لایه های بالایی و پیچیده تر هستند که به مسائل و سوالات انتزاعی تری مانند "کجا هستم" و "کجا می روم" می پردازند ، در حالی که موارد اخیر عبارتند از: لایه های نرم افزاری پایین تر که نحوه "نحوه صحبت/گوش دادن به سنسور A" یا "نحوه حرکت این چرخ" را کنترل می کنند.

در حال حاضر ، من نمی گویم که وقتی یک لایه را شروع می کنید ، آن را تکمیل کرده اید و سپس روی لایه بعدی قرار دارد ، هرگز به لایه قبلی باز نگردید. یک پروژه ربات می تواند بسیار شبیه به روشهای توسعه نرم افزاری مدرن و تکراری (چابک ، SCRUM و غیره) باشد.

من فقط می گویم برای هر کدام وقت بگذارید. شما باید میزان انجام هر کار را متعادل کنید و تصمیم بگیرید که در یک لایه خاص به چه وقت و مشکلی تلاش می کنید.

بین دو ایده یا جهت متقابل "تضاد" یا "تنش" خاصی وجود دارد.

یکی آن چیزی است که من برای حل مشکل A آن را "plug-n-play" می نامم.

مورد دیگر DIY است (خودتان انجام دهید). و این ممکن است حتی بهترین برچسب برای این ایده دیگر نباشد.

در اینجا یک نمونه از هر یک آورده شده است ، امیدوارم تنش یا تضاد بین دو انتخاب را مشاهده کنید.

برای این مثال ، بیایید SLAM ، اجتناب از موانع و حرکت اساسی اساسی را به عنوان یک مشکل در یک زمان حل کنیم.

  1. اگر تصمیم داریم مسیر plug-n-play را طی کنیم ، بلافاصله (بسته به بودجه) به مواردی مانند آن لیزرهای دوار بالا ، یا دوربین عمق میدان ، یا لیزرهای ToF و IMU (موضوع این مورد می پردازیم). قابل آموزش)
  2. اگر ما بخواهیم راه دوم را طی کنیم ، ممکن است سعی کنیم تمام اطلاعات ممکن را از برخی از سنسورهای آکوستیک یا حسگرهای IR یا اصلاً بدون سنسور استخراج کنیم - ما فقط از مانیتورینگ جریان موتور (bump) استفاده می کنیم.

در مورد شماره 1 در مقابل شماره 2 چه می توان گفت؟ یک چیز این است که ما با انجام شماره 2 چیزهای بیشتری یاد گرفته ایم. محدودیت های داشتن تنها سنسورهای صوتی برای کار ، ما را مجبور می کند که به مسائل بسیار بیشتری فکر کنیم.

از سوی دیگر ، اگر بیش از حد بر انجام کارها از طریق شماره 2 تمرکز کنیم ، ممکن است زمان را هدر دهیم ، زیرا ما بیش از آنچه که باید از سنسورهای صوتی درخواست می کنیم.

یک مفهوم یا ایده دیگر که باید در مورد آن فکر کنید: کدام مخلوط سخت افزار و نرم افزار به بهترین شکل به س questionsالات "چگونه انجام می شود" و چه مخلوطی از نرم افزار (و سخت افزار؟) به س "ال "چه" ، "وقتی" ، "کجا" پاسخ می دهد. به زیرا "چگونه" معمولاً یک پرسش سطح پایین است که "چه" ، "چه موقع" و "کجا" برای دریافت پاسخ به آن بستگی دارد.

به هر حال ، همه موارد فوق فقط برای اندیشیدن بود.

در مورد من ، پس از تلاش زیاد و داشتن مشکل آزاردهنده مداوم در مورد اصطکاک مسیر و ناتوانی در کنترل و حرکت مداوم ، زمان انجام کار دیگری فرا رسیده است.

بنابراین این دستورالعمل - یک IMU.

هدف این است که اگر IMU می گوید روبات در حال چرخش نیست ، چرخه وظیفه را افزایش دهیم. اگر خیلی سریع در حال چرخش هستیم ، چرخه وظیفه را کاهش می دهیم.

مرحله 1: سنسور IMU

سنسور IMU
سنسور IMU
سنسور IMU
سنسور IMU

و بنابراین سنسور بعدی ما برای افزودن به والاس ، IMU است. پس از برخی تحقیقات ، من در حال استفاده از MPU6050 بودم. اما در آن زمان ، MPU9050 (و حتی اخیراً ، MPU9250) حتی ایده بهتری به نظر می رسید.

منبع اصلی من آمازون (در ایالات متحده) بوده است. بنابراین من دو مورد از آنها را سفارش دادم.

آنچه من در واقع دریافت کردم (به نظر می رسد هیچ کنترلی روی این وجود ندارد ؛ این چیزی است که من در آمازون دوست ندارم) دو MPU92/65 بود. کمی در مورد تعیین نام تعجب می کنم. به تصاویر نگاهی بیندازید ؛ به نظر می رسد این یک "خانواده" است. در هر صورت ، این چیزی است که من به آن گیر کرده ام.

افزودن آن بسیار ساده است -یک تخته اولیه با آهنگ های متصل کنید ، سنسور را به صفحه بچسبانید ، یک بلوک ترمینال پیچ 10 پینی (که من از Pololu گرفتم) اضافه کنید.

به منظور به حداقل رساندن هرگونه تداخل ، سعی کردم این سنسورها را از هر چیز دیگری دور نگه دارم.

این همچنین به معنای استفاده از پیچ و مهره های نایلونی بود.

من قصد دارم از پروتکل 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" سپس هیچ دستگاهی را نشان نداد.

بنابراین ، در مرحله بعد ، سنسور را از قطب توتم جدا کردم و دوباره آن را مستقیماً به گذرگاه دو طرفه 5 ولت تا 3 ولت وصل کردم. یعنی مستقیم به تمشک. (سیم های کوتاه تر؟).

و voila. این بار موفقیت وجود دارد. ما می بینیم 0x68 با استفاده از "i2cdetect" نمایش داده می شود.

اما هنوز نمی دانیم چرا این بار کار کرد. ممکن است طول سیم ها باشد؟ محل قبلی؟

توجه: تفاوتی نمی کند که آیا ADO زمین گیر شده است یا خیر. ممکن است مقاومتهای کششی و کشویی روی صفحه وجود داشته باشد. همین امر ممکن است در مورد FSYNC صادق باشد.

بعد ، MCP23017 را دوباره وصل کردم. بنابراین اکنون ما دو دستگاه در گذرگاه I2C داریم. (تصویر را ببینید). موفق باشید ، ما هم اکنون 0x20 و 0x68 را با i2cdetect می بینیم.

ویدئوها کمی بیشتر به آنچه در طول عیب یابی اتفاق افتاده است اشاره می کنند.

مرحله 5: خواندن داده های سنسور

Image
Image
خواندن داده های سنسور
خواندن داده های سنسور
خواندن داده های سنسور
خواندن داده های سنسور

رویکردهای مختلف

تصمیم گرفتم برای بدست آوردن اطلاعات مفید از حسگر ، رویکردهای متعددی را در پیش بگیرم. در اینجا آنها هستند ، به هیچ ترتیب:

  1. برنامه نویسی اولیه را امتحان کنید
  2. برخی از اسناد آنلاین ثبت شده را بررسی کنید
  3. به نمونه ها و / یا کد دیگران نگاه کنید

چرا این رویکردها؟ چرا فقط به دنبال کتابخانه یا کد موجود نیستید؟

با آزمایش و آزمایش برخی از ایده ها ، می توانیم نه تنها اطلاعاتی را در مورد این سنسور خاص جذب کنیم ، بلکه برخی تکنیک ها ، مهارت ها و روش های تفکر در مورد مقابله با چیزهای جدید و چیزهایی را که ممکن است مستندات زیادی نداشته باشند ، به دست آوریم. چیزی که ممکن است مجهولات زیادی داشته باشد.

همچنین ، هنگامی که با ایده های خودمان بازی کرده و آنها را امتحان کرده ایم و بینش کسب کرده ایم ، در موقعیت بهتری برای ارزیابی کد یا کتابخانه شخص دیگری قرار داریم.

به عنوان مثال ، پس از مشاهده برخی از کد های C ++ برای MPU9250 در github ، متوجه شدم که این کار مرا مجبور به استفاده از وقفه می کند ، که هنوز مایل به انجام آن نیستم.

همچنین ، دارای موارد اضافی مانند کالیبراسیون است. دوباره ، چیزی که من هنوز به آن علاقه ندارم.

ممکن است آنچه را که باید برای پاسخ به س simpleال ساده "چرخش بله یا خیر روبات انجام دهد" انجام دهم ، فقط با خواندن برخی از رجیسترها بسیار ساده پاسخ داده شود.

ثبت می کند

در این نوشتار ، به نظر نمی رسد چیزهای زیادی روی این سنسور موجود باشد. در واقع ، اگر به تصاویری که همراه این دستورالعمل هستند نگاهی بیندازید و کتیبه های روی تراشه های واقعی را از نزدیک مشاهده کنید ، این باعث می شود که من تعجب کنم که آیا این یک برنامه حذفی نیست. من آنچه را که می بینم به چیزی از 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 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 HXHX HX5 HX5 HX4 HX4 HX5 HX4 HX4 HX4 HX4 HX4 HX4 HX4 HX4 HX4 HX4 09H HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HYH HY15 HY14 HY13 HY12 HY11 HY10 HY9 HY8 07H HZL HZ7 HZ6 HZ5 HZ4 HZ3 HZ2 HZ1 HZ0 08H HZH HZ15 HZ14 HZ13 HZ12 HZ11 HZ10 HZ9 HZ8 ST2 0 0 0 BITM HOFL 0 0 0 تجزیه و تحلیل معنی هر رجیستر: HXL [7: 0]: داده های اندازه گیری محور X پایین تر 8 بیت HXH [15: 8]: داده های اندازه گیری محور X بالاتر 8 بیت HYL [7: 0]: داده های اندازه گیری محور Y پایین تر 8bit HYH [15: 8]: داده های اندازه گیری محور Y بالاتر 8bit HZL [7: 0]: داده های اندازه گیری محور Z پایین تر 8bit HZH [15: 8]: داده های اندازه گیری محور Z بالاتر 8 بیت

برنامه نويسي

یکی دیگر از اطلاعات اسناد ثبت شده این است که به نظر می رسید فقط حدود 100 رجیستر وجود داشته باشد. بنابراین یک تاکتیک می تواند این باشد که یک برنامه ساده بنویسید که به دستگاه دسترسی داشته باشد (0x68) و تلاش کند تا یک سری از رجیسترها را به طور متوالی و بدون در نظر گرفتن معنی آنها بخواند ، فقط برای دیدن داده های قابل مشاهده.

و سپس ، گذرهای پی در پی را با استفاده از کد مشابه انجام دهید و داده های یک پاس را با پاس دیگر مقایسه کنید.

ایده این است که ما احتمالاً می توانیم هر ثبت کننده ای که به نظر می رسد فاقد داده است (صفر یا FF؟) یا که هرگز تغییر نمی کند را حذف کنیم و همچنین می توانیم بر روی مواردی که تغییر می کنند تمرکز کنیم.

سپس ، یکی از مواردی را که فقط در حال تغییر هستیم ، بررسی می کنیم ، یک تابع میانگین گیری که میانگین آخرین خواندن N آن ثبت نام است را اضافه کنید تا ببینید آیا در واقع مقدار ثابتی برای آن ثبات وجود دارد یا خیر. این فرض می کند که ما سنسور را بسیار بی حرکت و در همان مکان نگه می داریم.

سرانجام ، می توانیم مواردی را با حسگر به آرامی امتحان کنیم ، مانند تکان دادن آن (شتاب سنج ، ژیروسکوپ) ، یا دمیدن روی آن (دما) ، یا چرخاندن آن (دو مغناطیس سنج قبلی به علاوه) و ببینیم این چه تاثیری بر روی مقادیر دارد.

من دوست دارم تا آنجا که ممکن است از کتابخانه wiringPi استفاده کنم. از I2C پشتیبانی می کند.

اولین اجرا:

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

* برای ساخت: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * برای اجرا: sudo./first.test.mpu9265 * * این برنامه فقط تعدادی از رجیسترهای (ممکن) را از MCP23017 خروجی می دهد ، * و سپس از MPU9265 (یا هر MPU دیگری در آن آدرس 0x68) * * من از آن برای تأیید اگر بتوانم حتی از روی سنسور بخوانم استفاده کنم ، زیرا قبلاً * به MCP23017 اطمینان داشتم. *********************************************** *************************** # #شامل #شامل #شامل #شامل #شامل #شامل int main (int argc، char ** argv) {قرار می دهد ("بیایید ببینیم MCP23017 @ 0x20 چه می گوید:")؛ errno = 0؛ int deviceId1 = 0x20؛ int fd1 = سیم کشیPiI2CSetup (deviceId1) ؛ if (-1 == fd1) {fprintf (stderr ، "نمی توان سیم کشی دستگاه I2C را باز کرد:٪ s / n" ، strerror (errno)) ؛ بازگشت 1 ؛ } for (int reg = 0؛ reg <300؛ reg ++) {fprintf (stderr، "٪ d"، wiringPiI2CReadReg8 (fd1، reg))؛ fflush (stderr)؛ تأخیر (10) ؛ } قرار می دهد ("")؛ قرار می دهد ("بیایید ببینیم MPU9265 @ 0x20 چه می گوید:")؛ errno = 0؛ int deviceId2 = 0x68؛ int fd2 = سیم کشیPiI2CSetup (deviceId2) ؛ if (-1 == fd2) {fprintf (stderr ، "نمی توان سیم کشی دستگاه 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 * * این برنامه شماره ثبت را در کنار مقدار خوانده شده خروجی می دهد. * * این امر لوله کشی (تغییر مسیر) خروجی به یک فایل را مفید می کند ، و سپس * چندین اجرا را می توان برای مقایسه انجام داد. ممکن است بینشی راجع به * چه رجیستری مهم است و چگونه داده ها ممکن است رفتار کنند ، ارائه دهد. *********************************************** *************************** # #شامل #شامل #شامل #شامل #شامل #شامل #شامل int main (int argc، char ** argv) {int deviceId = -1؛ if (0) {} else if (! strncmp (argv [1]، "0x20"، strlen ("0x20"))) {deviceId = 0x20؛ } else if (! strncmp (argv [1] ، "0x68" ، strlen ("0x68"))) {deviceId = 0x68؛ } else if (! strncmp (argv [1] ، "0x69" ، strlen ("0x69"))) {deviceId = 0x69؛ } قرار می دهد ("بیایید ببینیم MPU9265 @ 0x20 چه می گوید:")؛ errno = 0؛ int fd = wiringPiI2CSetup (deviceId) ؛ if (-1 == fd) {fprintf (stderr ، "نمی توان سیم کشی دستگاه I2C را باز کرد:٪ s / n" ، strerror (errno)) ؛ بازگشت 1 ؛ } for (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 * * این برنامه نتیجه برنامه دوم است. فقط از رجیسترهای * که تفاوت بین یک اجرا و بعدی را نشان می دهد می خواند.*********************************************** *************************** # #شامل #شامل #شامل #شامل #شامل #شامل #شامل int main (int argc، char ** argv) {int deviceId = -1؛ if (0) {} else if (! strncmp (argv [1]، "0x68"، strlen ("0x68"))) {deviceId = 0x68؛ } else if (! strncmp (argv [1] ، "0x69" ، strlen ("0x69"))) {deviceId = 0x69؛ } قرار می دهد ("بیایید ببینیم MPU9265 @ 0x20 چه می گوید:")؛ errno = 0؛ int fd = wiringPiI2CSetup (deviceId) ؛ if (-1 == fd) {fprintf (stderr ، "نمی توان سیم کشی دستگاه I2C را باز کرد:٪ s / n" ، strerror (errno)) ؛ بازگشت 1 ؛ } برای (int reg = 61؛ reg <= 73؛ reg ++) {fprintf (stderr، "٪ d:٪ d / n"، reg، wiringPiI2CReadReg8 (fd، reg))؛ fflush (stderr)؛ تأخیر (10) ؛ } for (int reg = 111؛ reg <= 112؛ reg ++) {fprintf (stderr، "٪ d:٪ d / n"، reg، wiringPiI2CReadReg8 (fd، reg))؛ fflush (stderr) ؛ تأخیر (10) ؛ } for (int reg = 189؛ reg <= 201؛ reg ++) {fprintf (stderr، "٪ d:٪ d / n"، reg، wiringPiI2CReadReg8 (fd، reg))؛ fflush (stderr)؛ تأخیر (10) ؛ } for (int reg = 239؛ reg <= 240؛ reg ++) {fprintf (stderr، "٪ d:٪ d / n"، reg، wiringPiI2CReadReg8 (fd، reg))؛ fflush (stderr) ؛ تأخیر (10) ؛ } بازگشت 0؛ }

خب ما تا حالا چی یاد گرفتیم؟ تصویر جدول با مناطق برجسته رنگی نشان می دهد که به نظر می رسد خروجی با اولین مجموعه های ثبت مطابقت دارد.

نتایج تا کنون می تواند سوالات جدیدی ایجاد کند.

س:ال: چرا فقط یک نتیجه ثبت شده برای گروه "خارجی" وجود دارد؟

س:ال: همه آن ثبت نامعلوم ها چیست "" ؟؟؟؟؟؟"

س:ال: از آنجا که برنامه بر اساس وقفه عمل نمی کند ، آیا اطلاعات را بسیار کند درخواست می کند؟ خیلی سریع؟

س:ال: آیا می توانیم با کارکردن سنسور در حین کار ، نتایج را تحت تأثیر قرار دهیم؟

مرحله 6: بیایید بیشتر به خواندن / داده ها بپردازیم

من فکر می کنم قدم بعدی قبل از هر چیز این است که برنامه را به صورت زیر تقویت کنید:

  • در میزان تاخیر حلقه (ms) انعطاف پذیر باشید
  • انعطاف پذیری داشته باشید تا میانگین خوانده شده را برای هر ثبت ثبت کنید

(مجبور شدم برنامه را به عنوان یک فایل ضمیمه کنم. به نظر می رسد مشکلی در درج آن در اینجا وجود دارد. "4th.test.mpu9265.c")

در اینجا یک اجرا با استفاده از 10 قرائت آخر به طور متوسط ، در حلقه 10 میلی ثانیه وجود دارد:

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؛ // دستور hi را 8 بیت در قسمت بالای یک نتیجه مقدار 16 بیتی قرار دهید | = loByte؛ // حالا به ترتیب 8 بیت اضافه کنید و یک عدد 16 بیتی کامل بدست آورید // آن عدد را چاپ کنید یا از عملکرد نمودارهای افقی صفحه نمایش قبلی استفاده کنید

از مراحل قبلی ما مشاهده کردیم که ثبت 65 تقریباً ثابت است ، در حالی که ثبت 66 بسیار پر سر و صدا است. از آنجا که 65 بایت مرتبه بالا و 66 بایت مرتبه پایین است ، این منطقی است.

برای خواندن ، می توانیم داده های ثبت 65 را همانطور که هست بگیریم ، اما می توانیم مقادیر ثبت 66 را به طور متوسط محاسبه کنیم.

یا فقط می توانیم کل نتیجه را متوسط کنیم.

به آخرین ویدیوی این قسمت نگاهی بیندازید ؛ این نشان می دهد که کل مقدار دمای 16 بیت را می خوانید. کد "sixth.test.mpu9265.c" است

مرحله 8: شتاب سنج و ژیروسکوپ

Image
Image

ویدئوهای این بخش خروجی شتاب سنج و ژیروسکوپ را با استفاده از برنامه آزمایشی "heftth.test.mpu9265.c" نشان می دهد. این کد می تواند 1 ، 2 یا 3 بایت پیاپی متوالی (hi and lo bytes) را بخواند و مقادیر را به یک مقدار 16 بیتی تبدیل کند. بنابراین ، ما می توانیم هر محور را بخوانیم ، یا می توانیم دو محور را با هم بخوانیم (و تغییرات را جمع می کند) ، یا می توانیم هر سه را بخوانیم (و تغییرات را جمع می کند).

برای تأکید مجدد ، برای این مرحله ، برای این دستورالعمل ، من فقط به دنبال پاسخ به یک س simpleال ساده هستم: "آیا ربات چرخید/چرخید؟". من به دنبال هیچ مقدار دقیقی نیستم ، مانند اینکه آیا 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 مراحل اضافی لازم است.

از Invesense ثبت PDF PDF:

ثبت نامهای 37 تا 39 - کنترل I2C SLAVE 0

  • ثبت نام 37 - I2C_SLV0_ADDR
  • ثبت نام 38 - I2C_SLV0_REG
  • ثبت نام 39 - I2C_SLV0_CTRL

توصیه شده: