Arduino Portenta H7

Arduino Portenta H7 to przemysłowa płytka deweloperska o wymiarach 66 × 25 mm zbudowana wokół układu STMicroelectronics STM32H747XI — dwurdzeniowego SoC łączącego rdzeń Cortex‑M7 taktowany 400 MHz z rdzeniem Cortex‑M4 taktowanym 200 MHz. Oprogramowanie układowe OpenMV działa w całości na rdzeniu M7 i jest przeznaczone do użycia z nakładką Portenta Vision Shield (w wersji Ethernet lub LoRa), która dodaje do bazowej płytki Portenta H7 kamerę Himax HM01B0 / HM0360, dwa mikrofony PDM oraz gniazdo microSD.

Arduino Portenta H7

Pełną kartę katalogową, zdjęcia i wymiary znajdziesz na stronie produktu Arduino Portenta H7.

Najważniejsze cechy

  • STMicroelectronics STM32H747XI dwurdzeniowy Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). Oprogramowanie układowe OpenMV działa wyłącznie na rdzeniu M7; rdzeń M4 jest udostępniany przez openamp na potrzeby komunikacji międzyprocesorowej.

  • 8 MB zewnętrznej pamięci SDRAM oraz 2 MB wewnętrznej pamięci flash i 16 MB zewnętrznej pamięci flash QSPI.

  • Sprzętowy koder/dekoder JPEG.

  • Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 poprzez moduł Murata 1DX (CYW4343W) — łączy się z dołączoną anteną przez umieszczone na płytce złącze U.FL.

  • Wysokoprędkościowe USB‑C (480 Mb/s).

  • 22 piny użytkownika I/O na górnych goldpinach w stylu Arduino MKR — D0–D14 (cyfrowe) plus A0–A6 (analogowe).

  • Dwa 80‑pinowe złącza o dużej gęstości na spodzie udostępniają pełną strukturę STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UART‑y, dodatkowe SPI/I²C/liczniki czasu itd. Nakładki takie jak Vision Shield łączą się z tymi złączami.

  • JTAG / SWD wyprowadzone na dolne złącza HD na potrzeby zaawansowanego debugowania.

  • Obsługa akumulatora — złącze JST dla ogniwa Li‑Po 3,7 V plus wbudowana ładowarka i monitor akumulatora.

Wyprowadzenia (pinout)

Wyprowadzenia Arduino Portenta H7

Opis pinów

Na górnych goldpinach w stylu Arduino MKR wyprowadzono 22 piny użytkownika — 15 cyfrowych (D0-D14) plus 7 analogowych (A0-A6). Znacznie więcej pinów SoC jest dostępnych przez dolne 80‑pinowe złącza o dużej gęstości na potrzeby pracy z nakładkami; to mapowanie znajdziesz w pełnym pliku PDF z wyprowadzeniami od Arduino.

Nazwa pinu

Oznaczenie

Funkcja

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 (współdzielony z A3 / A5)

D9

3.3 V

SPI2 SCK

D10

3.3 V

