راه اندازی I2C رزبری پای پیکو – Raspberry Pi Pico I2C

I2C رزبری پای پیکو یکی از درگاههای سریال این برد است که برای ارتباط با سختافزارهایی که دارای درگاه I2C هستند به کار میرود. در این مقاله ابتدا نحوه کارکرد درگاه I2c را بررسی کرده و در ادامه راهاندازی I2C رزبری پای پیکو را با زبان میکروپایتون انجام میدهیم. در انتهای مقاله از طریق I2C رزبری پای پیکو اطلاعات شتاب MPU-9250 را به عنوان یک مثال عملی دریافت میکنیم.
I2C چیست
I2C مخفف عبارت Inter Integrated Circuit یک درگاه ارتباط سریال سنکرون و half duplex است که تنها با استفاده از دوسیم میتواند بین شبکهای از سختافزارها ارتباط برقرار کند. I2C در سال 1982 توسط شرکت philips معرفی شد و در سالهای بعد مورد استقبال عمومی از سوی دیگر شرکتهای فعال در حوزه سختافزار قرار گرفت.
برای نوشتن درون رجیستر یک slave، ابتدا باید طی یک ارتباط نوشتنی آدرس رجیستر مورد نظر را درون آن بنویسید و سپس در ادامه همان ارتباط، دادهها را بنویسید.
برای خواندن از رجیستر یک slave، ابتدا باید طی یک ارتباط نوشتنی، آدرس رجیستر مورد نظر را درون آن بنویسید و سپس طی یک ارتباط خواندنی دادههای مورد نظر را بخوانید.
اگر به اطلاعات بیشتر در مورد I2C نیاز دارید پیشنهاد میکنیم به مقاله I2C چیست؟ مراجعه کنید.
معرفی I2C رزبری پای پیکو
ویژگیهای اصلی واحد I2C رزبری پای پیکو به شرح زیر است:
- دارای دو واحد مجزای I2C0 و I2C1
- قابلیت کار در مد master و slave
- پشتیبانی از مدهای Standard Mode, Fast Mode, Fast Mode Plus
- پشتیبانی از آدرسدهی 7بیتی و 10بیتی
- بافر دیتاهای ارسالی
- بافر دیتاهای دریافتی
- قابلیت اتصال به DMA
- قابلیت ایجاد وقفه
برای ایجاد انعطاف در استفاده از پایههای میکروکنترلر، پایههای مختلفی به I2C رزبری پای پیکو اختصاص داده شده که میتوانید بر اساس نیاز، هرکدام را انتخاب کنید. جدول این پایهها در ادامه آورده شده است.

دقت داشته باشید توسط کتابخانههای نرم افزاری میتوان یک I2C نرم افزاری ایجاد کرد که رفتاری مشابه با واحد I2C داشته باشد. با این کار میتوان بیش از 2 عدد I2C در رزبری پای پیکو داشت و همچنین دست شما در انتخاب پایه برای I2C نرم افزاری کاملا باز است. اما لود این کار روی پروسسور میکروی شما خواهد بود و آن را به شدت مشغول میکند. توصیه میشود تا حد ممکن از ایجاد I2C نرم افزاری اجتناب کنید.
برای کسب اطلاعات بیشتر در مورد واحد I2C رزبری پای پیکو میتوانید به سند دیتاشیت میکروکنترلر RP2040 مراجعه کنید.
راه اندازی I2C رزبری پای پیکو – اتصال به ماژول MPU-9250
در این بخش استفاده از I2C رزبری پای پیکو را با یک پروژه عملی به شما نشان میدهیم. در این پروژه قصد داریم مقادیر زاویه در راستای محور X، محور Y و محور Z را با استفاده از شتاب سنج موجود در چیپ MPU-9250 بدست آوریم. چیپ MPU-9250 هم دارای درگاه SPI و هم دارای درگاه I2C است که در این نوشته از درگاه I2C آن استفاده شده است.
دقت داشته باشید در اینجا هدف ما ذکر قابلیتهای این چیپ یا نحوه عملکرد آن نیست بلکه تمرکز بر راه اندازی I2C رزبری پای پیکو با زبان میکرو پایتون است. بنابراین در رابطه با چیپ MPU-9250 تنها به ذکر اطلاعات مورد نیاز میپردازیم.

