Arduino Portenta H7

Arduino Portenta H7 är ett industriellt utvecklingskort på 66 × 25 mm byggt kring STMicroelectronics STM32H747XI — en dubbelkärnig SoC som kombinerar en Cortex‑M7 på 400 MHz med en Cortex‑M4 på 200 MHz. OpenMV-firmware körs helt på M7‑kärnan och är avsedd att användas med Portenta Vision Shield (Ethernet- eller LoRa‑utgåvan), som lägger till en Himax HM01B0 / HM0360-kamera, dubbla PDM‑mikrofoner och en microSD‑plats till bas-Portenta H7.

Arduino Portenta H7

För fullständigt datablad, foton och mått, se produktsidan för Arduino Portenta H7.

Höjdpunkter

  • STMicroelectronics STM32H747XI dubbel Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). OpenMV-firmware körs endast på M7‑kärnan; M4‑kärnan exponeras via openamp för kommunikation mellan processorer.

  • 8 MB externt SDRAM plus 2 MB internt flashminne och 16 MB externt QSPI-flashminne.

  • Hårdvarubaserad JPEG-kodare/-avkodare.

  • Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 via Murata 1DX-modulen (CYW4343W) — ansluts till den medföljande antennen via en inbyggd U.FL-kontakt.

  • Höghastighets-USB‑C (480 Mb/s).

  • 22 användar-I/O-stift på Arduino MKR‑liknande topplister — D0–D14 (digitala) plus A0–A6 (analoga).

  • Två 80‑stifts högdensitetskontakter på undersidan exponerar hela STM32H747-strukturen — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UART:ar, ytterligare SPI/I²C/timrar och så vidare. Shields som Vision Shield ansluts till dessa kontakter.

  • JTAG / SWD utbrutet på de undre HD‑kontakterna för avancerad felsökning.

  • Batteristöd — 3,7 V Li‑Po JST-kontakt plus inbyggd laddare och batteriövervakare.

Stiftschema

Stiftschema för Arduino Portenta H7

Stiftreferens

22 användarstift exponeras på Arduino MKR‑liknande topplister — 15 digitala (D0-D14) plus 7 analoga (A0-A6). Många fler SoC-stift är tillgängliga via de undre 80‑stifts högdensitetskontakterna för shield-arbete; se Arduinos fullständiga stiftschema-PDF för den mappningen.

Stiftnamn

Referens

Funktion

D0

3,3 V

TIM8 CH3N

D1

3,3 V

TIM1 CH1 / SPI5 NSS

D2

3,3 V

TIM1 CH2 / SPI5 MISO

D3

3,3 V

GPIO

D4

3,3 V

TIM3 CH2 / TIM8 CH2 / USART6 RX

D5

3,3 V

TIM3 CH1 / TIM8 CH1 / USART6 TX

D6

3,3 V

TIM1 CH1 / I2C3 SCL

D7

3,3 V

TIM5 CH4 / SPI2 NSS

D8

3,3 V

SPI2 MOSI (delas med A3 / A5)

D9

3,3 V

SPI2 SCK

D10

3,3 V

SPI2 MISO (delas med A2 / A4)

D11

3,3 V

I2C3 SDA

D12

3,3 V

I2C3 SCL

D13

3,3 V

USART1 RX / TIM1 CH3

D14

3,3 V

USART1 TX / TIM1 CH2

A0

3,3 V

ADC12 IN0 (endast analog)

A1

3,3 V

ADC12 IN1 (endast analog)

A2

3,3 V

ADC123 IN12 (endast analog; delas med D10)

A3

3,3 V

ADC12 IN13 (endast analog; delas med D8)

A4

3,3 V

ADC123 IN12 (delas med D10)

A5

3,3 V

ADC12 IN13 (delas med D8)

A6

3,3 V

DAC1 OUT1 / ADC12 IN18

A7

3,3 V

TIM3 CH1 / ADC12 IN3 (exponeras inte på listerna)

D20

3,3 V

alias för D8 / A3 / A5

D21

3,3 V

alias för A6 — DAC1 OUT1

RESET

3,3 V

tryck på den inbyggda brytaren eller dra till GND för att återställa

LED_RED

3,3 V

