OpenMV Cam M4¶
La OpenMV Cam M4 è una scheda compatta per la visione artificiale basata su Cortex‑M4, costruita attorno allo STMicroelectronics STM32F427 a 180 MHz con 256 KB di SRAM interna e 1 MB di flash interna. Il sensore OV7725 incluso cattura frame in scala di grigi o RGB565 a 320×240, e il connettore utente a 9 pin espone le periferiche UART, I²C, SPI, CAN, ADC/DAC e PWM.
Nota
L’OV7725 era il sensore standard sulle schede M4 di produzione. Le primissime varianti della M4 venivano fornite con l’OmniVision OV2640 — stessa pipeline di anteprima QVGA, ma l’OV2640 può anche catturare frame JPEG fino a UXGA (1600×1200). Entrambi i sensori sono pilotati attraverso la stessa API csi — sensori camera.
Per il datasheet completo, foto e dimensioni consulta la pagina prodotto della OpenMV Cam M4.
Caratteristiche principali¶
STMicroelectronics STM32F427 Cortex‑M4 a 180 MHz.
256 KB di SRAM interna — nessuna SDRAM esterna.
1 MB di flash interna (nessuna flash QSPI esterna).
Sensore OV7725 (oppure OV2640 sulle primissime varianti M4) — 320×240 in scala di grigi a 8 bit o RGB565; l’OV2640 può inoltre catturare JPEG fino a UXGA (1600×1200).
USB full‑speed (12 Mb/s) — appare all’host come VCP + dispositivo di archiviazione di massa USB.
Socket microSD — SD fino a 2 GB, SDHC fino a 32 GB, SDXC fino a 2 TB.
9 pin di I/O, tolleranti 5 V con uscita a 3,3 V, 25 mA per pin (120 mA totali sull’intero connettore), con supporto agli interrupt. Il P6 non è tollerante 5 V quando usato in modalità ADC o DAC.
LED RGB utente e due potenti LED IR a 850 nm per l’illuminazione attiva nella visione in condizioni di scarsa luminosità.
Nota
La M4 non ha alcun chip di gestione dell’alimentazione a bordo: non c’è connettore per batteria, né caricabatteria, né ADC per la tensione della batteria, né LED di stato carica/alimentazione, né pulsante hardware di accensione. Alimenta la scheda tramite USB o VIN.
Pinout¶
Riferimento dei pin¶
Nome pin |
Funzione |
|---|---|
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 |
collega a GND per resettare la scheda |
BOOT0 |
collega a 3,3 V all’accensione per DFU / bootloader ROM |
SWCLK |
clock ARM SWD (accesso debugger) |
SWDIO |
dati ARM SWD (accesso debugger) |
LED_RED |
canale rosso del LED RGB (attivo basso) |
LED_GREEN |
canale verde del LED RGB (attivo basso) |
LED_BLUE |
canale blu del LED RGB (attivo basso) |
LED_IR |
LED IR ad alta potenza (entrambi i canali pilotati insieme) |
Pin di alimentazione¶
3.3V — linea regolata a 3,3 V. Fino a 250 mA disponibili per gli shield (meno se la scheda microSD è in uso). A differenza delle camere più recenti questo pin è bidirezionale — vedi l’avvertenza qui sotto.
VIN — ingresso 3,6 – 5 V. Alimenta la scheda attraverso il regolatore a bordo.
GND — massa comune.
Nota
Quando sono presenti sia USB che VIN, alimenta la scheda quello con la tensione più alta — i diodi a bordo selezionano semplicemente la linea più forte.
Avvertimento
Puoi alimentare la M4 fornendo 3,3 V direttamente al pin 3.3V se non vuoi passare attraverso il regolatore a bordo. In tal caso, non applicare anche VIN o l’alimentazione USB nello stesso momento — alimentare a ritroso il regolatore mentre un’altra sorgente è attiva può danneggiare in modo permanente e distruggere la camera.
Suggerimento
Usa lo stimatore di durata della batteria per modellare per quanto tempo la M4 funzionerà a batteria per un dato ciclo di lavoro attivo / deep-sleep.
Pin di recupero e debug¶
RESET — collega a GND per resettare la scheda. Rilasciandolo l’MCU si avvia normalmente.
BOOT0 — collega a 3,3 V mentre alimenti la scheda per entrare nel bootloader ROM dello STM32 (modalità DFU). OpenMV IDE usa questa modalità per riprogrammare il bootloader a bordo.
SWCLK e SWDIO sono esposti come normali pin del connettore (non un connettore SWD dedicato). Collega RESET, SWCLK, SWDIO, GND e 3,3 V a un adattatore ST‑LINK o SEGGER J‑Link per eseguire il debug della scheda.
Periferiche a bordo¶
LED¶
La M4 dispone di un singolo LED RGB utente più una coppia di potenti LED IR a 850 nm:
LED RGB utente — controllabile via software, esposto come
LED_RED,LED_GREENeLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
LED IR — entrambi i LED sono pilotati insieme attraverso il pin
LED_IR.LED_IRè cablato attivo alto nell’hardware, mentre il firmware tratta ogni altro LED a bordo come attivo basso, quindi usalow()/high()invece dion()/off()(che invertirebbero il senso):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Sensore della camera¶
Il sensore incluso (OV7725 sulle schede standard, OV2640 sulle primissime varianti) è pilotato attraverso il modulo csi — sensori camera
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()
Sulla M4 il sensore è saldato alla scheda — non si trova su un modulo intercambiabile.
Nota
Sulle schede OV7725 il pin FSIN (frame‑sync) del sensore è cablato all’MCU ma il relativo supporto firmware non è stato aggiunto.
Sulle schede OV2640 i pin STROBE, FREX (frame exposure) ed EXPST (exposure reset) del sensore sono cablati all’MCU ma il relativo supporto firmware non è stato aggiunto.
Connettori per servo¶
Il lato posteriore della scheda dispone di due piazzole di saldatura per connettore servo che espongono il connettore servo standard a 3 pin (segnale / VIN / GND) per P7 e P8. I pin di segnale mappano direttamente sui canali 1 e 2 di TIM4 (gli stessi canali usati da pyb.Servo), e il pin V+ su ciascun connettore è cablato direttamente a VIN, in modo che i servo prelevino la corrente dalla linea di ingresso anziché dal regolatore a 3,3 V.
Salda una coppia di connettori a 3 pin ad angolo retto nelle piazzole e collega due servo hobbistici per pilotare un supporto 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)
Scheda microSD¶
Quando una scheda è inserita viene montata automaticamente su /sdcard ed è utilizzabile attraverso il normale file system:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Riferimento dei bus¶
GPIO¶
Usa machine.Pin per leggere o pilotare uno qualsiasi dei pin serigrafati. Le uscite sono CMOS a 3,3 V, tolleranti 5 V sul lato ingresso, e possono assorbire/erogare fino a 25 mA per pin (120 mA totali sull’intero connettore).
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())
Qualsiasi pin di ingresso può anche generare un interrupt sulle transizioni di fronte:
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 |
|---|---|---|
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 |
from machine import I2C
i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Lo stesso hardware può essere usato anche in modalità target (slave) attraverso machine.I2CTarget per esporre una regione di memoria a un altro controller 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 e DAC¶
Il P6 è l’unico pin analogico utente. Può essere usato come ingresso ADC a 12 bit oppure come uscita DAC.
ADC — fondo scala a 3,3 V sul 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 — attraverso
pyb.DAC. Il valore a 8 bit copre 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
In modalità ADC o DAC il P6 è tollerante solo 3,3 V — non fornirgli 5 V.
PWM¶
Pin |
Timer / canale |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Nota
TIM1 è riservato dal firmware per generare il clock dei pixel del sensore della camera, quindi i canali di TIM1 che sono fisicamente su P0/P1/P2 non possono essere usati per PWM utente senza compromettere la camera.
TIM4 è condiviso con pyb.Servo — istanziare un servo riconfigura l’intero timer per il funzionamento a 50 Hz, quindi non mescolare machine.PWM su P7/P8 con pyb.Servo nello stesso script.
Pilota uno qualsiasi di essi tramite machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Bus software bit‑banged¶
machine.SoftI2C e machine.SoftSPI funzionano su qualsiasi GPIO se hai bisogno di un bus aggiuntivo.
Sensore termico (esterno)¶
Il firmware include il driver fir — driver del sensore termico (fir == far infrared) per imager termici cablati esternamente:
MLX90621 — array IR 16 × 4
MLX90640 — array IR 32 × 24
MLX90641 — array IR 16 × 12
AMG8833 — array IR 8 × 8
Collega il modulo al bus I²C della scheda e leggi i frame 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())
Il driver fir comunica con il sensore solo tramite I²C 2 — collega il modulo a P4 (SCL) e P5 (SDA).
Temporizzazione¶
time¶
Il modulo time copre i ritardi bloccanti, i tick monotoni e la misurazione del tempo trascorso:
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)
Timer virtuali¶
machine.Timer pianifica callback periodiche o singole senza occupare uno slot di timer hardware. Passa -1 come id per usare un timer virtuale (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"))
I valori del periodo sono in millisecondi. Chiama deinit() per fermare e rilasciare lo slot.
Orologio in tempo reale¶
machine.RTC mantiene l’ora di sistema attraverso i reset:
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 resetta la scheda se l’applicazione si blocca. Una volta avviato non può essere fermato o riconfigurato — alimentalo periodicamente all’interno del tuo loop principale:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Informazioni su boot e runtime¶
Finestra del bootloader USB¶
Ad ogni accensione la camera esegue un breve bootloader (qualche secondo) che permette a OpenMV IDE di aggiornare il firmware senza che l’utente debba entrare in modalità DFU. Dopo che la finestra scade il bootloader passa il controllo a boot.py e poi a main.py.
Uno script in esecuzione può rientrare nel bootloader su richiesta chiamando machine.bootloader()
import machine
machine.bootloader()
Filesystem e ordine di boot¶
Il firmware della M4 monta fino a tre filesystem all’avvio:
Flash interna — sempre montata su
/flash. Contiene per impostazione predefinitamain.pyeREADME.txt; viene creata al primissimo avvio.Scheda microSD — se una scheda è inserita viene montata su
/sdcard.ROMFS — filesystem di sola lettura, mappato in memoria, su
/rom, usato per distribuire grandi asset di dati (ad es. modelli AI) che traggono vantaggio dall’accesso zero‑copy. Montato automaticamente da MicroPython all’avvio, prima dell’esecuzione di qualsiasi codice Python utente.
Dopo il montaggio, la directory di lavoro è impostata su /sdcard quando la scheda è presente, altrimenti su /flash. L’interprete esegue quindi gli script da quella directory:
boot.pyviene eseguito a ogni soft reset (avvio a freddo,Ctrl‑Ddal REPL, o ogni volta che lo script in esecuzione termina).main.pyviene eseguito solo all’avvio a freddo, immediatamente dopoboot.py. I successivi soft reset rieseguonoboot.pyma passano direttamente al REPL — per rieseguiremain.pydevi resettare completamente la scheda.
Posizionare un boot.py o un main.py sulla scheda SD sovrascrive la copia in flash senza toccarla — entrambi i file vengono cercati nella directory di boot (/sdcard quando la scheda è montata, altrimenti /flash).
Il main.py predefinito fornito su una scheda appena programmata si limita a far lampeggiare il canale blu del LED RGB utente come battito cardiaco (due brevi impulsi, breve pausa), così puoi capire che il firmware si è avviato correttamente senza alcun host collegato.
sys.path viene esteso per includere tutti e tre i filesystem e le rispettive sottodirectory lib/, in modo che i moduli importabili possano risiedere in /flash/lib, /sdcard/lib o /rom/lib.
Per forzare il sistema a ignorare una scheda SD inserita (ad esempio per eseguire il main.py della flash anche con una scheda presente), crea un file vuoto chiamato SKIPSD nella radice di /flash.
Quando è collegata via USB, il filesystem di boot (/sdcard se una scheda è presente, altrimenti /flash) viene enumerato anche come unità di archiviazione di massa USB sull’host, permettendoti di modificare direttamente boot.py, main.py e qualsiasi altro file. Espelli l’unità prima di resettare la camera così che l’host scriva le modifiche memorizzate nella cache.
Nota
Poiché il sistema operativo tratta l’unità come un dispositivo a blocchi passivo, i file creati o modificati dal codice in esecuzione sulla OpenMV Cam non compariranno finché l’host non rimonta l’unità. Se sia il sistema operativo che la OpenMV Cam scrivono sullo stesso filesystem nello stesso momento, il sistema operativo prevarrà e sovrascriverà le modifiche fatte dalla camera. Usa la scheda SD per qualsiasi dato che lo script riscrive, e rimonta prima di leggere quei file dall’host.
Nota
Il canale rosso del LED RGB utente può accendersi brevemente mentre l’host legge o scrive sull’unità di archiviazione di massa USB — è un indicatore di attività pilotato dal firmware, non un guasto.
Dimensioni di archiviazione¶
La M4 viene fornita con:
/flash— filesystem FAT da 32 KB, lettura/scrittura./rom— ROMFS di sola lettura mappata in memoria da 128 KB./sdcard— dimensione completa di qualunque scheda microSD sia inserita (quando presente), lettura/scrittura.
Indicatore di hard‑fault¶
Se il LED RGB utente cicla rapidamente attraverso tutti i colori — abbastanza velocemente da sembrare un LED bianco scintillante anziché tonalità distinte — il firmware ha incontrato un hard fault irrecuperabile. Riprogramma il firmware per recuperare; se la riprogrammazione non aiuta, la scheda potrebbe essere fisicamente danneggiata.
Librerie software¶
Consulta l”indice delle librerie per l’elenco completo dei moduli — incluso quali sono esclusivi della build M4.