OpenMV Cam H7 Plus¶
Die OpenMV Cam H7 Plus kombiniert den STMicroelectronics STM32H743 (Cortex‑M7 @ 480 MHz) mit 32 MB externem SDRAM, 32 MB QSPI-Flash, einem Hardware-JPEG-Codec und dem OV5640-5MP-Kameramodul auf einem abnehmbaren Träger. Der zusätzliche Speicher eignet sich hervorragend für hochauflösende Aufnahmen und große Bildpuffer.
Vollständiges Datenblatt, Fotos und Abmessungen finden Sie auf der OpenMV Cam H7 Plus-Produktseite.
Highlights¶
STMicroelectronics STM32H743 Cortex‑M7 mit 480 MHz (1027 DMIPS).
Hardware-JPEG-Encoder/-Decoder.
32 MB externes SDRAM (32‑Bit @ 100 MHz, 400 MB/s) plus 1 MB internes SRAM.
2 MB internes Flash + 32 MB externes QSPI-Flash (~100 MB/s Lesegeschwindigkeit).
OV5640 5MP-Rolling-Shutter-Sensor.
Full-Speed-USB (12 Mb/s) — erscheint dem Host gegenüber als VCP + USB-Massenspeicher.
microSD-Steckplatz — SD bis 2 GB, SDHC bis 32 GB, SDXC bis 2 TB.
LiPo-Akkuanschluss (kein integriertes Ladegerät — schließen Sie eine geladene Zelle an oder betreiben Sie das Board über VIN/USB).
10 I/O-Pins, 5 V-tolerant mit 3,3 V-Ausgang, 25 mA pro Pin (120 mA insgesamt über die Stiftleiste), interruptfähig. P6 ist im ADC- oder DAC-Modus nicht 5 V-tolerant.
RGB-Benutzer-LED und zwei leistungsstarke 850 nm-IR-LEDs für aktive Beleuchtung beim Sehen unter schlechten Lichtverhältnissen.
Bemerkung
Die H7 Plus hat keinen integrierten Power-Management-Chip: Es gibt kein Akkuladegerät, keinen ADC für die Akkuspannung, keine Lade-/Power-Status-LEDs und keinen Hardware-Power-Knopf. Schließen Sie einen vorgeladenen LiPo an den Akku-JST an oder betreiben Sie das Board über USB / VIN.
Pinbelegung¶
Pin-Referenz¶
Pin-Name |
Funktion |
|---|---|
P0 |
UART1 RX / SPI2 MOSI |
P1 |
UART1 TX / SPI2 MISO |
P2 |
SPI2 SCK / FDCAN2 TX |
P3 |
SPI2 NSS (CS) / FDCAN2 RX |
P4 |
I2C2 SCL / UART3 TX / TIM2 CH3 |
P5 |
I2C2 SDA / UART3 RX / TIM2 CH4 |
P6 |
ADC / DAC / TIM2 CH1 |
P7 |
I2C4 SCL / TIM4 CH1 |
P8 |
I2C4 SDA / TIM4 CH2 |
P9 |
digitales I/O |
RESET |
auf GND ziehen, um das Board zurückzusetzen |
SYN |
Frame-Sync-Pad — nur mit dem Kamerasensor verdrahtet |
BOOT0 |
beim Einschalten auf 3,3 V ziehen für DFU / ROM-Bootloader |
LED_RED |
Rotkanal der RGB-LED (Low-aktiv) |
LED_GREEN |
Grünkanal der RGB-LED (Low-aktiv) |
LED_BLUE |
Blaukanal der RGB-LED (Low-aktiv) |
LED_IR |
leistungsstarke IR-LEDs (beide Kanäle werden gemeinsam angesteuert) |
Bemerkung
Das SYN-Pad an der Stiftleiste ist direkt mit der Trigger-/Belichtungsleitung des Kamerasensors verbunden — es ist auf der H7 Plus nicht mit dem MCU verbunden. Steuern oder lesen Sie es extern; aus MicroPython lässt es sich nicht umschalten.
Power-Pins¶
3.3V — geregelte 3,3 V-Schiene. Bis zu 250 mA für Shields verfügbar (weniger, wenn die microSD-Karte verwendet wird). Anders als bei den neueren Kameras ist dieser Pin bidirektional — siehe die Warnung unten.
VIN — 3,6 – 5 V-Eingang. Versorgt das Board über den integrierten Regler.
GND — gemeinsame Masse.
Ein 3,7 V-LiPo-Anschluss ist ebenfalls vorhanden, aber die H7 Plus besitzt kein Akkuladegerät — schließen Sie eine vorgeladene Zelle an oder versorgen Sie das Board stattdessen über VIN / USB.
Bemerkung
Wenn sowohl USB als auch VIN/LiPo anliegen, gewinnt der VIN/LiPo-Eingang — der integrierte Power-Schalter wählt ihn gegenüber USB zur Versorgung des Boards.
Warnung
Der Akkuanschluss und VIN sind auf der H7 Plus miteinander verbunden. Schließen Sie nicht gleichzeitig einen LiPo an und legen Sie VIN an — die beiden Versorgungen arbeiten gegeneinander und können den Akku, das Board oder beides beschädigen.
Warnung
Sie dürfen die H7 Plus mit Strom versorgen, indem Sie 3,3 V direkt in den 3.3V-Pin einspeisen, wenn Sie den integrierten Regler umgehen möchten. In diesem Fall legen Sie nicht gleichzeitig auch VIN- oder USB-Strom an — das Rückspeisen des Reglers, während eine andere Versorgung aktiv ist, kann die Kamera dauerhaft beschädigen und zerstören.
Tipp
Verwenden Sie den Akkulaufzeit-Schätzer, um zu modellieren, wie lange die H7 Plus bei einem bestimmten Aktiv-/Deep-Sleep-Tastverhältnis mit einem Akku läuft.
Recovery- und Debug-Pins¶
RESET — auf GND ziehen, um das Board zurückzusetzen. Beim Loslassen startet der MCU normal hoch.
BOOT0 — beim Einschalten des Boards auf 3,3 V ziehen, um den STM32-ROM-Bootloader (DFU-Modus) zu starten. OpenMV IDE verwendet diesen Modus, um den integrierten Bootloader neu zu flashen.
Das Board stellt neben der GPIO-Stiftleiste eine SWD-Debug-Leiste (RST / SWCLK / SWDIO / SWO) bereit, die mit ST‑LINK- und SEGGER J‑Link-Adaptern kompatibel ist.
Bemerkung
Der SWO-Trace-Pin ist mit der SPI-Taktleitung der Kamera-Stiftleiste geteilt. SWO kann nicht gleichzeitig mit einem Kameramodul verwendet werden, das über SPI mit dem MCU kommuniziert — zum Beispiel dem FLIR® Lepton® Adapter Module — wählen Sie das eine oder das andere.
Integrierte Peripheriegeräte¶
LEDs¶
Die H7 Plus hat eine einzelne RGB-Benutzer-LED sowie ein Paar leistungsstarke 850 nm-IR-LEDs:
RGB-Benutzer-LED — softwaregesteuert, bereitgestellt als
LED_RED,LED_GREENundLED_BLUE:from machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
IR-LEDs — beide LEDs werden gemeinsam über den
LED_IR-Pin angesteuert.LED_IRist in der Hardware High-aktiv verdrahtet, während die Firmware jede andere integrierte LED als Low-aktiv behandelt. Verwenden Sie daherlow()/high()anstelle vonon()/off()(was die Logik umkehren würde):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Kamerasensor¶
Der OV5640 wird über das Modul csi — Kamerasensoren angesteuert:
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()
Der OV5640 verfügt über einen integrierten JPEG-Kompressor. Setzen Sie csi.CSI.pixformat auf csi.JPEG, und der Sensor liefert komprimierte Einzelbilder direkt über den Kamerabus an die Cam, was hochauflösende Aufnahmen praktikabel macht: csi.HD (1280×720), csi.FHD (1920×1080) und das volle 5MP-csi.WQXGA2 (2592×1944) werden alle als JPEG gestreamt. Stellen Sie die Kompression mit csi.CSI.quality ein (0-100, höher = größere Einzelbilder, mehr Details):
cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)
Der Sensor sitzt auf einem abnehmbaren Modul — tauschen Sie ihn gegen eines der anderen OpenMV-Kameramodule aus (Global Shutter, thermisch, höhere Auflösung usw.), ohne den Rest des Boards zu ändern.
Maschinelles Lernen¶
ml — Maschinelles Lernen führt quantisierte TFLite-Modelle auf dem Cortex‑M7 mit CMSIS‑NN-Kerneln aus — schnell genug für kompakte Detektoren mit einigen Einzelbildern pro Sekunde. Modelle auf dem schreibgeschützten /rom-Dateisystem werden direkt aus dem Flash geladen, ohne in den RAM kopiert zu werden. Hier ist ein 128×128-BlazeFace-Detektor, der das erkannte Gesicht und seine sechs Landmarken in jedem Einzelbild überlagert:
import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace
# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))
# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# faces is a list of ((x, y, w, h), score, keypoints) tuples
for r, score, keypoints in model.predict([img]):
ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)
# keypoints is a ndarray of shape (6, 2)
# 0 - right eye (x, y)
# 1 - left eye (x, y)
# 2 - nose (x, y)
# 3 - mouth (x, y)
# 4 - right ear (x, y)
# 5 - left ear (x, y)
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
print(clock.fps(), "fps")
microSD-Karte¶
Wenn eine Karte eingelegt ist, wird sie automatisch unter /sdcard eingehängt und ist über das reguläre Dateisystem nutzbar:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Bus-Referenz¶
GPIO¶
Verwenden Sie machine.Pin, um beliebige der bedruckten Pins zu lesen oder anzusteuern. Die Ausgänge sind 3,3 V-CMOS, eingangsseitig 5 V-tolerant und können bis zu 25 mA pro Pin senken/liefern (120 mA insgesamt über die gesamte Stiftleiste).
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())
Jeder Eingangspin kann außerdem einen Interrupt bei Flankenwechseln auslösen:
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 |
|---|---|---|
UART1 |
P1 |
P0 |
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 |
I2C4 |
P7 |
P8 |
from machine import I2C
i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Dieselbe Hardware kann über machine.I2CTarget auch im Target-Modus (Slave) verwendet werden, um einem anderen I²C-Controller einen Speicherbereich bereitzustellen:
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 (FDCAN)¶
Bus |
TX |
RX |
|---|---|---|
FDCAN2 |
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 und DAC¶
P6 ist der einzige analoge Benutzer-Pin. Er kann entweder als 12‑Bit-ADC-Eingang oder als DAC-Ausgang verwendet werden.
ADC — Vollausschlag bei 3,3 V am 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 — über
pyb.DAC. Der 8‑Bit-Wert deckt 0–3,3 V ab:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
Im ADC- oder DAC-Modus ist P6 nur 3,3 V-tolerant — speisen Sie keine 5 V ein.
PWM¶
Pin |
Timer / Kanal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Bemerkung
TIM1 ist von der Firmware reserviert, um den Pixeltakt des Kamerasensors zu erzeugen. Daher können die TIM1-Kanäle, die physisch auf P0/P1/P2 liegen, nicht für benutzerdefiniertes PWM verwendet werden, ohne die Kamera zu beeinträchtigen.
TIM4 wird mit pyb.Servo geteilt — das Instanziieren eines Servos konfiguriert den gesamten Timer für 50 Hz-Betrieb um. Mischen Sie daher nicht machine.PWM auf P7/P8 mit pyb.Servo im selben Skript.
Steuern Sie eine davon über machine.PWM an:
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Software-Bit-Banged-Busse¶
machine.SoftI2C und machine.SoftSPI funktionieren auf jedem GPIO, falls Sie einen zusätzlichen Bus benötigen.
Thermosensor (extern)¶
Die Firmware enthält den fir — Wärmesensortreiber (fir == far infrared)-Treiber für extern verdrahtete Wärmebildkameras:
MLX90621 — 16 × 4-IR-Array
MLX90640 — 32 × 24-IR-Array
MLX90641 — 16 × 12-IR-Array
AMG8833 — 8 × 8-IR-Array
Verdrahten Sie das Modul mit dem I²C-Bus des Boards und lesen Sie Einzelbilder mit 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())
Der fir-Treiber kommuniziert mit dem Sensor nur über I²C 2 — verdrahten Sie das Modul mit P4 (SCL) und P5 (SDA).
Timing¶
time¶
Das Modul time deckt blockierende Verzögerungen, monotone Ticks und Messung der verstrichenen Zeit ab:
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)
Virtuelle Timer¶
machine.Timer plant periodische oder einmalige Callbacks, ohne einen Hardware-Timer-Slot zu belegen. Übergeben Sie -1 als id, um einen virtuellen (Software-)Timer zu verwenden:
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"))
Die Periodenwerte sind in Millisekunden angegeben. Rufen Sie deinit() auf, um den Slot zu stoppen und freizugeben.
Echtzeituhr¶
machine.RTC hält die Echtzeit über Resets hinweg:
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 setzt das Board zurück, wenn die Anwendung hängt. Einmal gestartet, kann er nicht gestoppt oder umkonfiguriert werden — füttern Sie ihn regelmäßig innerhalb Ihrer Hauptschleife:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Boot- und Laufzeitinformationen¶
USB-Bootloader-Fenster¶
Bei jedem Einschalten führt die Kamera einen kurzen Bootloader (einige Sekunden) aus, der es OpenMV IDE ermöglicht, die Firmware zu aktualisieren, ohne dass der Benutzer den DFU-Modus aufrufen muss. Nach Ablauf des Fensters übergibt der Bootloader an boot.py und dann an main.py.
Ein laufendes Skript kann den Bootloader bei Bedarf erneut aufrufen, indem es machine.bootloader() aufruft:
import machine
machine.bootloader()
Dateisystem und Boot-Reihenfolge¶
Die H7 Plus-Firmware hängt beim Booten bis zu drei Dateisysteme ein:
Internes Flash — immer unter
/flasheingehängt. Enthält standardmäßigmain.pyundREADME.txt; wird beim allerersten Boot erstellt.microSD-Karte — wenn eine Karte eingelegt ist, wird sie unter
/sdcardeingehängt.ROMFS — schreibgeschütztes, speicherabgebildetes Dateisystem unter
/rom, das zum Ausliefern großer Datenbestände (z. B. KI-Modelle) verwendet wird, die von Zero-Copy-Zugriff profitieren. Wird von MicroPython beim Start automatisch eingehängt, bevor benutzerdefinierter Python-Code ausgeführt wird.
Nach dem Einhängen wird das Arbeitsverzeichnis auf /sdcard gesetzt, wenn die Karte vorhanden ist, andernfalls auf /flash. Der Interpreter führt dann Skripte aus diesem Verzeichnis aus:
boot.pywird bei jedem Soft-Reset ausgeführt (Kaltstart,Ctrl‑Daus dem REPL oder immer dann, wenn das laufende Skript zurückkehrt).main.pywird nur beim Kaltstart ausgeführt, unmittelbar nachboot.py. Nachfolgende Soft-Resets führenboot.pyerneut aus, springen aber direkt zum REPL — ummain.pyerneut auszuführen, müssen Sie das Board vollständig zurücksetzen.
Wenn Sie eine boot.py oder main.py auf die SD-Karte legen, überschreibt dies die Kopie im Flash, ohne sie zu verändern — beide Dateien werden im Boot-Verzeichnis gesucht (/sdcard, wenn die Karte eingehängt ist, andernfalls /flash).
Die standardmäßige main.py, die auf einem frisch geflashten Board ausgeliefert wird, lässt lediglich den blauen Kanal der RGB-Benutzer-LED als Heartbeat blinken (zwei kurze Impulse, kurze Pause), sodass Sie erkennen können, dass die Firmware sauber gebootet hat, ohne dass ein Host angeschlossen ist.
sys.path wird erweitert, um alle drei Dateisysteme und ihre lib/-Unterverzeichnisse einzuschließen, sodass importierbare Module in /flash/lib, /sdcard/lib oder /rom/lib liegen können.
Um das System zu zwingen, eine eingelegte SD-Karte zu ignorieren (zum Beispiel, um die main.py im Flash auszuführen, auch wenn eine Karte vorhanden ist), erstellen Sie eine leere Datei namens SKIPSD im Stammverzeichnis von /flash.
Bei Verbindung über USB wird das Boot-Dateisystem (/sdcard, wenn eine Karte vorhanden ist, andernfalls /flash) auf dem Host auch als USB-Massenspeicherlaufwerk erkannt, sodass Sie boot.py, main.py und alle anderen Dateien direkt bearbeiten können. Werfen Sie das Laufwerk aus, bevor Sie die Kamera zurücksetzen, damit der Host seine zwischengespeicherten Schreibvorgänge leert.
Bemerkung
Da das Betriebssystem das Laufwerk als passives Blockgerät behandelt, werden Dateien, die von Code auf der OpenMV Cam erstellt oder geändert wurden, erst angezeigt, wenn der Host das Laufwerk erneut einhängt. Wenn sowohl das Betriebssystem als auch die OpenMV Cam gleichzeitig auf dasselbe Dateisystem schreiben, gewinnt das Betriebssystem und überschreibt die von der Kamera vorgenommenen Änderungen. Verwenden Sie die SD-Karte für alle Daten, die das Skript zurückschreibt, und hängen Sie das Laufwerk erneut ein, bevor Sie diese Dateien vom Host aus lesen.
Bemerkung
Der rote Kanal der RGB-Benutzer-LED kann kurz aufleuchten, während der Host vom USB-Massenspeicherlaufwerk liest oder darauf schreibt — dies ist eine firmwaregesteuerte Aktivitätsanzeige, kein Fehler.
Speichergrößen¶
Die H7 Plus wird ausgeliefert mit:
/flash— 24 MB FAT-Dateisystem, lesen/schreiben./rom— 8 MB schreibgeschütztes, speicherabgebildetes ROMFS, das zum Ausliefern von Skripten und ML-Modellen verwendet wird, die von Zero-Copy-mmap-Zugriff profitieren./sdcard— volle Größe der eingelegten microSD-Karte (sofern vorhanden), lesen/schreiben.
Hard-Fault-Anzeige¶
Wenn die RGB-Benutzer-LED schnell durch alle Farben wechselt — so schnell, dass sie eher wie eine funkelnde weiße LED als wie einzelne Farbtöne aussieht — ist die Firmware auf einen nicht behebbaren Hard Fault gestoßen. Flashen Sie die Firmware neu, um sich zu erholen; falls das erneute Flashen nicht hilft, ist das Board möglicherweise physisch beschädigt.
Software-Bibliotheken¶
Im Bibliotheksindex finden Sie die vollständige Liste der Module — einschließlich derjenigen, die ausschließlich im H7 Plus-Build enthalten sind.