RGB-LED:ns röda kanal (aktiv låg)

LED_GREEN

3,3 V

RGB-LED:ns gröna kanal (aktiv låg)

LED_BLUE

3,3 V

RGB-LED:ns blåa kanal (aktiv låg)

Anteckning

A0-A3 är enbart analoga ytor på STM32H747 utan GPIO-funktion — behandla dem enbart som ADC-ingångar. A2/A4 och A3/A5 delar sina fysiska stift med D10 respektive D8, så du kan inte driva PWM eller SPI på dessa medan du läser dem som analoga. A7 ligger på de undre HD‑kontakterna.

Strömstift

MKR-listens stift:

  • VIN — huvudsaklig systemmatning in i den inbyggda PMIC:n. Matas via en diod från +5V-skenan, MKR VIN-stiftet eller de undre 80‑stifts HD‑kontakterna.

  • +5V — 5 V-skena matad från USB, ESLOV-kontakten eller MKR +5V-stiftet självt.

  • +3V3 — huvudsaklig 3,3 V-skena (utgång från PMIC:ns switchregulator).

  • AREF — analog spänningsreferens för ADC-stiften. Standard är 3,3 V; mata externt för att använda en annan referens.

  • GND — gemensam jord.

Batteriingång:

  • Li‑Po JST på kortets framsida tar emot en 3,7 V Li‑Po-cell. PMIC:n laddar den närhelst +5V eller VIN finns tillgänglig.

Portenta H7 kan strömförsörjas via vilken som helst av dessa vägar:

  • USB‑C — levererar 5 V till den inbyggda PMIC:n.

  • ESLOV-kontakt — upp till 5 V på VESLOV (se ESLOV-kontakt).

  • VIN-stift — mata en reglerad 5 V-källa direkt.

  • Li‑Po-batteri — anslut till JST på framsidan.

ESLOV-kontakt

På sidan av kortet finns en 5‑stifts lödfri ESLOV-kontakt:

Stift

Namn

Funktion

1

VESLOV

5 V strömutgång (samma skena som MKR-listens +5V)

2

INT

extern avbrottsingång på D7

3

SCL_EXT

delas med MKR-listens D12-yta — samma I²C 3-buss som användarlisten

4

SDA_EXT

delas med MKR-listens D11-yta — samma I²C 3-buss som användarlisten

5

GND

gemensam jord

ESLOV:s SCL_EXT/SDA_EXT och MKR-listens D12/D11 är samma stift — en I²C 3-buss exponerad på två kontakter.

Tips

Använd batterilivslängdsuppskattaren för att modellera hur länge Portenta H7 kommer att köra på ett batteri vid en given aktiv/djupsömns-arbetscykel.

Återställnings- och felsökningsstift

  • RESET — både ett exponerat stift på topplisten och en momentan brytare på sidan av kortet, kopplade till SoC:ns NRST-linje. Dra till GND eller tryck på knappen för att återställa.

Portenta H7 använder Arduinos standard dubbeltrycks-återställning för att gå in i Arduinos startladdare. Tryck snabbt på återställningsknappen två gånger — kortet räknas om över USB som en DFU-enhet och OpenMV IDE kan flasha en ny firmware-avbildning.

STM32 SWD-signalerna exponeras på den undre HD-kontakten J1:

  • J1‑73 — NRST

  • J1‑75 — SWDIO (PA13)

  • J1‑77 — SWCLK (PA14)

  • J1‑79 — SWO (PB3)

Koppla in dem via en Portenta Breakout, den officiella Arduino-felsökningsadaptern eller en anpassad bärare med en 1,27 mm-list. Alla felsökningssignaler är 3,3 V-refererade.

Anteckning

När Portenta Vision Shield är ansluten dras samma SWD/JTAG-signaler upp till den standardiserade 20‑stifts ARM Cortex Debug JTAG-listen på shieldet (1,27 mm / 0,05″ delning).

Inbyggd kringutrustning

LED:ar

Portenta H7 har en enda RGB-LED för användaren, programstyrbar via machine.LED

from machine import LED

LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()

En separat orange ladd-LED bredvid batteri-JST:n lyser när den inbyggda laddaren matar ström till en ansluten Li‑Po; den är inte användarstyrbar.

