OpenMV Cam RT1062

إن OpenMV Cam RT1062 لوحة رؤية آلية منخفضة الطاقة مبنية حول NXP i.MX RT1062 (Cortex‑M7 بتردد 600 MHz). تجمع اللوحة بين شبكات USB‑C عالية السرعة وWi‑Fi/Bluetooth وإيثرنت 10/100 مع مستشعر OV5640 بدقة 5MP على حامل قابل للإزالة. لا تسحب الكاميرا سوى نحو 30 ميكرو أمبير من بطارية LiPo في وضع السبات العميق، مما يجعلها مناسبة تماماً للمشاريع التي تعمل بالبطارية.

OpenMV Cam RT1062

للاطلاع على ورقة البيانات الكاملة والصور والأبعاد، راجع صفحة منتج OpenMV Cam RT1062.

أبرز الميزات

  • NXP i.MX RT1062 Cortex‑M7 بتردد 600 MHz.

  • 32 MB من ذاكرة SDRAM الخارجية (16‑بت بتردد 160 MHz، 320 MB/s) بالإضافة إلى 1 MB من ذاكرة SRAM الداخلية و16 MB من ذاكرة QSPI flash (133 MHz 4‑بت SDR، قراءة 66 MB/s)؛ 4 KB EEPROM على إصدار R6+.

  • مستشعر OV5640 بدقة 5MP وغالق متدحرج (rolling‑shutter).

  • وحدة IMU مدمجة (مقياس تسارع ثلاثي المحاور بدقة 12‑بت، ‏±2/4/8 g).

  • USB‑C عالي السرعة (480 Mb/s، بحد تيار 1.5 A)، وإيثرنت 10/100 Mb/s (داعم لـ PoE عبر درع توسعة)، وWi‑Fi a/b/g/n + Bluetooth 5.1 (هوائي رقاقة أو خيار U.FL).

  • مقبس microSD — بطاقات SD حتى 2 GB، وSDHC حتى 32 GB، وSDXC حتى 2 TB.

  • شاحن LiPo (500 mA على R6+، و100 mA على R4/R5)، وساعة RTC مع وسادات بطارية احتياطية. يسحب وضع السبات العميق نحو 30 ميكرو أمبير من البطارية.

  • 14 دبوس إدخال/إخراج، جميعها بإخراج 3.3 V / تحمّل 3.3 V، و4 mA لكل دبوس، وقادرة على المقاطعة.

  • مؤشر RGB LED للمستخدم، وزر SW للمستخدم، وزر طاقة عتادي (آلة حالات للسبات العميق / الاستيقاظ)، ومؤشر LED حالة منفصل للشحن / USB / طاقة VIN.

تحذير

دبابيس الإدخال/الإخراج في RT1062 غير متحمّلة لـ 5 V. لا توصّل الجهاز مباشرة بمتحكم دقيق يعمل بـ 5 V مثل Arduino Mega. زوّد اللوحة بالطاقة عبر VIN فقط.

مخطط الدبابيس

OpenMV Cam RT1062 OV5640 Pinout

مرجع الدبابيس

اسم الدبوس

الوظيفة

P0

SPI1 MOSI / PWM2 B3

P1

SPI1 MISO / CAN0 TX

P2

SPI1 SCLK / PWM2 B3

P3

SPI1 SS / CAN0 RX

P4

I2C1 SCL / UART1 TX / PWM1 X2

P5

I2C1 SDA / UART1 RX / PWM1 X3

P6

ADC

P7

PWM2 A0

P8

PWM2 B0

P9

PWM1 A3

P10

PWM1 B3 / إدخال/إخراج مزامنة الإطارات

P11

الاستيقاظ (نشط عند المستوى المنخفض، صِله بـ GND للاستيقاظ)

P12

RESET — اسحبه إلى GND لإعادة تعيين اللوحة (ليس دبوس GPIO)

P13

إدخال/إخراج رقمي

P14

إدخال/إخراج رقمي

ON/OFF

وسادة موصّل تكرّر زر الطاقة العتادي (نشط عند المستوى المنخفض)

