OpenMV N6

تم بناء OpenMV N6 حول معالج STMicroelectronics STM32N657 (Cortex‑M55 بتردد 800 MHz) مع وحدة معالجة عصبية (NPU) بتردد 1 GHz على الشريحة تبلغ قدرتها 600 GOPS INT8. تقرن اللوحة وحدة NPU بمستشعر PAG7936 من نوع global‑shutter بدقة 1 MP على حامل قابل للإزالة، مع شبكة Ethernet جيجابت، وUSB‑C عالي السرعة، وWi‑Fi، وBluetooth 5.1، وتشغّل استدلال YOLOv8/YOLOv11 بمعدل 30 FPS إلى جانب البث المباشر للفيديو.

OpenMV N6

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

أبرز الميزات

  • STM32N657 Cortex‑M55 بتردد 800 MHz (1280 DMIPS) مع ARM Helium 128‑bit SIMD — إنتاجية متجهية تبلغ 6.4 gigaops.

  • NPU بتردد 1 GHz، 600 GOPS INT8 — يشغّل كشف YOLOv8/YOLOv11 بمعدل 30 FPS.

  • ISP لدعم Bayer RAW حتى 5MP، و2D GPU لتغيير الحجم والتدوير ثلاثي الأبعاد، وترميز H.264 حتى 1080p، وبرنامج ترميز JPEG عتادي.

  • ذاكرة SDRAM خارجية بسعة 64 MB (16‑bit بتردد 200 MHz DDR، 800 MB/s) إضافة إلى ذاكرة SRAM داخلية بسعة 4.2 MB وذاكرة فلاش octal بسعة 32 MB (200 MHz DDR، 400 MB/s).

  • PAG7936 مستشعر ملون من نوع global‑shutter بدقة 1 MP.

  • وحدة IMU مدمجة (مقياس تسارع + جيروسكوب) وميكروفون لدمج الصوت والحركة.

  • USB‑C عالي السرعة (480 Mb/s، حد تيار 1.5 A)، وEthernet جيجابت (متوافق مع 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)، وADC لجهد البطارية، وRTC مع 8 KB من ذاكرة RAM احتياطية ودبوس مخصص للبطارية الاحتياطية.

  • 18 دبوس I/O، جميعها بخرج 3.3 V / تتحمل 3.3 V، و20 mA لكل دبوس، وقادرة على المقاطعة.

  • RGB LED للمستخدم، وزر للمستخدم، وLED حالة منفصل للشحن / USB / طاقة VIN.

تحذير

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

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

OpenMV N6 PAG7936 Pinout

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

اسم الدبوس

الوظيفة

P0

SPI2 MOSI / I2S2 SDO

P1

SPI2 MISO / I2S2 SDI

P2

SPI2 SCLK / UART4 TX / CAN1 TX / I2S2 CK

P3

SPI2 SS / UART4 RX / CAN1 RX / I2S2 WS

P4

I2C2 SCL / UART3 TX / TIM2 CH3 / I3C2 SCL

P5

I2C2 SDA / UART3 RX / TIM2 CH4 / I3C2 SDA

P6

TIM12 CH1 (لا يوجد ADC على هذا الدبوس — راجع P6_ADC)

P6_ADC

دخل ADC مخصص بدقة 12‑bit (موصول داخلياً بـ P6)

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2 / مزامنة الإطار I/O

P11

إيقاظ (نشط عند المستوى المنخفض، WKUP3)

P12

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

P13

UART7 RX

P14

UART7 TX

P15

SPI4 CS

P16

SPI4 SCK

P17

SPI4 MISO

P18

SPI4 MOSI

SW

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

ONOFF (SW2)

زر الإيقاظ من النوم العميق (نشط عند المستوى المنخفض، WKUP2)

ST

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

CHG

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

PG

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

BAT_ADC

قناة ADC داخلية تقيس جهد بطارية LiPo المتصلة

LED_RED

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

LED_GREEN

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

LED_BLUE

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

ملاحظة

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

ملاحظة

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

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

ملاحظة

يتشارك P15–P18 مع طبقة Gigabit Ethernet PHY، وهي موصولة ونشطة افتراضياً. لاستخدام هذه الدبابيس كـ I/O للمستخدم، يجب أن تعيد لحام مقاومة 0‑أوم الموجودة على ظهر اللوحة إلى موضع GPIO. هذا يعطّل Ethernet جيجابت فقط — تبقى Ethernet بسرعة 10/100 Mb/s عاملة على دبابيسها المخصصة.

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

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

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

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

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

ملاحظة

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

ملاحظة