Kamerasensor (Vision Shield)

Med Portenta Vision Shield (Ethernet- eller LoRa‑utgåvan) ansluten drivs Himax-sensorn genom modulen csi — kamerasensorer

import csi

cam = csi.CSI()
cam.reset()
cam.pixformat(csi.GRAYSCALE)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000)       # let auto‑exposure settle

while True:
    img = cam.snapshot()

Två Vision Shield-revisioner stöds:

  • HM01B0 — 320 × 320 monokrom.

  • HM0360 — 640 × 480 monokrom.

Varning

Medan Vision Shield-kameran är initierad är följande MKR-listens stift upptagna av firmware och kan inte användas:

MKR-stift

Orsak

D1

TIM1 CH1 — kamerans huvudklocka

D6

TIM1 CH1 (alt) — kamerans huvudklocka

D11

I²C 3 SDA — delas med kameran; bussen är användbar men undvik sensorns I²C-adress (0x24)

D12

I²C 3 SCL — delas med kameran; bussen är användbar men undvik sensorns I²C-adress (0x24)

A6 / D21

DCMI HSYNC — inaktiverar även DAC:n

A7

DCMI PXCLK

Maskininlärning

ml — Maskininlärning kör kvantiserade TFLite-modeller på Cortex‑M7 med CMSIS‑NN-kärnor — snabbt nog för kompakta detektorer vid några bildrutor per sekund. Modeller på det skrivskyddade filsystemet /rom laddas direkt från flashminnet utan att kopieras till RAM. Här är en 128×128 BlazeFace-detektor som lägger det detekterade ansiktet och dess sex landmärken som överlägg på varje bildruta från Vision Shield-kameran:

import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace

# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.QVGA)
csi0.window((240, 240))

# 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)
        ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))

    print(clock.fps(), "fps")

M4-kärna

Cortex‑M4-kärnan exponeras via openamp för kommunikation mellan processorer. OpenMV-firmware körs endast på M7; M4 har ingen egen MicroPython-körmiljö, så att använda den innebär att bygga en separat C-firmware-avbildning och ladda den från filsystemet via openamp.RemoteProc. Förbyggd exempel-firmware som implementerar en virtuell UART-ändpunkt finns i förvaret openamp_vuart — följ dess README för att bygga vuart.elf

import openamp
import time

def ept_recv_callback(src_addr, data):
    print("Received:", data.decode())

ept = openamp.Endpoint("vuart-channel", callback=ept_recv_callback)

rproc = openamp.RemoteProc("vuart.elf")
rproc.start()

count = 0
while True:
    if ept.is_ready():
        ept.send("Hello World %d!" % count, timeout=1000)
        count += 1
    time.sleep_ms(1000)

I praktiken är detta stöd bäst att betrakta som en demonstration av openamp-gränssnittet snarare än en fungerande dubbelkärnig plattform — M4 kan inte återställas oberoende av M7, så att stoppa M4 framtvingar en fullständig systemomstart.

Mikrofon (Vision Shield)

Vision Shield bär dubbla PDM-mikrofoner som fångas genom audio — Ljudmodul över STM32:ns SAI4-kringutrustning. Varje buffert anländer som signerad 16-bitars PCM-bytearray, redo att matas in i ulab/numpy för DSP — till exempel en enkel ljudstyrkedetektor:

import audio
from ulab import numpy as np

def loudness(pcmbuf):
    samples = np.array(np.frombuffer(pcmbuf, dtype=np.int16), dtype=np.float)
    rms = np.sqrt(np.mean(samples ** 2))
    if rms > 10000:
        print("Loud!", int(rms))

audio.init(channels=1, frequency=16000, gain_db=24)
audio.start_streaming(loudness)

while True:
    pass

Skicka channels=2 till audio.init för att ta emot sammanvävda sampel från båda mikrofonerna.

Batteribränslemätare

Maxims MAX17262 ModelGauge m5-bränslemätare spårar Li‑Po-batteriets spänning, ström, temperatur och laddningstillstånd. Den sitter på I²C 1 på adress 0x36.

