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 제품 페이지 를 참조하세요.
주요 특징¶
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으로 보드에 전원을 공급하세요.
핀아웃¶
핀 참조¶
핀 이름 |
기능 |
|---|---|
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)
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 |
P9 |
TIM4 CH3 |
참고
TIM1은 카메라 센서의 픽셀 클록을 생성하기 위해 펌웨어에 의해 예약되어 있으므로, P0/P1/P2에 물리적으로 존재하는 TIM1 채널은 카메라를 손상시키지 않고는 사용자 PWM에 사용할 수 없습니다.
TIM4는 pyb.Servo 와 공유됩니다 — 서보를 인스턴스화하면 타이머 전체가 50 Hz 동작으로 재구성되므로, 같은 스크립트에서 P7/P8/P9의 machine.PWM 과 pyb.Servo 를 혼용하지 마세요.
machine.PWM 을 통해 이들 중 아무거나 구동할 수 있습니다:
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
소프트웨어 비트뱅 버스¶
machine.SoftI2C 와 machine.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.py와README.txt를 담고 있으며 최초 부팅 시 생성됩니다.microSD 카드 — 카드가 삽입되어 있으면
/sdcard에 마운트됩니다.ROMFS —
/rom에 있는 읽기 전용 메모리 매핑 파일 시스템으로, 제로 카피 액세스가 유리한 대용량 데이터 자산(예: AI 모델)을 제공하는 데 사용됩니다. MicroPython이 시작 시 사용자 Python 코드가 실행되기 전에 자동으로 마운트합니다.
마운트 후 작업 디렉터리는 카드가 있으면 /sdcard 로, 그렇지 않으면 /flash 로 설정됩니다. 그런 다음 인터프리터는 해당 디렉터리에서 스크립트를 실행합니다:
boot.py는 모든 소프트 리셋(콜드 부팅, REPL에서Ctrl‑D, 또는 실행 중인 스크립트가 반환될 때마다)에서 실행됩니다.main.py는boot.py직후 콜드 부팅 시에만 실행됩니다. 이후의 소프트 리셋은boot.py를 다시 실행하지만 곧바로 REPL로 진입합니다.main.py를 다시 실행하려면 보드를 완전히 리셋해야 합니다.
SD 카드에 boot.py 나 main.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에는 다음이 함께 제공됩니다:
/flash— 96 KB FAT 파일 시스템, 읽기/쓰기./rom— 256 KB 읽기 전용 메모리 매핑 ROMFS./sdcard— 삽입된 microSD 카드의 전체 크기(있을 때), 읽기/쓰기.
하드 폴트 표시기¶
사용자 RGB LED가 모든 색상을 빠르게 순환하여 — 뚜렷한 색조라기보다 반짝이는 흰색 LED 처럼 보일 정도로 빠르게 — 깜빡이면, 펌웨어가 복구 불가능한 하드 폴트에 도달한 것입니다. 복구하려면 펌웨어를 다시 플래시하세요. 다시 플래시해도 해결되지 않으면 보드가 물리적으로 손상되었을 수 있습니다.
소프트웨어 라이브러리¶
M7 빌드에만 고유한 모듈을 포함한 전체 모듈 목록은 라이브러리 인덱스 를 참조하세요.