يتيح بروتوكول I2C الشائع التواصل بين لوحتين أو أكثر من لوحات Arduino. اكتشف كيفية الاتصال بها ورمزها.
في حين أن Arduino واحد يمكنه إنجاز العديد من المهام ، فقد تتطلب بعض المشاريع استخدام أكثر من لوحة واحدة للتعامل مع وظائف مختلفة. لذلك ، لتمكين نقل البيانات بين اثنين من وحدات التحكم الدقيقة ، يجب إعداد بروتوكول اتصال مثل CAN أو SPI أو I2C أو UART.
في هذا الدليل ، سنغطي أساسيات كيفية عمل I2C ، وتوصيلات الأجهزة ، وتنفيذ البرامج اللازمة لإعداد لوحتين من Arduino كأجهزة I2C الرئيسية والأجهزة التابعة.
ما هو I2C؟
Inter-Integrated Circuit (I2C) هو بروتوكول اتصال يستخدم على نطاق واسع في الأنظمة المدمجة والميكروكونترولر لتمكين نقل البيانات بين الأجهزة الإلكترونية. على عكس SPI (الواجهة الطرفية التسلسلية) ، يسمح لك I2C بتوصيل أكثر من جهاز رئيسي بناقل باستخدام أجهزة فرعية مفردة أو متعددة. تم استخدامه لأول مرة بواسطة Philips وهو معروف أيضًا باسم بروتوكول الاتصال بواجهة سلكية (TWI).
كيف تعمل اتصالات I2C؟
تستخدم I2C خطين ثنائي الاتجاه: البيانات التسلسلية (SDA) والساعة التسلسلية (SCL) لنقل البيانات ومزامنة الاتصال بين الأجهزة. كل جهاز متصل بناقل I2C له عنوان فريد يحدده أثناء الاتصال. يسمح بروتوكول I2C لأجهزة متعددة بمشاركة نفس الناقل ، ويمكن لكل جهاز أن يعمل كسيد أو تابع.
يبدأ الاتصال بواسطة الجهاز الرئيسي ، ويمكن أن تتسبب العنونة غير الصحيحة للأجهزة التابعة في حدوث أخطاء في النقل. تحقق من دليلنا المتعمق حول كيف تعمل الاتصالات التسلسلية UART و SPI و I2C لإعطائك بعض السياق.
الميزة الرئيسية لاتصالات I2C الجديرة بالملاحظة هي المرونة التي توفرها عندما يتعلق الأمر بإدارة الطاقة. لا يزال بإمكان الأجهزة التي تعمل بمستويات جهد مختلفة أن تتواصل بشكل فعال بمساعدة محولات الجهد. هذا يعني أن الأجهزة التي تعمل عند 3.3 فولت تحتاج إلى محولات جهد لتوصيلها بحافلة 5V I2C.
مكتبة الأسلاك
مكتبة Wire هي مكتبة Arduino مضمنة توفر وظائف للتواصل عبر I2C. يستخدم دبابيس - SDA و SCL - على لوحة Arduino لاتصالات I2C.
دبابيس I2C على Arduino Uno:
دبابيس Arduino Nano I2C:
لاستخدام المكتبة ، يجب عليك تضمين الامتداد سلك header في بداية رسم Arduino الخاص بك.
#يشمل
توفر مكتبة Wire وظائف لبدء الاتصال بجهاز I2C وإرسال البيانات واستقبال البيانات. تتضمن بعض الوظائف المهمة التي يجب أن تعرفها ما يلي:
- Wire.begin (): تستخدم للانضمام إلى ناقل I2C وبدء الاتصال.
- Wire.beginTransmission (): يستخدم لتحديد عنوان الرقيق وبدء الإرسال.
- Wire.write (): تستخدم لإرسال البيانات إلى جهاز I2C.
- Wire.endTransmission (): يستخدم لإنهاء الإرسال والتحقق من الأخطاء.
- طلب تحويل من (): يستخدم لطلب البيانات من جهاز I2C.
- Wire.available (): تستخدم للتحقق مما إذا كانت البيانات متاحة للقراءة من جهاز I2C.
- Wire.read (): تستخدم لقراءة البيانات من جهاز I2C.
استخدم ال Wire.beginTransmission () وظيفة لتعيين عنوان المستشعر ، والذي يتم إدراجه كوسيطة. على سبيل المثال ، إذا كان عنوان المستشعر هو 0x68، يمكنك استخدام:
الأسلاك.يبدأ الإرسال(0x68);
إعداد أجهزة Arduino I2C
لتوصيل لوحتين من Arduino باستخدام I2C ، ستحتاج إلى مكونات الأجهزة التالية:
- لوحان اردوينو (رئيسي وعبد)
- اللوح
- أسلاك العبور
- مقاومات سحب 4.7kΩ
ربط SDA و SCL دبابيس كل من لوحي Arduino على لوح التجارب. قم بتوصيل مقاومات السحب بين SDA و SCL دبابيس و 5 فولت قضيب كهربائي على اللوح. أخيرًا ، قم بتوصيل اللوحين معًا باستخدام أسلاك توصيل.
دائرة اردوينو أونو
حلبة اردوينو نانو
إعداد لوحات Arduino كأجهزة I2C Master و Slave
استخدم ال طلب تحويل من () وظيفة لتحديد عنوان الجهاز التابع الذي نريد التواصل معه. ثم استخدم ملف Wire.read () وظيفة للحصول على البيانات من جهاز الرقيق.
كود الجهاز الرئيسي:
#يشمل
فارغيثبت(){
الأسلاك.يبدأ(); // انضم إلى حافلة i2c
مسلسل.يبدأ(9600); // بدء المسلسل للإخراج
}
فارغاستقبال البيانات(){
int العنوان = 8;
int bytesToRead = 6;
الأسلاك.طلب من(العنوان ، bytesToRead) ؛
بينما (الأسلاك.متاح()) {
شار البيانات = الأسلاك.يقرأ();
مسلسل.مطبعة(بيانات)؛
}
تأخير(500);
}
فارغحلقة(){
استقبال البيانات()؛
}
ال Wire.onReceive () تُستخدم الوظيفة لتحديد ما يجب فعله عندما يتلقى العبد بيانات من الجهاز الرئيسي. في الكود أعلاه ، فإن ملف Wire.available () تتحقق الوظيفة مما إذا كانت البيانات متاحة ، و Wire.read () وظيفة يقرأ البيانات المرسلة من قبل الجهاز الرئيسي.
كود الجهاز الرقيق:
#يشمل
فارغيثبت(){
الأسلاك.يبدأ(8); // انضم إلى ناقل I2C بالعنوان 8
الأسلاك.عند الاستلام(استقبال الحدث) ؛ // call Recevent عند تلقي البيانات
}
فارغحلقة(){
تأخير(100);
}
فارغاستقبل الحدث(int بايت){
الأسلاك.يكتب("مرحبًا "); // رد برسالة من 6 بايت كما هو متوقع بواسطة السيد
}
إرسال واستقبال البيانات باستخدام I2C
في هذا المثال ، دعنا نقرأ درجة الحرارة من مستشعر درجة حرارة DHT11 المتداخل مع العبد Arduino ونطبعه على الشاشة التسلسلية للسيد Arduino.
دعنا نعدل الكود الذي كتبناه سابقًا ليشمل قياس درجة الحرارة الذي سنرسله بعد ذلك إلى اللوحة الرئيسية عبر ناقل I2C. يمكن للوحة الرئيسية بعد ذلك قراءة القيمة التي أرسلناها ، ثم عرضها على الشاشة التسلسلية.
كود الجهاز الرئيسي:
#يشمل
فارغيثبت(){
الأسلاك.يبدأ();
مسلسل.يبدأ(9600);
مسلسل.println("ماجستير مهيأ!");
}
فارغحلقة(){
الأسلاك.طلب من(8, 1); // طلب بيانات درجة الحرارة من العبيد
لو (الأسلاك.متاح()) {
بايت درجة الحرارة = الأسلاك.يقرأ(); // قراءة بيانات درجة الحرارة من الرقيق
مسلسل.مطبعة("درجة حرارة: ");
مسلسل.مطبعة(درجة حرارة)؛
مسلسل.println("درجة مئوية");
}
تأخير(2000); // انتظر لمدة ثانيتين قبل طلب درجة الحرارة مرة أخرى
}
كود الجهاز الرقيق:
#يشمل
#يشمل#يُعرِّف DHTPIN 4 // دبوس متصل بجهاز استشعار DHT
#يُعرِّف DHTTYPE DHT11 // نوع مستشعر DHT
دهت dht(DHTPIN ، DHTTYPE);
بايت درجة حرارة؛فارغيثبت(){
الأسلاك.يبدأ(8); // عنوان الرقيق هو 8
الأسلاك.تحت الطلب(طلب الحدث) ؛
dht.يبدأ();
}فارغحلقة(){
تأخير(2000); // انتظر لمدة ثانيتين حتى يستقر DHT
درجة الحرارة = dht.قراءة درجة الحرارة(); // قراءة درجة الحرارة من مستشعر DHT
}
فارغطلب الحدث(){
الأسلاك.يكتب(درجة حرارة)؛ // إرسال بيانات درجة الحرارة لإتقان
}
يمكنك تخصيص هذا الرمز ليناسب أيًا من المستشعرات التي قد تكون لديك في مشروعك ، أو حتى عرض قيم المستشعر على وحدة العرض اصنع ميزان حرارة غرفتك ومقياس الرطوبة.
معالجة الرقيق باستخدام I2C على Arduino
لقراءة القيم من المكونات المضافة إلى ناقل I2C في مثل هذا المشروع ، من المهم أن تقوم بتضمين عنوان الرقيق الصحيح عند الترميز. لحسن الحظ ، يقدم Arduino مكتبة ماسح ضوئي تبسط عملية التعرف على الرقيق العناوين ، مما يلغي الحاجة إلى غربلة أوراق بيانات المستشعر المطولة والتشويش عبر الإنترنت توثيق.
استخدم الكود التالي لتحديد عنوان أي جهاز تابع موجود في ناقل I2C.
#يشمل
// تضمين مكتبة Wire لاتصالات I2C فارغيثبت(){
الأسلاك.يبدأ(); // تهيئة اتصال I2C
مسلسل.يبدأ(9600); // تهيئة الاتصال التسلسلي بمعدل باود 9600
بينما (!مسلسل); // انتظر حتى يتم إنشاء الاتصال التسلسلي
مسلسل.println("\ n ماسح ضوئي I2C"); // طباعة رسالة تشير إلى بدء مسح I2C
}فارغحلقة(){
بايت خطأ ، عنوان ؛ // قم بتعريف المتغيرات لتخزين الأخطاء وعناوين الجهاز
int n الأجهزة. // أعلن عن متغير لتخزين عدد الأجهزة التي تم العثور عليهامسلسل.println("يتم المسح..."); // طباعة رسالة تشير إلى بدء مسح I2C
n الأجهزة = 0; // اضبط عدد الأجهزة التي تم العثور عليها على 0
ل (العنوان = 1; العنوان < 127; العنوان ++) { // كرر عبر جميع عناوين I2C الممكنة
الأسلاك.يبدأ الإرسال(عنوان)؛ // بدء الإرسال إلى العنوان الحالي
خطأ = الأسلاك.نهاية الإرسال(); // قم بإنهاء الإرسال وتخزين أي أخطاءلو (خطأ == 0) { // إذا لم يتم العثور على أخطاء
مسلسل.مطبعة("تم العثور على جهاز I2C على العنوان 0x"); // طباعة رسالة تشير إلى العثور على جهاز
لو (العنوان < 16) مسلسل.مطبعة("0"); // إذا كان العنوان أقل من 16 ، أضف صفرًا بادئًا لأغراض التنسيق
مسلسل.مطبعة(العنوان ، HEX) ؛ // اطبع العنوان بتنسيق سداسي عشري
مسلسل.println(" !"); // طباعة رسالة تشير إلى العثور على جهاز
nDevices ++ ؛ // زيادة عدد الأجهزة التي تم العثور عليها
}
آخرلو (خطأ == 4) { // إذا تم العثور على خطأ
مسلسل.مطبعة("خطأ غير معروف في العنوان 0x"); // طباعة رسالة تشير إلى وجود خطأ
لو (العنوان < 16) مسلسل.مطبعة("0"); // إذا كان العنوان أقل من 16 ، أضف صفرًا بادئًا لأغراض التنسيق
مسلسل.println(العنوان ، HEX) ؛ // اطبع العنوان بتنسيق سداسي عشري
}
}
لو (الأجهزة == 0) { // إذا لم يتم العثور على أجهزة
مسلسل.println("لم يتم العثور على أجهزة I2C \ n"); // طباعة رسالة تشير إلى عدم العثور على أجهزة
}
آخر { // إذا تم العثور على أجهزة
مسلسل.println("تم \ n"); // طباعة رسالة تشير إلى نهاية مسح I2C
}
تأخير(5000); // تأخير لمدة 5 ثوان قبل بدء الفحص التالي
}
وسّع مشروعك اليوم
يوفر الربط بين لوحين من Arduino باستخدام بروتوكول الاتصال I2C طريقة مرنة وفعالة لتحقيق المهام المعقدة التي لا يمكن التعامل معها بواسطة لوحة واحدة. بمساعدة مكتبة Wire ، أصبح الاتصال بين اللوحين باستخدام I2C أمرًا سهلاً ، مما يتيح لك إضافة المزيد من المكونات إلى مشروعك.