MAX17262 har intern strömavkänning, så strömregistret läses direkt ut i mikroampere utan någon extern Rsense-faktor att tillämpa. Att läsa bränslemätaren är ofarligt — det finns ingen medföljande drivrutin, men registren som dokumenteras i MAX17262-databladet kan läsas direkt:

import time
import struct
from machine import I2C

FUEL_GAUGE = 0x36   # MAX17262

def read_reg(bus, addr, reg):
    return struct.unpack("<H", bus.readfrom_mem(addr, reg, 2))[0]

def read_signed(bus, addr, reg):
    v = read_reg(bus, addr, reg)
    return v - 0x10000 if v & 0x8000 else v

bus = I2C(1)

while True:
    # 0x05 RepCap — remaining capacity, raw × 0.5 mAh
    rep_cap   = read_reg(bus, FUEL_GAUGE, 0x05) * 0.5
    # 0x06 RepSOC — state of charge, raw / 256 %
    soc       = read_reg(bus, FUEL_GAUGE, 0x06) / 256
    # 0x08 Temp — die temperature, signed, raw / 256 °C
    temp      = read_signed(bus, FUEL_GAUGE, 0x08) / 256
    # 0x09 VCell — battery voltage, raw × 78.125 µV
    vcell     = read_reg(bus, FUEL_GAUGE, 0x09) * 78.125 / 1_000_000
    # 0x0A Current — signed, raw × 156.25 µA
    current   = read_signed(bus, FUEL_GAUGE, 0x0A) * 156.25 / 1000
    # 0x0B AvgCurrent — averaged current
    avg_curr  = read_signed(bus, FUEL_GAUGE, 0x0B) * 156.25 / 1000
    # 0x10 FullCapRep — learned full capacity, raw × 0.5 mAh
    full_cap  = read_reg(bus, FUEL_GAUGE, 0x10) * 0.5
    # 0x11 TTE — time-to-empty (valid while discharging), raw × 5.625 s
    tte_s     = read_reg(bus, FUEL_GAUGE, 0x11) * 5.625
    # 0x20 TTF — time-to-full   (valid while charging),  raw × 5.625 s
    ttf_s     = read_reg(bus, FUEL_GAUGE, 0x20) * 5.625
    # 0x17 Cycles — charge-cycle counter, 1% per LSB
    cycles    = read_reg(bus, FUEL_GAUGE, 0x17) / 100

    print("V:        %.3f V" % vcell)
    print("Capacity: %.1f / %.1f mAh (%.1f %%)" % (rep_cap, full_cap, soc))
    print("Temp:     %.1f C" % temp)
    print("Current:  %.1f mA  (avg %.1f mA)" % (current, avg_curr))
    print("TTE:      %.0f s   TTF: %.0f s" % (tte_s, ttf_s))
    print("Cycles:   %.2f" % cycles)
    print()
    time.sleep_ms(1000)

Current är signerad tvåkomplement: positiv vid laddning, negativ vid urladdning. TTE är endast meningsfull när strömmen är negativ; TTF endast när strömmen är positiv.

Strömhanteringskrets

NXP:s PF1550 PMIC hanterar varje regulator på Portenta H7 — +3V3-huvudskenan, +1V8 SoC-kärn-/I/O-skenan och Li‑Po-laddaren. Den sitter på I²C 1 på adress 0x08.

Varning

Att läsa PMIC-register är okej; att skriva till dem är farligt. Felkonfiguration av en buck-regulator eller en laddarinställning kan permanent skada kortet, batteriet eller båda. Behandla PMIC:n som skrivskyddad om du inte vet exakt vad du gör.

Det mest användbara som PMIC:n berättar för dig som bränslemätaren inte kan är laddarens tillståndsmaskin — om kortet just nu körs på USB / ESLOV / VIN, vilket skede i laddningscykeln Li‑Po:n befinner sig i, och om laddaren är i ett termiskt fel eller ett watchdog-fel. Laddarregistren ligger på en offset av 0x80 i PF1550:ns huvudsakliga I²C-adressutrymme (se §22.2 i PF1550-databladet), så till exempel läses CHG_INT_OK på laddaradress 0x04 från PMIC-register 0x84

import time
from machine import I2C

PMIC = 0x08