تنظیمات سنسور است که میتوانید با نوشتن درون آنها تنظیمات سنسور را تغییر دهید و برخی نیز شامل اطلاعات خواندنی است از جمله اطلاعات اندازه گیری شده توسط سنسور که با خواندن آنها به اطلاعات مورد نظرتان دسترسی پیدا میکنید. برای انجام یک عملیات در این سنسورها ابتدا باید مشخص کنید با کدام رجیستر میخواهید ارتباط برقرار کنید و قصد شما خواندن اطلاعات آن رجیستر است یا نوشتن اطلاعات در آن رجیستر و سپس اقدام به خواندن یا نوشتن اطلاعات کنید.
با این توضیحات مشخص میشود که ما به دو دسته اطلاعات در مورد کار با سنسور MPU-9250 احتیاج داریم
- اطلاعات مربوط به آدرس I2C ذخیره شده در چیپ
- اطلاعات مربوط به سرعت درگاه I2C
- اطلاعات مربوط به آدرس رجیسترها، یعنی اینکه هر رجیستری در چه آدرسی قرار گرفته است.
به این منظور بخشهای کوچکی از دیتاشیت سنسور را در اینجا آوردهایم. اگر علاقهمند به مطالعه کامل دیتاشیت هستید به سند MPU-9250 Datasheet مراجعه کنید.

از تصویر فوق مشخص میشود اگر پایه AD0 چیپ را به GND متصل کنیم آدرس I2C چیپ 104 (معادل دسیمال عدد باینری 1101000) میشود و اگر پایه AD0 چیپ را به VCC متصل کنیم آدرس I2C چیپ 105 (معادل دسیمال عدد باینری 1101001) خواهد بود.

همچنین مشاهده میشود چیپ از Standard mode و Fast mode پشتیبانی میکند.
در مورد آدرس رجیسترها به تصویر زیر توجه کنید

از سمت چپ ستون اول آدرس رجیسترها به صورت هگزادسیمال و ستون دوم آدرس رجیستارها به صورت دسیمال است. مطابق این جدول برای بدست آوردن مقادیر شتاب در سه جهت X, Y, Z کافی است از آدرس 59 شروع کنیم و 6 بایت بخوانیم. برای اطلاعات بیشتر درمورد لیت رجیسترهای MPU-9250 میتوانید به سند MPU-9250 Register Map مراجعه کنید.
حالا که اطلاعات مورد نظر برای خواندن اطلاعات شتاب سنج موجود در چیپ MPU-9250 از طریق درگاه I2C را بدست آوردهایم میتوانیم شروع به نوشتن برنامه کنیم.
در اولین قدم کلاسهای I2C و Pin را از ماژول machine ایمپورت میکنیم.
from machine import Pin, I2C
در قدم بعدی یک نمونه (instance) از کلاس I2C با نام i2c0 میسازیم (این نام اختیاری است) و واحد I2C0 را به آن اختصاص میدهیم. همچنین تنظیمات I2C در همین مرحله قابل اعمال است.
i2c0 = I2C( 0, freq=400_000, scl=Pin(17), sda=Pin(16) )
اولین پارامتر مربوط به انتخاب I2C0 یا I2C1 است که به ترتیب با عدد 0 یا 1 مشخص میشود. ما در اینجا از I2C0 استفاده کردهایم . فرکانس SCK را برابر با 400KHz (Fast Mode) قرار داده و از پایههای GP16 و GP17 استفاده کردهایم اما استفاده از هرکدام از پایههایی که رزبری پای پیکو برای I2C0 قرار داده بلامانع است.
اگر در مورد GPIO، کلاس Pin و یا نحوه import کردن ماژولها در پایتون به اطلاعات بیشتری نیاز دارید میتوانید مقاله راه اندازی پایه های رزبری پای پیکو را مطالعه کنید.
register_address_buf = bytearray([59]) i2c0.writeto(104, register_address_buf) data_buff = i2c0.readfrom(104, 6)
به توضیحات کد توجه کنید:
- خط 1: یک متغیر از جنس byte array و با مقدار آدرس رجیستر مورد نظرمان که 59 است مقداردهی میکنیم. دلیل استفاده از byue array این است که متد writeto استفاده شده در خط بعدی برای پارامتر دوم نیاز به متغیر از جنس byte array دارد.
- خط 2: با استفاده از متد writeto مقدار آدرس رجیستر را در آدرس slave مورد نظر (یعنی 104) نوشتهایم. این متد دو پارامتر دارد. پارامتر اول آدرس Slave روی باس است و پارامتر دوم بافری از اطالاعات که باید روی Slave نوشته شود.
- خط 3: با استفاده از متد read تعداد 6 بایت داده را از Slave با آدرس 104 خواندهایم. این متد دو پارامتر دارد. پارامتر اول آدرس Slave روی باس است که میخواهیم از آن بخوانیم و پارامتر دوم تعداد بایتهایی است که باید خوانده شود. همچنین این متد اطلاعات خوانده شده را در قالب یک byte array برمیگرداند.
یک متد مفید کلاس I2C متد scan است. این متد آدرس تمام Slaveهای روی باس را برمیگرداند. در مواردی که از آدرس Slaveی که میخواهید با آن ارتباط برقرار کنید اطلاع ندارید این متد میتواند مفید واقع شود.
اطلاعات خوانده شده در متغیر data_buff به صورت byte array است. برای آنکه بتوانیم در محاسبات ریاضی از آنها استفاده کنیم ابتدا باید آنها را به فرمت عددی درآوریم. این کار در قطعه کد زیر انجام شده است.
data_x = int.from_bytes(data_buff[0:2], 'big') data_y = int.from_bytes(data_buff[2:4], 'big') data_z = int.from_bytes(data_buff[4:6], 'big')
تا اینجا اطلاعات مربوط به شتاب در راستای X (متغیر data_x)، شتاب در راستای Y (متغیر data_y) و شتاب در راستای Z (متغیر data_z) را داریم. برای بدست آوردن زاویه خطی از این شتابها یک رابطه ریاضی وجود دارد.