SW

زر المستخدم (نشط عند المستوى المنخفض)

ST

منخفض عند الطاقة من VIN، ومرتفع عند الطاقة من USB

CHG

نشط عند المستوى المنخفض؛ منخفض أثناء شحن بطارية LiPo متصلة

PG

نشط عند المستوى المنخفض؛ منخفض عند وجود طاقة VIN أو USB

LED_RED

قناة الأحمر في مؤشر RGB LED (نشطة عند المستوى المنخفض)

LED_GREEN

قناة الأخضر في مؤشر RGB LED (نشطة عند المستوى المنخفض)

LED_BLUE

قناة الأزرق في مؤشر RGB LED (نشطة عند المستوى المنخفض)

ملاحظة

خط مزامنة الإطارات P10 هو ناقل مشترك. فهو موصول بالمتحكم الدقيق ودبوس التشغيل / التعريض في مستشعر الكاميرا وموصّل المستخدم في آن واحد. الاتجاه محدّد بحسب التطبيق — يمكن للمتحكم الدقيق أو المستشعر أو إشارة خارجية أن تقود الخط بحسب طريقة إعداد المستشعر. تأكد من أن مشغّلاً واحداً فقط نشط في كل مرة.

ملاحظة

يُرجَع ON/OFF وP11 إلى سكة RAW الدائمة التشغيل (لا إلى سكة 3.3 V المُبدَّلة)، لذا يبقيان فعّالين بينما تكون بقية اللوحة في وضع السبات العميق / منخفض الطاقة. كلا المدخلين نشطان عند المستوى المنخفض.

تمرّ هذه الدبابيس عبر مغيّرات مستوى لتتمكن من العمل على سكة RAW. إذا كنت بحاجة ماسّة إلى سلوك GPIO مباشر بـ 3.3 V على ON/OFF أو P11 (مثلاً لقيادتهما من متحكم دقيق بـ 3.3 V دون المرور عبر المغيّر)، فإن اللوحة توفر وسادات وصلات سحب علوي ووصلات 0 أوم تتيح لك تجاوز المغيّر. هذا تعديل عتادي متقدّم — وعلى معظم المستخدمين تركه دون مساس.

ملاحظة

P13 وP14 هما GPIO عادي افتراضياً دون أي وظيفة خاصة. يمكن اختيارياً إعادة توجيه الوسادتين إلى إشارات أخرى عبر إعادة لحام جسور مقاومة 0 أوم على ظهر اللوحة:

  • P13 ↔ حالة CHG / JTAG TRSTB

  • P14 ↔ حالة ST / JTAG TDI

معظم المستخدمين لن يلمسوا هذه الوصلات — اتركها على وضع GPIO الافتراضي ما لم تكن بحاجة تحديداً إلى قراءة إدارة الطاقة أو إلى JTAG.

دبابيس الطاقة

  • 3.3V — سكة 3.3 V منظَّمة. للإخراج فقط على RT1062 — لا تغذّ طاقة خارجية إلى هذا الدبوس. يتوفر حتى 1 A لدروع التوسعة.

  • VIN — دخل 5 V. يزوّد اللوحة وشاحن LiPo المدمج بالطاقة.

  • RAW — إدخال/إخراج، دائم التشغيل (3.6 V – 5 V). يحمل أي مصدر يكون نشطاً (VIN أو USB أو البطارية المتصلة)، ويمكن استخدامه أيضاً كمدخل. يجب أن تقود RAW عبر ثنائي متسلسل عند تغذية الطاقة إليه — وإلا فسيتدفق التيار عائداً إلى VIN/USB ويتلف مزوّد الطاقة أو الحماية المدمجة.

  • GND — الأرضي المشترك.

ملاحظة

تختار رقاقة إدارة الطاقة المدمجة تلقائياً أياً من USB أو VIN ذي الجهد الأعلى لتزويد اللوحة وشاحن البطارية بالطاقة. وإذا كانت بطارية LiPo متصلة فإنها تُشحن من الفائض المتبقي، ويرجع المتحكم إلى البطارية للحفاظ على تشغيل اللوحة إذا انخفض جهد VIN/USB أو فُصلا.