SPI2 MISO (współdzielony z 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 (tylko analogowy)

A1

3.3 V

ADC12 IN1 (tylko analogowy)

A2

3.3 V

ADC123 IN12 (tylko analogowy; współdzielony z D10)

A3

3.3 V

ADC12 IN13 (tylko analogowy; współdzielony z D8)

A4

3.3 V

ADC123 IN12 (współdzielony z D10)

A5

3.3 V

ADC12 IN13 (współdzielony z D8)

A6

3.3 V

DAC1 OUT1 / ADC12 IN18

A7

3.3 V

TIM3 CH1 / ADC12 IN3 (niewyprowadzony na goldpiny)

D20

3.3 V

alias D8 / A3 / A5

D21

3.3 V

alias A6 — DAC1 OUT1

RESET

3.3 V

naciśnij wbudowany przełącznik lub zewrzyj do GND, aby zresetować

LED_RED

3.3 V

czerwony kanał diody RGB (aktywny stanem niskim)

LED_GREEN

3.3 V

zielony kanał diody RGB (aktywny stanem niskim)

LED_BLUE

3.3 V

niebieski kanał diody RGB (aktywny stanem niskim)

Informacja

A0-A3 to pady wyłącznie analogowe na STM32H747 bez funkcji GPIO — traktuj je jako wejścia ADC. A2/A4 oraz A3/A5 współdzielą swoje fizyczne piny odpowiednio z D10 i D8, więc nie możesz na nich sterować PWM ani SPI w trakcie odczytu jako analogowe. A7 znajduje się na dolnych złączach HD.

Piny zasilania

Piny goldpinów MKR:

  • VIN — główna szyna systemowa wprowadzana do wbudowanego PMIC. Zasilana przez diodę z szyny +5V, pinu VIN MKR lub dolnych 80‑pinowych złączy HD.

  • +5V — szyna 5 V zasilana z USB, złącza ESLOV lub samego pinu +5V MKR.

  • +3V3 — główna szyna 3,3 V (wyjście przetwornicy PMIC).

  • AREF — analogowe napięcie odniesienia dla pinów ADC. Domyślnie 3,3 V; podaj zewnętrznie, aby użyć innego odniesienia.

  • GND — wspólna masa.

Wejście akumulatora:

  • Złącze JST Li‑Po z przodu płytki przyjmuje ogniwo Li‑Po 3,7 V. PMIC ładuje je zawsze, gdy obecne jest +5V lub VIN.

Portenta H7 może być zasilana którąkolwiek z tych dróg:

  • USB‑C — dostarcza 5 V do wbudowanego PMIC.

  • Złącze ESLOV — do 5 V na VESLOV (zob. Złącze ESLOV).

  • Pin VIN — podaj bezpośrednio stabilizowane zasilanie 5 V.

  • Akumulator Li‑Po — podłącz do złącza JST z przodu.

Złącze ESLOV

Z boku płytki znajduje się 5‑pinowe, lutowane bez konieczności lutowania złącze ESLOV:

Pin

Nazwa

Funkcja

1

VESLOV

wyjście zasilania 5 V (ta sama szyna co +5V goldpinów MKR)

2

INT

wejście przerwania zewnętrznego na D7

3

SCL_EXT

współdzielony z padem D12 goldpinów MKR — ta sama magistrala I²C 3 co goldpiny użytkownika

4

SDA_EXT

współdzielony z padem D11 goldpinów MKR — ta sama magistrala I²C 3 co goldpiny użytkownika

5

GND

wspólna masa

Piny SCL_EXT/SDA_EXT złącza ESLOV oraz D12/D11 goldpinów MKR to te same piny — jedna magistrala I²C 3 wyprowadzona na dwa złącza.

Wskazówka

Użyj kalkulatora żywotności akumulatora, aby oszacować, jak długo Portenta H7 będzie działać na akumulatorze przy zadanym cyklu pracy aktywny / głęboki uśpienie.

Piny do odzyskiwania i debugowania

  • RESET — zarówno wyprowadzony pin na górnym goldpinie, jak i chwilowy przełącznik z boku płytki, połączone z linią NRST układu SoC. Zewrzyj do GND lub naciśnij przycisk, aby zresetować.

Portenta H7 wykorzystuje standardowy podwójny stuknięcie resetu Arduino, aby wejść do bootloadera Arduino. Szybko naciśnij dwukrotnie przycisk resetu — płytka ponownie wyliczy się przez USB jako urządzenie DFU, a OpenMV IDE może wgrać nowy obraz oprogramowania układowego.

Sygnały SWD STM32 są wyprowadzone na dolnym złączu HD J1:

  • J1‑73 — NRST

  • J1‑75 — SWDIO (PA13)

  • J1‑77 — SWCLK (PA14)

  • J1‑79 — SWO (PB3)

Podłącz je przez Portenta Breakout, oficjalny adapter debugowania Arduino lub własną płytkę nośną z goldpinem o rastrze 1,27 mm. Wszystkie sygnały debugowania są odniesione do 3,3 V.

Informacja

Gdy podłączona jest nakładka Portenta Vision Shield, te same sygnały SWD/JTAG są wyprowadzone na standardowy 20‑pinowy goldpin debugowania ARM Cortex Debug JTAG na nakładce (raster 1,27 mm / 0,05″).

Wbudowane urządzenia peryferyjne

Diody LED

Portenta H7 ma pojedynczą diodę RGB użytkownika, sterowaną programowo przez machine.LED

from machine import LED

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

Osobna pomarańczowa dioda ładowania obok złącza JST akumulatora świeci, gdy wbudowana ładowarka dostarcza prąd do podłączonego ogniwa Li‑Po; nie podlega sterowaniu przez użytkownika.

Sensor kamery (Vision Shield)

Po podłączeniu nakładki Portenta Vision Shield (w wersji Ethernet lub LoRa) sensor Himax jest sterowany przez moduł csi — sensory kamery

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()

Obsługiwane są dwie wersje Vision Shield:

  • HM01B0 — 320 × 320 monochromatyczny.

  • HM0360 — 640 × 480 monochromatyczny.

Ostrzeżenie

Gdy kamera Vision Shield jest zainicjalizowana, następujące piny goldpinów MKR są zajmowane przez oprogramowanie układowe i nie mogą być używane:

Pin MKR

Przyczyna

D1

TIM1 CH1 — zegar główny kamery

D6

TIM1 CH1 (alt) — zegar główny kamery

D11

I²C 3 SDA — współdzielony z kamerą; magistrala jest używalna, ale unikaj adresu I²C sensora (0x24)

D12

I²C 3 SCL — współdzielony z kamerą; magistrala jest używalna, ale unikaj adresu I²C sensora (0x24)

A6 / D21

DCMI HSYNC — wyłącza również DAC

A7

DCMI PXCLK

Uczenie maszynowe

ml — Uczenie maszynowe uruchamia skwantyzowane modele TFLite na rdzeniu Cortex‑M7 z jądrami CMSIS‑NN — wystarczająco szybko dla kompaktowych detektorów przy kilku klatkach na sekundę. Modele w systemie plików tylko do odczytu /rom ładują się bezpośrednio z pamięci flash bez kopiowania do RAM. Oto detektor BlazeFace 128×128 nakładający wykrytą twarz i jej sześć punktów charakterystycznych na każdą ramkę z kamery Vision Shield:

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")

Rdzeń M4

Rdzeń Cortex‑M4 jest udostępniany przez openamp na potrzeby komunikacji międzyprocesorowej. Oprogramowanie układowe OpenMV działa wyłącznie na M7; M4 nie ma własnego środowiska uruchomieniowego MicroPython, więc jego użycie oznacza zbudowanie osobnego obrazu oprogramowania w C i załadowanie go z systemu plików przez openamp.RemoteProc. Gotowe przykładowe oprogramowanie implementujące wirtualny punkt końcowy UART jest dostępne w repozytorium openamp_vuart — postępuj zgodnie z jego plikiem README, aby zbudować 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)

