OpenMV Cam H7 Plus¶
La OpenMV Cam H7 Plus combina el STMicroelectronics STM32H743 (Cortex‑M7 @ 480 MHz) con 32 MB de SDRAM externa, 32 MB de memoria flash QSPI, un códec JPEG por hardware y el módulo de cámara OV5640 de 5MP sobre un soporte extraíble. La memoria adicional es ideal para la captura de alta resolución y los búferes de imagen grandes.
Para consultar la hoja de datos completa, fotos y dimensiones, visita la página del producto OpenMV Cam H7 Plus.
Aspectos destacados¶
STMicroelectronics STM32H743 Cortex‑M7 a 480 MHz (1027 DMIPS).
Codificador/decodificador JPEG por hardware.
32 MB de SDRAM externa (32 bits @ 100 MHz, 400 MB/s) más 1 MB de SRAM interna.
2 MB de memoria flash interna + 32 MB de memoria flash QSPI externa (~100 MB/s de lectura).
Sensor de obturador rodante OV5640 de 5MP.
USB de velocidad completa (12 Mb/s) — aparece como VCP + almacenamiento masivo USB ante el host.
Ranura microSD — SD hasta 2 GB, SDHC hasta 32 GB, SDXC hasta 2 TB.
Conector de batería LiPo (sin cargador integrado — suministra una celda cargada o aliméntala desde VIN/USB).
10 pines de E/S, tolerantes a 5 V con salida de 3,3 V, 25 mA por pin (120 mA en total en el conector), con capacidad de interrupción. P6 no es tolerante a 5 V cuando se usa en modo ADC o DAC.
LED RGB de usuario y dos LED IR de 850 nm de alta potencia para iluminación activa en visión con poca luz.
Nota
La H7 Plus no tiene chip de gestión de energía integrado: no hay cargador de batería, ni ADC de voltaje de batería, ni LED de carga / estado de energía, ni botón de encendido por hardware. Conecta una LiPo precargada al JST de batería o alimenta la placa desde USB / VIN.
Disposición de pines (pinout)¶
Referencia de pines¶
Nombre del pin |
Función |
|---|---|
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 |
E/S digital |
RESET |
conecta a GND para reiniciar la placa |
SYN |
pad de sincronización de fotograma (frame‑sync) — cableado únicamente al sensor de la cámara |
BOOT0 |
conecta a 3,3 V al encender para DFU / gestor de arranque (bootloader) en ROM |
LED_RED |
canal rojo del LED RGB (activo en bajo) |
LED_GREEN |
canal verde del LED RGB (activo en bajo) |
LED_BLUE |
canal azul del LED RGB (activo en bajo) |
LED_IR |
LED IR de alta potencia (ambos canales se controlan juntos) |
Nota
El pad SYN del conector está conectado directamente a la línea de disparo / exposición del sensor de la cámara — no se enruta al MCU en la H7 Plus. Contrólalo o léelo externamente; no puedes conmutarlo desde MicroPython.
Pines de alimentación¶
3.3V — riel regulado de 3,3 V. Hasta 250 mA disponibles para los shields (menos si la tarjeta microSD está en uso). A diferencia de las cámaras más nuevas, este pin es bidireccional — consulta la advertencia a continuación.
VIN — entrada de 3,6 – 5 V. Alimenta la placa a través del regulador integrado.
GND — tierra común.
También hay presente un conector LiPo de 3,7 V, pero la H7 Plus no tiene cargador de batería — conecta una celda precargada o suministra VIN / USB en su lugar.
Nota
Cuando hay presentes tanto USB como VIN/LiPo, gana la entrada VIN/LiPo — el conmutador de energía integrado la elige por encima de USB para alimentar la placa.
Advertencia
El conector de batería y VIN están unidos entre sí en la H7 Plus. No conectes una LiPo y apliques VIN al mismo tiempo — las dos fuentes competirán entre sí y pueden dañar la batería, la placa o ambas.
Advertencia
Puedes alimentar la H7 Plus inyectando 3,3 V directamente en el pin 3.3V si no quieres pasar por el regulador integrado. En ese caso, no apliques también VIN o alimentación USB al mismo tiempo — retroalimentar el regulador mientras otra fuente está activa puede dañar y destruir la cámara de forma permanente.
Truco
Usa el estimador de duración de la batería para modelar cuánto tiempo funcionará la H7 Plus con una batería para un ciclo de trabajo activo / sueño profundo determinado.
Pines de recuperación y depuración¶
RESET — conecta a GND para reiniciar la placa. Al soltarlo, el MCU arranca normalmente.
BOOT0 — conecta a 3,3 V mientras alimentas la placa para entrar en el gestor de arranque (bootloader) en ROM del STM32 (modo DFU). OpenMV IDE usa este modo para reflashear el gestor de arranque integrado.
La placa expone un conector de depuración SWD (RST / SWCLK / SWDIO / SWO) junto al conector GPIO, compatible con adaptadores ST‑LINK y SEGGER J‑Link.
Nota
El pin de traza SWO se comparte con la línea de reloj SPI del conector de la cámara. SWO no se puede usar al mismo tiempo que ningún módulo de cámara que se comunique con el MCU por SPI — por ejemplo el Módulo Adaptador FLIR® Lepton® — elige uno u otro.
Periféricos integrados¶
LED¶
La H7 Plus tiene un único LED RGB de usuario más un par de LED IR de 850 nm de alta potencia:
LED RGB de usuario — controlable por software, expuesto como
LED_RED,LED_GREENyLED_BLUE:from machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
LED IR — ambos LED se controlan juntos a través del pin
LED_IR.LED_IRestá cableado activo en alto en el hardware, mientras que el firmware trata todos los demás LED integrados como activos en bajo, así que usalow()/high()en lugar deon()/off()(que invertirían el sentido):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Sensor de la cámara¶
El OV5640 se controla a través del módulo csi — sensores de cámara:
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()
El OV5640 tiene un compresor JPEG integrado. Configura csi.CSI.pixformat a csi.JPEG y el sensor entrega fotogramas comprimidos directamente a la cámara a través del bus de la cámara, lo que hace prácticas las capturas de alta resolución: csi.HD (1280×720), csi.FHD (1920×1080) y los 5MP completos csi.WQXGA2 (2592×1944) se transmiten todos como JPEG. Ajusta la compresión con csi.CSI.quality (0-100, mayor = fotogramas más grandes, más detalle):
cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)
El sensor está montado sobre un módulo extraíble — cámbialo por cualquiera de los otros módulos de cámara de OpenMV (obturador global, térmico, mayor resolución, etc.) sin modificar el resto de la placa.
Aprendizaje automático¶
ml — Aprendizaje automático ejecuta modelos TFLite cuantizados en el Cortex‑M7 con kernels CMSIS‑NN — lo bastante rápido para detectores compactos a unos pocos fotogramas por segundo. Los modelos en el sistema de archivos de solo lectura /rom se cargan directamente desde la memoria flash sin copiar a la RAM. Aquí tienes un detector BlazeFace de 128×128 que superpone el rostro detectado y sus seis puntos de referencia en cada fotograma:
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")
tarjeta microSD¶
Cuando se inserta una tarjeta, se monta automáticamente en /sdcard y se puede usar a través del sistema de archivos habitual:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Referencia de buses¶
GPIO¶
Usa machine.Pin para leer o controlar cualquiera de los pines serigrafiados. Las salidas son CMOS de 3,3 V, tolerantes a 5 V en el lado de entrada, y pueden absorber/suministrar hasta 25 mA por pin (120 mA en total en todo el conector).
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())
Cualquier pin de entrada también puede disparar una interrupción en las transiciones de borde:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Bus |
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¶
Bus |
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")
El mismo hardware también se puede usar en modo destino (esclavo) a través de machine.I2CTarget para exponer una región de memoria a otro controlador I²C:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)
SPI¶
Bus |
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)¶
Bus |
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 y DAC¶
P6 es el único pin analógico de usuario. Se puede usar como entrada ADC de 12 bits o como salida DAC.
ADC — fondo de escala a 3,3 V en el pin:
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 — a través de
pyb.DAC. El valor de 8 bits cubre 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
En modo ADC o DAC, P6 es tolerante solo a 3,3 V — no le apliques 5 V.
PWM¶
Pin |
Temporizador / canal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Nota
TIM1 está reservado por el firmware para generar el reloj de píxel del sensor de la cámara, por lo que los canales de TIM1 que físicamente están en P0/P1/P2 no se pueden usar para PWM de usuario sin afectar a la cámara.
TIM4 se comparte con pyb.Servo — instanciar un servo reconfigura todo el temporizador para funcionamiento a 50 Hz, así que no mezcles machine.PWM en P7/P8 con pyb.Servo en el mismo script.
Controla cualquiera de ellos mediante machine.PWM:
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Buses emulados por software (bit‑banged)¶
machine.SoftI2C y machine.SoftSPI funcionan en cualquier GPIO si necesitas un bus adicional.
Sensor térmico (externo)¶
El firmware incluye el controlador fir — controlador de sensor térmico (fir == infrarrojo lejano) para cámaras térmicas cableadas externamente:
MLX90621 — matriz IR de 16 × 4
MLX90640 — matriz IR de 32 × 24
MLX90641 — matriz IR de 16 × 12
AMG8833 — matriz IR de 8 × 8
Cablea el módulo al bus I²C de la placa y lee los fotogramas con 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())
El controlador fir solo se comunica con el sensor por I²C 2 — cablea el módulo a P4 (SCL) y P5 (SDA).
Temporización¶
time¶
El módulo time cubre los retardos bloqueantes, los ticks monotónicos y la medición de tiempo transcurrido:
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)
Temporizadores virtuales¶
machine.Timer programa funciones de retorno (callbacks) periódicas o de una sola vez sin consumir una ranura de temporizador por hardware. Pasa -1 como id para usar un temporizador virtual (por software):
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"))
Los valores de período están en milisegundos. Llama a deinit() para detener y liberar la ranura.
Reloj en tiempo real¶
machine.RTC mantiene la hora del reloj de pared a través de los reinicios:
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())
Watchdog¶
machine.WDT reinicia la placa si la aplicación se cuelga. Una vez iniciado, no se puede detener ni reconfigurar — aliméntalo periódicamente dentro de tu bucle principal:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Información de arranque y ejecución¶
Ventana del gestor de arranque (bootloader) USB¶
En cada encendido, la cámara ejecuta un breve gestor de arranque (bootloader) (unos pocos segundos) que permite a OpenMV IDE actualizar el firmware sin que el usuario tenga que entrar en modo DFU. Cuando expira la ventana, el gestor de arranque cede el control a boot.py y luego a main.py.
Un script en ejecución puede volver a entrar en el gestor de arranque (bootloader) bajo demanda llamando a machine.bootloader():
import machine
machine.bootloader()
Sistema de archivos y orden de arranque¶
El firmware de la H7 Plus monta hasta tres sistemas de archivos en el arranque:
Memoria flash interna — siempre montada en
/flash. Contienemain.pyyREADME.txtde forma predeterminada; se crea en el primer arranque.Tarjeta microSD — si se inserta una tarjeta, se monta en
/sdcard.ROMFS — sistema de archivos de solo lectura, mapeado en memoria, en
/rom, usado para distribuir grandes activos de datos (p. ej. modelos de IA) que se benefician del acceso sin copia (zero‑copy). MicroPython lo monta automáticamente al inicio, antes de que se ejecute cualquier código Python de usuario.
Tras el montaje, el directorio de trabajo se establece en /sdcard cuando la tarjeta está presente, de lo contrario en /flash. El intérprete ejecuta entonces los scripts desde ese directorio:
boot.pyse ejecuta en cada reinicio en caliente (arranque en frío,Ctrl‑Ddesde el REPL, o cada vez que el script en ejecución retorna).main.pyse ejecuta solo en el arranque en frío, inmediatamente después deboot.py. Los reinicios en caliente posteriores vuelven a ejecutarboot.pypero pasan directamente al REPL — para volver a ejecutarmain.pytienes que reiniciar la placa por completo.
Colocar un boot.py o main.py en la tarjeta SD anula la copia en la memoria flash sin tocarla — ambos archivos se buscan en el directorio de arranque (/sdcard cuando la tarjeta está montada, de lo contrario /flash).
El main.py predeterminado que viene en una placa recién flasheada simplemente parpadea el canal azul del LED RGB de usuario como latido (dos pulsos cortos, una breve pausa), de modo que puedas saber que el firmware arrancó correctamente sin ningún host conectado.
sys.path se extiende para incluir los tres sistemas de archivos y sus subdirectorios lib/, de modo que los módulos importables pueden residir en /flash/lib, /sdcard/lib o /rom/lib.
Para forzar que el sistema ignore una tarjeta SD insertada (por ejemplo, para ejecutar el main.py de la memoria flash incluso con una tarjeta presente), crea un archivo vacío llamado SKIPSD en la raíz de /flash.
Cuando está conectada por USB, el sistema de archivos de arranque (/sdcard si hay una tarjeta presente, de lo contrario /flash) también se enumera como una unidad de almacenamiento masivo USB en el host, lo que te permite editar boot.py, main.py y cualquier otro archivo directamente. Expulsa la unidad antes de reiniciar la cámara para que el host vacíe sus escrituras en caché.
Nota
Dado que el SO trata la unidad como un dispositivo de bloques pasivo, los archivos creados o modificados por el código que se ejecuta en la OpenMV Cam no aparecerán hasta que el host vuelva a montar la unidad. Si tanto el SO como la OpenMV Cam escriben en el mismo sistema de archivos al mismo tiempo, el SO ganará y sobrescribirá los cambios hechos por la cámara. Usa la tarjeta SD para cualquier dato que el script escriba de vuelta, y vuelve a montar antes de leer esos archivos desde el host.
Nota
El canal rojo del LED RGB de usuario puede encenderse brevemente mientras el host lee o escribe en la unidad de almacenamiento masivo USB — esto es un indicador de actividad gestionado por el firmware, no un fallo.
Tamaños de almacenamiento¶
La H7 Plus viene con:
/flash— sistema de archivos FAT de 24 MB, lectura/escritura./rom— ROMFS de 8 MB de solo lectura mapeado en memoria, usado para distribuir scripts y modelos de ML que se benefician del acceso mmap sin copia (zero‑copy)./sdcard— el tamaño completo de la tarjeta microSD que esté insertada (cuando está presente), lectura/escritura.
Indicador de fallo grave (hard fault)¶
Si el LED RGB de usuario cicla rápidamente a través de todos los colores — lo bastante rápido como para parecer un LED blanco titilante en lugar de tonos distintos — el firmware ha encontrado un fallo grave (hard fault) irrecuperable. Reflashea el firmware para recuperarte; si reflashear no ayuda, puede que la placa esté dañada físicamente.
Bibliotecas de software¶
Consulta el índice de la biblioteca para ver la lista completa de módulos — incluyendo cuáles son exclusivos de la versión de la H7 Plus.