ملاحظة

يحتوي ظهر اللوحة على وسادات لحام لـبطارية احتياطية خارجية بـ 3.3 V للـ RTC. يؤدي توصيل خلية على شكل عملة بهذه الوسادات إلى إبقاء RTC قيد التشغيل بينما تكون بقية اللوحة دون طاقة.

نصيحة

استخدم مقدّر عمر البطارية لتقدير المدة التي سيعمل خلالها RT1062 على بطارية ما عند دورة عمل نشطة / سبات عميق معينة.

دبابيس الإيثرنت

يعرض RT1062 أزواج MDI الخاصة بطبقة PHY للإيثرنت 10/100 Mb/s على وسادات مخصصة بجوار موصّل GPIO. ليس من الآمن توصيل دبابيس MDI مباشرة بموصّل RJ45 — إذ يُشترط وجود مغناطيسات الإيثرنت (محوّل عزل، إما مدمج في magjack أو على درع التوسعة) بين PHY والكابل. يتضمنها درع OpenMV PoE؛ وإذا كنت تصنع موصّلك بنفسك، فاستخدم RJ45 مدمجاً للمغناطيسات أو محوّلاً خارجياً.

  • ETH_LED — مؤشر LED للوصلة/النشاط. نشط عند المستوى المنخفض عندما تكون الوصلة قائمة؛ ويومض عند حركة المرور.

  • ETH_TXP / ETH_TXN — زوج الإرسال.

  • ETH_RXP / ETH_RXN — زوج الاستقبال.

ملاحظة

يعرض الموصّل أيضاً أربع وسادات منقوش عليها Reserved. وهذه متوافقة في البصمة مع أزواج إيثرنت الجيجابت في OpenMV N6 (‏DC P/N وDD P/N) بحيث يمكن توصيل درع الإيثرنت / PoE نفسه بأي من اللوحتين. لا تدعم طبقة PHY في RT1062 سوى 10/100 Mb/s، لذا فإن هذه الوسادات الأربع بلا أي توصيل كهربائي — اتركها غير موصولة.

دبابيس الاستعادة والتنقيح

  • RESET — اسحبه إلى GND لإعادة تعيين اللوحة. يؤدي تحريره إلى السماح للمتحكم الدقيق ببدء التشغيل بشكل طبيعي.

  • SBL — اسحبه إلى 3.3 V أثناء تزويد اللوحة بالطاقة لدخول وضع محمّل الإقلاع من ROM (Serial Boot Loader). يستخدم OpenMV IDE هذا الوضع لإعادة كتابة محمّل الإقلاع المدمج.

تم تركيب موصّل SWD/JTAG من ARM بعشرة دبابيس مخصص، متوافق مع محوّلات ST‑LINK وSEGGER J‑Link.

ملاحظة

يعرض RT1062 تنقيح SWD فقط عبر هذا الموصّل افتراضياً. وليس JTAG الكامل متاحاً جاهزاً.

الطرفيات المدمجة

مؤشرات LED

يحتوي RT1062 على مؤشري RGB LED:

  • مؤشر RGB LED للمستخدم — قابل للتحكم بالبرمجيات، ومعروض كـ LED_RED وLED_GREEN وLED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • مؤشر LED للطاقة — مدفوع مباشرة بعتاد إدارة الطاقة المدمج، دون تحكم برمجي. استخدمه لقراءة ما يفعله مزوّد الطاقة بنظرة سريعة.

    أثناء التشغيل:

    القناة

    المعنى

    أزرق

    VIN يزوّد اللوحة بالطاقة (مطفأ عند USB)

    أخضر

    وجود طاقة USB أو VIN

    أحمر

    شحن بطارية LiPo متصلة

    في وضع السبات العميق تكون جميع القنوات مطفأة باستثناء الأحمر، الذي يظل مضيئاً أثناء شحن بطارية LiPo.

الأزرار

