OpenMV Cam M4¶
إن OpenMV Cam M4 هي لوحة رؤية آلية مدمجة من نوع Cortex‑M4 مبنية حول معالج STMicroelectronics STM32F427 بتردد 180 MHz مع 256 KB من ذاكرة SRAM الداخلية و1 MB من ذاكرة الفلاش الداخلية. يلتقط المستشعر المرفق OV7725 إطارات بدقة 320×240 بتدرج الرمادي أو RGB565، ويوفر ترويسة المستخدم ذات الـ9 دبابيس طرفيات UART وI²C وSPI وCAN وADC/DAC وPWM.
ملاحظة
كان OV7725 هو المستشعر القياسي على لوحات M4 الإنتاجية. شُحنت إصدارات مبكرة جدًا من M4 مع OmniVision OV2640 بدلًا منه — بنفس مسار المعاينة QVGA، لكن يمكن لـ OV2640 أيضًا التقاط إطارات JPEG بدقة تصل إلى UXGA (1600×1200). يُشغَّل كلا المستشعرين عبر واجهة csi --- مستشعرات الكاميرا نفسها.
للاطلاع على صحيفة البيانات الكاملة والصور والأبعاد، راجع صفحة منتج OpenMV Cam M4.
أبرز الميزات¶
STMicroelectronics STM32F427 من نوع Cortex‑M4 بتردد 180 MHz.
256 KB من ذاكرة SRAM الداخلية — بدون SDRAM خارجية.
1 MB من ذاكرة الفلاش الداخلية (بدون ذاكرة فلاش QSPI خارجية).
مستشعر OV7725 (أو OV2640 على إصدارات M4 المبكرة جدًا) — 320×240 بتدرج رمادي 8‑بت أو RGB565؛ ويمكن لـ OV2640 إضافةً إلى ذلك التقاط JPEG بدقة تصل إلى UXGA (1600×1200).
USB بالسرعة الكاملة (12 Mb/s) — يظهر كـ VCP + وحدة تخزين USB كبيرة السعة للمضيف.
مقبس microSD — بطاقات SD حتى 2 GB، وSDHC حتى 32 GB، وSDXC حتى 2 TB.
9 دبابيس إدخال/إخراج، متحملة للجهد 5 V مع إخراج بجهد 3.3 V، و25 mA لكل دبوس (120 mA إجماليًا عبر الترويسة)، وقادرة على المقاطعة. الدبوس P6 غير متحمل للجهد 5 V عند استخدامه في وضع ADC أو DAC.
LED RGB للمستخدم واثنان من مصابيح LED بالأشعة تحت الحمراء عالية الطاقة بطول موجة 850 nm للإضاءة النشطة في الرؤية ضمن الإضاءة المنخفضة.
ملاحظة
لا تحتوي M4 على شريحة إدارة طاقة على اللوحة: لا يوجد موصل بطارية، ولا شاحن بطارية، ولا ADC لجهد البطارية، ولا مصابيح LED للشحن / حالة الطاقة، ولا زر طاقة مادي. شغّل اللوحة من USB أو VIN.
مخطط الدبابيس¶
مرجع الدبابيس¶
اسم الدبوس |
الوظيفة |
|---|---|
P0 |
SPI2 MOSI |
P1 |
SPI2 MISO |
P2 |
SPI2 SCK / CAN2 TX |
P3 |
SPI2 NSS (CS) / CAN2 RX |
P4 |
I2C2 SCL / UART3 TX / TIM2 CH3 |
P5 |
I2C2 SDA / UART3 RX / TIM2 CH4 |
P6 |
ADC / DAC / TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
RESET |
اربطه بالأرضي GND لإعادة ضبط اللوحة |
BOOT0 |
اربطه بجهد 3.3 V عند تشغيل الطاقة لوضع DFU / محمّل الإقلاع ROM |
SWCLK |
ساعة ARM SWD (وصول المنقّح) |
SWDIO |
بيانات ARM SWD (وصول المنقّح) |
LED_RED |
القناة الحمراء لـ LED RGB (نشطة عند المستوى المنخفض) |
LED_GREEN |
القناة الخضراء لـ LED RGB (نشطة عند المستوى المنخفض) |
LED_BLUE |
القناة الزرقاء لـ LED RGB (نشطة عند المستوى المنخفض) |
LED_IR |
مصابيح LED بالأشعة تحت الحمراء عالية الطاقة (تُشغَّل كلتا القناتين معًا) |
دبابيس الطاقة¶
3.3V — خط جهد 3.3 V منظَّم. يتوفر حتى 250 mA للدروع (أقل إذا كانت بطاقة microSD قيد الاستخدام). خلافًا للكاميرات الأحدث، هذا الدبوس ثنائي الاتجاه — راجع التحذير أدناه.
VIN — دخل بجهد 3.6 – 5 V. يغذّي اللوحة عبر المنظِّم المدمج على اللوحة.
GND — الأرضي المشترك.
ملاحظة
عندما يكون كل من USB وVIN موجودَين، فإن صاحب الجهد الأعلى هو الذي يغذّي اللوحة — تختار الثنائيات المدمجة على اللوحة الخط الأقوى ببساطة.
تحذير
يمكنك تشغيل M4 بتغذية جهد 3.3 V مباشرةً إلى الدبوس 3.3V إذا لم ترغب في المرور عبر المنظِّم المدمج على اللوحة. في تلك الحالة، لا تطبّق أيضًا VIN أو طاقة USB في الوقت نفسه — فإن الدفع العكسي للمنظِّم بينما يكون مصدر آخر نشطًا قد يُتلف الكاميرا بشكل دائم ويدمّرها.
نصيحة
استخدم مقدِّر عمر البطارية لتقدير المدة التي ستعمل فيها M4 على بطارية لدورة تشغيل معيّنة بين الوضع النشط والنوم العميق.
دبابيس الاستعادة والتنقيح¶
RESET — اربطه بالأرضي GND لإعادة ضبط اللوحة. تحريره يجعل المتحكم MCU يبدأ التشغيل بشكل طبيعي.
BOOT0 — اربطه بجهد 3.3 V أثناء تشغيل اللوحة للدخول إلى محمّل الإقلاع ROM الخاص بـ STM32 (وضع DFU). يستخدم OpenMV IDE هذا الوضع لإعادة وميض محمّل الإقلاع المدمج على اللوحة.
يُخرَج SWCLK وSWDIO كدبابيس ترويسة عادية (وليس كموصل SWD مخصص). صِل RESET وSWCLK وSWDIO وGND و3.3 V بمُهايئ ST‑LINK أو SEGGER J‑Link لتنقيح اللوحة.
الطرفيات المدمجة على اللوحة¶
مصابيح LED¶
تحتوي M4 على LED RGB واحد للمستخدم بالإضافة إلى زوج من مصابيح LED بالأشعة تحت الحمراء عالية الطاقة بطول موجة 850 nm:
LED RGB للمستخدم — قابل للتحكم برمجيًا، ويُعرَض كـ
LED_REDوLED_GREENوLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
مصابيح LED بالأشعة تحت الحمراء — يُشغَّل كلا المصباحين معًا عبر الدبوس
LED_IR. الدبوسLED_IRموصول نشطًا عند المستوى المرتفع في العتاد بينما يعامل البرنامج الثابت كل مصباح LED آخر مدمج على اللوحة كنشط عند المستوى المنخفض، لذا استخدمlow()/high()بدلًا منon()/off()(اللذين سيعكسان الاتجاه):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
مستشعر الكاميرا¶
يُشغَّل المستشعر المرفق (OV7725 على اللوحات القياسية، وOV2640 على الإصدارات المبكرة جدًا) عبر وحدة 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()
المستشعر ملحوم باللوحة على M4 — فهو ليس على وحدة قابلة للتبديل.
ملاحظة
على لوحات OV7725 يكون دبوس FSIN (مزامنة الإطار) الخاص بالمستشعر موصولًا بالمتحكم MCU لكن لم يُضَف دعم له في البرنامج الثابت.
على لوحات OV2640 تكون دبابيس المستشعر STROBE وFREX (تعريض الإطار) وEXPST (إعادة ضبط التعريض) موصولة بالمتحكم MCU لكن لم يُضَف دعم لها في البرنامج الثابت.
ترويسات السيرفو¶
يحتوي الجانب الخلفي من اللوحة على مساحتي لحام لموصل السيرفو تُخرجان ترويسة السيرفو القياسية ذات الـ3 دبابيس (الإشارة / VIN / GND) للدبوسين P7 وP8. ترتبط دبابيس الإشارة مباشرةً بقناتي TIM4 رقم 1 و2 (القناتان نفساهما المستخدمتان من قبل pyb.Servo)، ودبوس V+ في كل ترويسة موصول مباشرةً بـ VIN، لذا تسحب السيرفوات تيارها من خط الدخل وليس من منظِّم 3.3 V.
الحم زوجًا من ترويسات الـ3 دبابيس بزاوية قائمة في المساحات وصِل سيرفوَين هواية لتشغيل حامل إمالة وتدوير:
from pyb import Servo
pan = Servo(1) # P7 — TIM4 CH1
tilt = Servo(2) # P8 — TIM4 CH2
pan.angle(0)
tilt.angle(0)
بطاقة microSD¶
عند إدخال بطاقة تُركَّب تلقائيًا في /sdcard وتكون قابلة للاستخدام عبر نظام الملفات العادي:
import os
for entry in os.listdir("/sdcard"):
print(entry)
مرجع الناقل¶
GPIO¶
استخدم machine.Pin لقراءة أو تشغيل أي من الدبابيس المطبوعة على اللوحة. المخارج بجهد 3.3 V من نوع CMOS، ومتحملة للجهد 5 V على جانب الدخل، ويمكنها سحب/تزويد ما يصل إلى 25 mA لكل دبوس (120 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 |
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 |
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 |
|---|---|---|
CAN2 |
P2 |
P3 |
from machine import CAN
can = CAN(2, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())
ADC وDAC¶
الدبوس P6 هو دبوس المستخدم التناظري الوحيد. يمكن استخدامه إما كدخل ADC بدقة 12‑بت أو كخرج DAC.
ADC — المقياس الكامل عند 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)
DAC — عبر
pyb.DAC. القيمة ذات الـ8‑بت تغطي 0–3.3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
في وضع ADC أو DAC يكون P6 متحملًا للجهد 3.3 V فقط — لا تغذّه بجهد 5 V.
PWM¶
الدبوس |
المؤقت / القناة |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
ملاحظة
TIM1 محجوز من قبل البرنامج الثابت لتوليد ساعة بكسل مستشعر الكاميرا، لذا لا يمكن استخدام قنوات TIM1 الموجودة ماديًا على P0/P1/P2 لـ PWM المستخدم دون تعطيل الكاميرا.
TIM4 مشترك مع pyb.Servo — إن إنشاء سيرفو يعيد تكوين المؤقت بأكمله للعمل بتردد 50 Hz، لذا لا تمزج بين machine.PWM على P7/P8 وpyb.Servo في البرنامج النصي نفسه.
شغّل أيًا منها عبر machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
النواقل البرمجية بتقنية bit‑banging¶
تعمل 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 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 على وقت الساعة الجدارية عبر عمليات إعادة الضبط:
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())
كلب الحراسة¶
تعيد 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()
نظام الملفات وترتيب الإقلاع¶
يركّب البرنامج الثابت لـ M4 ما يصل إلى ثلاثة أنظمة ملفات عند الإقلاع:
ذاكرة الفلاش الداخلية — تُركَّب دائمًا في
/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 الافتراضي المشحون على لوحة حديثة الوميض يومض فقط بالقناة الزرقاء لـ LED RGB للمستخدم كنبضة قلب (نبضتان قصيرتان، فاصل قصير)، حتى تتمكن من معرفة أن البرنامج الثابت أقلع بشكل سليم دون أي مضيف متصل.
يُوسَّع 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 لأي بيانات يكتبها البرنامج النصي، وأعد التركيب قبل قراءة تلك الملفات من المضيف.
ملاحظة
قد تضيء القناة الحمراء لـ LED RGB للمستخدم لفترة وجيزة بينما يقرأ المضيف من قرص تخزين USB كبير السعة أو يكتب إليه — هذا مؤشر نشاط يقوده البرنامج الثابت، وليس عطلًا.
أحجام التخزين¶
تُشحَن M4 مع:
/flash— نظام ملفات FAT بسعة 32 KB، للقراءة/الكتابة./rom— نظام ملفات ROMFS مُسقَط في الذاكرة للقراءة فقط بسعة 128 KB./sdcard— الحجم الكامل لأي بطاقة microSD مُدخلة (عند وجودها)، للقراءة/الكتابة.
مؤشر العطل الجسيم¶
إذا كان LED RGB للمستخدم يدور بسرعة عبر جميع الألوان — بسرعة كافية بحيث يبدو وكأنه LED أبيض متلألئ بدلًا من ألوان مميزة — فإن البرنامج الثابت قد واجه عطلًا جسيمًا غير قابل للاسترداد. أعد وميض البرنامج الثابت للاستعادة؛ وإذا لم تساعد إعادة الوميض، فقد تكون اللوحة تالفة ماديًا.
المكتبات البرمجية¶
راجع فهرس المكتبة للحصول على القائمة الكاملة للوحدات — بما في ذلك تلك التي تنفرد بها بنية M4.