يحتوي ظهر اللوحة على وسادات لحام لـ بطارية احتياطية خارجية لـ RTC بجهد 3.3 V. توصيل خلية عملة بهذه الوسادات يُبقي RTC و8 KB من ذاكرة RAM الاحتياطية عاملين بينما تكون بقية اللوحة غير مزوّدة بالطاقة.

نصيحة

استخدم أداة تقدير عمر البطارية لنمذجة المدة التي سيعمل خلالها N6 على بطارية لدورة عمل معينة من النشاط / النوم العميق.

دبابيس Ethernet

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

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

  • DA P / DA N — الزوج A (TX في 10/100، مستخدم بجميع السرعات).

  • DB P / DB N — الزوج B (RX في 10/100، مستخدم بجميع السرعات).

  • DC P / DC N — الزوج C، يُستخدم فقط عند سرعة جيجابت.

  • DD P / DD N — الزوج D، يُستخدم فقط عند سرعة جيجابت.

تحتاج سرعة 10/100 Mb/s إلى الزوجين A وB فقط. وتحتاج سرعة جيجابت إلى الأزواج الأربعة جميعها A–D.

دبابيس الاسترداد والتصحيح

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

  • BOOT0 — اسحبه إلى 3.3 V أثناء تشغيل اللوحة للدخول إلى وضع محمّل إقلاع ROM. يستخدم OpenMV IDE هذا الوضع لإعادة برمجة محمّل الإقلاع المدمج.

  • BOOT1 — مفتاح يضع اللوحة في وضع المطوّر للاستخدام مع أدوات ST (ST‑LINK متصل بوصلة ARM ذات 10 دبابيس SWD/JTAG). اتركه معطّلاً للتشغيل العادي مع برنامج OpenMV الثابت وأدواته.

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

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

مصابيح LED

يحتوي N6 على مصباحي 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.

أزرار المستخدم

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

  • SW — زر مستخدم للأغراض العامة. نشط عند سحبه إلى المستوى المنخفض.

  • ONOFF (SW2) — زر الإيقاظ. الزر الوحيد الذي يمكنه إخراج اللوحة من النوم العميق.

from machine import Pin

sw    = Pin("SW",    Pin.IN)   # user button
onoff = Pin("ONOFF", Pin.IN)   # SW2 — wakes from deep sleep
print(sw.value(), onoff.value())

لوضع اللوحة في النوم العميق وجعل ONOFF (SW2) يوقظها، ما عليك سوى استدعاء machine.deepsleep() — لا يلزم تهيئة للإيقاظ، فالزر موصول مباشرة بدخل WKUP2:

import machine

machine.deepsleep()   # press ONOFF (SW2) to wake the board

يمكنك أيضاً توصيل ONOFF كمفتاح طاقة برمجي. شغّل المقاطعة على الحافة الصاعدة — يستقر الخط عند المستوى المرتفع بعد أن يحرّر المستخدم الزر، فيكون الضغط التالي حدث إيقاظ لا لبس فيه:

import machine
from machine import Pin

def power_off(_):
    machine.deepsleep()

Pin("ONOFF", Pin.IN).irq(power_off, Pin.IRQ_RISING)

# ...rest of the application runs here. Press ONOFF once to sleep,
# press it again to wake.

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

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

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

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

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

from machine import Pin

on_vin    = not Pin("ST",  Pin.IN).value()
charging  = not Pin("CHG", Pin.IN).value()
power_ok  = not Pin("PG",  Pin.IN).value()

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

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

import csi

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

while True:
    img = cam.snapshot()

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

يدعم PAG7936 الوضع المُحفَّز — حيث تتطابق خطوط تكامل البكسل تماماً مع كل استدعاء لـ csi.CSI.snapshot بدلاً من ساعة الإطار الحرة، وهو مفيد لمزامنة الالتقاط مع حدث خارجي أو مستشعر آخر. فعّله عبر csi.CSI.ioctl مع csi.IOCTL_SET_TRIGGERED_MODE. ينخفض معدل الإطارات إلى نحو نصف وضع التشغيل الحر لأن القراءة لم تعد تتداخل مع تكامل الإطار التالي:

cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)

NPU

تُكشف وحدة Neural‑ART NPU في N6 بتردد 1 GHz (600 GOPS INT8) عبر وحدة ml --- التعلم الآلي. النماذج المخزنة على نظام الملفات للقراءة فقط /rom تُحمّل مباشرة من الفلاش دون نسخها إلى RAM، فحتى الكواشف الكبيرة تتسع بسهولة إلى جانب مخزن الإطارات المباشر. شغّل كاشف YOLOv8 على كل إطار وارسم التنبؤات فوق الصورة المباشرة:

import csi
import time
import ml
from ml.postprocessing.ultralytics import YoloV8

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

