OpenMV Cam M7

OpenMV Cam M7 — это плата машинного зрения на базе Cortex‑M7, построенная вокруг STMicroelectronics STM32F765 с частотой 216 МГц, 512 КБ внутренней SRAM и 2 МБ внутренней флеш‑памяти. Входящий в комплект датчик OV7725 захватывает кадры 640×480 в оттенках серого или 320×240 в RGB565 со скоростью до 150 кадров/с, а 10‑контактный пользовательский разъём предоставляет периферию UART, I²C, SPI, CAN, ADC/DAC и PWM.

OpenMV Cam M7

Полный паспорт, фотографии и размеры см. на странице продукта OpenMV Cam M7.

Основные характеристики

  • STMicroelectronics STM32F765 Cortex‑M7 на 216 МГц.

  • 512 КБ внутренней SRAM — внешняя SDRAM отсутствует.

  • 2 МБ внутренней флеш‑памяти (внешняя QSPI‑флеш отсутствует).

  • Датчик OV7725 — 640×480 в оттенках серого или 320×240 в RGB565 со скоростью до 150 кадров/с.

  • Полноскоростной USB (12 Мбит/с) — определяется хостом как VCP + USB‑накопитель.

  • Слот microSD — SD до 2 ГБ, SDHC до 32 ГБ, SDXC до 2 ТБ.

  • 10 вводов/выводов, толерантны к 5 В с выходом 3,3 В, 25 мА на вывод (120 мА суммарно по всему разъёму), с поддержкой прерываний. P6 не толерантен к 5 В при использовании в режиме ADC или DAC.

  • Пользовательский RGB‑светодиод и два мощных ИК‑светодиода на 850 нм для активной подсветки при работе в условиях слабого освещения.

Примечание

У M7 нет встроенной микросхемы управления питанием: нет разъёма для батареи, нет зарядного устройства, нет ADC для измерения напряжения батареи, нет светодиодов зарядки/состояния питания и нет аппаратной кнопки питания. Питайте плату от USB или VIN.

Распиновка

Распиновка OpenMV Cam M7 OV7725

Справочник по выводам

Имя вывода

Функция

P0

UART1 RX / SPI2 MOSI

P1

UART1 TX / 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

I2C4 SCL / TIM4 CH1

P8

I2C4 SDA / TIM4 CH2

P9

TIM4 CH3

RESET

замкните на GND для сброса платы

SYN

контактная площадка синхронизации кадров — подключена только к датчику камеры

BOOT0

подайте 3,3 В при включении питания для входа в DFU / ROM‑загрузчик

LED_RED

красный канал RGB‑светодиода (активный низкий уровень)

LED_GREEN

зелёный канал RGB‑светодиода (активный низкий уровень)

LED_BLUE

синий канал RGB‑светодиода (активный низкий уровень)

LED_IR

мощные ИК‑светодиоды (оба канала управляются совместно)

Примечание

Площадка SYN на разъёме подключена напрямую к линии триггера / экспозиции датчика камеры — на M7 она не соединена с MCU. Управляйте ею или считывайте её внешними средствами; из MicroPython переключить её нельзя.

Выводы питания

  • 3.3V — стабилизированная шина 3,3 В. Для шилдов доступно до 250 мА (меньше, если используется карта microSD). В отличие от более новых камер этот вывод двунаправленный — см. предупреждение ниже.

  • VIN — вход 3,6 – 5 В. Питает плату через встроенный стабилизатор.

  • GND — общая земля.

Примечание

Когда присутствуют и USB, и VIN, плату питает тот из них, у которого выше напряжение — встроенные диоды просто выбирают более сильную шину.

Предупреждение

Вы можете питать M7, подавая 3,3 В напрямую на вывод 3.3V, если не хотите использовать встроенный стабилизатор. В этом случае не подавайте одновременно питание на VIN или USB — обратная подача напряжения на стабилизатор при активном другом источнике питания может необратимо повредить и вывести камеру из строя.

Совет

Используйте оценщик времени работы от батареи, чтобы смоделировать, как долго M7 проработает от батареи при заданном цикле работы активный режим / глубокий сон.

Выводы восстановления и отладки

  • RESET — замкните на GND для сброса платы. Отпускание позволяет MCU запуститься в обычном режиме.

  • BOOT0 — подайте 3,3 В во время подачи питания на плату для входа в ROM‑загрузчик STM32 (режим DFU). OpenMV IDE использует этот режим для перепрошивки встроенного загрузчика.

На плате рядом с разъёмом GPIO выведен отладочный разъём SWD (RST / SWCLK / SWDIO), совместимый с адаптерами ST‑LINK и SEGGER J‑Link.

Встроенная периферия

Светодиоды

У M7 есть один пользовательский 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 управляется через модуль 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()

На M7 датчик припаян к плате — он не находится на сменном модуле.

Карта 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

UART1

P1

P0

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

I2C4

P7

P8

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

P9

TIM4 CH3

Примечание

TIM1 зарезервирован прошивкой для генерации пиксельной тактовой частоты датчика камеры, поэтому каналы TIM1, физически расположенные на P0/P1/P2, нельзя использовать для пользовательского PWM, не нарушив работу камеры.

TIM4 совместно используется с pyb.Servo — создание экземпляра серво перенастраивает весь таймер на работу на 50 Гц, поэтому не смешивайте machine.PWM на P7/P8/P9 с 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 в качестве 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()

Файловая система и порядок загрузки

Прошивка M7 при загрузке монтирует до трёх файловых систем:

  • Внутренняя флеш‑память — всегда монтируется в /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‑накопителя или пишет на него — это индикатор активности, управляемый прошивкой, а не неисправность.

Размеры хранилища

M7 поставляется с:

  • /flash — файловая система FAT 96 КБ, чтение/запись.

  • /rom — отображённая в память ROMFS 256 КБ, только для чтения.

  • /sdcard — полный размер любой вставленной карты microSD (при наличии), чтение/запись.

Индикатор аппаратного сбоя

Если пользовательский RGB‑светодиод быстро перебирает все цвета — настолько быстро, что это обычно выглядит как мерцающий белый светодиод, а не как отдельные оттенки — прошивка столкнулась с неустранимым аппаратным сбоем (hard fault). Перепрошейте прошивку для восстановления; если перепрошивка не помогает, плата может быть физически повреждена.

Программные библиотеки

Полный список модулей — включая те, что уникальны для сборки M7 — см. в индексе библиотек.