OpenMV Cam M7

OpenMV Cam M7은 STMicroelectronics STM32F765를 216 MHz로 구동하고 512 KB의 내부 SRAM과 2 MB의 내부 플래시를 갖춘 Cortex‑M7 기반 머신 비전 보드입니다. 기본 제공되는 OV7725 센서는 640×480 그레이스케일 또는 320×240 RGB565 프레임을 최대 150 FPS로 캡처하며, 10핀 사용자 헤더에는 UART, I²C, SPI, CAN, ADC/DAC, PWM 주변장치가 노출되어 있습니다.

OpenMV Cam M7

전체 데이터시트, 사진, 치수는 OpenMV Cam M7 제품 페이지 를 참조하세요.

주요 특징

  • STMicroelectronics STM32F765 Cortex‑M7, 216 MHz.

  • 512 KB 내부 SRAM — 외부 SDRAM 없음.

  • 2 MB 내부 플래시 (외부 QSPI 플래시 없음).

  • OV7725 센서 — 640×480 그레이스케일 또는 320×240 RGB565, 최대 150 FPS.

  • 풀 스피드 USB (12 Mb/s) — 호스트에 VCP + USB 대용량 저장 장치로 인식됩니다.

  • microSD 소켓 — SD는 최대 2 GB, SDHC는 최대 32 GB, SDXC는 최대 2 TB.

  • 10개의 I/O 핀, 5 V 허용 입력에 3.3 V 출력, 핀당 25 mA(헤더 전체 합계 120 mA), 인터럽트 지원. P6은 ADC 또는 DAC 모드로 사용할 때 5 V 허용이 아닙니다.

  • 저조도 비전을 위한 능동 조명용 사용자 RGB LED 및 두 개의 고출력 850 nm IR LED.

참고

M7에는 온보드 전원 관리 칩이 없습니다. 배터리 커넥터, 배터리 충전기, 배터리 전압 ADC, 충전/전원 상태 LED, 하드웨어 전원 버튼이 모두 없습니다. 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 V로 당기면 DFU / ROM 부트로더 진입

LED_RED

RGB LED 적색 채널 (액티브 로우)

LED_GREEN

RGB LED 녹색 채널 (액티브 로우)

LED_BLUE

RGB LED 청색 채널 (액티브 로우)

LED_IR

고출력 IR LED (두 채널이 함께 구동됨)

참고

헤더의 SYN 패드는 카메라 센서의 트리거 / 노출 라인에 직접 연결되어 있습니다. M7에서는 MCU로 라우팅되지 않습니다. 외부에서 구동하거나 읽어야 하며, MicroPython에서 토글할 수 없습니다.

전원 핀

  • 3.3V — 안정화된 3.3 V 레일. 실드용으로 최대 250 mA 사용 가능(microSD 카드 사용 중이면 더 적음). 최신 카메라와 달리 이 핀은 양방향입니다 — 아래 경고를 참조하세요.

  • VIN — 3.6 – 5 V 입력. 온보드 레귤레이터를 통해 보드에 전원을 공급합니다.

  • GND — 공통 접지.

참고

USB와 VIN이 모두 연결된 경우 전압이 더 높은 쪽이 보드에 전원을 공급합니다 — 온보드 다이오드가 단순히 더 강한 레일을 선택합니다.

경고

온보드 레귤레이터를 거치지 않으려면 3.3V 핀에 직접 3.3 V를 공급하여 M7에 전원을 공급할 수도 있습니다. 이 경우 VIN이나 USB 전원을 동시에 인가하지 마세요 — 다른 전원이 활성화된 상태에서 레귤레이터를 역구동하면 카메라가 영구적으로 손상되고 파괴될 수 있습니다.

배터리 수명 추정기 를 사용하면 지정한 활성 / 딥 슬립 듀티 사이클에서 M7이 배터리로 얼마나 오래 작동할지 모델링할 수 있습니다.