# Charger state machine (low nibble of CHG_SNS, register 0x87)
CHG_STATES = {
    0x0: "precharge",
    0x1: "fast charge (constant current)",
    0x2: "fast charge (constant voltage)",
    0x3: "end of charge",
    0x4: "done",
    0x6: "timer fault",
    0x7: "thermistor suspend",
    0x8: "off — input invalid or charger disabled",
    0x9: "battery overvoltage",
    0xA: "thermal shutdown",
    0xC: "linear mode (not charging)",
}

bus = I2C(1)

while True:
    # 0x84 CHG_INT_OK — single-bit indicators
    ok = bus.readfrom_mem(PMIC, 0x84, 1)[0]
    vbus_ok = bool(ok & (1 << 5))   # bit 5 — VBUS valid (USB/VIN)
    bat_ok  = bool(ok & (1 << 2))   # bit 2 — battery OK
    chg_ok  = bool(ok & (1 << 3))   # bit 3 — charger actively charging
    thm_ok  = bool(ok & (1 << 7))   # bit 7 — thermistor in normal range

    # 0x87 CHG_SNS — charger state + thermal regulation flag
    chg_sns = bus.readfrom_mem(PMIC, 0x87, 1)[0]
    state   = CHG_STATES.get(chg_sns & 0x0F, "reserved")
    treg    = bool(chg_sns & (1 << 7))   # thermal regulation active

    print("VBUS valid:         ", vbus_ok)
    print("battery OK:         ", bat_ok)
    print("charger active:     ", chg_ok)
    print("thermistor normal:  ", thm_ok)
    print("thermal reg active: ", treg)
    print("state:              ", state)
    print()
    time.sleep_ms(1000)

Andra skrivskyddade register värda att titta på i databladet (alla på laddar-offset 0x80): 0x80 CHG_INT (låsta laddaravbrott — felflaggor), 0x86 VBUS_SNS (det flerbitars VBUS-tillståndet inklusive OVLO / UVLO / DPM) och 0x88 BATT_SNS (batterinärvaro och överströmstillstånd).

Wi‑Fi

Den inbyggda Murata 1DX (CYW4343W) exponeras via network — nätverkskonfiguration som ett stationsgränssnitt. Anslut den medföljande antennen till den inbyggda U.FL-kontakten innan du startar radion:

import network, time

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
    time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])

Bluetooth

Samma Murata 1DX exponerar även Bluetooth LE 5.1. Använd aioble — Asynkron BLE för asyncio-vänlig BLE — till exempel, annonsera som en kringutrustning och vänta på att en central ansluter:

import asyncio
import aioble

async def run():
    while True:
        conn = await aioble.advertise(250_000, name="Portenta-H7")
        print("Connected:", conn.device)
        await conn.disconnected()

asyncio.run(run())

LoRa (Vision Shield)

LoRa-utgåvan av Vision Shield lägger till en Murata CMWX1ZZABZ LoRaWAN-modul kopplad till Portenta H7 över UART. Modulen lora omsluter AT-kommando-firmware och stöder OTAA- eller ABP-anslutning, upplänk och nedlänk:

from lora import Lora
from lora import BAND_EU868
from lora import LoraErrorTimeout

lora = Lora(band=BAND_EU868, poll_ms=60000)
print("Device EUI:", lora.get_device_eui())

appEui = "1234567890123456"
appKey = "12345678901234567890123456789012"

try:
    lora.join_OTAA(appEui, appKey)
except LoraErrorTimeout as e:
    print("Join timed out — try moving near a window:", e)

lora.set_port(3)
lora.send_data("HeLoRA world!", True)

while True:
    if lora.available():
        data = lora.receive_data()
        if data:
            print("Port:", data["port"], "Data:", data["data"])
    lora.poll()

Använd BAND_US915 / BAND_AS923 / BAND_AU915 osv. för regioner utanför EU, och växla till lora.Lora.join_ABP() om din nätverksserver använder ABP-aktivering.

Varning

Medan LoRa-modulen används tar drivrutinen följande MKR-listens stift i anspråk som styrlinjer för Murata CMWX1ZZABZ — de kan inte användas:

MKR-stift

Orsak

D3

LoRa-modulens BOOT-stift

D5

LoRa-modulens RST-stift

Ethernet (Vision Shield)

