به نام خدا : در این مطلب از سری مطالب آموزش رزبری پای قصد داریم :1) آموزش راه انداری پروتکول I2C رزبری پای 2) آموزش راه اندازی ماژل MPU6050 با رزبری پای ، رو بگم.
آموزش راه انداری پروتکول i2c رزبری پای
تنظیمات i2c در رزبری پای
قسمت اول : تنظیمات i2c در رزبری پای؛ برای آشنایی با ارتباط i2C، به لینک زیر مراجعه فرمایید : آموزش جامع آردوینو جلسه ۱۶ پروتکول i2c twi
روند کار کاملا مشابه آردینو هست فقط سینتکست(املا)متفاوته؛ خب برای فعال سازی i2c در رزبری پای، مسیر زیر رو طی کنید :
سیستم را ریبوت کنید. بعدش ترمینال رو باز کنید و درش تایپ کنید :
1 |
sudo apt-get install –y i2c-tools |
سپس :
1 |
i2cdetect |
نتیجه کد قبلی شبیه زیر است :
خب حالا ماژول زاویه سنج mpu6050 رو به صورت زیر به رزبری وصل کنید :
سپس در ترمینال رزبری کد زیر رو وارد کنید :
1 |
i2cdetect –y 1 |
نتیجه زیر رو خواهید دید :
عدد 68، آدرس ماژول ما در باس i2c(به هگز) است که بعدا در برنامه نویسی به کار میره.
هرگاه نیکوکاري، بر روزگار و مردم آن غالب آیـد، اگرکسـی به دیگري گمان بد برد، درحالیکه از او عمل زشتی آشـکار نشـده سـتمکار است و اگر بـدي بر زمـانه و مردم آن غـالب شود، و کسی به دیگري خوش گمان باشد،خود را فریب داده.
راه اندازی ماژول mpu6050 با رزبری پای
قسمت دوم : خب حالا میریم سراغ کدی به زبان c++ برای راه اندازی ماژول mpu6050 با رسپری پای.
ماژول نامبرده شده، یک مجموعه شامل ژیروسکوپ و شتاب سنج است. که دارای ابعاد کوچک است. خروجی ژیروسکوپ، مقدار زاویه بر حسب ثانیه در جهت هر یک از بردارهای xوyوz است. و خروجی شتاب سنج، مقدار شتاب لحظه ای بر حسب g است ( 9.8 m/s*s ) از ژیروسکوپ و شتاب سنج، به صورت مجزا میتوان انحراف از محور های مختصات ( pitch و roll و yaw ) رو بدست آورد. جهت جلوگیری از نویز و همچنین دقت بیشتر در اندازه گیری زوایا، از هر دو استفاده می کنیم. برای مثال در کنترل کواد کوپتر، برای جلو گیری از پدیده دریفت و یا مقدار اولیه خطا از ژیروسکوپ و شتاب سنج، به طور همزمان استفاده می شود. ما در این پروژه فقط از شتاب سنج استفاده می کنیم. ( شما هم یه کمی تکون به خودتون بدید ) برای استخراج زاویه از ژیروسکوپ، نیاز به محاسبه زمان است. کافی است، مقدار ژیروسکوپ را بخوانیم و در زمان حرکت ضرب کنیم تا زاویه به دست آید.
ابتدا ماژول رو تست می کنیم ببینیم کار میکنه یا نه؟ ترمینال رزبری رو باز کنید و یک فایل با پسوند cpp بسازید.
1 |
sudo nano mputest.cpp |
و قطعه کد زیر رو در اون بنویسید :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <stdint.h> #include <wiringPi.h> #include <wiringPiI2C.h> #include <math.h> #include <time.h> #include <iostream> using namespace std; void dlay(float d) { long d1; for(d1=0;d1<d*140000.0;d1++){} } #define MPU6050_ACCEL_XOUT_H 0x3B #define MPU6050_ACCEL_XOUT_L 0x3C #define MPU6050_ACCEL_YOUT_H 0x3D #define MPU6050_ACCEL_YOUT_L 0x3E #define MPU6050_ACCEL_ZOUT_H 0x3F #define MPU6050_ACCEL_ZOUT_L 0x40 #define MPU6050_PWR_MGMT_1 0x6B #define MPU6050_I2C_ADDRESS 0x68 int main() { int fd = wiringPiI2CSetup(MPU6050_I2C_ADDRESS); if (fd == -1) return 0; wiringPiI2CWriteReg16(fd, MPU6050_PWR_MGMT_1,0); wiringPiI2CWriteReg16(fd, 0x1C,0x10); int16_t ax1=0,ay1=0,az1=0,ax=0,ay=0,az=0; while(1) { ax = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_XOUT_H ) << 8 |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_XOUT_L); ay = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_YOUT_H ) << 8 |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_YOUT_L ); az = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_ZOUT_H ) << 8 |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_ZOUT_L); cout<<"ax : "<<ax<<" "<<"ay : " << ay << " " << "az : " << az << endl; dlay(100); } } |
خروجی برنامه یه مثل شکل زیره :
ویدئو زیر هم تغییرات این اعداد بنا بر تغییر زاویه ماژول رو نشون میده و در ادامه، کد های نوشته شده رو خط به خط توضیح میده : http://www.aparat.com/v/iMFL3
خب تغییرات زیر رو هم اعمال کنید تا دو زاویه pitch و roll بر حسب درجه نمایش داده بشه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <stdint.h> #include <wiringPi.h> #include <wiringPiI2C.h> #include <math.h> #include <time.h> #include <iostream> using namespace std; void dlay(float d) { long d1; for(d1=0;d1<d*140000.0;d1++){} } #define MPU6050_ACCEL_XOUT_H 0x3B #define MPU6050_ACCEL_XOUT_L 0x3C #define MPU6050_ACCEL_YOUT_H 0x3D #define MPU6050_ACCEL_YOUT_L 0x3E #define MPU6050_ACCEL_ZOUT_H 0x3F #define MPU6050_ACCEL_ZOUT_L 0x40 #define MPU6050_PWR_MGMT_1 0x6B #define MPU6050_I2C_ADDRESS 0x68 int main() { int fd = wiringPiI2CSetup(MPU6050_I2C_ADDRESS); if (fd == -1) return 0; wiringPiI2CWriteReg16(fd, MPU6050_PWR_MGMT_1,0); wiringPiI2CWriteReg16(fd, 0x1C,0x10); int16_t ax1=0,ay1=0,az1=0,ax=0,ay=0,az=0; while(1) { ax = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_XOUT_H ) << 8 |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_XOUT_L); ay = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_YOUT_H ) << 8 |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_YOUT_L ); az = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_ZOUT_H ) << 8 |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_ZOUT_L); double acc_total_vector =10*sqrt(((ax/10)*(ax/10))+((ay/10)*(ay/10))+((az/10)*(az/10))); double angle_pitch_acc = asin((float)ay/acc_total_vector) * 57.296; double angle_roll_acc = asin((float)ax / acc_total_vector) * (-57.296); printf(" pitch:%f\n roll:%f\n ",angle_pitch_acc,angle_roll_acc); dlay(100); } } |
نتیجه رو در ویدئو زیر می بینید : http://www.aparat.com/v/vjSGM
توضیح زوایای pitch و roll وyaw رو در شکل زیر مشاهده می فرمایید ( در کنترل پایداری پهبادها، زاویه yaw بی تاثیر است. ما هم اونو حساب نکردیم. از این محور برای جهت یابی استفاده میشه. ) :
منبع جهت محاسبه زوایا : brokking.net
به امید خدا در مطلب بعدی، با ابزار QT به برنامه نویسی گرافیکی در رزبری پای می پردازیم.
جهت هرچه مستحکم تر شدن مقام ولایت فقیه و ظهور بابای خوبمون مهدی(عج) صلوات
مهمان
سلام.
با رزبری مینی میشه یک شی رو ردیابی گرد و با لیزری که بهش وصله بهش شلبک کرد؟
مهمان
سلام و احترام فراوان خدمت استاد عزیز یک سوالی تفاوت زاویه ای که از طریقaccle بدست میاریم با زاویه ای که Gyro به ما میده چیه چکار کنیم که مقدار زاویه دقیق داشته باشیم
ممنونم البت ببخشید دو تا شد.
نویسنده این مطلب
سلام.
در حالت سکون،تفاوت در عدد زاویه نیست.شتاب سنج،در لرزش،مقدارش نویز داره و ژیروسکوپ هم دریفت داره.برای رفع این دوتا مشکل،دوتا داده رو ترکیب می کنیم.
دوتاویدئو مربوط به زاویه سنجی موجود در مطلب کوادکوپتر با رزبری-قسمت۱ رو مشاهده فرمایید.
مهمان
ax = wiringPiI2CReadReg8(fd, MPU6050_ACCEL_XOUT_H ) << ۸ |wiringPiI2CReadReg8(fd,MPU6050_ACCEL_XOUT_L);
ممکنه توضیح بدین دقیق چی کار میکنه
نویسنده این مطلب
سلام
چون رجیستر های مورد نظر ما در ماژول، هشت بیتی هستند
و مقدار هر محور ما،شانزده بیتی است.هشت بیتر کم ارزشL و هشت بیت پر ارزشH رو با کد بالا کنار هم قرار میدیم تا شانزده بیت بشه.
به این ترتیب که مقدار پر ارزش رو می خونیم و هشت واحد به چپ شیفت میدیم و با هشت بیت کم ارزش or می کنیم تا در نهایت، عدد کامل هر محور رو داشته باشیم
مهمان
سلام میخوام با ماژول mpu60 یه قطب نما بسازم ماژولو راه اندازی کردم ولی موندم چطوری زاویه بهش بدم وچطوری در یه lcd گرافیکی طرفه قبله رو نشون بدم اگ کمک کنید ممنون میشم
نویسنده این مطلب
سلام
مدل دقیق ماژلتون رو بفرستید ترجیها با لینک فروشگاه یا دیتا شیت
چون mpu6050 قطب نما نداره!!!(احتمالا)
مهمان
سلام واسه من آدرس i2c 68 هست همین کد رو زدم ولی wiringPiI2Csetup مقدار -1 رومیده چه کنم ؟
نویسنده این مطلب
salam
code zir ro compile konid bebinid mishe ya na
http://s8.picofile.com/file/8274062750/mpu.cpp.html
اگر جواب نداد،فایل cppکدی که نوشتید رو آپلود کنید و لینکش رو بذارید.
مهمان
البته من دارم از mpu9250 استفاده میکنم ولی خب این دستور باید برای ارتباط i2c جواب بده دیگه؟
نویسنده این مطلب
احتمالا baud rate واحد i2c رسپری شما،100 کیلو بیت بر ثانیه نیست.برای تنظیم اون،در ترمینال تایپ کنید
sudo nano /boot/config.txt
خط زیر رو به محل اشاره شده در عکس زیر اضافه کنید و ذخیره کنید
http://s9.picofile.com/file/8274184600/i2cd.jpg
dtparam=i2c1_baudrate=100000
اگر این خط از قبل وجود داره،فقط مقدارش رو تغییر بدید
بعدش ریبوت کنید ببینید درست میشه یا نه
مهمان
این خط اونجا وجود نداشت ، اضافه کردم ولی بازم درست نشد
نویسنده این مطلب
ظاهرا نحوه کار ماژول شما،با ماژول این مطلب متفاوت است.
حدس میزنم که baudrate ماژول شما 100کیلو بیت بر ثانیه نباشه.(احتمال ضعیف چون در کد avr مقدارش 100 کیلو هست)
مثلا شاید 400000 باشه تغییرش بدید شاید درست شد
…سعی کنید کد پایتون براش پیدا کنید.تا از سالم بودن ماژولتون مطمئن بشید.
در لینک زیر،ماژول رو با جاوا راه انداخته.هیچ سر رشته ای از جاوا ندارم.نمیدونم چجوری میشه ازش استفاده کرد.
https://github.com/miniben-90/mpu9250
ویا اگر میکرو avr دارید،اونا با کد زیر پروگرم کنید.
http://www.avrfreaks.net/forum/zero-output-mpu9250-atmega32-i2c-codevision
مهمان
salam
.text+0xa4): undefined reference to
.text+0xf0): undefined reference to
.text+0x128): undefined reference to
.text+0x160): undefined reference to
man in code ro run kardam vali errore ziro mide :
/tmp/ccIYffJi.o: In function
main':
wiringPiI2CSetup’test1.cpp:(.text+0x78): undefined reference to
test1.cpp
wiringPiI2CWriteReg16'
wiringPiI2CWriteReg16′test1.cpp:(.text+0xb4): undefined reference to
test1.cpp
wiringPiI2CReadReg8'
wiringPiI2CReadReg8′test1.cpp:(.text+0x108): undefined reference to
test1.cpp
wiringPiI2CReadReg8'
wiringPiI2CReadReg8′test1.cpp:(.text+0x140): undefined reference to
test1.cpp
wiringPiI2CReadReg8'
wiringPiI2CReadReg8′ follow/tmp/ccIYffJi.o:test1.cpp:(.text+0x178): more undefined references to
collect2: error: ld returned 1 exit status
che konam?
نویسنده این مطلب
سلام. این ارور موقع ران نیست.ارور کامپایله…
همون طور که در ویدئو آورده شده،با دستور زیر کامپایل کنید
g++ -o exename project_name.cpp -l wiringPi
به جای exename،نام دلخواه فایل خروجی و به جای project_name ،
نام فایل cpp رو بذارید.
مهمان
اشتباه نکن الکترونیک تو ایران بدرد نمیخوره اگه ئنبال پیشرفتی برو یه کار دیگه
مدیر سایت
حرف شما رو تصحیح میکنم : الکترونیک تو ایران به درد افراد … نمیخوره.
نویسنده این مطلب
سلام.بستگی داره،ایران رو کجا در نظر بگیرید و دیگه اینکه پیشرفت رو چی تعریف می کنید.
بنده منتظر “یه روز خوب میاد…”نیستم.به امید خدا،روز خوبم رو خودم می سازم…