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.

OpenMV Cam H7 Plus

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

OpenMV Cam H7 Plus OV5640 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_GREEN und LED_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_IR ist in der Hardware High-aktiv verdrahtet, während die Firmware jede andere integrierte LED als Low-aktiv behandelt. Verwenden Sie daher low() / high() anstelle von on() / 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 /flash eingehängt. Enthält standardmäßig main.py und README.txt; wird beim allerersten Boot erstellt.

  • microSD-Karte — wenn eine Karte eingelegt ist, wird sie unter /sdcard eingehä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.py wird bei jedem Soft-Reset ausgeführt (Kaltstart, Ctrl‑D aus dem REPL oder immer dann, wenn das laufende Skript zurückkehrt).

  • main.py wird nur beim Kaltstart ausgeführt, unmittelbar nach boot.py. Nachfolgende Soft-Resets führen boot.py erneut aus, springen aber direkt zum REPL — um main.py erneut 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:

  • /flash24 MB FAT-Dateisystem, lesen/schreiben.

  • /rom8 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.