Ethernet-utgåvan av Vision Shield lägger till ett RJ45-uttag med magnetik kopplat till STM32H747:ns 10/100 Ethernet-MAC över RMII. Koppla in en Ethernet-kabel så visas PHY:n som ett LAN-gränssnitt; DHCP körs automatiskt så fort länken kommer upp:

import network
import time

lan = network.LAN()
lan.active(True)
while not lan.isconnected():
    time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])

microSD-kort (Vision Shield)

När ett kort sätts i monteras det automatiskt på /sdcard och är användbart via 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 och kan sänka/leverera upp till 20 mA per stift (140 mA totalt över hela listen).

from machine import Pin

out = Pin("D0", Pin.OUT)
out.on()
out.off()
out.value(1)

inp = Pin("D1", Pin.IN, Pin.PULL_UP)
print(inp.value())

Vilket ingångsstift som helst kan även utlösa ett avbrott vid kanttransitioner:

def handler(pin):
    print("triggered:", pin)

Pin("D1", Pin.IN, Pin.PULL_UP).irq(
    handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)

UART

Buss

TX

RX

UART1

D14

D13

UART6

D5

D4

from machine import UART

uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)

I²C

Buss

SCL

SDA

I2C3

D12

D11

from machine import I2C

i2c = I2C(3, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")

D11/D12-ytorna på MKR-listen och ESLOV-kontaktens SDA_EXT/SCL_EXT-stift hamnar på samma I²C 3-buss — se ESLOV-kontakt ovan för ESLOV-stiftschemat.

Samma hårdvara kan även användas i mål-läge (slav) via machine.I2CTarget för att exponera ett minnesområde för en annan I²C-styrenhet:

from machine import I2CTarget

buf = bytearray(32)
target = I2CTarget(3, addr=0x42, mem=buf)

SPI

Buss

MOSI

MISO

SCK

CS

SPI2

D8

D10

D9

D7

from machine import SPI
from machine import Pin

spi = SPI(2, baudrate=10_000_000)
cs = Pin("D7", Pin.OUT, value=1)   # CS is not driven by the SPI peripheral

cs.value(0)
spi.write(b"hello")
cs.value(1)

ADC

Portenta H7 exponerar åtta 12‑bitars ADC-kanaler på A0–A7. Alla är 3,3 V-refereraderead_u16 returnerar 0–65535 över 0–3,3 V vid stiftet:

from machine import ADC
import time

adc = ADC("A0")
while True:
    voltage = adc.read_u16() * 3.3 / 65535
    print(voltage)
    time.sleep_ms(100)

DAC

En enda 12‑bitars DAC-kanal exponeras på DAC1 (A6 / D21) via pyb.DAC

from pyb import DAC

dac = DAC("DAC1")
dac.write(int(0.5 * 255))   # 8‑bit output, ~1.65 V

PWM

Stift

Timer / kanal

D0

TIM8 CH3N

D1

TIM1 CH1, TIM8 CH3N

D2

TIM1 CH2, TIM8 CH2N

D4

TIM3 CH2, TIM8 CH2

D5

TIM3 CH1, TIM8 CH1

D6

TIM1 CH1

D7

TIM5 CH4

D13

TIM1 CH3

D14

TIM1 CH2

A7

TIM3 CH1

Driv vilken som helst av dem via machine.PWM

from machine import Pin, PWM

pwm = PWM(Pin("D4"), freq=1_000, duty_u16=32768)

Anteckning

Flera stift delar timerkanaler:

  • TIM1 CH1 finns på D1 och D6.

  • TIM1 CH2 finns på D2 och D14.

  • TIM8 CH3N finns på D0 och D1.

Välj en konsument per timerkanal.

Varning

TIM1 är reserverad för kamerans huvudklocka när Vision Shield initieras via csi — kamerasensorerD1, D2, D6, D13 och D14 kan inte PWM-drivas medan kameran är aktiv.

Programvarustyrda bit-bangade bussar

machine.SoftI2C och machine.SoftSPI fungerar på vilken GPIO som helst om du behöver en extra buss.

Värmesensor (extern)

Firmware innehåller drivrutinen fir — drivrutin för värmesensor (fir == far infrared) för externt kopplade värmekameror:

  • 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 endast med sensorn över I²C 3 — koppla modulen till D12 (SCL) och D11 (SDA).

Tidtagning

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 (programvarubaserad) 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. HD-kontakten exponerar även en COINCELL-yta som kan stödja RTC:n från ett CR2032 vid strömavbrott:

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 återställer kortet om applikationen hänger sig. När den väl startats 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()

Boot- och körtidsinformation

Firmware-uppdatering (DFU)

Portenta H7 använder Arduinos standard dubbeltrycks-återställning för att gå in i Arduinos startladdare. Tryck snabbt på återställningsknappen två gånger — kortet räknas om över USB som en DFU-enhet och OpenMV IDE kan flasha en ny firmware-avbildning.

Ett körande skript kan gå in i startladdaren igen på begäran genom att anropa machine.bootloader()

import machine

machine.bootloader()

Filsystem och bootordning

Portenta H7-firmware monterar upp till tre filsystem vid uppstart:

  • Internt flashminne — alltid monterat på /flash. Innehåller main.py och README.txt som standard; skapas vid allra första uppstarten.

  • microSD-kort — om en Vision Shield är ansluten och ett kort är isatt monteras det på /sdcard.

  • ROMFS — skrivskyddat, minnesmappat filsystem på /rom som monteras automatiskt av MicroPython vid uppstart.

Efter monteringen sätts arbetskatalogen till /sdcard när kortet är närvarande, annars /flash. Tolken kör sedan skript från den katalogen:

  • boot.py körs vid varje mjuk återställning (kallstart, Ctrl‑D från REPL:en, eller närhelst det körande skriptet returnerar).

  • main.py körs endast vid kallstart, omedelbart efter boot.py. Efterföljande mjuka återställningar kör om boot.py men hoppar direkt till REPL:en — för att köra om main.py må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 bootkatalogen (/sdcard när kortet är monterat, annars /flash).

Standard-main.py som levereras på ett nyflashat kort blinkar bara RGB-LED:ns blåa kanal som ett hjärtslag (två korta pulser, kort paus), så att du kan se att firmware startade rent utan någon ansluten värd.

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 flashminnets main.py även med ett kort närvarande), skapa en tom fil med namnet SKIPSD i roten av /flash.