W praktyce tę obsługę najlepiej traktować jako demonstrację interfejsu openamp, a nie działającą platformę dwurdzeniową — M4 nie może być resetowany niezależnie od M7, więc zatrzymanie M4 wymusza pełny restart systemu.

Mikrofon (Vision Shield)

Vision Shield jest wyposażony w dwa mikrofony PDM przechwytywane przez audio — Moduł Audio za pośrednictwem peryferium SAI4 układu STM32. Każdy bufor dociera jako 16‑bitowy ze znakiem PCM bytearray, gotowy do podania do ulab/numpy w celu przetwarzania DSP — na przykład prosty detektor głośności:

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

Przekaż channels=2 do audio.init, aby otrzymywać przeplecione próbki z obu mikrofonów.

Wskaźnik naładowania akumulatora

Wskaźnik paliwa Maxim MAX17262 ModelGauge m5 śledzi napięcie, prąd, temperaturę i stan naładowania akumulatora Li‑Po. Znajduje się na I²C 1 pod adresem 0x36.

MAX17262 ma wewnętrzny pomiar prądu, więc rejestr prądu odczytuje się bezpośrednio w mikroamperach, bez konieczności stosowania zewnętrznego współczynnika Rsense. Odczyt wskaźnika paliwa jest nieszkodliwy — nie dostarczono sterownika, ale rejestry udokumentowane w karcie katalogowej MAX17262 można odczytywać bezpośrednio:

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 to wartość ze znakiem w kodzie uzupełnień do dwóch: dodatnia podczas ładowania, ujemna podczas rozładowywania. TTE ma sens tylko wtedy, gdy prąd jest ujemny; TTF tylko gdy prąd jest dodatni.

Układ zarządzania zasilaniem

PMIC NXP PF1550 obsługuje każdy stabilizator na płytce Portenta H7 — główną szynę +3V3, szynę rdzenia / I/O SoC +1V8 oraz ładowarkę Li‑Po. Znajduje się na I²C 1 pod adresem 0x08.