بر اساس روابط فوق قطعه کد زیر عمل تبدیل شتاب خطی به زاویه خطی را انجام میدهد. دقت داشته باشید برای استفاده از توابع ریاضی مانند atan و sqrt ابتدا باید آنها را از ماژول math ایمپورت کرده باشید.
angle_x_radian = atan(data_x/sqrt(data_y**2 + data_z**2)) angle_y_radian = atan(data_y/sqrt(data_x**2 + data_z**2)) angle_z_radian = atan(data_z/sqrt(data_x**2 + data_y**2))
زوایای بدست آمده از این رابطه بر حسب رادیان هستند. در ادامه برای درک بهتر، آنها را به درجه تبدیل میکنیم.
angle_x_degree = (angle_x_radian/3.14)*180 angle_y_degree = (angle_y_radian/3.14)*180 angle_z_degree = (angle_z_radian/3.14)*180
در نهایت دادهها را چاپ میکنیم.
print('angle x is : ', angle_x_degree) print('angle y is : ', angle_y_degree) print('angle z is : ', angle_z_degree)
کد کامل این بخش به صورت زیر است:
from machine import Pin, I2C from math import sqrt, atan i2c0 = I2C( 0, freq=400_000, scl=Pin(17), sda=Pin(16) ) register_address_buf = bytearray([59]) i2c0.writeto(104, register_address_buf) data_buff = i2c0.readfrom(104, 6) data_x = int.from_bytes(data_buff[0:2], 'big') data_y = int.from_bytes(data_buff[2:4], 'big') data_z = int.from_bytes(data_buff[4:6], 'big') angle_x_radian = atan(data_x/sqrt(data_y**2 + data_z**2)) angle_y_radian = atan(data_y/sqrt(data_x**2 + data_z**2)) angle_z_radian = atan(data_z/sqrt(data_x**2 + data_y**2)) angle_x_degree = (angle_x_radian/3.14)*180 angle_y_degree = (angle_y_radian/3.14)*180 angle_z_degree = (angle_z_radian/3.14)*180 print('angle x is : ', angle_x_degree) print('angle y is : ', angle_y_degree) print('angle z is : ', angle_z_degree)
در انتهای این مقاله از شما دعوت میکنیم تا تجربیات ارزشمند خود در مورد I2C رزبری پای پیکو را در بخش دیدگاهها با ما و دیگر دوستانتان به اشتراک بگذارید.
دیدگاهتان را بنویسید