يحتوي RT1062 على زرين:

  • SW — زر مستخدم للأغراض العامة. يمكن قراءته من الشيفرة كمدخل GPIO عادي نشط عند المستوى المنخفض:

    from machine import Pin
    
    sw = Pin("SW", Pin.IN)
    print(sw.value())
    
  • زر الطاقة — مدفوع بآلة حالات متحكم طاقة مخصصة على لوحة RT1062، بالكامل في العتاد. وهو غير معروض لشيفرة المستخدم؛ إذ يقرر المتحكم ما يفعله بناءً على مدة الضغط عليه:

    • اضغط مع الاستمرار لنحو 5 ثوانٍ أثناء تشغيل اللوحة ← تنتقل آلة الحالات إلى السبات العميق.

    • اضغط مع الاستمرار لنحو 1 ثانية أثناء وجود اللوحة في السبات العميق ← تعيد آلة الحالات تشغيل النظام.

    إن سحب وسادة موصّل ON/OFF إلى المستوى المنخفض له التأثير نفسه لضغط زر الطاقة المدمج — وهو مفيد لتوصيل مفتاح خارجي أو قيادة الخط من متحكم دقيق آخر.

دبابيس حالة الطاقة

ثلاثة مدخلات حالة نشطة عند المستوى المنخفض من رقاقة إدارة الطاقة المدمجة:

  • PG — منخفض عند وجود طاقة VIN أو USB. موصول دائماً.

  • ST — منخفض عندما تعمل اللوحة على VIN، ومرتفع عندما تعمل على طاقة USB. غير موصول افتراضياً.

  • CHG — منخفض أثناء شحن بطارية LiPo متصلة. غير موصول افتراضياً.

from machine import Pin

power_ok = not Pin("PG", Pin.IN).value()

مستشعر الكاميرا

تُقاد OV5640 عبر وحدة csi --- مستشعرات الكاميرا

import csi

cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000)       # let auto‑exposure settle

while True:
    img = cam.snapshot()

يحتوي OV5640 على ضاغط JPEG مدمج. اضبط csi.CSI.pixformat على csi.JPEG فيسلّم المستشعر إطارات مضغوطة مباشرة إلى الكاميرا عبر ناقل الكاميرا، مما يجعل الالتقاطات عالية الدقة عملية: ‏csi.HD (1280×720) وcsi.FHD (1920×1080) وكامل دقة 5MP عبر csi.WQXGA2 (2592×1944) تُبث جميعها بصيغة JPEG. اضبط الضغط عبر csi.CSI.quality (0‑100، الأعلى = إطارات أكبر وتفاصيل أكثر):

cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)

يقع المستشعر على وحدة قابلة للإزالة — استبدلها بأي من وحدات كاميرا OpenMV الأخرى (غالق عالمي، حراري، دقة أعلى، إلخ) دون تغيير بقية اللوحة.

تعلّم الآلة

يشغّل ml --- التعلم الآلي نماذج TFLite المكمَّمة على Cortex‑M7 بنوى CMSIS‑NN — بسرعة كافية للكواشف المدمجة بمعدل بضعة إطارات في الثانية. تُحمَّل النماذج الموجودة على نظام الملفات للقراءة فقط /rom مباشرة من ذاكرة flash دون نسخها إلى RAM. وفيما يلي كاشف BlazeFace بدقة 128×128 يضع الوجه المكتشف ومعالمه الست فوق كل إطار:

import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace

# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))

# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)

clock = time.clock()
while True:
    clock.tick()
    img = csi0.snapshot()

    # faces is a list of ((x, y, w, h), score, keypoints) tuples
    for r, score, keypoints in model.predict([img]):
        ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)

        # keypoints is a ndarray of shape (6, 2)
        # 0 - right eye (x, y)
        # 1 - left eye (x, y)
        # 2 - nose (x, y)
        # 3 - mouth (x, y)
        # 4 - right ear (x, y)
        # 5 - left ear (x, y)
        ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))

    print(clock.fps(), "fps")

IMU