Ostrzeżenie

Odczyt rejestrów PMIC jest bezpieczny; zapis do nich jest niebezpieczny. Błędna konfiguracja przetwornicy obniżającej lub ustawienia ładowarki może trwale uszkodzić płytkę, akumulator lub oba. Traktuj PMIC jako tylko do odczytu, chyba że dokładnie wiesz, co robisz.

Najbardziej przydatną rzeczą, którą PMIC ujawnia, a której nie potrafi wskaźnik paliwa, jest maszyna stanów ładowarki — czy płytka jest aktualnie zasilana z USB / ESLOV / VIN, na jakim etapie cyklu ładowania znajduje się Li‑Po oraz czy ładowarka jest w stanie awarii termicznej lub watchdog. Rejestry ładowarki znajdują się z przesunięciem 0x80 w głównej przestrzeni adresowej I²C układu PF1550 (zob. §22.2 karty katalogowej PF1550), więc na przykład CHG_INT_OK pod adresem ładowarki 0x04 odczytuje się z rejestru PMIC 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)

Inne rejestry tylko do odczytu warte sprawdzenia w karcie katalogowej (wszystkie z przesunięciem ładowarki 0x80): 0x80 CHG_INT (zatrzaśnięte przerwania ładowarki — flagi awarii), 0x86 VBUS_SNS (wielobitowy stan VBUS, w tym OVLO / UVLO / DPM) oraz 0x88 BATT_SNS (obecność akumulatora i stan przeciążenia prądowego).

Wi‑Fi

Wbudowany Murata 1DX (CYW4343W) jest udostępniany przez network — konfiguracja sieci jako interfejs stacji. Przed uruchomieniem radia podłącz dołączoną antenę do wbudowanego złącza U.FL

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

Ten sam Murata 1DX udostępnia również Bluetooth LE 5.1. Użyj aioble — Asynchroniczne BLE dla przyjaznego dla asyncio BLE — na przykład rozgłaszaj jako urządzenie peryferyjne i czekaj na połączenie urządzenia centralnego:

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)

Wersja LoRa nakładki Vision Shield dodaje moduł LoRaWAN Murata CMWX1ZZABZ podłączony do Portenta H7 przez UART. Moduł lora opakowuje oprogramowanie układowe sterowane komendami AT i obsługuje dołączanie OTAA lub ABP, łącze w górę (uplink) i łącze w dół (downlink):

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()

Dla regionów spoza UE użyj BAND_US915 / BAND_AS923 / BAND_AU915 itd. i przełącz się na lora.Lora.join_ABP(), jeśli twój serwer sieciowy korzysta z aktywacji ABP.

Ostrzeżenie

Gdy moduł LoRa jest w użyciu, sterownik zajmuje następujące piny goldpinów MKR jako linie sterujące dla Murata CMWX1ZZABZ — nie mogą one być używane:

Pin MKR

Przyczyna

D3

Pin BOOT modułu LoRa

D5

Pin RST modułu LoRa

Ethernet (Vision Shield)

Wersja Ethernet nakładki Vision Shield dodaje gniazdo RJ45 z transformatorem podłączone do kontrolera MAC Ethernet 10/100 układu STM32H747 przez RMII. Podłącz kabel Ethernet, a PHY pojawi się jako interfejs LAN; DHCP uruchamia się automatycznie po nawiązaniu łącza:

import network
import time

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

Karta microSD (Vision Shield)

Po włożeniu karty jest ona montowana automatycznie pod /sdcard i jest używalna przez zwykły system plików:

import os

for entry in os.listdir("/sdcard"):
    print(entry)

Opis magistral

GPIO

Użyj machine.Pin, aby odczytywać lub sterować dowolnym z opisanych na płytce pinów. Wyjścia są typu CMOS 3,3 V i mogą pochłaniać/dostarczać do 20 mA na pin (140 mA łącznie dla całego goldpinu).

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())

Dowolny pin wejściowy może również wyzwalać przerwanie przy zmianach na zboczu:

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

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

UART

Magistrala

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

Magistrala

SCL

SDA

I2C3

D12

D11

from machine import I2C

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

Pady D11/D12 na goldpinie MKR oraz piny SDA_EXT/SCL_EXT złącza ESLOV trafiają na tę samą magistralę I²C 3 — zobacz Złącze ESLOV powyżej, aby poznać wyprowadzenia ESLOV.