복구 및 디버그 핀

  • RESET — GND로 당겨 보드를 리셋합니다. 다시 놓으면 MCU가 정상적으로 시작됩니다.

  • BOOT0 — 보드에 전원을 공급하는 동안 3.3 V로 당기면 STM32 ROM 부트로더(DFU 모드)에 진입합니다. OpenMV IDE는 이 모드를 사용하여 온보드 부트로더를 다시 플래시합니다.

보드에는 GPIO 헤더 옆에 ST‑LINK 및 SEGGER J‑Link 어댑터와 호환되는 SWD 디버그 헤더(RST / SWCLK / SWDIO)가 노출되어 있습니다.

온보드 주변장치

LED

M7에는 사용자 RGB LED 1개와 고출력 850 nm IR 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()
    
  • IR LEDs — 두 LED는 모두 LED_IR 핀을 통해 함께 구동됩니다. LED_IR 는 하드웨어에서 액티브 하이(active high) 로 배선되어 있는 반면 펌웨어는 그 외의 모든 온보드 LED를 액티브 로우(active low)로 취급하므로, on() / off() (이 경우 의미가 반전됩니다) 대신 low() / high() 를 사용하십시오:

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

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

동일한 하드웨어는 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 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)
    
  • DACpyb.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

P9

TIM4 CH3

참고

TIM1은 카메라 센서의 픽셀 클록을 생성하기 위해 펌웨어에 의해 예약되어 있으므로, P0/P1/P2에 물리적으로 존재하는 TIM1 채널은 카메라를 손상시키지 않고는 사용자 PWM에 사용할 수 없습니다.

TIM4는 pyb.Servo 와 공유됩니다 — 서보를 인스턴스화하면 타이머 전체가 50 Hz 동작으로 재구성되므로, 같은 스크립트에서 P7/P8/P9의 machine.PWMpyb.Servo 를 혼용하지 마세요.

machine.PWM 을 통해 이들 중 아무거나 구동할 수 있습니다:

from machine import Pin, PWM

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

소프트웨어 비트뱅 버스

machine.SoftI2Cmachine.SoftSPI 는 추가 버스가 필요할 때 모든 GPIO에서 동작합니다.

열화상 센서 (보드 외부)

펌웨어에는 외부에 배선된 열화상 이미저용 fir — 열 센서 드라이버 (fir == far infrared, 원적외선) 드라이버가 포함되어 있습니다:

  • MLX90621 — 16 × 4 IR 어레이

  • MLX90640 — 32 × 24 IR 어레이

  • MLX90641 — 16 × 12 IR 어레이

  • AMG8833 — 8 × 8 IR 어레이

모듈을 보드의 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 는 하드웨어 타이머 슬롯을 소비하지 않고 주기적 또는 일회성 콜백을 스케줄링합니다. 가상(소프트웨어) 타이머를 사용하려면 id로 -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 부트로더 창

전원이 켜질 때마다 카메라는 짧은(몇 초) 부트로더를 실행하여 사용자가 DFU 모드에 진입하지 않고도 OpenMV IDE가 펌웨어를 업데이트할 수 있게 합니다. 이 창이 만료되면 부트로더는 boot.py 로, 이어서 main.py 로 제어를 넘깁니다.

실행 중인 스크립트는 machine.bootloader() 를 호출하여 필요할 때 부트로더에 다시 진입할 수 있습니다:

import machine

machine.bootloader()

파일 시스템 및 부팅 순서

M7 펌웨어는 부팅 시 최대 세 개의 파일 시스템을 마운트합니다:

  • 내부 플래시 — 항상 /flash 에 마운트됩니다. 기본적으로 main.pyREADME.txt 를 담고 있으며 최초 부팅 시 생성됩니다.

  • microSD 카드 — 카드가 삽입되어 있으면 /sdcard 에 마운트됩니다.

  • ROMFS/rom 에 있는 읽기 전용 메모리 매핑 파일 시스템으로, 제로 카피 액세스가 유리한 대용량 데이터 자산(예: AI 모델)을 제공하는 데 사용됩니다. MicroPython이 시작 시 사용자 Python 코드가 실행되기 전에 자동으로 마운트합니다.