# Load YOLO V8 model from ROM FS.
model = ml.Model("/rom/yolov8n_192.tflite", postprocess=YoloV8(threshold=0.4))
print(model)

# Visualization parameters.
n = len(model.labels)
model_class_colors = [
    (int(255 * i // n), int(255 * (n - i - 1) // n), 255)
    for i in range(n)
]

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

    # boxes is a list of list per class of ((x, y, w, h), score) tuples
    boxes = model.predict([img])

    # Draw bounding boxes around the detected objects
    for i, class_detections in enumerate(boxes):
        rects = [r for r, score in class_detections]
        labels = [model.labels[i] for j in range(len(rects))]
        colors = [model_class_colors[i] for j in range(len(rects))]
        ml.utils.draw_predictions(img, rects, labels, colors, format=None)

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

الميكروفون

يُلتقط الميكروفون المدمج عبر audio --- وحدة الصوت. يصل كل مخزن مؤقت على هيئة PCM موقّع 16‑bit بصيغة bytearray، مما يجعل تغذيته إلى ulab/numpy لمعالجة DSP سريعة أمراً بالغ السهولة. إليك كاشف صوت بسيط — يطبع كلما تجاوزت قيمة RMS للصوت عتبة معينة:

import audio
from ulab import numpy as np

def loudness(pcmbuf):
    samples = np.array(np.frombuffer(pcmbuf, dtype=np.int16), dtype=np.float)
    rms = np.sqrt(np.mean(samples ** 2))
    if rms > 10000:
        print("Loud!", int(rms))

audio.init(channels=1, frequency=16000, gain_db=24)
audio.start_streaming(loudness)

while True:
    pass

IMU

يُكشف مقياس التسارع + الجيروسكوب المدمج الموجود أسفل وحدة الكاميرا عبر imu --- مستشعر imu

import imu
import time

while True:
    print(imu.acceleration_mg())   # (x, y, z) in milli‑g
    print(imu.angular_rate_mdps()) # (x, y, z) in milli‑deg/s
    time.sleep_ms(100)

Wi‑Fi

تُكشف شريحة CYW43439 المدمجة عبر 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

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

import asyncio
import aioble

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

asyncio.run(run())

Ethernet

عند توصيل RJ45 (مع مغناطيسات) بوسادات MDI، تظهر طبقة الجيجابت PHY كواجهة 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 ويمكنها سحب/مصدر ما يصل إلى 20 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

UART3

P4

P5

UART4

P2

P3

UART7

P14

P13

from machine import UART

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

I²C

الناقل

SCL

SDA

I2C2

P4

P5

from machine import I2C

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

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

from machine import I2CTarget

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

SPI

الناقل

MOSI

MISO

SCK

CS

SPI2

P0

P1

P2

P3

SPI4

P18

P17

P16

P15

from machine import SPI
from machine import Pin

spi = SPI(2, 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

P2

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 عبر مقسّم جهد مخزّن بمكبر عمليات قبل الوصول إلى المتحكم الدقيق، لذا يُربط read_u16() بجهد دخل مختلف بالمقياس الكامل على كل دبوس.

الدبوس

المقياس الكامل

ملاحظات

P6_ADC

~3.3 V

وسادة للأغراض العامة، موصولة داخلياً بـ P6

BAT_ADC

~5.0 V

قناة داخلية لبطارية LiPo

from machine import ADC
import time

adc = ADC("P6_ADC")
bat = ADC("BAT_ADC")

while True:
    print("P6:", adc.read_u16() * 3.3 / 65535, "V")
    print("BAT:", bat.read_u16() * 5.0 / 65535, "V")
    time.sleep_ms(100)

PWM

الدبوس

المؤقت / القناة

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM12 CH1

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2

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

from machine import Pin, PWM

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

الناقلات المنفّذة برمجياً بطريقة bit‑banged

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

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

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

  • MLX90621 — مصفوفة IR بحجم 16 × 4

  • MLX90640 — مصفوفة IR بحجم 32 × 24

  • MLX90641 — مصفوفة IR بحجم 16 × 12

  • AMG8833 — مصفوفة IR بحجم 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 2 فقط — وصّل الوحدة بـ 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().

المراقب

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()

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

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

  • الفلاش الداخلي — يُركّب دائماً عند /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 يتجاوز النسخة الموجودة في الفلاش دون المساس بها — يُبحث عن كلا الملفين في دليل الإقلاع (/sdcard عند تركيب البطاقة، وإلا /flash).

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

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

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

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

ملاحظة

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

ملاحظة

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

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

يأتي N6 مزوداً بما يلي:

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

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

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

مؤشر العطل الجسيم

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

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

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