OpenMV Cam M4¶
A OpenMV Cam M4 é uma placa compacta de visão de máquina baseada em 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 quadros 320×240 em escala de cinza ou RGB565, e o conector de usuário de 9 pinos expõe os 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 vinham com o OmniVision OV2640 — o mesmo pipeline de pré-visualização QVGA, mas o OV2640 também pode capturar quadros JPEG de até UXGA (1600×1200). Ambos os sensores são controlados pela mesma API csi — sensores de câmera.
Para o datasheet completo, fotos e dimensões, consulte a página do 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) — 320×240 em escala de cinza de 8 bits ou RGB565; o OV2640 também pode capturar até UXGA (1600×1200) em JPEG.
USB full‑speed (12 Mb/s) — aparece como VCP + armazenamento em massa USB para o host.
Soquete microSD — SD de até 2 GB, SDHC de até 32 GB, SDXC de até 2 TB.
9 pinos de E/S, tolerantes a 5 V com saída de 3,3 V, 25 mA por pino (120 mA no total em todo o conector), capazes de interrupção. O P6 não é tolerante a 5 V quando usado em modo ADC ou DAC.
LED RGB de usuário 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 tem chip de gerenciamento de energia embarcado: não há conector de bateria, carregador de bateria, ADC de tensão de bateria, LEDs de carregamento / status de energia nem botão de energia em hardware. Alimente a placa pela USB ou pela VIN.
Pinagem¶
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 |
puxe para o GND para resetar a placa |
BOOT0 |
puxe para 3,3 V na inicialização para o bootloader DFU / ROM |
SWCLK |
clock 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 juntos) |
Pinos de alimentação¶
3.3V — barramento regulado de 3,3 V. Até 250 mA disponíveis para shields (menos se o cartão microSD estiver em uso). Diferente das câmeras mais novas, este pino é bidirecional — veja o aviso abaixo.
VIN — entrada de 3,6 – 5 V. Alimenta a placa através do regulador embarcado.
GND — terra comum.
Nota
Quando USB e VIN estão ambos presentes, qualquer um que tenha a tensão mais alta alimenta a placa — os diodos embarcados simplesmente escolhem o barramento mais forte.
Aviso
Você pode alimentar a M4 fornecendo 3,3 V diretamente no pino 3.3V se não quiser passar pelo regulador embarcado. Nesse caso, não aplique também a VIN ou a alimentação USB ao mesmo tempo — alimentar o regulador no sentido reverso enquanto outra fonte está ativa pode danificar permanentemente e destruir a câmera.
Dica
Use o estimador de vida útil da bateria para modelar por quanto tempo a M4 funcionará com uma bateria para um dado ciclo de trabalho ativo / sono profundo.
Pinos de recuperação e depuração¶
RESET — puxe para o GND para resetar a placa. Soltá-lo permite que o MCU inicialize normalmente.
BOOT0 — puxe para 3,3 V ao alimentar a placa para entrar no bootloader de ROM do STM32 (modo DFU). A OpenMV IDE usa esse modo para regravar o bootloader embarcado.
SWCLK e SWDIO são disponibilizados como pinos de conector comuns (não um conector SWD dedicado). Conecte RESET, SWCLK, SWDIO, GND e 3,3 V a um adaptador ST‑LINK ou SEGGER J‑Link para depurar a placa.
Periféricos embarcados¶
LEDs¶
A M4 tem um único LED RGB de usuário mais um par de LEDs IR de 850 nm de alta potência:
LED RGB de usuário — 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 juntos através do pino
LED_IR. OLED_IRé ligado como ativo alto no hardware, enquanto o firmware trata todos os outros LEDs embarcados como ativos baixos, então uselow()/high()em vez deon()/off()(que inverteriam a lógica):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Sensor da câmera¶
O sensor incluído (OV7725 nas placas padrão, OV2640 em variantes muito iniciais) é controlado através do módulo csi — sensores de câmera
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()
Na M4, o sensor é soldado à placa — ele não está em um módulo substituível.
Nota
Nas placas OV7725, o pino FSIN (sincronismo de quadro) do sensor é ligado ao MCU, mas o suporte de firmware para ele não foi adicionado.
Nas placas OV2640, os pinos STROBE, FREX (exposição de quadro) e EXPST (reset de exposição) do sensor são ligados ao MCU, mas o suporte de firmware para eles não foi adicionado.
Conectores de servo¶
A parte traseira da placa tem duas ilhas de solda de conector de servo que disponibilizam o conector de servo padrão de 3 pinos (sinal / VIN / GND) para o P7 e o P8. Os pinos de sinal mapeiam diretamente para os canais 1 e 2 do TIM4 (os mesmos canais usados por pyb.Servo), e o pino V+ de cada conector é ligado diretamente à VIN, então os servos consomem corrente do barramento de entrada em vez do regulador de 3,3 V.
Solde um par de conectores de 3 pinos em ângulo reto nas ilhas e conecte dois servos de modelismo 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, ele é montado automaticamente em /sdcard e fica utilizável através do sistema de arquivos comum:
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 serigrafados. As saídas são CMOS de 3,3 V, tolerantes a 5 V no lado de entrada, e podem drenar/fornecer até 25 mA por pino (120 mA no total em todo o 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())
Qualquer pino de entrada também pode disparar uma interrupção em transições de borda:
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¶
O P6 é o único pino analógico de usuário. Ele pode ser usado como entrada ADC de 12 bits ou como saída DAC.
ADC — fundo de escala em 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, o P6 é tolerante apenas a 3,3 V — não forneça 5 V a ele.
PWM¶
Pino |
Timer / canal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Nota
O TIM1 é reservado pelo firmware para gerar o clock de pixel do sensor da câmera, então os canais do TIM1 que estão fisicamente em P0/P1/P2 não podem ser usados para PWM de usuário sem quebrar a câmera.
O TIM4 é compartilhado com pyb.Servo — instanciar um servo reconfigura o timer inteiro para operação a 50 Hz, então 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 bit‑banging em software¶
machine.SoftI2C e machine.SoftSPI funcionam em qualquer GPIO caso você precise de um barramento extra.
Sensor térmico (externo)¶
O firmware inclui o driver fir — driver de sensor térmico (fir == far infrared) para imageadores térmicos conectados externamente:
MLX90621 — array IR de 16 × 4
MLX90640 — array IR de 32 × 24
MLX90641 — array IR de 16 × 12
AMG8833 — array IR de 8 × 8
Conecte o módulo ao barramento I²C da placa e leia quadros 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 driver fir só se comunica com o sensor pela I²C 2 — conecte 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)
Timers virtuais¶
machine.Timer agenda callbacks periódicos ou de disparo único sem consumir um slot de timer de hardware. Passe -1 como id para usar um timer virtual (em 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 são em milissegundos. Chame deinit() para parar e liberar o slot.
Relógio de tempo real¶
machine.RTC mantém a hora do relógio entre resets:
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 reseta a placa se a aplicação travar. Uma vez iniciado, ele não pode ser parado nem reconfigurado — alimente-o periodicamente dentro do seu laço principal:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Informações de boot e tempo de execução¶
Janela do bootloader USB¶
A cada ligação, a câmera executa um bootloader curto (alguns segundos) que permite à OpenMV IDE atualizar o firmware sem que o usuário precise entrar no modo DFU. Após a janela expirar, o bootloader passa o controle para o boot.py e, em seguida, para o main.py.
Um script em execução pode reentrar no bootloader sob demanda chamando machine.bootloader()
import machine
machine.bootloader()
Sistema de arquivos e ordem de boot¶
O firmware da M4 monta até três sistemas de arquivos no boot:
Flash interna — sempre montada em
/flash. Contémmain.pyeREADME.txtpor padrão; criada no primeiro boot.Cartão microSD — se um cartão estiver inserido, ele é montado em
/sdcard.ROMFS — sistema de arquivos somente leitura, mapeado em memória, em
/rom, usado para distribuir grandes ativos de dados (por exemplo, modelos de IA) que se beneficiam de acesso sem cópia. Montado automaticamente pelo MicroPython na inicialização, antes de qualquer código Python de usuário ser executado.
Após a montagem, o diretório de trabalho é definido como /sdcard quando o cartão está presente, caso contrário /flash. O interpretador então executa scripts a partir desse diretório:
boot.pyé executado em todo soft reset (cold boot,Ctrl‑Dno REPL ou sempre que o script em execução retorna).main.pyé executado somente no cold boot, imediatamente após oboot.py. Soft resets subsequentes reexecutam oboot.pymas caem direto no REPL — para reexecutar omain.pyvocê precisa resetar totalmente a placa.
Colocar um boot.py ou main.py no cartão SD substitui a cópia na flash sem alterá-la — ambos os arquivos são procurados no diretório de boot (/sdcard quando o cartão está montado, caso contrário /flash).
O main.py padrão fornecido em uma placa recém-gravada apenas pisca o canal azul do LED RGB de usuário como um heartbeat (dois pulsos curtos, intervalo curto), para que você possa saber que o firmware inicializou corretamente sem nenhum host conectado.
O sys.path é estendido para incluir os três sistemas de arquivos e seus subdiretórios lib/, de modo que módulos importáveis podem ficar 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 arquivo vazio chamado SKIPSD na raiz de /flash.
Quando conectada por USB, o sistema de arquivos de boot (/sdcard se um cartão estiver presente, caso contrário /flash) também é enumerado como uma unidade de armazenamento em massa USB no host, permitindo editar boot.py, main.py e quaisquer outros arquivos diretamente. Ejete a unidade antes de resetar a câmera para que o host descarregue suas gravações em cache.
Nota
Como o SO trata a unidade como um dispositivo de bloco passivo, arquivos criados ou modificados por código em execução na OpenMV Cam não aparecerão até que o host remonte a unidade. Se tanto o SO quanto a OpenMV Cam gravarem no mesmo sistema de arquivos ao mesmo tempo, o SO vence e sobrescreve as alterações feitas pela câmera. Use o cartão SD para quaisquer dados que o script grava de volta, e remonte antes de ler esses arquivos a partir do host.
Nota
O canal vermelho do LED RGB de usuário pode acender brevemente enquanto o host está lendo ou gravando na unidade de armazenamento em massa USB — esse é um indicador de atividade controlado pelo firmware, não uma falha.
Tamanhos de armazenamento¶
A M4 vem com:
/flash— sistema de arquivos FAT de 32 KB, leitura/gravação./rom— ROMFS somente leitura, mapeado em memória, de 128 KB./sdcard— o tamanho total de qualquer cartão microSD inserido (quando presente), leitura/gravação.
Indicador de hard fault¶
Se o LED RGB de usuário estiver ciclando rapidamente por todas as cores — rápido o suficiente para parecer um LED branco cintilante em vez de tons distintos — o firmware encontrou um hard fault irrecuperável. Regrave o firmware para recuperar; se a regravação não ajudar, a placa pode estar fisicamente danificada.
Bibliotecas de software¶
Consulte o índice da biblioteca para a lista completa de módulos — incluindo quais são exclusivos da build da M4.