OpenMV Cam M4¶
OpenMV Cam M4 är ett kompakt Cortex‑M4-kort för maskinseende byggt kring STMicroelectronics STM32F427 på 180 MHz med 256 KB internt SRAM och 1 MB internt flashminne. Den medföljande OV7725-sensorn fångar 320×240 bildrutor i gråskala eller RGB565, och det 9-poliga användarheadern exponerar kringutrustning för UART, I²C, SPI, CAN, ADC/DAC och PWM.
Anteckning
OV7725 var standardsensorn på M4-kort i produktion. Mycket tidiga varianter av M4 levererades i stället med OmniVision OV2640 — samma QVGA-förhandsvisningspipeline, men OV2640 kan dessutom fånga JPEG-bildrutor i upp till UXGA (1600×1200). Båda sensorerna styrs genom samma csi — kamerasensorer-API.
För fullständigt datablad, foton och mått, se produktsidan för OpenMV Cam M4.
Höjdpunkter¶
STMicroelectronics STM32F427 Cortex‑M4 på 180 MHz.
256 KB internt SRAM — inget externt SDRAM.
1 MB internt flashminne (inget externt QSPI-flashminne).
OV7725-sensor (eller OV2640 på mycket tidiga M4-varianter) — 320×240 8‑bitars gråskala eller RGB565; OV2640 kan dessutom fånga JPEG i upp till UXGA (1600×1200).
Full‑speed USB (12 Mb/s) — visas som VCP + USB-masslagring för värddatorn.
microSD-uttag — SD upp till 2 GB, SDHC upp till 32 GB, SDXC upp till 2 TB.
9 I/O-stift, 5 V-toleranta med 3,3 V-utgång, 25 mA per stift (120 mA totalt över headern), avbrottskapabla. P6 är inte 5 V-tolerant när det används i ADC- eller DAC-läge.
Användbar RGB-LED och två högeffekts 850 nm IR-LED:er för aktiv belysning i seende vid svag belysning.
Anteckning
M4 har inget krets för strömhantering ombord: det finns ingen batterikontakt, ingen batteriladdare, ingen ADC för batterispänning, inga LED:er för laddning/strömstatus och ingen strömknapp i hårdvaran. Driv kortet från USB eller VIN.
Stiftschema¶
Stiftreferens¶
Stiftnamn |
Funktion |
|---|---|
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 |
dra till GND för att återställa kortet |
BOOT0 |
dra till 3,3 V vid påslagning för DFU / ROM-startladdare |
SWCLK |
ARM SWD-klocka (felsökaråtkomst) |
SWDIO |
ARM SWD-data (felsökaråtkomst) |
LED_RED |
RGB-LED:ens röda kanal (aktiv låg) |
LED_GREEN |
RGB-LED:ens gröna kanal (aktiv låg) |
LED_BLUE |
RGB-LED:ens blå kanal (aktiv låg) |
LED_IR |
högeffekts IR-LED:er (båda kanalerna drivs tillsammans) |
Strömstift¶
3.3V — reglerad 3,3 V-skena. Upp till 250 mA tillgängligt för sköldar (mindre om microSD-kortet används). Till skillnad från de nyare kamerorna är detta stift dubbelriktat — se varningen nedan.
VIN — 3,6 – 5 V ingång. Driver kortet genom regulatorn ombord.
GND — gemensam jord.
Anteckning
När både USB och VIN är anslutna driver den med högre spänning kortet — dioderna ombord väljer helt enkelt den starkare skenan.
Varning
Du får driva M4 genom att mata 3,3 V direkt in i stiftet 3.3V om du inte vill gå genom regulatorn ombord. I så fall, anslut inte även VIN eller USB-ström samtidigt — att baktdriva regulatorn medan en annan strömkälla är aktiv kan permanent skada och förstöra kameran.
Tips
Använd batteritidsuppskattaren för att modellera hur länge M4 kommer att köra på ett batteri för en given driftcykel av aktivt läge / djup sömn.
Återställnings- och felsökningsstift¶
RESET — dra till GND för att återställa kortet. Att släppa det låter MCU:n starta upp normalt.
BOOT0 — dra till 3,3 V medan kortet får ström för att gå in i STM32 ROM-startladdaren (DFU-läge). OpenMV IDE använder detta läge för att flasha om startladdaren ombord.
SWCLK och SWDIO är utbrutna som vanliga header-stift (inte en dedikerad SWD-kontakt). Koppla RESET, SWCLK, SWDIO, GND och 3,3 V till en ST‑LINK- eller SEGGER J‑Link-adapter för att felsöka kortet.
Kringutrustning ombord¶
LED:er¶
M4 har en enda användbar RGB-LED plus ett par högeffekts 850 nm IR-LED:er:
Användbar RGB-LED — mjukvarustyrbar, exponerad som
LED_RED,LED_GREENochLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
IR-LED:er — båda LED:erna drivs tillsammans genom stiftet
LED_IR.LED_IRär kopplad aktiv hög i hårdvaran medan den fasta programvaran behandlar varje annan LED ombord som aktiv låg, så användlow()/high()snarare änon()/off()(som skulle invertera betydelsen):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Kamerasensor¶
Den medföljande sensorn (OV7725 på standardkort, OV2640 på mycket tidiga varianter) styrs genom modulen csi — kamerasensorer
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()
Sensorn är lödd till kortet på M4 — den sitter inte på en utbytbar modul.
Anteckning
På OV7725-kort är sensorns FSIN-stift (frame‑sync) kopplat till MCU:n men stöd för det i den fasta programvaran har inte lagts till.
På OV2640-kort är sensorns stift STROBE, FREX (frame exposure) och EXPST (exposure reset) kopplade till MCU:n men stöd för dem i den fasta programvaran har inte lagts till.
Servoheaders¶
Kortets baksida har två lödplattor för servokontakter som bryter ut den standardiserade 3-poliga servoheadern (signal / VIN / GND) för P7 och P8. Signalstiften mappas direkt till TIM4-kanal 1 och 2 (samma kanaler som används av pyb.Servo), och V+-stiftet på varje header är kopplat direkt till VIN, så servona drar sin ström från ingångsskenan i stället för 3,3 V-regulatorn.
Löd ett par vinklade 3-poliga headers i plattorna och anslut två hobbyservon för att driva ett pan‑och‑tilt-fäste:
from pyb import Servo
pan = Servo(1) # P7 — TIM4 CH1
tilt = Servo(2) # P8 — TIM4 CH2
pan.angle(0)
tilt.angle(0)
microSD-kort¶
När ett kort sätts i monteras det automatiskt på /sdcard och är användbart genom det vanliga filsystemet:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Bussreferens¶
GPIO¶
Använd machine.Pin för att läsa eller driva något av de silktryckta stiften. Utgångar är 3,3 V CMOS, 5 V-toleranta på ingångssidan, och kan ta emot/leverera upp till 25 mA per stift (120 mA totalt över hela headern).
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())
Vilket ingångsstift som helst kan också utlösa ett avbrott vid flankövergångar:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Buss |
TX |
RX |
|---|---|---|
UART3 |
P4 |
P5 |
from machine import UART
uart = UART(3, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
Buss |
SCL |
SDA |
|---|---|---|
I2C2 |
P4 |
P5 |
from machine import I2C
i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Samma hårdvara kan också användas i målläge (slav) genom machine.I2CTarget för att exponera en minnesregion för en annan I²C-kontroller:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)
SPI¶
Buss |
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¶
Buss |
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 och DAC¶
P6 är det enda analoga användarstiftet. Det kan användas antingen som en 12‑bitars ADC-ingång eller en DAC-utgång.
ADC — fullskala vid 3,3 V på stiftet:
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 — genom
pyb.DAC. Det 8‑bitars värdet täcker 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
I ADC- eller DAC-läge är P6 endast 3,3 V-tolerant — mata det inte med 5 V.
PWM¶
Stift |
Timer / kanal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Anteckning
TIM1 är reserverad av den fasta programvaran för att generera kamerasensorns pixelklocka, så TIM1-kanalerna som fysiskt finns på P0/P1/P2 kan inte användas för användar-PWM utan att kameran slutar fungera.
TIM4 delas med pyb.Servo — att instansiera ett servo konfigurerar om hela timern för 50 Hz-drift, så blanda inte machine.PWM på P7/P8 med pyb.Servo i samma skript.
Driv någon av dem via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Mjukvaru-bitbangade bussar¶
machine.SoftI2C och machine.SoftSPI fungerar på vilken GPIO som helst om du behöver en extra buss.
Termisk sensor (utanför kortet)¶
Den fasta programvaran innehåller drivrutinen fir — drivrutin för värmesensor (fir == far infrared) för externt kopplade termiska kameror:
MLX90621 — 16 × 4 IR-array
MLX90640 — 32 × 24 IR-array
MLX90641 — 16 × 12 IR-array
AMG8833 — 8 × 8 IR-array
Koppla modulen till kortets I²C-buss och läs bildrutor med 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())
Drivrutinen fir kommunicerar med sensorn endast över I²C 2 — koppla modulen till P4 (SCL) och P5 (SDA).
Tidshantering¶
time¶
Modulen time täcker blockerande fördröjningar, monotona tick och mätning av förfluten tid:
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)
Virtuella timrar¶
machine.Timer schemalägger periodiska eller engångs-återanrop utan att förbruka en hårdvarutimerplats. Skicka -1 som id för att använda en virtuell (mjukvaru-)timer:
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"))
Periodvärden anges i millisekunder. Anropa deinit() för att stoppa och frigöra platsen.
Realtidsklocka¶
machine.RTC håller väggklockstid över återställningar:
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())
Vakthund¶
machine.WDT återställer kortet om applikationen hänger sig. När den väl är startad kan den inte stoppas eller konfigureras om — mata den periodiskt inuti din huvudloop:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Start- och körtidsinformation¶
USB-startladdarfönster¶
Vid varje påslagning kör kameran en kort startladdare (några sekunder) som låter OpenMV IDE uppdatera den fasta programvaran utan att användaren behöver gå in i DFU-läge. Efter att fönstret löpt ut lämnar startladdaren över till boot.py och sedan main.py.
Ett körande skript kan gå in i startladdaren på begäran genom att anropa machine.bootloader()
import machine
machine.bootloader()
Filsystem och startordning¶
M4-firmware monterar upp till tre filsystem vid start:
Internt flashminne — alltid monterat på
/flash. Innehållermain.pyochREADME.txtsom standard; skapas vid den allra första starten.microSD-kort — om ett kort sätts i monteras det på
/sdcard.ROMFS — skrivskyddat, minnesmappat filsystem på
/romsom används för att leverera stora datatillgångar (t.ex. AI-modeller) som drar nytta av nollkopieringsåtkomst. Monteras automatiskt av MicroPython vid uppstart, innan någon användar-Python körs.
Efter montering sätts arbetskatalogen till /sdcard när kortet finns, annars /flash. Tolken kör sedan skript från den katalogen:
boot.pykörs vid varje mjuk återställning (kallstart,Ctrl‑Dfrån REPL:en, eller närhelst det körande skriptet returnerar).main.pykörs endast vid kallstart, omedelbart efterboot.py. Efterföljande mjuka återställningar kör omboot.pymen släpper direkt till REPL:en — för att köra ommain.pymåste du återställa kortet fullständigt.
Att lägga en boot.py eller main.py på SD-kortet åsidosätter kopian i flashminnet utan att röra den — båda filerna slås upp i startkatalogen (/sdcard när kortet är monterat, annars /flash).
Standard-main.py som levereras på ett nyligen flashat kort blinkar bara RGB-LED:ens blå kanal som en pulsindikator (två korta pulser, kort paus), så att du kan se att den fasta programvaran startade rent utan någon värd ansluten.
sys.path utökas till att inkludera alla tre filsystem och deras lib/-underkataloger, så importerbara moduler kan ligga i /flash/lib, /sdcard/lib eller /rom/lib.
För att tvinga systemet att ignorera ett isatt SD-kort (till exempel för att köra main.py i flashminnet även med ett kort isatt), skapa en tom fil med namnet SKIPSD i roten av /flash.
När ansluten över USB enumereras även startfilsystemet (/sdcard om ett kort finns, annars /flash) som en USB-masslagringsenhet på värden, så att du kan redigera boot.py, main.py och andra filer direkt. Mata ut enheten innan du återställer kameran så att värden tömmer sina cachade skrivningar.
Anteckning
Eftersom operativsystemet behandlar enheten som en passiv blockenhet kommer filer som skapas eller ändras av kod som körs på OpenMV Cam inte att visas förrän värden monterar om enheten. Om både operativsystemet och OpenMV Cam skriver till samma filsystem samtidigt kommer operativsystemet att vinna och skriva över ändringar som gjorts av kameran. Använd SD-kortet för data som skriptet skriver tillbaka, och montera om innan du läser de filerna från värden.
Anteckning
RGB-LED:ens röda kanal kan kortvarigt tändas medan värden läser från eller skriver till USB-masslagringsenheten — detta är en aktivitetsindikator driven av den fasta programvaran, inte ett fel.
Lagringsstorlekar¶
M4 levereras med:
/flash— 32 KB FAT-filsystem, läs/skriv./rom— 128 KB skrivskyddat minnesmappat ROMFS./sdcard— full storlek på vilket microSD-kort som än sätts i (när det finns), läs/skriv.
Indikator för allvarligt fel¶
Om RGB-LED:en snabbt växlar genom alla färger — tillräckligt snabbt att det tenderar att se ut som en glittrande vit LED snarare än distinkta nyanser — har den fasta programvaran träffat ett oåterkalleligt allvarligt fel (hard fault). Flasha om den fasta programvaran för att återhämta; om omflashning inte hjälper kan kortet vara fysiskt skadat.
Mjukvarubibliotek¶
Se biblioteksindexet för den fullständiga listan över moduler — inklusive vilka som är unika för M4-bygget.