لا يوصّل برنامج RT1062 الثابت مقياس التسارع المدمج بوحدة imu --- مستشعر imu. تخاطب معه مباشرة عبر ناقل I²C الداخلي بدلاً من ذلك — توجد الرقاقة على العنوان 0x15 وتحتوي ثلاث قنوات تسارع موقّعة بدقة 12‑بت بالإضافة إلى بايت حرارة بدقة 8‑بت بدءاً من السجل 0x03

import machine
import time

ADDR     = 0x15
DATA_REG = 0x03
LSB_PER_G = 1024.0    # ±2 g range

def s12(hi, lo):
    v = ((hi << 8) | lo) >> 4
    return v - 0x1000 if v & 0x800 else v

bus = machine.I2C(2)
print("Devices on I²C2:", bus.scan())

while True:
    d = bus.readfrom_mem(ADDR, DATA_REG, 7)
    x = s12(d[0], d[1]) / LSB_PER_G
    y = s12(d[2], d[3]) / LSB_PER_G
    z = s12(d[4], d[5]) / LSB_PER_G
    temp_c = d[6] * 0.586 + 25.0
    print("x=%+.2fg  y=%+.2fg  z=%+.2fg  T=%.1f°C" % (x, y, z, temp_c))
    time.sleep_ms(100)

EEPROM

لوحات R6 وما بعدها تتضمن EEPROM عام بسعة 4 KB عبر I²C على الناقل الداخلي نفسه الذي يضم مقياس التسارع. (لا تحتوي الإصدارات الأقدم عليه — إذ سيؤدي استدعاء هذه المقتطفات على R4/R5 إلى انتهاء المهلة بسبب فقدان إقرار I²C.) استخدم واجهة برمجة machine.I2C القياسية readfrom_mem / writeto_mem بعنوان ذاكرة من 16‑بت:

import machine
import time

EEPROM_ADDR = 0x50            # default address
PAGE_SIZE   = 32              # bytes per page (both read and write)
EEPROM_SIZE = 4096

bus = machine.I2C(2)

# Dump the entire 4 KB one page at a time
data = bytearray()
for offset in range(0, EEPROM_SIZE, PAGE_SIZE):
    data += bus.readfrom_mem(EEPROM_ADDR, offset, PAGE_SIZE, addrsize=16)
print(len(data), "bytes")

# Write a small payload back at offset 0 (fits in one page)
bus.writeto_mem(EEPROM_ADDR, 0, b"hello, world", addrsize=16)
time.sleep_ms(10)             # ~5 ms write cycle after each page

# Read it back
print(bus.readfrom_mem(EEPROM_ADDR, 0, 12, addrsize=16))

يجب أن تبقى كل من عمليات القراءة والكتابة ضمن صفحة من 32 بايت. قسّم أي نقل أكبر إلى استدعاء واحد لكل صفحة، وأضف تأخير دورة الكتابة البالغ نحو 5 ms بين عمليات الكتابة المتتالية.

Wi‑Fi

تُعرض وحدة عائلة CYW43 المدمجة عبر network --- تهيئة الشبكة كواجهة محطة. بعد الاتصال، تُرجع ipconfig("addr4") الزوج (ip, netmask)

import network, time

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
    time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])

Bluetooth

تعرض الوحدة اللاسلكية نفسها أيضاً Bluetooth 5.1. استخدم aioble --- BLE غير المتزامن لـ BLE المتوافق مع asyncio — على سبيل المثال، الإعلان كطرفية وانتظار اتصال من جهاز مركزي:

import asyncio
import aioble

async def run():
    while True:
        conn = await aioble.advertise(250_000, name="OpenMV-RT1062")
        print("Connected:", conn.device)
        await conn.disconnected()

asyncio.run(run())

إيثرنت

عند توصيل موصّل RJ45 (مع مغناطيسات) بوسادات MDI، تظهر طبقة PHY بسرعة 10/100 كواجهة LAN. يعمل DHCP تلقائياً بمجرد قيام الوصلة:

import network, time

lan = network.LAN()
lan.active(True)
while not lan.isconnected():
    time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])

بطاقة microSD

عند إدراج بطاقة، تُركّب تلقائياً على /sdcard وتصبح قابلة للاستخدام عبر نظام الملفات المعتاد:

