arduino_i2c_slave.py

# هذا العمل مرخص بموجب ترخيص MIT.
# حقوق النشر (c) 2013-2023 OpenMV LLC. جميع الحقوق محفوظة.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# I2C مع Arduino كجهاز رئيسي (master) و OpenMV Cam كجهاز تابع (slave).
#
# يرجى توصيل جهاز OpenMV Cam بجهاز Arduino كما يلي:
#
# OpenMV Cam Master I2C Data (P5) - Arduino Uno Data (A4)
# OpenMV Cam Master I2C Clock (P4) - Arduino Uno Clock (A5)
# OpenMV Cam Ground - Arduino Ground

import pyb
import struct

text = "Hello World!\n"
data = struct.pack("<%ds" % len(text), text)
# استخدم "struct" لبناء حزم البيانات المراد إرسالها.
# "<" يضع البيانات في البنية (struct) بترتيب little endian.
# "%ds" يضع نصاً (string) في تدفق البيانات. على سبيل المثال "13s" لـ "Hello World!\n" (13 محرفاً).
# انظر https://docs.python.org/3/library/struct.html

# اقرأني!!!
#
# من فضلك افهم أنه عندما لا تكون كاميرا OpenMV Cam هي جهاز I2C الرئيسي (master)، فقد لا تستجيب
# لإرسال البيانات كجهاز I2C ثانوي (slave) بغض النظر عمّا إذا كنت تستدعي "i2c.send()" داخل دالة استدعاء مقاطعة (interrupt callback) أو في
# الحلقة الرئيسية أدناه. عند حدوث ذلك سيحصل Arduino على NAK وسيتعين عليه إعادة المحاولة في القراءة من
# كاميرا OpenMV Cam مرة أخرى. لاحظ أن كلًا من تعريفات I2C الخاصة بـ Arduino و OpenMV Cam ليست جيدة في
# الخروج من حالة التعليق بعد مواجهة أي أخطاء I2C. على كاميرا OpenMV Cam و Arduino يمكنك الاستعادة عن طريق
# إلغاء تهيئة (de-init) ثم إعادة تهيئة (re-init) أجهزة I2C الطرفية.

# ناقل I2C الخاص بالعتاد لكاميرا OpenMV Cam هو دائمًا ناقل I2C رقم 2.
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
bus.deinit()  # إعادة تعيين جهاز I2C بالكامل...
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
print("Waiting for Arduino...")

# لاحظ أنه لكي تعمل عملية المزامنة بشكل صحيح، يجب أن تكون كاميرا OpenMV Cam تُشغّل هذا السكربت قبل أن
# يبدأ Arduino في استطلاع كاميرا OpenMV Cam للحصول على البيانات. وإلا فإن تأطير بايتات I2C سيختل،
# وما إلى ذلك. لذا، أبقِ Arduino في وضع إعادة الضبط حتى تصبح كاميرا OpenMV Cam في حالة "Waiting for Arduino...".

while True:
    try:
        bus.send(
            struct.pack("<h", len(data)), timeout=10000
        )  # أرسل الطول (len) أولًا (16 بت).
        try:
            bus.send(data, timeout=10000)  # أرسل البيانات ثانيًا.
            print("Sent Data!")  # يتم الوصول إلى هذا الجزء فقط عند عدم وجود خطأ.
        except OSError as err:
            pass  # لا داعي للاهتمام بالأخطاء - لذا استخدم pass.
            # لاحظ أن هناك 3 أخطاء محتملة: خطأ انتهاء المهلة (timeout)، خطأ عام، أو
            # خطأ الانشغال (busy). أكواد الأخطاء هي 116 و5 و16 على التوالي لـ "err.arg[0]".
    except OSError as err:
        pass  # لا داعي للاهتمام بالأخطاء - لذا استخدم pass.
        # لاحظ أن هناك 3 أخطاء محتملة: خطأ انتهاء المهلة (timeout)، خطأ عام، أو
        # خطأ الانشغال (busy). أكواد الأخطاء هي 116 و5 و16 على التوالي لـ "err.arg[0]".

###################################################################################################
# كود Arduino
###################################################################################################
#
# #include <Wire.h>
# #define BAUD_RATE 19200
# #define CHAR_BUF 128
#
# void setup() {
#   Serial.begin(BAUD_RATE);
#   Wire.begin();
# delay(1000); // امنح جهاز OpenMV Cam وقتاً للإقلاع (bootup).
# }
#
# void loop() {
#   int32_t temp = 0;
#   char buff[CHAR_BUF] = {0};
#
#   Wire.requestFrom(0x12, 2);
# if(Wire.available() == 2) { // هل تم استلام الطول؟
#
#     temp = Wire.read() | (Wire.read() << 8);
# delay(1); // امنح بعض الوقت للإعداد...
#
#     Wire.requestFrom(0x12, temp);
# if(Wire.available() == temp) { // هل تم استلام الرسالة كاملة؟
#
#       temp = 0;
#       while(Wire.available()) buff[temp++] = Wire.read();
#
#     } else {
# while(Wire.available()) Wire.read(); // تجاهل البايتات غير المرغوب فيها.
#     }
#   } else {
# while(Wire.available()) Wire.read(); // تجاهل البايتات غير المرغوب فيها.
#   }
#
#   Serial.print(buff);
# delay(1); // لا تكرر الحلقة بسرعة زائدة.
# }

results matching ""

    No results matching ""