OpenMV Cam M4¶
De OpenMV Cam M4 is een compact Cortex‑M4 machine vision-bord opgebouwd rond de STMicroelectronics STM32F427 op 180 MHz met 256 KB intern SRAM en 1 MB intern flashgeheugen. De meegeleverde OV7725-sensor legt 320×240 grijswaarden- of RGB565-frames vast, en de 9‑pins gebruikersheader stelt UART, I²C, SPI, CAN, ADC/DAC en PWM-randapparaten beschikbaar.
Notitie
De OV7725 was de standaardsensor op productie‑M4‑borden. Zeer vroege varianten van de M4 werden in plaats daarvan geleverd met de OmniVision OV2640 — dezelfde QVGA‑previewpijplijn, maar de OV2640 kan ook tot UXGA (1600×1200) JPEG‑frames vastleggen. Beide sensoren worden aangestuurd via dezelfde csi — camerasensoren API.
Voor het volledige datasheet, foto’s en afmetingen, zie de productpagina van de OpenMV Cam M4.
Hoogtepunten¶
STMicroelectronics STM32F427 Cortex‑M4 op 180 MHz.
256 KB intern SRAM — geen extern SDRAM.
1 MB intern flashgeheugen (geen extern QSPI-flashgeheugen).
OV7725-sensor (of OV2640 op zeer vroege M4-varianten) — 320×240 8‑bits grijswaarden of RGB565; de OV2640 kan daarnaast tot UXGA (1600×1200) JPEG vastleggen.
Full‑speed USB (12 Mb/s) — verschijnt als VCP + USB-massaopslag bij de host.
microSD-aansluiting — SD tot 2 GB, SDHC tot 32 GB, SDXC tot 2 TB.
9 I/O-pinnen, 5 V-tolerant met 3,3 V-uitgang, 25 mA per pin (120 mA totaal over de header), interrupt‑capabel. P6 is niet 5 V-tolerant bij gebruik in ADC- of DAC-modus.
Gebruikers-RGB-LED en twee krachtige 850 nm IR-LED’s voor actieve verlichting bij machine vision in zwak licht.
Notitie
De M4 heeft geen ingebouwde voedingsbeheerchip: er is geen accu-aansluiting, geen accu-oplader, geen ADC voor accuspanning, geen oplaad-/voedingsstatus-LED’s en geen hardware-aan/uitknop. Voed het bord via USB of VIN.
Pinout¶
Pinreferentie¶
Pinnaam |
Functie |
|---|---|
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 |
trek naar GND om het bord te resetten |
BOOT0 |
trek naar 3,3 V bij het inschakelen voor DFU / ROM-bootloader |
SWCLK |
ARM SWD-klok (debugger-toegang) |
SWDIO |
ARM SWD-data (debugger-toegang) |
LED_RED |
rood kanaal van de RGB-LED (actief laag) |
LED_GREEN |
groen kanaal van de RGB-LED (actief laag) |
LED_BLUE |
blauw kanaal van de RGB-LED (actief laag) |
LED_IR |
krachtige IR-LED’s (beide kanalen samen aangestuurd) |
Voedingspinnen¶
3.3V — gereguleerde 3,3 V-rail. Tot 250 mA beschikbaar voor shields (minder als de microSD-kaart in gebruik is). Anders dan bij de nieuwere camera’s is deze pin bidirectioneel — zie de waarschuwing hieronder.
VIN — 3,6 – 5 V-ingang. Voedt het bord via de ingebouwde regelaar.
GND — gemeenschappelijke massa.
Notitie
Wanneer zowel USB als VIN aanwezig zijn, voedt diegene met de hogere spanning het bord — de ingebouwde diodes kiezen simpelweg de sterkste rail.
Waarschuwing
Je mag de M4 voeden door rechtstreeks 3,3 V op de 3.3V-pin te zetten als je de ingebouwde regelaar wilt omzeilen. Pas in dat geval niet ook tegelijkertijd VIN- of USB-voeding toe — het terugdrijven van de regelaar terwijl een andere voeding actief is, kan de camera permanent beschadigen en vernietigen.
Tip
Gebruik de schatter voor accuduur om te modelleren hoe lang de M4 op een accu draait bij een bepaalde actieve/diepe-slaap-bedrijfscyclus.
Herstel- en debugpinnen¶
RESET — trek naar GND om het bord te resetten. Bij loslaten start de MCU normaal op.
BOOT0 — trek naar 3,3 V terwijl het bord wordt gevoed om de STM32 ROM-bootloader (DFU-modus) te openen. OpenMV IDE gebruikt deze modus om de ingebouwde bootloader opnieuw te flashen.
SWCLK en SWDIO zijn uitgebroken als gewone headerpinnen (geen speciale SWD-connector). Bedraad RESET, SWCLK, SWDIO, GND en 3,3 V naar een ST‑LINK- of SEGGER J‑Link-adapter om het bord te debuggen.
Ingebouwde randapparaten¶
LED’s¶
De M4 heeft één gebruikers-RGB-LED plus een paar krachtige 850 nm IR-LED’s:
Gebruikers-RGB-LED — softwarematig bestuurbaar, beschikbaar als
LED_RED,LED_GREENenLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
IR-LED’s — beide LED’s worden samen aangestuurd via de
LED_IR-pin.LED_IRis in hardware actief hoog bedraad, terwijl de firmware elke andere ingebouwde LED als actief laag behandelt, dus gebruiklow()/high()in plaats vanon()/off()(die de betekenis zouden omkeren):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Camerasensor¶
De meegeleverde sensor (OV7725 op standaardborden, OV2640 op zeer vroege varianten) wordt aangestuurd via de csi — camerasensoren-module:
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()
De sensor is op de M4 aan het bord gesoldeerd — hij zit niet op een verwisselbare module.
Notitie
Op OV7725-borden is de FSIN-pin (frame‑sync) van de sensor bedraad naar de MCU, maar firmware-ondersteuning daarvoor is niet toegevoegd.
Op OV2640-borden zijn de STROBE-, FREX- (frame‑belichting) en EXPST-pinnen (belichtingsreset) van de sensor bedraad naar de MCU, maar firmware-ondersteuning daarvoor is niet toegevoegd.
Servoheaders¶
De achterzijde van het bord heeft twee soldeervlakken voor servoconnectoren die de standaard 3‑pins servoheader (signaal / VIN / GND) uitbreken voor P7 en P8. De signaalpinnen koppelen rechtstreeks aan TIM4-kanalen 1 en 2 (dezelfde kanalen die door pyb.Servo worden gebruikt), en de V+-pin op elke header is rechtstreeks bedraad naar VIN, zodat de servo’s hun stroom uit de ingangsrail trekken in plaats van uit de 3,3 V-regelaar.
Soldeer een paar haakse 3‑pins headers in de vlakken en sluit twee hobbyservo’s aan om een pan‑en‑tilt-bevestiging aan te sturen:
from pyb import Servo
pan = Servo(1) # P7 — TIM4 CH1
tilt = Servo(2) # P8 — TIM4 CH2
pan.angle(0)
tilt.angle(0)
microSD-kaart¶
Wanneer een kaart wordt geplaatst, wordt deze automatisch aangekoppeld op /sdcard en is deze bruikbaar via het reguliere bestandssysteem:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Busreferentie¶
GPIO¶
Gebruik machine.Pin om een van de op het bord gemarkeerde pinnen te lezen of aan te sturen. Uitgangen zijn 3,3 V CMOS, 5 V-tolerant aan de ingangszijde, en kunnen tot 25 mA per pin verbruiken/leveren (120 mA totaal over de hele header).
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())
Elke ingangspin kan ook een interrupt afvuren bij randovergangen:
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")
Dezelfde hardware kan ook in target-modus (slave) worden gebruikt via machine.I2CTarget om een geheugengebied bloot te stellen aan een andere I²C-controller:
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 en DAC¶
P6 is de enige analoge gebruikerspin. Hij kan worden gebruikt als 12‑bits ADC-ingang of als DAC-uitgang.
ADC — volledige schaal bij 3,3 V op de 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 — via
pyb.DAC. De 8‑bits waarde dekt 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
In ADC- of DAC-modus is P6 alleen 3,3 V-tolerant — voed hem geen 5 V.
PWM¶
Pin |
Timer / kanaal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Notitie
TIM1 is gereserveerd door de firmware om de pixelklok van de camerasensor te genereren, dus de TIM1-kanalen die fysiek op P0/P1/P2 zitten, kunnen niet voor gebruikers-PWM worden gebruikt zonder de camera te onderbreken.
TIM4 wordt gedeeld met pyb.Servo — het instantiëren van een servo herconfigureert de hele timer voor 50 Hz-werking, dus combineer machine.PWM op P7/P8 niet met pyb.Servo in hetzelfde script.
Stuur een van hen aan via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Softwarematig bit‑banged bussen¶
machine.SoftI2C en machine.SoftSPI werken op elke GPIO als je een extra bus nodig hebt.
Thermische sensor (extern)¶
De firmware bevat de fir — thermische sensor-driver (fir == far infrared)-driver voor extern bedrade thermische beeldvormers:
MLX90621 — 16 × 4 IR-array
MLX90640 — 32 × 24 IR-array
MLX90641 — 16 × 12 IR-array
AMG8833 — 8 × 8 IR-array
Bedraad de module naar de I²C-bus van het bord en lees frames met 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())
De fir-driver communiceert alleen met de sensor via I²C 2 — bedraad de module naar P4 (SCL) en P5 (SDA).
Timing¶
time¶
De time-module dekt blokkerende vertragingen, monotone ticks en het meten van verstreken tijd:
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)
Virtuele timers¶
machine.Timer plant periodieke of eenmalige callbacks zonder een hardware-timerslot te verbruiken. Geef -1 op als id om een virtuele (software)timer te gebruiken:
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"))
Periodewaarden zijn in milliseconden. Roep deinit() aan om het slot te stoppen en vrij te geven.
Realtimeklok¶
machine.RTC houdt de kloktijd bij over resets heen:
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 reset het bord als de applicatie vastloopt. Eenmaal gestart kan hij niet meer worden gestopt of opnieuw geconfigureerd — voed hem periodiek binnen je hoofdlus:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Boot- en runtime-informatie¶
USB-bootloadervenster¶
Bij elke inschakeling draait de camera een korte bootloader (enkele seconden) waarmee OpenMV IDE de firmware kan bijwerken zonder dat de gebruiker de DFU-modus hoeft te openen. Nadat het venster verstrijkt, draagt de bootloader over aan boot.py en vervolgens main.py.
Een draaiend script kan op verzoek opnieuw de bootloader openen door machine.bootloader() aan te roepen:
import machine
machine.bootloader()
Bestandssysteem en bootvolgorde¶
De M4-firmware koppelt tot drie bestandssystemen aan bij het opstarten:
Intern flashgeheugen — altijd aangekoppeld op
/flash. Bevat standaardmain.pyenREADME.txt; aangemaakt bij de allereerste boot.microSD-kaart — als een kaart is geplaatst, wordt deze aangekoppeld op
/sdcard.ROMFS — alleen-lezen, in geheugen gemapt bestandssysteem op
/romdat wordt gebruikt om grote data-assets (bijv. AI-modellen) te leveren die profiteren van zero‑copy-toegang. Wordt automatisch door MicroPython bij het opstarten aangekoppeld, voordat enige gebruikers-Python draait.
Na het aankoppelen wordt de werkmap ingesteld op /sdcard wanneer de kaart aanwezig is, anders /flash. De interpreter draait vervolgens scripts uit die map:
boot.pywordt uitgevoerd bij elke soft reset (koude boot,Ctrl‑Dvanuit de REPL, of telkens wanneer het draaiende script terugkeert).main.pywordt alleen bij een koude boot uitgevoerd, direct naboot.py. Volgende soft resets draaienboot.pyopnieuw, maar vallen meteen terug naar de REPL — ommain.pyopnieuw te draaien moet je het bord volledig resetten.
Het plaatsen van een boot.py of main.py op de SD-kaart overschrijft de kopie in het flashgeheugen zonder die aan te raken — beide bestanden worden opgezocht in de bootmap (/sdcard wanneer de kaart is aangekoppeld, anders /flash).
De standaard main.py die op een vers geflasht bord wordt geleverd, laat alleen het blauwe kanaal van de gebruikers-RGB-LED knipperen als hartslag (twee korte pulsen, korte pauze), zodat je kunt zien dat de firmware schoon is opgestart zonder dat er een host is aangesloten.
sys.path wordt uitgebreid met alle drie de bestandssystemen en hun lib/-submappen, zodat importeerbare modules kunnen staan in /flash/lib, /sdcard/lib of /rom/lib.
Om het systeem te dwingen een geplaatste SD-kaart te negeren (bijvoorbeeld om de main.py uit het flashgeheugen te draaien zelfs met een kaart aanwezig), maak je een leeg bestand met de naam SKIPSD in de hoofdmap van /flash.
Bij verbinding via USB enumereert het bootbestandssysteem (/sdcard als een kaart aanwezig is, anders /flash) ook als een USB-massaopslagstation bij de host, waarmee je boot.py, main.py en andere bestanden rechtstreeks kunt bewerken. Werp het station uit voordat je de camera reset zodat de host zijn in de cache opgeslagen schrijfacties wegschrijft.
Notitie
Omdat het besturingssysteem het station als een passief blokapparaat behandelt, verschijnen bestanden die zijn aangemaakt of gewijzigd door code die op de OpenMV Cam draait pas wanneer de host het station opnieuw aankoppelt. Als zowel het besturingssysteem als de OpenMV Cam tegelijkertijd naar hetzelfde bestandssysteem schrijven, wint het besturingssysteem en overschrijft het de wijzigingen van de camera. Gebruik de SD-kaart voor data die het script terugschrijft, en koppel opnieuw aan voordat je die bestanden vanaf de host leest.
Notitie
Het rode kanaal van de gebruikers-RGB-LED kan kort oplichten terwijl de host van het USB-massaopslagstation leest of ernaartoe schrijft — dit is een firmware-aangestuurde activiteitsindicator, geen storing.
Opslaggroottes¶
De M4 wordt geleverd met:
/flash— 32 KB FAT-bestandssysteem, lezen/schrijven./rom— 128 KB alleen-lezen in geheugen gemapt ROMFS./sdcard— volledige grootte van welke microSD-kaart ook is geplaatst (indien aanwezig), lezen/schrijven.
Hard‑fault-indicator¶
Als de gebruikers-RGB-LED snel door alle kleuren cyclet — snel genoeg dat het eerder op een flikkerende witte LED lijkt dan op afzonderlijke tinten — heeft de firmware een onherstelbare hard fault opgelopen. Flash de firmware opnieuw om te herstellen; als opnieuw flashen niet helpt, is het bord mogelijk fysiek beschadigd.
Softwarebibliotheken¶
Zie de bibliotheekindex voor de volledige lijst met modules — inclusief welke uniek zijn voor de M4-build.