När den är ansluten över USB räknas även bootfilsystemet (/sdcard om ett kort är närvarande, annars /flash) upp som en USB-masslagringsenhet på värden, vilket låter dig redigera boot.py, main.py och alla andra filer direkt. Mata ut enheten innan du återställer kortet så att värden tömmer sina cachade skrivningar.

Anteckning

Eftersom operativsystemet behandlar enheten som en passiv blockenhet kommer filer som skapats eller ändrats av kod som körs på kameran inte att synas förrän värden monterar om enheten. Om både operativsystemet och kameran skriver till samma filsystem samtidigt kommer operativsystemet att vinna och skriva över ändringar som gjorts av kameran. Använd SD-kortet för all data som skriptet skriver tillbaka, och montera om innan du läser dessa filer från värden.

Anteckning

RGB-LED:ns röda kanal kan tillfälligt lysa upp medan värden läser från eller skriver till USB-masslagringsenheten — detta är en firmware-styrd aktivitetsindikator, inte ett fel.

Lagringsstorlekar

Portenta H7 levereras med:

  • /flash11 MB FAT-filsystem, läs/skriv.

  • /rom4 MB skrivskyddat minnesmappat ROMFS, används för att leverera skript och ML-modeller som drar nytta av zero-copy mmap-åtkomst.

  • /sdcard — full storlek på vilket microSD-kort som än sätts i en Vision Shield (när närvarande), läs/skriv.

Indikator för allvarligt fel (hard fault)

Om RGB-LED:n snabbt växlar genom alla färger — snabbt nog att det tenderar att se ut som en tindrande vit LED snarare än distinkta nyanser — har firmware stött på ett oåterhämtbart allvarligt fel (hard fault). Flasha om firmware för att återhämta dig; om omflashning inte hjälper kan kortet vara fysiskt skadat.

Programvarubibliotek

Se biblioteksindexet för den fullständiga listan över moduler — inklusive vilka som är unika för Portenta H7-bygget.