OpenMV Cam H7 Plus¶
OpenMV Cam H7 Plus는 STMicroelectronics STM32H743(Cortex‑M7 @ 480 MHz)에 32 MB의 외부 SDRAM, 32 MB의 QSPI 플래시, 하드웨어 JPEG 코덱, 그리고 분리형 캐리어에 장착된 OV5640 5MP 카메라 모듈을 결합한 제품입니다. 추가 메모리는 고해상도 캡처와 대용량 이미지 버퍼에 매우 적합합니다.
전체 데이터시트, 사진, 치수는 OpenMV Cam H7 Plus 제품 페이지를 참조하세요.
주요 특징¶
STMicroelectronics STM32H743 Cortex‑M7, 480 MHz(1027 DMIPS).
하드웨어 JPEG 인코더/디코더.
32 MB 외부 SDRAM(32비트 @ 100 MHz, 400 MB/s) 및 1 MB 내부 SRAM.
2 MB 내부 플래시 + 32 MB 외부 QSPI 플래시 (~100 MB/s 읽기).
OV5640 5MP 롤링 셔터 센서.
풀 스피드 USB (12 Mb/s) — 호스트에 VCP + USB 대용량 저장장치로 나타납니다.
microSD 소켓 — SD는 최대 2 GB, SDHC는 최대 32 GB, SDXC는 최대 2 TB.
LiPo 배터리 커넥터 (온보드 충전기 없음 — 충전된 셀을 공급하거나 VIN/USB로 구동하세요).
10개의 I/O 핀, 5 V 허용이며 3.3 V 출력, 핀당 25 mA(헤더 전체 합계 120 mA), 인터럽트 지원. P6은 ADC 또는 DAC 모드에서 사용할 때 5 V를 허용하지 않습니다.
사용자 RGB LED 및 저조도 비전에서 능동 조명을 위한 두 개의 고출력 850 nm IR LED.
참고
H7 Plus에는 온보드 전원 관리 칩이 없습니다. 배터리 충전기, 배터리 전압 ADC, 충전/전원 상태 LED, 하드웨어 전원 버튼이 모두 없습니다. 사전 충전된 LiPo를 배터리 JST에 연결하거나 보드를 USB / VIN으로 구동하세요.
핀아웃¶
핀 레퍼런스¶
핀 이름 |
기능 |
|---|---|
P0 |
UART1 RX / SPI2 MOSI |
P1 |
UART1 TX / SPI2 MISO |
P2 |
SPI2 SCK / FDCAN2 TX |
P3 |
SPI2 NSS (CS) / FDCAN2 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 |
디지털 I/O |
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 패드는 카메라 센서의 트리거 / 노출 라인에 직접 연결되어 있습니다. H7 Plus에서는 MCU로 라우팅되지 않습니다. 외부에서 구동하거나 읽으세요. MicroPython에서는 토글할 수 없습니다.
전원 핀¶
3.3V — 안정화된 3.3 V 레일. 실드에 최대 250 mA를 사용할 수 있습니다(microSD 카드 사용 시 더 적음). 최신 카메라들과 달리 이 핀은 양방향입니다 — 아래 경고를 참조하세요.
VIN — 3.6 – 5 V 입력. 온보드 레귤레이터를 통해 보드에 전원을 공급합니다.
GND — 공통 접지.
3.7 V LiPo 커넥터도 있지만 H7 Plus에는 배터리 충전기가 없습니다. 사전 충전된 셀을 연결하거나 대신 VIN / USB를 공급하세요.
참고
USB와 VIN/LiPo가 모두 연결된 경우 VIN/LiPo 입력이 우선합니다. 온보드 전원 스위치가 USB보다 이를 선택하여 보드에 전원을 공급합니다.
경고
H7 Plus에서는 배터리 커넥터와 VIN이 서로 연결되어 있습니다. LiPo를 연결한 상태에서 VIN을 동시에 인가하지 마세요. 두 전원이 서로 충돌하여 배터리, 보드 또는 둘 다 손상될 수 있습니다.
경고
온보드 레귤레이터를 거치지 않으려면 3.3 V를 3.3V 핀에 직접 공급하여 H7 Plus에 전원을 공급할 수 있습니다. 이 경우 VIN이나 USB 전원을 동시에 인가하지 마세요. 다른 전원이 활성화된 상태에서 레귤레이터를 역구동하면 카메라가 영구적으로 손상되고 파괴될 수 있습니다.
팁
배터리 수명 추정기를 사용하여 주어진 활성 / 딥 슬립 듀티 사이클에서 H7 Plus가 배터리로 얼마나 오래 동작할지 모델링하세요.
복구 및 디버그 핀¶
RESET — GND로 당겨서 보드를 리셋합니다. 이를 놓으면 MCU가 정상적으로 시작됩니다.
BOOT0 — 보드에 전원을 공급하는 동안 3.3 V로 당겨서 STM32 ROM 부트로더(DFU 모드)에 진입합니다. OpenMV IDE는 이 모드를 사용하여 온보드 부트로더를 다시 플래시합니다.
보드는 GPIO 헤더 옆에 SWD 디버그 헤더(RST / SWCLK / SWDIO / SWO)를 제공하며, ST‑LINK 및 SEGGER J‑Link 어댑터와 호환됩니다.
참고
SWO 트레이스 핀은 카메라 헤더의 SPI 클럭 라인과 공유됩니다. SWO는 MCU와 SPI로 통신하는 카메라 모듈(예: FLIR® Lepton® 어댑터 모듈)과 동시에 사용할 수 없습니다. 둘 중 하나만 선택하세요.
온보드 주변장치¶
LED¶
H7 Plus에는 단일 사용자 RGB LED와 한 쌍의 고출력 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 LED — 두 LED는
LED_IR핀을 통해 함께 구동됩니다.LED_IR은 하드웨어에서 액티브 하이로 배선되어 있지만 펌웨어는 다른 모든 온보드 LED를 액티브 로우로 취급합니다. 따라서on()/off()(의미가 반전됨) 대신low()/high()를 사용하세요:from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
카메라 센서¶
OV5640은 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()
OV5640에는 온보드 JPEG 압축기가 내장되어 있습니다. csi.CSI.pixformat 을 csi.JPEG 으로 설정하면 센서가 압축된 프레임을 카메라 버스를 통해 곧바로 카메라로 전달하므로 고해상도 캡처가 실용적이 됩니다: csi.HD (1280×720), csi.FHD (1920×1080), 그리고 전체 5MP인 csi.WQXGA2 (2592×1944)가 모두 JPEG로 스트리밍됩니다. csi.CSI.quality (0-100, 높을수록 = 프레임이 커지고 디테일이 많아짐)로 압축을 조정하세요:
cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)
센서는 분리형 모듈에 장착되어 있습니다. 보드의 나머지 부분을 바꾸지 않고 다른 OpenMV 카메라 모듈(글로벌 셔터, 열화상, 더 높은 해상도 등) 중 하나로 교체할 수 있습니다.
머신 러닝¶
ml — 머신 러닝은 CMSIS‑NN 커널을 사용하여 Cortex‑M7에서 양자화된 TFLite 모델을 실행합니다 — 초당 몇 프레임으로 소형 검출기를 실행할 만큼 충분히 빠릅니다. 읽기 전용 /rom 파일 시스템의 모델은 RAM으로 복사하지 않고 플래시에서 직접 로드됩니다. 다음은 검출된 얼굴과 6개의 랜드마크를 매 프레임에 오버레이하는 128×128 BlazeFace 검출기입니다:
import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace
# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))
# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# faces is a list of ((x, y, w, h), score, keypoints) tuples
for r, score, keypoints in model.predict([img]):
ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)
# keypoints is a ndarray of shape (6, 2)
# 0 - right eye (x, y)
# 1 - left eye (x, y)
# 2 - nose (x, y)
# 3 - mouth (x, y)
# 4 - right ear (x, y)
# 5 - left ear (x, y)
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
print(clock.fps(), "fps")
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 (FDCAN)¶
버스 |
TX |
RX |
|---|---|---|
FDCAN2 |
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 |
참고
TIM1은 카메라 센서의 픽셀 클럭을 생성하기 위해 펌웨어에 의해 예약되어 있으므로, 물리적으로 P0/P1/P2에 있는 TIM1 채널은 카메라를 손상시키지 않고는 사용자 PWM에 사용할 수 없습니다.
TIM4는 pyb.Servo와 공유됩니다 — 서보를 인스턴스화하면 타이머 전체가 50 Hz 동작으로 재구성되므로, 동일한 스크립트에서 P7/P8의 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는 애플리케이션이 멈추면 보드를 리셋합니다. 일단 시작되면 중지하거나 재구성할 수 없으므로, 메인 루프 안에서 주기적으로 피드(feed)하세요:
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()
파일 시스템 및 부트 순서¶
H7 Plus 펌웨어는 부트 시 최대 세 개의 파일 시스템을 마운트합니다:
내부 플래시 — 항상
/flash에 마운트됩니다. 기본적으로main.py와README.txt를 보관하며, 최초 부트 시 생성됩니다.microSD 카드 — 카드가 삽입되어 있으면
/sdcard에 마운트됩니다.ROMFS — 제로 카피 액세스의 이점을 누리는 대용량 데이터 자산(예: AI 모델)을 제공하는 데 사용되는,
/rom의 읽기 전용 메모리 매핑 파일 시스템입니다. 모든 사용자 Python이 실행되기 전, 시작 시 MicroPython에 의해 자동으로 마운트됩니다.
마운트 후, 카드가 있으면 작업 디렉터리가 /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 및 기타 파일을 직접 편집할 수 있습니다. 호스트가 캐시된 쓰기를 플러시하도록 카메라를 리셋하기 전에 드라이브를 꺼내세요(eject).
참고
OS는 드라이브를 수동적인 블록 장치로 취급하므로, OpenMV Cam에서 실행되는 코드가 생성하거나 수정한 파일은 호스트가 드라이브를 다시 마운트할 때까지 나타나지 않습니다. OS와 OpenMV Cam이 동시에 같은 파일 시스템에 쓰면 OS가 우선하여 카메라가 만든 변경 사항을 덮어씁니다. 스크립트가 다시 쓰는 모든 데이터에는 SD 카드를 사용하고, 호스트에서 해당 파일을 읽기 전에 다시 마운트하세요.
참고
호스트가 USB 대용량 저장 드라이브에서 읽거나 쓰는 동안 사용자 RGB LED의 빨강 채널이 잠깐 켜질 수 있습니다. 이는 펌웨어가 구동하는 활동 표시이며 오류가 아닙니다.
저장 용량¶
H7 Plus에는 다음이 기본 제공됩니다:
/flash— 24 MB FAT 파일 시스템, 읽기/쓰기./rom— 8 MB 읽기 전용 메모리 매핑 ROMFS로, 제로 카피 mmap 액세스의 이점을 누리는 스크립트와 ML 모델을 제공하는 데 사용됩니다./sdcard— 삽입된 microSD 카드의 전체 크기(있을 경우), 읽기/쓰기.
하드 폴트 표시기¶
사용자 RGB LED가 모든 색상을 빠르게 순환하고 있다면 — 구분되는 색조라기보다는 반짝이는 흰색 LED처럼 보일 만큼 빠르게 — 펌웨어가 복구 불가능한 하드 폴트에 도달한 것입니다. 복구하려면 펌웨어를 다시 플래시하세요. 다시 플래시해도 도움이 되지 않으면 보드가 물리적으로 손상되었을 수 있습니다.
소프트웨어 라이브러리¶
H7 Plus 빌드에만 고유한 모듈을 포함하여 전체 모듈 목록은 라이브러리 색인을 참조하세요.