마운트 후 작업 디렉터리는 카드가 있으면 /sdcard 로, 그렇지 않으면 /flash 로 설정됩니다. 그런 다음 인터프리터는 해당 디렉터리에서 스크립트를 실행합니다:

  • boot.py모든 소프트 리셋(콜드 부팅, REPL에서 Ctrl‑D, 또는 실행 중인 스크립트가 반환될 때마다)에서 실행됩니다.

  • main.pyboot.py 직후 콜드 부팅 시에만 실행됩니다. 이후의 소프트 리셋은 boot.py 를 다시 실행하지만 곧바로 REPL로 진입합니다. main.py 를 다시 실행하려면 보드를 완전히 리셋해야 합니다.

SD 카드에 boot.pymain.py 를 넣으면 플래시의 사본을 건드리지 않고 재정의합니다 — 두 파일 모두 부팅 디렉터리(카드가 마운트되어 있으면 /sdcard, 그렇지 않으면 /flash)에서 조회됩니다.

갓 플래시된 보드에 기본으로 제공되는 main.py 는 사용자 RGB LED의 청색 채널을 하트비트로 깜빡이기만 합니다(짧은 펄스 두 번, 짧은 간격). 따라서 호스트가 연결되지 않아도 펌웨어가 정상적으로 부팅되었는지 알 수 있습니다.

sys.path 는 세 파일 시스템 모두와 각각의 lib/ 하위 디렉터리를 포함하도록 확장되므로, 임포트 가능한 모듈을 /flash/lib, /sdcard/lib, /rom/lib 에 둘 수 있습니다.

삽입된 SD 카드를 시스템이 무시하도록 강제하려면(예: 카드가 있어도 플래시의 main.py 를 실행하려면) /flash 의 루트에 SKIPSD 라는 빈 파일을 만드세요.

USB로 연결되면 부팅 파일 시스템(카드가 있으면 /sdcard, 그렇지 않으면 /flash)도 호스트에 USB 대용량 저장 드라이브로 열거되어 boot.py, main.py 및 기타 파일을 직접 편집할 수 있습니다. 카메라를 리셋하기 전에 드라이브를 안전하게 제거하여 호스트가 캐시된 쓰기를 플러시하도록 하세요.

참고

OS가 드라이브를 수동 블록 장치로 취급하기 때문에 OpenMV Cam에서 실행되는 코드가 생성하거나 수정한 파일은 호스트가 드라이브를 다시 마운트할 때까지 표시되지 않습니다. OS와 OpenMV Cam이 동시에 같은 파일 시스템에 쓰면 OS가 우선하여 카메라가 변경한 내용을 덮어씁니다. 스크립트가 다시 기록하는 데이터에는 SD 카드를 사용하고, 호스트에서 해당 파일을 읽기 전에 다시 마운트하세요.

참고

호스트가 USB 대용량 저장 드라이브에서 읽거나 쓰는 동안 사용자 RGB LED의 적색 채널이 잠깐 켜질 수 있습니다 — 이는 펌웨어가 구동하는 활동 표시기이며 오류가 아닙니다.

저장소 크기

M7에는 다음이 함께 제공됩니다:

  • /flash96 KB FAT 파일 시스템, 읽기/쓰기.

  • /rom256 KB 읽기 전용 메모리 매핑 ROMFS.

  • /sdcard — 삽입된 microSD 카드의 전체 크기(있을 때), 읽기/쓰기.

하드 폴트 표시기

사용자 RGB LED가 모든 색상을 빠르게 순환하여 — 뚜렷한 색조라기보다 반짝이는 흰색 LED 처럼 보일 정도로 빠르게 — 깜빡이면, 펌웨어가 복구 불가능한 하드 폴트에 도달한 것입니다. 복구하려면 펌웨어를 다시 플래시하세요. 다시 플래시해도 해결되지 않으면 보드가 물리적으로 손상되었을 수 있습니다.

소프트웨어 라이브러리

M7 빌드에만 고유한 모듈을 포함한 전체 모듈 목록은 라이브러리 인덱스 를 참조하세요.