OpenMV Cam M4¶
OpenMV Cam M4 — это компактная плата машинного зрения на базе Cortex‑M4, построенная на микроконтроллере STMicroelectronics STM32F427 с частотой 180 МГц, 256 КБ внутренней SRAM и 1 МБ внутренней флеш-памяти. Поставляемый в комплекте датчик OV7725 захватывает кадры 320×240 в оттенках серого или RGB565, а 9-контактный пользовательский разъём предоставляет периферийные устройства UART, I²C, SPI, CAN, ADC/DAC и PWM.
Примечание
OV7725 был стандартным датчиком на серийных платах M4. Самые ранние варианты M4 поставлялись вместо него с OmniVision OV2640 — тот же конвейер предпросмотра QVGA, но OV2640 может также захватывать JPEG-кадры вплоть до UXGA (1600×1200). Оба датчика управляются через один и тот же API csi — датчики камеры.
Полный технический паспорт, фотографии и габариты см. на странице продукта OpenMV Cam M4.
Ключевые особенности¶
STMicroelectronics STM32F427 Cortex‑M4 на частоте 180 МГц.
256 КБ внутренней SRAM — без внешней SDRAM.
1 МБ внутренней флеш-памяти (без внешней флеш-памяти QSPI).
Датчик OV7725 (или OV2640 на самых ранних вариантах M4) — 320×240 8-битные оттенки серого или RGB565; OV2640 дополнительно может захватывать JPEG вплоть до UXGA (1600×1200).
Full‑speed USB (12 Мбит/с) — определяется хостом как VCP + USB-накопитель.
Разъём microSD — SD до 2 ГБ, SDHC до 32 ГБ, SDXC до 2 ТБ.
9 выводов I/O, толерантны к 5 В с выходом 3,3 В, 25 мА на вывод (120 мА суммарно по всему разъёму), с поддержкой прерываний. P6 не толерантен к 5 В при использовании в режиме ADC или DAC.
Пользовательский RGB-светодиод и два мощных ИК-светодиода 850 нм для активной подсветки при машинном зрении в условиях низкой освещённости.
Примечание
У M4 нет встроенной микросхемы управления питанием: отсутствуют разъём для аккумулятора, зарядное устройство для аккумулятора, ADC для измерения напряжения аккумулятора, светодиоды зарядки / состояния питания и аппаратная кнопка питания. Подавайте питание на плату через 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 В при включении питания для DFU / ROM-загрузчика |
SWCLK |
тактовый сигнал ARM SWD (доступ для отладчика) |
SWDIO |
данные ARM SWD (доступ для отладчика) |
LED_RED |
красный канал RGB-светодиода (активный низкий уровень) |
LED_GREEN |
зелёный канал RGB-светодиода (активный низкий уровень) |
LED_BLUE |
синий канал RGB-светодиода (активный низкий уровень) |
LED_IR |
мощные ИК-светодиоды (оба канала управляются вместе) |
Выводы питания¶
3.3V — стабилизированная шина 3,3 В. Доступно до 250 мА для шилдов (меньше, если используется карта microSD). В отличие от более новых камер этот вывод двунаправленный — см. предупреждение ниже.
VIN — вход 3,6 – 5 В. Питает плату через встроенный стабилизатор.
GND — общая земля.
Примечание
Когда присутствуют и USB, и VIN, плату питает тот из них, у которого выше напряжение — встроенные диоды просто выбирают более сильную шину.
Предупреждение
Вы можете питать M4, подавая 3,3 В напрямую на вывод 3.3V, если не хотите проходить через встроенный стабилизатор. В этом случае не подавайте одновременно также питание VIN или USB — обратная подача тока на стабилизатор при активном другом источнике может необратимо повредить и вывести из строя камеру.
Совет
Используйте оценщик времени работы от батареи, чтобы смоделировать, как долго M4 проработает от батареи при заданном рабочем цикле активность / глубокий сон.
Выводы восстановления и отладки¶
RESET — подтяните к GND для сброса платы. Отпускание позволяет MCU запуститься нормально.
BOOT0 — подтяните к 3,3 В при подаче питания на плату, чтобы войти в ROM-загрузчик STM32 (режим DFU). OpenMV IDE использует этот режим для перепрошивки встроенного загрузчика.
SWCLK и SWDIO выведены как обычные выводы разъёма (а не как выделенный разъём SWD). Подключите RESET, SWCLK, SWDIO, GND и 3,3 В к адаптеру ST‑LINK или SEGGER J‑Link для отладки платы.
Встроенные периферийные устройства¶
Светодиоды¶
У M4 есть один пользовательский RGB-светодиод плюс пара мощных ИК-светодиодов 850 нм:
Пользовательский RGB-светодиод — управляется программно, доступен как
LED_RED,LED_GREENиLED_BLUE:from machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
ИК-светодиоды — оба светодиода управляются вместе через вывод
LED_IR.LED_IRподключён аппаратно как активный высокий уровень, тогда как прошивка трактует все остальные встроенные светодиоды как активные низкие, поэтому используйте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. Сигнальные выводы напрямую отображаются на каналы 1 и 2 TIM4 (те же каналы, что использует pyb.Servo), а вывод V+ на каждом разъёме подключён напрямую к VIN, поэтому сервоприводы потребляют ток с входной шины, а не со стабилизатора 3,3 В.
Впаяйте пару угловых 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 В CMOS, толерантны к 5 В на стороне входа и могут принимать/выдавать до 25 мА на вывод (120 мА суммарно по всему разъёму).
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")
Это же оборудование можно также использовать в режиме целевого устройства (slave) через 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 — единственный пользовательский аналоговый вывод. Его можно использовать либо как 12-битный вход ADC, либо как выход DAC.
ADC — полная шкала при 3,3 В на выводе:
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 В:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
В режиме ADC или DAC P6 толерантен только к 3,3 В — не подавайте на него 5 В.
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 Гц, поэтому не смешивайте machine.PWM на P7/P8 с pyb.Servo в одном скрипте.
Управляйте любым из них через machine.PWM:
from machine import Pin, PWM
pwm = PWM(Pin("P7"), 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 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 в качестве id, чтобы использовать виртуальный (программный) таймер:
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 по умолчанию, поставляемый на свежепрошитой плате, просто мигает синим каналом пользовательского 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-карту для любых данных, которые скрипт записывает обратно, и перемонтируйте перед чтением этих файлов с хоста.
Примечание
Красный канал пользовательского RGB-светодиода может ненадолго загораться, пока хост считывает с USB-накопителя или записывает на него — это управляемый прошивкой индикатор активности, а не неисправность.
Объёмы хранилища¶
M4 поставляется с:
/flash— файловая система FAT 32 КБ, чтение/запись./rom— отображённая в память ROMFS 128 КБ только для чтения./sdcard— полный объём вставленной карты microSD (при наличии), чтение/запись.
Индикатор аппаратного сбоя (hard fault)¶
Если пользовательский RGB-светодиод быстро перебирает все цвета — настолько быстро, что это обычно выглядит как мерцающий белый светодиод, а не как отдельные оттенки — прошивка столкнулась с неустранимым аппаратным сбоем (hard fault). Перепрошейте прошивку для восстановления; если перепрошивка не помогает, плата может быть физически повреждена.
Программные библиотеки¶
См. индекс библиотек для полного списка модулей — включая те, что уникальны для сборки M4.