Ten sam sprzęt może być również używany w trybie urządzenia docelowego (slave) przez machine.I2CTarget, aby udostępnić obszar pamięci innemu kontrolerowi I²C:

from machine import I2CTarget

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

SPI

Magistrala

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 udostępnia osiem 12‑bitowych kanałów ADC na A0–A7. Wszystkie są odniesione do 3,3 Vread_u16 zwraca 0–65535 w zakresie 0–3,3 V na pinie:

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

Pojedynczy 12‑bitowy kanał DAC jest udostępniany na DAC1 (A6 / D21) przez pyb.DAC

from pyb import DAC

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

PWM

Pin

Licznik czasu / kanał

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

Steruj którymkolwiek z nich przez machine.PWM

from machine import Pin, PWM

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

Informacja

Kilka pinów współdzieli kanały licznika czasu:

  • TIM1 CH1 jest na D1 oraz D6.

  • TIM1 CH2 jest na D2 oraz D14.

  • TIM8 CH3N jest na D0 oraz D1.

Wybierz jednego odbiorcę na kanał licznika czasu.

Ostrzeżenie

TIM1 jest zarezerwowany dla zegara głównego kamery, gdy Vision Shield jest inicjalizowany przez csi — sensory kameryD1, D2, D6, D13 i D14 nie mogą być sterowane PWM, gdy kamera jest aktywna.

Programowe magistrale bit‑bang

machine.SoftI2C i machine.SoftSPI działają na dowolnym GPIO, jeśli potrzebujesz dodatkowej magistrali.

Sensor termiczny (zewnętrzny)

Oprogramowanie układowe zawiera sterownik fir — sterownik sensora termicznego (fir == far infrared, daleka podczerwień) dla zewnętrznie podłączonych kamer termowizyjnych:

  • MLX90621 — matryca IR 16 × 4

  • MLX90640 — matryca IR 32 × 24

  • MLX90641 — matryca IR 16 × 12

  • AMG8833 — matryca IR 8 × 8

Podłącz moduł do magistrali I²C płytki i odczytuj ramki za pomocą 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())

Sterownik fir komunikuje się z sensorem wyłącznie przez I²C 3 — podłącz moduł do D12 (SCL) i D11 (SDA).

Pomiar czasu

time

Moduł time obejmuje blokujące opóźnienia, monotoniczne tyknięcia oraz pomiar upływającego czasu:

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)

Wirtualne liczniki czasu

machine.Timer planuje okresowe lub jednorazowe wywołania zwrotne bez zajmowania sprzętowego slotu licznika czasu. Przekaż -1 jako id, aby użyć wirtualnego (programowego) licznika czasu:

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"))

Wartości okresu są podawane w milisekundach. Wywołaj deinit(), aby zatrzymać i zwolnić slot.

Zegar czasu rzeczywistego

machine.RTC utrzymuje czas zegara ściennego pomiędzy resetami. Złącze HD udostępnia również pad COINCELL, który może podtrzymywać RTC z ogniwa CR2032 podczas zaniku zasilania:

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 resetuje płytkę, jeśli aplikacja się zawiesi. Po uruchomieniu nie można go zatrzymać ani ponownie skonfigurować — karm go okresowo wewnątrz swojej głównej pętli:

from machine import WDT

wdt = WDT(timeout=5_000)   # 5 second window
while True:
    # ...do work...
    wdt.feed()

Informacje o rozruchu i czasie wykonania

Aktualizacja oprogramowania układowego (DFU)

Portenta H7 wykorzystuje standardowy podwójny stuknięcie resetu Arduino, aby wejść do bootloadera Arduino. Szybko naciśnij dwukrotnie przycisk resetu — płytka ponownie wyliczy się przez USB jako urządzenie DFU, a OpenMV IDE może wgrać nowy obraz oprogramowania układowego.

Działający skrypt może ponownie wejść do bootloadera na żądanie, wywołując machine.bootloader()

import machine

machine.bootloader()

System plików i kolejność rozruchu

Oprogramowanie układowe Portenta H7 montuje przy rozruchu do trzech systemów plików:

  • Wewnętrzna pamięć flash — zawsze montowana pod /flash. Domyślnie przechowuje main.py i README.txt; tworzona przy pierwszym rozruchu.

  • Karta microSD — jeśli podłączony jest Vision Shield i włożona jest karta, jest ona montowana pod /sdcard.

  • ROMFS — system plików tylko do odczytu, mapowany w pamięci pod /rom, montowany automatycznie przez MicroPython przy starcie.

