OpenMV Cam M7¶
La OpenMV Cam M7 es una placa de visión artificial Cortex‑M7 construida en torno al STMicroelectronics STM32F765 a 216 MHz, con 512 KB de SRAM interna y 2 MB de memoria flash interna. El sensor OV7725 incluido captura fotogramas de 640×480 en escala de grises o de 320×240 en RGB565 a hasta 150 FPS, y el conector de usuario de 10 pines expone periféricos UART, I²C, SPI, CAN, ADC/DAC y PWM.
Para consultar la hoja de datos completa, las fotos y las dimensiones, visita la página del producto OpenMV Cam M7.
Aspectos destacados¶
STMicroelectronics STM32F765 Cortex‑M7 a 216 MHz.
512 KB de SRAM interna — sin SDRAM externa.
2 MB de memoria flash interna (sin memoria flash QSPI externa).
Sensor OV7725 — 640×480 en escala de grises o 320×240 en RGB565 a hasta 150 FPS.
USB de velocidad completa (12 Mb/s) — aparece como VCP + almacenamiento masivo USB ante el host.
Ranura microSD — SD de hasta 2 GB, SDHC de hasta 32 GB, SDXC de hasta 2 TB.
10 pines de E/S, tolerantes a 5 V con salida a 3,3 V, 25 mA por pin (120 mA en total a través del 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 alta potencia de 850 nm para iluminación activa en visión con poca luz.
Nota
La M7 no tiene chip de gestión de energía a bordo: no hay conector de batería, ni cargador de batería, ni ADC de tensión de batería, ni LED de carga / estado de energía, ni botón de encendido por hardware. Alimenta la placa desde USB o VIN.
Distribución de pines¶
Referencia de pines¶
Nombre del pin |
Función |
|---|---|
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 |
conéctalo a GND para reiniciar la placa |
SYN |
pad de sincronización de fotogramas — cableado únicamente al sensor de la cámara |
BOOT0 |
conéctalo a 3,3 V al encender para DFU / gestor de arranque 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 accionan juntos) |
Nota
El pad SYN del conector está conectado directamente a la línea de disparo / exposición del sensor de la cámara — en la M7 no se enruta al MCU. Acciónalo 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 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 más abajo.
VIN — entrada de 3,6 – 5 V. Alimenta la placa a través del regulador a bordo.
GND — tierra común.
Nota
Cuando hay presentes tanto USB como VIN, la fuente con la tensión más alta alimenta la placa — los diodos a bordo simplemente eligen el riel más fuerte.
Advertencia
Puedes alimentar la M7 inyectando 3,3 V directamente en el pin 3.3V si no quieres pasar por el regulador a bordo. 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 batería para modelar cuánto tiempo funcionará la M7 con una batería para un ciclo de trabajo activo / de sueño profundo dado.
Pines de recuperación y depuración¶
RESET — conéctalo a GND para reiniciar la placa. Al soltarlo, el MCU arranca normalmente.
BOOT0 — conéctalo a 3,3 V mientras alimentas la placa para entrar en el gestor de arranque ROM del STM32 (modo DFU). OpenMV IDE usa este modo para reprogramar el gestor de arranque a bordo.
La placa expone un conector de depuración SWD (RST / SWCLK / SWDIO) junto al conector GPIO, compatible con adaptadores ST‑LINK y SEGGER J‑Link.
Periféricos a bordo¶
LED¶
La M7 tiene un único LED RGB de usuario más un par de LED IR de alta potencia de 850 nm:
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 accionan juntos a través del pin
LED_IR.LED_IRestá cableado como activo en alto en hardware, mientras que el firmware trata todos los demás LED a bordo 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 OV7725 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()
En la M7, el sensor está soldado a la placa — no está en un módulo intercambiable.
tarjeta microSD¶
Cuando se inserta una tarjeta, se monta automáticamente en /sdcard y es utilizable a través del sistema de archivos normal:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Referencia de buses¶
GPIO¶
Usa machine.Pin para leer o accionar 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 a través de 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 puede usarse 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¶
Bus |
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 y DAC¶
P6 es el único pin analógico de usuario. Puede usarse 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 de 0 a 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 |
P9 |
TIM4 CH3 |
Nota
TIM1 está reservado por el firmware para generar el reloj de píxeles del sensor de la cámara, por lo que los canales TIM1 que están físicamente en P0/P1/P2 no pueden usarse para PWM de usuario sin afectar a la cámara.
TIM4 se comparte con pyb.Servo — instanciar un servo reconfigura todo el temporizador para funcionar a 50 Hz, así que no mezcles machine.PWM en P7/P8/P9 con pyb.Servo en el mismo script.
Acciona cualquiera de ellos mediante machine.PWM:
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Buses 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 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 a través de 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 del 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 un solo disparo 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 periodo 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 entre 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 puede detenerse ni reconfigurarse — 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 de ejecución¶
Ventana del gestor de arranque USB¶
En cada encendido, la cámara ejecuta un breve gestor de arranque (unos segundos) que permite a OpenMV IDE actualizar el firmware sin que el usuario tenga que entrar en modo DFU. Una vez que 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 a demanda llamando a machine.bootloader():
import machine
machine.bootloader()
Sistema de archivos y orden de arranque¶
El firmware de la M7 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 hay una tarjeta insertada, se monta en
/sdcard.ROMFS — sistema de archivos de solo lectura, mapeado en memoria en
/rom, usado para distribuir grandes recursos de datos (p. ej., modelos de IA) que se benefician del acceso sin copia. MicroPython lo monta automáticamente al inicio, antes de que se ejecute cualquier código Python del usuario.
Tras el montaje, el directorio de trabajo se establece en /sdcard cuando la tarjeta está presente, y en caso 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 completamente la placa.
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, y en caso contrario /flash).
El main.py predeterminado que viene en una placa recién programada simplemente parpadea el canal azul del LED RGB de usuario como latido (dos pulsos cortos, una breve pausa), para que puedas saber que el firmware arrancó correctamente sin ningún host conectado.
sys.path se amplía 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 al sistema a ignorar una tarjeta SD insertada (por ejemplo, para ejecutar el main.py de la memoria flash aun 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, y en caso 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 sistema operativo 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 sistema operativo como la OpenMV Cam escriben en el mismo sistema de archivos al mismo tiempo, el sistema operativo ganará y sobrescribirá los cambios realizados por la cámara. Usa la tarjeta SD para cualquier dato que el script vuelva a escribir, 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 — es un indicador de actividad gestionado por el firmware, no un fallo.
Tamaños de almacenamiento¶
La M7 viene con:
/flash— sistema de archivos FAT de 96 KB, lectura/escritura./rom— ROMFS de solo lectura mapeado en memoria de 256 KB./sdcard— el tamaño completo de la tarjeta microSD que esté insertada (cuando esté presente), lectura/escritura.
Indicador de hard fault¶
Si el LED RGB de usuario está recorriendo rápidamente todos los colores — lo bastante rápido como para que tienda a parecer un LED blanco parpadeante en lugar de tonos distintos — el firmware ha encontrado un hard fault irrecuperable. Reprograma el firmware para recuperarte; si reprogramar no ayuda, la placa puede estar dañada físicamente.
Bibliotecas de software¶
Consulta el índice de bibliotecas para ver la lista completa de módulos — incluyendo cuáles son exclusivos de la versión para la M7.