در این آموزش قصد داریم چگونگی راهاندازی و استفاده از ارتباط I2C در آردوینو را برای شما علاقهمندان به الکترونیک مورد بررسی قرار میدهیم. در این آموزش پایههای I2C روی برد آردوینو UNO، پیکربندی MASTER و SLAVE و در نهایت ارتباط دو آردوینو uno از طریق I2C را مورد بررسی قرار میدهیم.
فهرست مطالب
پروتکل I2C چیست و چگونه کار می کند؟
I2C کوتاه شده عبارت Inter-Integrated Circuit یک پروتکل ارتباط سریال همزمان میباشد. این پروتکل توسط شرکت فیلیپس جهت ارتباط بین میکروکنترلرهای نسبتا سریع با تجهیزات جانبی نسبتا کند مانند حافظهها و سنسورها تنها از طریق دو رشته سیم ساخته و طراحی شده است. از اینرو از این پروتکل به عنوان TWI (Tow Wire Interface) نیز یاد میشود.
با استفاده از I2C میتوانید دادهها را با سرعت 100 کیلوبیت بر ثانیه (کلاک 100 کیلوهرتز – حالت استاندارد) ، 400 کیلوبیت بر ثانیه (کلاک 400 کیلوهرتز – حالت سریع)، 1 مگابیت در ثانیه (کلاک 1 مگاهرتز – حالت سریع پلاس) و 3.4 مگابیت در ثانیه (ساعت 3.4 مگاهرتز – حالت با سرعت بالا) انتقال دهید. در نگاه اول ممکن است این سرعتها بالا به نظر نرسد ولی این سرعت برای ارتباط با سنسورها، حافظهها و نمایشگرها در فواصل کوتاه مناسب است.
درگاه یا I2C BUS در آردوینو
درگاه I2C از دو سیم به نامهای Serial Data (SDA) و Serial Clock (SCL) تشکیل شده است. دادهها از طریق لاین SDA منتقل میشوند در حالی که از لاین SCL برای همگامسازی یا سنکرون کردن ستگاه با یک کلاک استفاده میشود. هر دو این خطوط به صورت OPEN-DRAIN راهاندازی میشوند و برای استفاده نیاز به مقاومت بالاکش یا PULL-UP دارند.
در درگاه I2C یکی از دستگاهها به عنوان مستر MASTER و دیگری به عنوان اسلیو SLAVE خواهد بود. درگاه مستر وظیفه ارسال و دریافت اطلاعات از اسلیو را بر عهده دارد. این در حالی است که سیگنال کلاک هم توسط مستر ارائه میشود.
شبکه I2C میتواند در آن واحد چندین مستر و یا چندین اسلیو داشته باشد (ولی معمولا شاهد یک دستگاه به عنوان مستر و چندین دستگاه به عنوان اسلیو هستیم). هر یک از دستگاههای اسلیو که به گذرگاه I2C متصل هستند آدرس 7 بیتی منحصر به فرد دارند. با استفاده از این آدرس، دستگاه مستر یه دستگاه اسلیو را برای انتقال داده انتخاب میکند و دستگاه اسلیو منتخب شده بر اساس درخواست دستگاه مستر پاسخ میدهد.
ارتباط I2C در آردینو
آردوینو از ارتباط I2C پشتیبانی میکند. پینهای ورودی A4 و A5 دارای عملکرد جایگزین I2C هستند. پایه A4 مانند SDA عمل میکند در حالی که پایه A5 مانند SCL عمل میکند. در نسخه 3 برد آردوینو دو پایه در نزدیکی پین 13 برد (نزدیک سوکت USB) برای SDA و SCL اختصاص داده شده است.
اگر از برد دیگری استفاده میکنید طبق جدول زیر همانطور که پایههای I2C را به طور کامل برای شما توضیح میدهد.
میکروکنترلر ATMEGA328P به کار گرفته شده در برد آردوینو UNO و NANO از ارتباط داده I2C با سرعت بیشتر از 400 کیلو هرتز پشتیبانی میکند.
لوازم مورد نیاز برای ارتباط I2C در آردینو
برای نمایش عملکرد I2C در آردوینو، اجازه دهید یک مدار کوچک بسازیم. در این مقاله دو برد آردوینو UNO را برای برقراری ارتباط از طریق درگاه I2C به هم متصل میکنیم. برای جذاب کردن این نمایش و دیدن انتقال داده در واقعیت از چند LED و پتانسیومتر (برای هر دو برد) استفاده میکنیم.
پتانسیومترها به پینهای ورودی آنالوگ مربوطه (A0) و LED ها به پین دیجیتال IO که دارای PWM میباشد متصل میشوند. یکی از بردها به عنوان مستر و دیگری به عنوان اسلیو پیکربندی شدهاند.
هنگامی که با چرخاندن پتانسیومتر متصل به برد مستر مقاومت را تغییر میدهیم این تغییر آنالوگ توسط POT ضبط میشود و این مقدار را به یک عدد دیجیتال تبدیل میکند (در محدوده 0- 1023) که این مقدار به یک مقدار مناسب PWM در محدود 0 تا 255 تبدیل میشود و درنهایت همین مقدار از باس I2C به برد اسلیو منتقل میشود.
برد اسلیو آردوینو با دریافت مقدار PWM میزان روشنایی LED را تغییر میدهد. هم چنین برد اسلیو مقدار پتانسیومتر متصل به خود را به برد مستر (در صورت ارسال درخواست از برد مستر) ارسال میکند. سپس برد مستر مقدار PWM را از برد اسلیو قرائت کرده و روشنایی LED متصل به خود را با مقدار خوانده شده تنطیم میکند. این ارتباط ادامه مییابد و به صورت یکپارچه از طریق درگاه I2C تکرار میشود.
این یک مدار ساده برای درک ارتباط از طریق پروتکل I2C میباشد. شما میتوانید مدارات با پیچیدگی بیشتر و افزایش تعداد دستگاههای اسلیو بر همین مبنا پیادهسازی کنید. دستگاههای مختلفی مانند آیسی های EEPROM، السیدی، سنسورهای فشار و غیره را طراحی کنید.
برای ساخت این مدار به قطعات زیر نیاز دارید:
دو عدد برد آردوینو UNO
دو عدد پتانسیومتر 10 کیلو اهم
دو عدد LED
دو عدد مقاومت 330 اهم
برد ازمایشی
وایر و منبع تغذیه
دیاگرام مدار
در تصویر زیر شماتیک مدار مورد بحث نمایش داده شده است…
نرمافزار ارتباط I2C در آردوینو
برای برنامهریزی بردهای اردینو باید کتابخانه WIRE را کامل درک کرده باشید. این کتابخانه به شما این امکان را میدهد که با دستگاههایی که از پروتکل I2C پشتیبانی میکنند از طریق درگاه I2C (خطوط SDA و SCL) ارتباط برقرار کنید.
برنامه نویسی
این کتابخانه همراه با محیط یکپارچه توسعه نرمافزار یا IDE ارائه شده است و شما مجبور به دانلود چیز اضافهای نیستید. تنها کاری که شما باید بکنید اضافه کردن کتابخانه با دستور INCLUDE به صورت زیر است:<include <Wire.h#
کتابخانه WIRE برای کاربردهای مربتط با I2C ده تابع تعریف کرده است که به شرخ زیر است.
- ()Wire.begin
- ()Wire.requestFrom
- ()Wire.beginTransmission
- ()Wire.endTransmission
- ()Wire.write
- ()Wire.available
- ()Wire.read
- ()Wire.SetClock
- ()Wire.onReceive
- ()Wire.onRequest
تمام توابع فوق را بررسی میکنیم
الف) ()Wire.begin
تابع اول ()Wire.begin می باشد که برای شروع کار با این پروتکل از این کد باید استفاده کنیم. اگر ادرس 7 بیتی به عنوان یک ارگومان دستگاه را درون این کد قرار دهید دستگاه به درگاه I2C به عنوان اسلیو متصل میشود. اگر ادرس وارد نشود دستگاه به عنوان مستر انتخاب میشود.
- Wire.begin() – Master
- Wire.begin(address) – Slave
ب) Wire.beginTransmission(address)
این تابع برای شروع انتقال داده به دستگاه اسلیو با آدرس مشخص مورد استفاده قرار میگیرد.
پ) ()Wire.write
پس از شروع انتقال با استفاده از کد بالا، اکنون میتوانید ارسال دادههای واقعی را با استفاده از این کد آغاز کنید. همچنین شما میتوانید از این دستور هنگامی که دستگاه مستر از تابع ()Wire.RequestFrom استفاده میکند برای نوشتن داده از دستگاه اسلیو استفاده کنید.
- Wire.write(value) – Send a single Byte value
- Wire.write(string) – Send a series of Bytes in the form of string
- Wire.write(data, length) – Send an array of data of specified length
ت) ()Wire.endTransmission
در انتها هرانتقال از این کد استفاده میکنیم
ث) ()Wire.read
از این تابع برای خواندن بایت دادهها که از مستر به اسلیو یا برعکس منتقل میشود استفاده کرد زمانی که مستر تابع ()Wire.requestFrom را فراخوانی کرده است.
ج) ()Wire.requestFrom
دستگاه مستر از این کد برای درخواست داده از اسلیو استفاده میکند. برای بازیابی دادهها از تابع ()Wire.write استفاده میشود. نحوه استفاد از این کد به صورت زیر است:
Wire.requestFrom(address, quantity)
درخواست تعداد بایت داده (مقدار quantity ) از اسلیو با ادرس مشخص
چ) ()Wire.onReceive
این تایع یک تابع کنترلکننده است و زمانی که اسلیو دادهها رو از مستر دریافت میکند فراخوانی میشود.
ح) ()Wire.onRequest
این تابع یک تابع کنترلکننده است و زمانی استفاده میشود که مستر درخواست داده از اسلیو دارد فراخوانی میشود.
کد مستر
پس از معرفی تابعهای کتابخانه wire زمان نوشتن کد میباشد. با استفاده از این تابعهای ساده یک کد ساده در ادامه نمایش داده شده است. کد زیر برای ارسال مقدار PWM به اسلیو و همچنین درخواست یک بایت از جانب اسلیو است.
/*Arduino Master I2C*/ #include <Wire.h> #define ledPin 9 byte rcvData; int potValue; void setup() { Wire.begin(); rcvData = 255; pinMode(ledPin, OUTPUT); } void loop() { potValue = analogRead(A0); potValue = map(potValue, 0, 1023, 0, 255); Wire.beginTransmission(0x14); Wire.write(potValue); Wire.endTransmission(); Wire.requestFrom(0x14, 1); if(Wire.available()) { rcvData = Wire.read(); } analogWrite(ledPin, rcvData); }
کد اسلیو ارتباط I2C در آردوینو
در بدنه کد اسلیو برای ادرسدهی دستگاه اسلیو از عدد 0*14 استفاده کردم. شما میتوانید برای اینکار از اعداد کوچکتر 128 استفاده کنید. نکته مهم در کتابخانه WIRE این است که از 7 بیت برای ادرسدهی بدون بیتهای خواندن و نوشتن استفاده میکند. بنابراین اگر ادرس 8 بیتی (شامل بیت خواندن و نوشتن) دارید، ادرس را باید یک بیت شیفت دهید و سپس از ان در کتابخانه استفاده کنید. کتابخانه به طور اتوماتیک ادرس را با توجه به تابع خواندن و نوشتن تنظیم میکند.
همچنین اطمینان داشته باشید که ادرس اسلیو منحصربه فرد است و هیج دو دستگاه اسلیو نباید یک آدرس یکسان داشته باشند.
با بازگشت به کد دو تابع DataReceive و DataRequest مورد استفاده قرار گرفته است که وقتی دادهها توسط اسلیو دریافت میشود یا دادهها از اسیلو درخواست میشود، فراخوانی میشوند. دادههای دریافت شده توسط اسلیو در تابع DataReceive حاوی مقدار PWM ارسال شده توسط مستر میباشد. دادههایی که از طریق DataRequest انتقال داده میشوند مقدار PWM از اسلیو به مستر میباشد.
/*Arduino Slave I2C*/ #include <Wire.h> #define ledPin 9 byte rcvData; int potValue; void setup() { Wire.begin(0x14); /*Event Handlers*/ Wire.onReceive(DataReceive); Wire.onRequest(DataRequest); rcvData = 255; pinMode(ledPin, OUTPUT); } void loop() { potValue = analogRead(A0); potValue = map(potValue, 0, 1023, 0, 255); analogWrite(ledPin, rcvData); } void DataReceive(int numBytes) { while(Wire.available()) { rcvData = Wire.read(); } } void DataRequest() { Wire.write(potValue); }
در این مطلب ارتباط دوطرفه ساده بین دو برد اردوینو با استفاده از ارتباط I2C نمایش داده شده است. شما در مورد نحوه ارتباط I2C در اردوینو، نکات مهم در رابطه با ارتباط I2C و کتابخانه WIRE و همچنین نحوه راهاندازی و استفاده از ارتباط I2C را فراگرفتید.