Po zamontowaniu katalog roboczy jest ustawiany na /sdcard, gdy karta jest obecna, w przeciwnym razie na /flash. Interpreter uruchamia następnie skrypty z tego katalogu:

  • boot.py jest wykonywany przy każdym miękkim resecie (zimny rozruch, Ctrl‑D z REPL lub za każdym razem, gdy działający skrypt zakończy działanie).

  • main.py jest wykonywany tylko przy zimnym rozruchu, bezpośrednio po boot.py. Kolejne miękkie resety ponownie uruchamiają boot.py, ale przechodzą prosto do REPL — aby ponownie uruchomić main.py, musisz w pełni zresetować płytkę.

Umieszczenie pliku boot.py lub main.py na karcie SD nadpisuje kopię w pamięci flash bez jej naruszania — oba pliki są wyszukiwane w katalogu rozruchowym (/sdcard, gdy karta jest zamontowana, w przeciwnym razie /flash).

Domyślny main.py dostarczany na świeżo wgranej płytce po prostu miga niebieskim kanałem diody RGB użytkownika jako sygnał życia (dwa krótkie impulsy, krótka przerwa), dzięki czemu możesz stwierdzić, że oprogramowanie układowe uruchomiło się poprawnie bez podłączonego hosta.

sys.path jest rozszerzane o wszystkie trzy systemy plików i ich podkatalogi lib/, więc importowalne moduły mogą znajdować się w /flash/lib, /sdcard/lib lub /rom/lib.

Aby zmusić system do ignorowania włożonej karty SD (na przykład w celu uruchomienia main.py z pamięci flash nawet przy obecnej karcie), utwórz pusty plik o nazwie SKIPSD w katalogu głównym /flash.

Po podłączeniu przez USB rozruchowy system plików (/sdcard, jeśli karta jest obecna, w przeciwnym razie /flash) wylicza się również na hoście jako dysk pamięci masowej USB, umożliwiając bezpośrednią edycję boot.py, main.py i wszelkich innych plików. Wysuń dysk przed zresetowaniem płytki, aby host opróżnił buforowane zapisy.

Informacja

Ponieważ system operacyjny traktuje dysk jako pasywne urządzenie blokowe, pliki utworzone lub zmodyfikowane przez kod działający na kamerze nie pojawią się, dopóki host nie zamontuje dysku ponownie. Jeśli zarówno system operacyjny, jak i kamera zapisują ten sam system plików w tym samym czasie, system operacyjny wygra i nadpisze zmiany wprowadzone przez kamerę. Używaj karty SD do wszelkich danych, które skrypt zapisuje, i montuj ponownie przed odczytaniem tych plików z hosta.

Informacja

Czerwony kanał diody RGB użytkownika może na chwilę się zaświecić, gdy host odczytuje lub zapisuje dysk pamięci masowej USB — jest to sterowany przez oprogramowanie układowe wskaźnik aktywności, a nie awaria.

Rozmiary pamięci masowej

Portenta H7 jest dostarczana z:

  • /flash — system plików FAT o pojemności 11 MB, do odczytu/zapisu.

  • /rom4 MB mapowanego w pamięci ROMFS tylko do odczytu, używanego do dostarczania skryptów i modeli ML korzystających z dostępu mmap bez kopiowania (zero-copy).

  • /sdcard — pełna pojemność dowolnej karty microSD włożonej do Vision Shield (gdy jest obecna), do odczytu/zapisu.

Wskaźnik krytycznej awarii (hard fault)

Jeśli dioda RGB użytkownika szybko przełącza się przez wszystkie kolory — na tyle szybko, że zwykle wygląda jak migotliwa biała dioda LED, a nie odrębne barwy — oznacza to, że oprogramowanie układowe napotkało nieodwracalną krytyczną awarię (hard fault). Aby przywrócić działanie, wgraj ponownie oprogramowanie układowe; jeśli ponowne wgranie nie pomaga, płytka może być fizycznie uszkodzona.

Biblioteki programowe

Pełną listę modułów — w tym te unikalne dla wersji Portenta H7 — znajdziesz w indeksie bibliotek.