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.

OpenMV Cam M4

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

OpenMV Cam M4 OV7725 Pinout

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_GREEN e LED_BLUE

    from 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. O LED_IR está ligado em ativo alto por hardware, enquanto o firmware trata todos os outros LEDs a bordo como ativo baixo, por isso use low() / high() em vez de on() / 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ém main.py e README.txt por 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‑D a partir do REPL, ou sempre que o script em execução termina).

  • main.py é executado apenas no arranque a frio, imediatamente após boot.py. Reinicializações suaves subsequentes re-executam boot.py mas passam diretamente para o REPL — para re-executar main.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.