OpenMV Cam M4¶
A OpenMV Cam M4 é uma placa compacta de visão por computador Cortex‑M4 construída em torno do STMicroelectronics STM32F427 a 180 MHz com 256 KB de SRAM interna e 1 MB de flash interna. O sensor OV7725 incluído captura fotogramas em escala de cinzentos 320×240 ou RGB565, e o conector de utilizador de 9 pinos expõe periféricos UART, I²C, SPI, CAN, ADC/DAC e PWM.
Nota
O OV7725 era o sensor padrão nas placas M4 de produção. Variantes muito iniciais da M4 foram fornecidas com o OmniVision OV2640 — o mesmo pipeline de pré-visualização QVGA, mas o OV2640 também pode capturar fotogramas JPEG até UXGA (1600×1200). Ambos os sensores são controlados através da mesma API csi — sensores de câmara.
Para ficha técnica completa, fotografias e dimensões, consulte a página de produto OpenMV Cam M4.
Destaques¶
STMicroelectronics STM32F427 Cortex‑M4 a 180 MHz.
256 KB de SRAM interna — sem SDRAM externa.
1 MB de flash interna (sem flash QSPI externa).
Sensor OV7725 (ou OV2640 em variantes muito iniciais da M4) — escala de cinzentos de 8 bits 320×240 ou RGB565; o OV2640 pode adicionalmente capturar até UXGA (1600×1200) JPEG.
USB full‑speed (12 Mb/s) — aparece como VCP + armazenamento de massa USB para o anfitrião.
Conector microSD — SD até 2 GB, SDHC até 32 GB, SDXC até 2 TB.
9 pinos de E/S, tolerantes a 5 V com saída a 3,3 V, 25 mA por pino (120 mA no total pelo conector), com capacidade de interrupção. P6 não é tolerante a 5 V quando utilizado em modo ADC ou DAC.
LED RGB de utilizador e dois LEDs IR de 850 nm de alta potência para iluminação ativa em visão com pouca luz.
Nota
A M4 não possui chip de gestão de energia a bordo: não há conector de bateria, carregador de bateria, ADC de tensão de bateria, LEDs de estado de carga/energia, nem botão de alimentação por hardware. Alimente a placa a partir de USB ou VIN.
Diagrama de pinos¶
Referência de pinos¶
Nome do pino |
Função |
|---|---|
P0 |
SPI2 MOSI |
P1 |
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 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
RESET |
ligar a GND para reiniciar a placa |
BOOT0 |
ligar a 3,3 V na alimentação para DFU / bootloader de ROM |
SWCLK |
relógio ARM SWD (acesso do depurador) |
SWDIO |
dados ARM SWD (acesso do depurador) |
LED_RED |
canal vermelho do LED RGB (ativo baixo) |
LED_GREEN |
canal verde do LED RGB (ativo baixo) |
LED_BLUE |
canal azul do LED RGB (ativo baixo) |
LED_IR |
LEDs IR de alta potência (ambos os canais acionados em conjunto) |
Pinos de alimentação¶
3.3V — barramento regulado de 3,3 V. Até 250 mA disponíveis para módulos de expansão (menos se o cartão microSD estiver em uso). Ao contrário das câmaras mais recentes, este pino é bidirecional — consulte o aviso abaixo.
VIN — entrada de 3,6 – 5 V. Alimenta a placa através do regulador a bordo.
GND — terra comum.
Nota
Quando USB e VIN estão presentes simultaneamente, o que tiver tensão mais alta alimenta a placa — os díodos a bordo selecionam simplesmente o barramento mais forte.
Aviso
Pode alimentar a M4 fornecendo 3,3 V diretamente no pino 3.3V se não pretender passar pelo regulador a bordo. Nesse caso, não aplique VIN ou alimentação USB ao mesmo tempo — acionar o regulador em sentido inverso enquanto outra fonte está ativa pode danificar e destruir permanentemente a câmara.
Dica
Utilize o estimador de autonomia de bateria para modelar durante quanto tempo a M4 funcionará com uma bateria para um determinado ciclo de ativo/sono profundo.
Pinos de recuperação e depuração¶
RESET — ligar a GND para reiniciar a placa. Ao libertar, o MCU arranca normalmente.
BOOT0 — ligar a 3,3 V ao alimentar a placa para entrar no bootloader de ROM do STM32 (modo DFU). O OpenMV IDE utiliza este modo para reflashear o bootloader a bordo.
SWCLK e SWDIO estão expostos como pinos de conector comuns (não como um conector SWD dedicado). Ligue RESET, SWCLK, SWDIO, GND e 3,3 V a um adaptador ST‑LINK ou SEGGER J‑Link para depurar a placa.
Periféricos a bordo¶
LEDs¶
A M4 possui um único LED RGB de utilizador mais um par de LEDs IR de 850 nm de alta potência:
LED RGB de utilizador — controlável por software, exposto como
LED_RED,LED_GREENeLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
LEDs IR — ambos os LEDs são acionados em conjunto através do pino
LED_IR. OLED_IRestá ligado em ativo alto por hardware, enquanto o firmware trata todos os outros LEDs a bordo como ativo baixo, por isso uselow()/high()em vez deon()/off()(que inverteriam o sentido):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Sensor da câmara¶
O sensor incluído (OV7725 nas placas padrão, OV2640 em variantes muito iniciais) é controlado através do 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()
O sensor está soldado à placa na M4 — não se encontra num módulo amovível.
Nota
Nas placas OV7725, o pino FSIN (sincronização de fotograma) do sensor está ligado ao MCU, mas o suporte de firmware para o mesmo ainda não foi adicionado.
Nas placas OV2640, os pinos STROBE, FREX (exposição de fotograma) e EXPST (reposição de exposição) do sensor estão ligados ao MCU, mas o suporte de firmware para os mesmos ainda não foi adicionado.
Conectores de servo¶
O lado traseiro da placa possui dois pads de solda para conector de servo que expõem o conector de servo padrão de 3 pinos (sinal / VIN / GND) para P7 e P8. Os pinos de sinal mapeiam diretamente para os canais 1 e 2 do TIM4 (os mesmos canais utilizados por pyb.Servo), e o pino V+ em cada conector está ligado diretamente a VIN, por isso os servos retiram a sua corrente do barramento de entrada em vez do regulador de 3,3 V.
Solde um par de conectores de 3 pinos em ângulo reto nos pads e ligue dois servos de hobby para acionar um suporte pan‑and‑tilt:
from pyb import Servo
pan = Servo(1) # P7 — TIM4 CH1
tilt = Servo(2) # P8 — TIM4 CH2
pan.angle(0)
tilt.angle(0)
Cartão microSD¶
Quando um cartão é inserido, é montado automaticamente em /sdcard e está disponível através do sistema de ficheiros normal:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Referência de barramentos¶
GPIO¶
Use machine.Pin para ler ou acionar qualquer um dos pinos impressos na placa. As saídas são CMOS a 3,3 V, tolerantes a 5 V no lado de entrada, e podem afundar/fornecer até 25 mA por pino (120 mA no total pelo conector inteiro).
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())
Qualquer pino de entrada também pode disparar uma interrupção em transições de flanco:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Barramento |
TX |
RX |
|---|---|---|
UART3 |
P4 |
P5 |
from machine import UART
uart = UART(3, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
Barramento |
SCL |
SDA |
|---|---|---|
I2C2 |
P4 |
P5 |
from machine import I2C
i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
O mesmo hardware também pode ser usado em modo alvo (escravo) através de machine.I2CTarget para expor uma região de memória a outro controlador I²C:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)
SPI¶
Barramento |
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¶
Barramento |
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 e DAC¶
P6 é o único pino analógico de utilizador. Pode ser usado como entrada ADC de 12 bits ou como saída DAC.
ADC — escala completa a 3,3 V no pino:
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 — através de
pyb.DAC. O valor de 8 bits cobre 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
Em modo ADC ou DAC, P6 é tolerante apenas a 3,3 V — não lhe aplique 5 V.
PWM¶
Pino |
Temporizador / canal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Nota
TIM1 está reservado pelo firmware para gerar o relógio de pixel do sensor da câmara, pelo que os canais do TIM1 que estão fisicamente em P0/P1/P2 não podem ser usados para PWM de utilizador sem quebrar a câmara.
TIM4 é partilhado com pyb.Servo — instanciar um servo reconfigura o temporizador inteiro para operação a 50 Hz, por isso não misture machine.PWM em P7/P8 com pyb.Servo no mesmo script.
Acione qualquer um deles via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Barramentos por software (bit‑banging)¶
machine.SoftI2C e machine.SoftSPI funcionam em qualquer GPIO se necessitar de um barramento adicional.
Sensor térmico (externo)¶
O firmware inclui o controlador fir — driver de sensor térmico (fir == infravermelho longínquo) para imagiadores térmicos ligados 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
Ligue o módulo ao barramento I²C da placa e leia fotogramas com 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())
O controlador fir apenas comunica com o sensor através de I²C 2 — ligue o módulo a P4 (SCL) e P5 (SDA).
Temporização¶
time¶
O módulo time cobre atrasos bloqueantes, ticks monotónicos e medição de tempo decorrido:
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 virtuais¶
machine.Timer agenda callbacks periódicos ou de disparo único sem consumir um slot de temporizador por hardware. Passe -1 como id para usar um 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"))
Os valores de período estão em milissegundos. Chame deinit() para parar e libertar o slot.
Relógio de tempo real¶
machine.RTC mantém a hora do relógio entre reinicializações:
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 a placa se a aplicação travar. Uma vez iniciado, não pode ser parado nem reconfigurado — alimente‑o periodicamente dentro do ciclo principal:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Arranque e informação de execução¶
Janela do bootloader USB¶
Em cada arranque, a câmara executa um bootloader curto (alguns segundos) que permite ao OpenMV IDE atualizar o firmware sem que o utilizador tenha de entrar no modo DFU. Após o término da janela, o bootloader passa o controlo para boot.py e depois para main.py.
Um script em execução pode voltar a entrar no bootloader sob pedido chamando machine.bootloader()
import machine
machine.bootloader()
Sistema de ficheiros e ordem de arranque¶
O firmware da M4 monta até três sistemas de ficheiros no arranque:
Flash interna — montada sempre em
/flash. Contémmain.pyeREADME.txtpor defeito; criada no primeiro arranque.Cartão microSD — se um cartão estiver inserido, é montado em
/sdcard.ROMFS — sistema de ficheiros ROMFS mapeado em memória e só de leitura em
/rom, usado para distribuir grandes recursos de dados (por exemplo, modelos de IA) que beneficiam de acesso sem cópia. Montado automaticamente pelo MicroPython no arranque, antes de qualquer código Python do utilizador ser executado.
Após a montagem, o diretório de trabalho é definido para /sdcard quando o cartão está presente, caso contrário para /flash. O interpretador executa então scripts a partir desse diretório:
boot.pyé executado em todas as reinicializações suaves (arranque a frio,Ctrl‑Da partir do REPL, ou sempre que o script em execução termina).main.pyé executado apenas no arranque a frio, imediatamente apósboot.py. Reinicializações suaves subsequentes re-executamboot.pymas passam diretamente para o REPL — para re-executarmain.pyé necessário reiniciar completamente a placa.
Colocar um boot.py ou main.py no cartão SD substitui a cópia em flash sem a modificar — ambos os ficheiros são procurados no diretório de arranque (/sdcard quando o cartão está montado, caso contrário /flash).
O main.py padrão fornecido numa placa recém-flashada apenas faz piscar o canal azul do LED RGB de utilizador como batimento cardíaco (dois pulsos curtos, pausa curta), para que se possa verificar que o firmware arrancou corretamente sem qualquer anfitrião ligado.
sys.path é expandido para incluir os três sistemas de ficheiros e os seus subdiretórios lib/, de modo que os módulos importáveis podem residir em /flash/lib, /sdcard/lib ou /rom/lib.
Para forçar o sistema a ignorar um cartão SD inserido (por exemplo, para executar o main.py da flash mesmo com um cartão presente), crie um ficheiro vazio com o nome SKIPSD na raiz de /flash.
Quando ligado via USB, o sistema de ficheiros de arranque (/sdcard se um cartão estiver presente, caso contrário /flash) também é enumerado como uma unidade de armazenamento de massa USB no anfitrião, permitindo editar diretamente boot.py, main.py e quaisquer outros ficheiros. Ejete a unidade antes de reiniciar a câmara para que o anfitrião sincronize as escritas em cache.
Nota
Como o sistema operativo trata a unidade como um dispositivo de blocos passivo, os ficheiros criados ou modificados por código em execução na OpenMV Cam não aparecerão até que o anfitrião remonte a unidade. Se tanto o sistema operativo como a OpenMV Cam escreverem no mesmo sistema de ficheiros ao mesmo tempo, o sistema operativo prevalecerá e irá sobrescrever as alterações feitas pela câmara. Use o cartão SD para quaisquer dados que o script escreva, e remonte antes de ler esses ficheiros a partir do anfitrião.
Nota
O canal vermelho do LED RGB de utilizador pode acender brevemente enquanto o anfitrião está a ler ou a escrever na unidade de armazenamento de massa USB — trata-se de um indicador de atividade controlado por firmware, não de uma falha.
Tamanhos de armazenamento¶
A M4 é fornecida com:
/flash— sistema de ficheiros FAT de 32 KB, leitura/escrita./rom— ROMFS mapeado em memória só de leitura de 128 KB./sdcard— tamanho total do cartão microSD inserido (quando presente), leitura/escrita.
Indicador de falha grave¶
Se o LED RGB de utilizador estiver a ciclar rapidamente por todas as cores — suficientemente rápido para parecer um LED branco cintilante em vez de tonalidades distintas — o firmware encontrou uma falha grave irrecuperável. Reflasheie o firmware para recuperar; se o reflash não ajudar, a placa pode estar fisicamente danificada.
Bibliotecas de software¶
Consulte o índice de bibliotecas para a lista completa de módulos — incluindo quais são exclusivos da versão M4.