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.
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¶
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 |
D21 |
3,3 V |
alias för |
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, MKRVIN-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
+5VellerVINfinns 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 |
2 |
INT |
extern avbrottsingång på |
3 |
SCL_EXT |
delas med MKR-listens |
4 |
SDA_EXT |
delas med MKR-listens |
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— NRSTJ1‑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 |
|---|---|
|
TIM1 CH1 — kamerans huvudklocka |
|
TIM1 CH1 (alt) — kamerans huvudklocka |
|
I²C 3 SDA — delas med kameran; bussen är användbar men undvik sensorns I²C-adress ( |
|
I²C 3 SCL — delas med kameran; bussen är användbar men undvik sensorns I²C-adress ( |
|
DCMI HSYNC — inaktiverar även DAC:n |
|
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 |
|---|---|
|
LoRa-modulens BOOT-stift |
|
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-refererade — read_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å
D1ochD6.TIM1 CH2 finns på
D2ochD14.TIM8 CH3N finns på
D0ochD1.
Välj en konsument per timerkanal.
Varning
TIM1 är reserverad för kamerans huvudklocka när Vision Shield initieras via csi — kamerasensorer — D1, 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ållermain.pyochREADME.txtsom 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å
/romsom 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.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 hoppar 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 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:
/flash— 11 MB FAT-filsystem, läs/skriv./rom— 4 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.