import os

for entry in os.listdir("/sdcard"):
    print(entry)

مرجع الناقلات

GPIO

استخدم machine.Pin لقراءة أو قيادة أي من الدبابيس المنقوشة. المخرجات هي 3.3 V CMOS ويمكنها امتصاص/مصدرة ما يصل إلى 4 mA لكل دبوس.

from machine import Pin

out = Pin("P0", Pin.OUT)
out.on()
out.off()
out.value(1)

inp = Pin("P1", Pin.IN, Pin.PULL_UP)
print(inp.value())

يمكن لأي دبوس إدخال أيضاً إطلاق مقاطعة عند انتقالات الحافة:

def handler(pin):
    print("triggered:", pin)

Pin("P1", Pin.IN, Pin.PULL_UP).irq(
    handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)

UART

الناقل

TX

RX

UART1

P4

P5

from machine import UART

uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)

I²C

الناقل

SCL

SDA

I2C1

P4

P5

from machine import I2C

i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")

يمكن أيضاً استخدام العتاد نفسه في وضع الهدف (التابع) عبر machine.I2CTarget لعرض منطقة ذاكرة لمتحكم I²C آخر:

from machine import I2CTarget

buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)

SPI

الناقل

MOSI

MISO

SCK

CS

SPI1

P0

P1

P2

P3

from machine import SPI
from machine import Pin

spi = SPI(1, baudrate=10_000_000)
cs = Pin("P3", Pin.OUT, value=1)   # CS is not driven by the SPI peripheral

cs.value(0)
spi.write(b"hello")
cs.value(1)

CAN

الناقل

TX

RX

CAN1

P1

P3

ملاحظة

CAN غير مدعوم بعد على هذه اللوحة في البرنامج الثابت v5.0.0.

from machine import CAN

can = CAN(1, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())

ADC

دبوس ADC الوحيد للمستخدم هو P6، وهو بنطاق كامل عند نحو 3.3 V:

from machine import ADC
import time

adc = ADC("P6")
while True:
    voltage = adc.read_u16() * 3.3 / 65535
    print(voltage)
    time.sleep_ms(100)

PWM

الدبوس

قناة FlexPWM

P0

PWM2 B3

P2

PWM2 B3

P4

PWM1 X2

P5

PWM1 X3

P7

PWM2 A0

P8

PWM2 B0

P9

PWM1 A3

P10

PWM1 B3

قُد أياً منها عبر machine.PWM

from machine import Pin, PWM

pwm = PWM(Pin("P9"), freq=1_000, duty_u16=32768)

الناقلات المُولَّدة برمجياً (bit‑banged)

تعمل machine.SoftI2C وmachine.SoftSPI على أي دبوس GPIO إذا كنت بحاجة إلى ناقل إضافي.

المستشعر الحراري (خارج اللوحة)

يتضمن البرنامج الثابت مشغّل fir --- مشغّل المستشعر الحراري (fir == far infrared) لأجهزة التصوير الحراري الموصولة خارجياً:

  • MLX90621 — مصفوفة أشعة تحت حمراء 16 × 4

  • MLX90640 — مصفوفة أشعة تحت حمراء 32 × 24

  • MLX90641 — مصفوفة أشعة تحت حمراء 16 × 12

  • AMG8833 — مصفوفة أشعة تحت حمراء 8 × 8

وصّل الوحدة بناقل I²C الخاص باللوحة واقرأ الإطارات عبر fir.init() + fir.snapshot()

import time
import image
import fir

fir.init()                          # auto‑detects the sensor
clock = time.clock()

while True:
    clock.tick()
    try:
        img = fir.snapshot(x_scale=5, y_scale=5,
                           color_palette=image.PALETTE_IRONBOW,
                           hint=image.BICUBIC,
                           copy_to_fb=True)
    except OSError:
        continue
    print(clock.fps())

يتخاطب مشغّل fir مع المستشعر عبر I²C 4 فقط — وصّل الوحدة بـ P4 (SCL) وP5 (SDA).

التوقيت

time

تغطي وحدة time التأخيرات الحاجبة، والنبضات الرتيبة، وقياس الزمن المنقضي:

import time

time.sleep(1)              # seconds
time.sleep_ms(500)
time.sleep_us(10)

start = time.ticks_ms()
# ...do work...
elapsed = time.ticks_diff(time.ticks_ms(), start)

المؤقتات الافتراضية

تجدول machine.Timer دوال رد نداء دورية أو ذات إطلاق واحد دون استهلاك خانة مؤقت عتادي. مرّر -1 كمعرّف لاستخدام مؤقت افتراضي (برمجي):

from machine import Timer

one_shot = Timer(-1)
one_shot.init(period=5_000, mode=Timer.ONE_SHOT,
              callback=lambda t: print("once"))

periodic = Timer(-1)
periodic.init(period=2_000, mode=Timer.PERIODIC,
              callback=lambda t: print("tick"))

قيم الفترة بالميلي ثانية. استدعِ deinit() لإيقاف الخانة وتحريرها.

ساعة الوقت الحقيقي

تحافظ machine.RTC على وقت الساعة الجدارية عبر عمليات إعادة التعيين (ومع البطارية الاحتياطية الاختيارية بـ 3.3 V الموصولة بالوسادات الخلفية، انظر دبابيس الطاقة) عبر فقدان الطاقة الكامل:

from machine import RTC

rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0))   # Y, M, D, weekday, h, m, s, subsec
print(rtc.datetime())

تعمل RTC أيضاً خلال السبات العميق، لذا يمكنك استخدامها كمصدر استيقاظ لـ machine.deepsleep().

المراقب (Watchdog)

تعيد machine.WDT تعيين اللوحة إذا تعلّق التطبيق. وبمجرد بدئها لا يمكن إيقافها أو إعادة تهيئتها — أطعمها دورياً داخل حلقتك الرئيسية:

from machine import WDT

wdt = WDT(timeout=5_000)   # 5 second window
while True:
    # ...do work...
    wdt.feed()

معلومات الإقلاع ووقت التشغيل

نافذة محمّل الإقلاع عبر USB

عند كل تشغيل، تشغّل الكاميرا محمّل إقلاع قصير (بضع ثوانٍ) يتيح لـ OpenMV IDE تحديث البرنامج الثابت دون اضطرار المستخدم للدخول في وضع DFU. وبعد انتهاء النافذة، يسلّم محمّل الإقلاع المهمة إلى boot.py ثم main.py.

يمكن لبرنامج نصي قيد التشغيل إعادة الدخول إلى محمّل الإقلاع عند الطلب باستدعاء machine.bootloader()

import machine

machine.bootloader()

نظام الملفات وترتيب الإقلاع

يركّب برنامج RT1062 الثابت ما يصل إلى ثلاثة أنظمة ملفات عند الإقلاع:

  • ذاكرة flash الداخلية — مركّبة دائماً على /flash. تحمل main.py وREADME.txt افتراضياً؛ وتُنشأ عند أول إقلاع على الإطلاق.

  • بطاقة microSD — إذا أُدرجت بطاقة فإنها تُركّب على /sdcard.

  • ROMFS — نظام ملفات للقراءة فقط مُسقَط في الذاكرة على /rom يُستخدم لشحن أصول بيانات كبيرة (مثل نماذج الذكاء الاصطناعي) تستفيد من الوصول دون نسخ. يركّبه MicroPython تلقائياً عند بدء التشغيل، قبل تشغيل أي شيفرة Python للمستخدم.

بعد التركيب، يُضبط دليل العمل على /sdcard عند وجود البطاقة، وإلا فعلى /flash. ثم يشغّل المفسّر البرامج النصية من ذلك الدليل:

  • يُنفَّذ boot.py عند كل إعادة تعيين ناعمة (إقلاع بارد، أو Ctrl‑D من REPL، أو كلما عاد البرنامج النصي قيد التشغيل).

  • يُنفَّذ main.py عند الإقلاع البارد فقط، مباشرة بعد boot.py. أما عمليات إعادة التعيين الناعمة اللاحقة فتعيد تشغيل boot.py لكنها تنتقل مباشرة إلى REPL — ولإعادة تشغيل main.py عليك إعادة تعيين اللوحة بالكامل.

إن وضع ملف boot.py أو main.py على بطاقة SD يتجاوز النسخة الموجودة في ذاكرة flash دون المساس بها — إذ يُبحث عن كلا الملفين في دليل الإقلاع (/sdcard عند تركيب البطاقة، وإلا /flash).

يقتصر ملف main.py الافتراضي المشحون على لوحة حديثة الكتابة على وميض قناة الأزرق في مؤشر RGB LED للمستخدم كنبضة قلب (نبضتان قصيرتان، وفجوة قصيرة)، بحيث يمكنك معرفة أن البرنامج الثابت أقلع بنجاح دون أي مضيف متصل.

يُوسَّع sys.path ليشمل أنظمة الملفات الثلاثة جميعها وأدلتها الفرعية lib/، بحيث يمكن أن توجد الوحدات القابلة للاستيراد في /flash/lib أو /sdcard/lib أو /rom/lib.

لإجبار النظام على تجاهل بطاقة SD مُدرجة (مثلاً لتشغيل main.py الموجود في flash حتى مع وجود بطاقة)، أنشئ ملفاً فارغاً باسم SKIPSD في جذر /flash.

عند الاتصال عبر USB، يظهر نظام ملفات الإقلاع (/sdcard عند وجود بطاقة، وإلا /flash) أيضاً كقرص تخزين كتلي USB على المضيف، مما يتيح لك تحرير boot.py وmain.py وأي ملفات أخرى مباشرة. أخرِج القرص قبل إعادة تعيين الكاميرا ليُفرّغ المضيف عمليات الكتابة المخزنة مؤقتاً.

ملاحظة

لأن نظام التشغيل يعامل القرص كجهاز كتلي سلبي، فإن الملفات التي تُنشئها أو تعدّلها الشيفرة العاملة على OpenMV Cam لن تظهر حتى يعيد المضيف تركيب القرص. وإذا كتب نظام التشغيل وOpenMV Cam على نظام الملفات نفسه في الوقت نفسه، فسيفوز نظام التشغيل ويستبدل التغييرات التي أجرتها الكاميرا. استخدم بطاقة SD لأي بيانات يكتبها البرنامج النصي، وأعد التركيب قبل قراءة تلك الملفات من المضيف.

ملاحظة

قد تضيء قناة الأحمر في مؤشر RGB LED للمستخدم لوهلة أثناء قراءة المضيف من قرص تخزين USB الكتلي أو الكتابة إليه — وهذا مؤشر نشاط مدفوع بالبرنامج الثابت، وليس عطلاً.

أحجام التخزين

يأتي RT1062 مزوداً بـ:

  • /flash — نظام ملفات FAT بسعة 4 MB، قراءة/كتابة.

  • /rom — ‏ROMFS مُسقَط في الذاكرة للقراءة فقط بسعة 8 MB، يُستخدم لشحن البرامج النصية ونماذج تعلّم الآلة التي تستفيد من الوصول عبر mmap دون نسخ.

  • /sdcard — الحجم الكامل لأي بطاقة microSD مُدرجة (عند وجودها)، قراءة/كتابة.

مؤشر العطل القاسي (Hard‑fault)

إذا كان مؤشر RGB LED للمستخدم يتنقل بسرعة عبر جميع الألوان — بسرعة كافية ليبدو وكأنه مؤشر LED أبيض متلألئ بدلاً من ألوان متمايزة — فهذا يعني أن البرنامج الثابت قد واجه عطلاً قاسياً لا يمكن التعافي منه. أعد كتابة البرنامج الثابت للتعافي؛ وإذا لم تساعد إعادة الكتابة، فقد تكون اللوحة تالفة فيزيائياً.

مكتبات البرمجيات

راجع فهرس المكتبة للاطلاع على القائمة الكاملة للوحدات — بما في ذلك الوحدات الفريدة لبناء RT1062.