Arduino Portenta H7

Arduino Portenta H7 este o placă de dezvoltare industrială de 66 × 25 mm construită în jurul cipului STMicroelectronics STM32H747XI — un SoC dual‑core care combină un Cortex‑M7 la 400 MHz cu un Cortex‑M4 la 200 MHz. Firmware‑ul OpenMV rulează în întregime pe nucleul M7 și este conceput pentru a fi utilizat cu Portenta Vision Shield (ediția Ethernet sau LoRa), care adaugă o cameră Himax HM01B0 / HM0360, două microfoane PDM și un slot microSD plăcii de bază Portenta H7.

Arduino Portenta H7

Pentru fișa tehnică completă, fotografii și dimensiuni, consultați pagina produsului Arduino Portenta H7.

Puncte importante

  • STMicroelectronics STM32H747XI dual Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). Firmware‑ul OpenMV rulează doar pe nucleul M7; nucleul M4 este expus prin openamp pentru comunicarea inter‑procesor.

  • 8 MB de SDRAM extern plus 2 MB de memorie flash internă și 16 MB de memorie flash QSPI externă.

  • Codificator/decodificator JPEG hardware.

  • Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 prin modulul Murata 1DX (CYW4343W) — se conectează la antena furnizată printr‑un conector U.FL integrat pe placă.

  • USB‑C de mare viteză (480 Mb/s).

  • 22 de pini I/O de utilizator pe anteturile superioare în stil Arduino MKR — D0–D14 (digital) plus A0–A6 (analogic).

  • Doi conectori de mare densitate cu 80 de pini pe partea inferioară expun întreaga structură a STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UART‑uri, SPI/I²C/temporizatoare suplimentare și așa mai departe. Shield‑uri precum Vision Shield se conectează la acești conectori.

  • JTAG / SWD scos pe conectorii HD inferiori pentru depanare avansată.

  • Suport pentru baterie — conector JST Li‑Po de 3,7 V plus încărcător și monitor de baterie integrate pe placă.

Pinout

Pinout Arduino Portenta H7

Referință pini

22 de pini de utilizator sunt expuși pe anteturile de pe marginea superioară în stil Arduino MKR — 15 digitali (D0-D14) plus 7 analogici (A0-A6). Mai mulți pini ai SoC‑ului sunt disponibili prin conectorii de mare densitate cu 80 de pini inferiori pentru lucrul cu shield‑uri; consultați PDF‑ul cu pinout‑ul complet de la Arduino pentru această mapare.

Nume pin

Referință

Funcție

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 (partajat cu A3 / A5)

D9

3.3 V

SPI2 SCK

D10

3.3 V

SPI2 MISO (partajat cu 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 (doar analogic)

A1

3.3 V

ADC12 IN1 (doar analogic)

A2

3.3 V

ADC123 IN12 (doar analogic; partajat cu D10)

A3

3.3 V

ADC12 IN13 (doar analogic; partajat cu D8)

A4

3.3 V

ADC123 IN12 (partajat cu D10)

A5

3.3 V

ADC12 IN13 (partajat cu D8)

A6

3.3 V

DAC1 OUT1 / ADC12 IN18

A7

3.3 V

TIM3 CH1 / ADC12 IN3 (neexpus pe anteturi)

D20

3.3 V

alias pentru D8 / A3 / A5

D21

3.3 V

alias pentru A6 — DAC1 OUT1

RESET

3.3 V

apăsați comutatorul integrat pe placă sau conectați la GND pentru a reseta

LED_RED

3.3 V

canalul roșu al LED‑ului RGB (activ pe nivel jos)

LED_GREEN

3.3 V

canalul verde al LED‑ului RGB (activ pe nivel jos)

LED_BLUE

3.3 V

canalul albastru al LED‑ului RGB (activ pe nivel jos)

Notă

A0-A3 sunt pad‑uri doar analogice pe STM32H747, fără funcție GPIO — tratați‑le exclusiv ca intrări ADC. A2/A4 și A3/A5 își partajează pinii fizici cu D10 și, respectiv, D8, așa că nu puteți comanda PWM sau SPI pe aceștia în timp ce îi citiți ca analogici. A7 se află pe conectorii HD inferiori.

Pini de alimentare

Pini anter MKR:

  • VIN — magistrala principală de alimentare a sistemului către PMIC‑ul integrat pe placă. Alimentat printr‑o diodă de pe magistrala +5V, pinul VIN MKR sau conectorii HD inferiori cu 80 de pini.

  • +5V — magistrală de 5 V alimentată de la USB, de la conectorul ESLOV sau de la pinul +5V MKR însuși.

  • +3V3 — magistrala principală de 3,3 V (ieșirea regulatorului de comutație al PMIC‑ului).

  • AREF — referința de tensiune analogică pentru pinii ADC. Implicit 3,3 V; alimentați extern pentru a utiliza o altă referință.

  • GND — masă comună.

Intrare baterie:

  • JST Li‑Po de pe partea frontală a plăcii acceptă o celulă Li‑Po de 3,7 V. PMIC‑ul o încarcă ori de câte ori +5V sau VIN este prezent.

Portenta H7 poate fi alimentată prin oricare dintre aceste căi:

  • USB‑C — furnizează 5 V către PMIC‑ul integrat pe placă.

  • Conector ESLOV — până la 5 V pe VESLOV (consultați Conector ESLOV).

  • Pin VIN — alimentați direct cu o sursă reglată de 5 V.

  • Baterie Li‑Po — conectați la JST‑ul de pe partea frontală.

Conector ESLOV

Pe partea laterală a plăcii se află un conector ESLOV cu 5 pini, fără lipire:

Pin

Nume

Funcție

1

VESLOV

ieșire de alimentare de 5 V (aceeași magistrală ca +5V de pe anterul MKR)

2

INT

intrare de întrerupere externă pe D7

3

SCL_EXT

partajat cu pad‑ul D12 de pe anterul MKR — aceeași magistrală I²C 3 ca anterul de utilizator

4

SDA_EXT

partajat cu pad‑ul D11 de pe anterul MKR — aceeași magistrală I²C 3 ca anterul de utilizator

5

GND

masă comună

SCL_EXT/SDA_EXT ale ESLOV și D12/D11 de pe anterul MKR sunt aceiași pini — o singură magistrală I²C 3 expusă pe doi conectori.

Sfat

Folosiți estimatorul duratei de viață a bateriei pentru a modela cât timp va funcționa Portenta H7 pe o baterie pentru un anumit ciclu de utilizare activ / somn profund.

Pini de recuperare și depanare

  • RESET — atât un pin expus pe anterul superior, cât și un comutator momentan pe partea laterală a plăcii, legate la linia NRST a SoC‑ului. Conectați la GND sau apăsați butonul pentru a reseta.

Portenta H7 folosește resetarea standard prin dublă apăsare de la Arduino pentru a intra în bootloader‑ul Arduino. Apăsați rapid butonul de resetare de două ori — placa se re‑enumeră prin USB ca dispozitiv DFU, iar OpenMV IDE poate scrie o nouă imagine de firmware.

Semnalele SWD ale STM32 sunt expuse pe conectorul HD J1 inferior:

  • J1‑73 — NRST

  • J1‑75 — SWDIO (PA13)

  • J1‑77 — SWCLK (PA14)

  • J1‑79 — SWO (PB3)

Conectați‑le printr‑un Portenta Breakout, adaptorul oficial de depanare Arduino sau un carrier personalizat cu un anter de 1,27 mm. Toate semnalele de depanare sunt referențiate la 3,3 V.

Notă

Când Portenta Vision Shield este atașat, aceleași semnale SWD/JTAG sunt direcționate către anterul standard ARM Cortex Debug JTAG cu 20 de pini de pe shield (pas de 1,27 mm / 0,05″).

Periferice integrate pe placă

LED‑uri

Portenta H7 are un singur LED RGB de utilizator, controlabil din software prin machine.LED

from machine import LED

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

Un LED de încărcare portocaliu separat, aflat lângă JST‑ul bateriei, se aprinde când încărcătorul integrat pe placă furnizează curent către o baterie Li‑Po conectată; acesta nu este controlabil de utilizator.

Senzor de cameră (Vision Shield)

Cu Portenta Vision Shield (ediția Ethernet sau LoRa) atașat, senzorul Himax este comandat prin modulul csi — senzori de cameră

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

Sunt acceptate două revizii ale Vision Shield:

  • HM01B0 — monocrom 320 × 320.

  • HM0360 — monocrom 640 × 480.

Atenționare

În timp ce camera Vision Shield este inițializată, următorii pini ai anterului MKR sunt revendicați de firmware și nu pot fi utilizați:

Pin MKR

Motiv

D1

TIM1 CH1 — ceasul principal al camerei

D6

TIM1 CH1 (alt) — ceasul principal al camerei

D11

I²C 3 SDA — partajat cu camera; magistrala este utilizabilă, dar evitați adresa I²C a senzorului (0x24)

D12

I²C 3 SCL — partajat cu camera; magistrala este utilizabilă, dar evitați adresa I²C a senzorului (0x24)

A6 / D21

DCMI HSYNC — dezactivează de asemenea DAC‑ul

A7

DCMI PXCLK

Învățare automată

ml — Învățare automată rulează modele TFLite cuantizate pe Cortex‑M7 cu nuclee CMSIS‑NN — suficient de rapid pentru detectoare compacte la câteva cadre pe secundă. Modelele de pe sistemul de fișiere /rom doar‑citire se încarcă direct din memoria flash fără a fi copiate în RAM. Iată un detector BlazeFace de 128×128 care suprapune fața detectată și cele șase repere ale sale peste fiecare cadru de la camera 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")

Nucleul M4

Nucleul Cortex‑M4 este expus prin openamp pentru comunicarea inter‑procesor. Firmware‑ul OpenMV rulează doar pe M7; M4 nu are propriul runtime MicroPython, așa că utilizarea sa înseamnă construirea unei imagini de firmware C separate și încărcarea ei din sistemul de fișiere prin openamp.RemoteProc. Un firmware exemplu pre‑construit care implementează un punct final UART virtual este disponibil în depozitul openamp_vuart — urmați fișierul README pentru a construi 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)

În practică, acest suport este cel mai bine tratat ca o demonstrație a interfeței openamp, mai degrabă decât ca o platformă dual‑core funcțională — M4 nu poate fi resetat independent de M7, așa că oprirea M4 forțează o repornire completă a sistemului.

Microfon (Vision Shield)

Vision Shield poartă două microfoane PDM captate prin audio — Modulul Audio peste perifericul SAI4 al STM32‑ului. Fiecare tampon sosește ca PCM bytearray pe 16 biți cu semn, gata să fie introdus în ulab/numpy pentru DSP — de exemplu, un simplu detector de intensitate sonoră:

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

Transmiteți channels=2 către audio.init pentru a primi eșantioane intercalate de la ambele microfoane.

Indicator de încărcare a bateriei

Indicatorul de încărcare ModelGauge m5 MAX17262 de la Maxim urmărește tensiunea, curentul, temperatura și starea de încărcare ale bateriei Li‑Po. Acesta se află pe I²C 1 la adresa 0x36.

MAX17262 are detectare a curentului internă, așa că registrul de curent indică direct în microamperi, fără un factor Rsense extern de aplicat. Citirea indicatorului de încărcare este inofensivă — nu este livrat niciun driver, dar registrele documentate în fișa tehnică MAX17262 pot fi citite direct:

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 este complement față de doi cu semn: pozitiv în timpul încărcării, negativ în timpul descărcării. TTE este relevant doar când curentul este negativ; TTF doar când curentul este pozitiv.

Circuit integrat de gestionare a alimentării

PMIC‑ul NXP PF1550 gestionează fiecare regulator de pe Portenta H7 — magistrala principală +3V3, magistrala +1V8 a nucleului SoC / I/O și încărcătorul Li‑Po. Acesta se află pe I²C 1 la adresa 0x08.

Atenționare

Citirea registrelor PMIC este în regulă; scrierea în ele este periculoasă. Configurarea greșită a unui regulator buck sau a unei setări a încărcătorului poate deteriora permanent placa, bateria sau ambele. Tratați PMIC‑ul ca doar‑citire dacă nu știți exact ce faceți.

Cel mai util lucru pe care PMIC‑ul vi‑l spune și pe care indicatorul de încărcare nu îl poate spune este mașina de stări a încărcătorului — dacă placa rulează în prezent pe USB / ESLOV / VIN, în ce stadiu al ciclului de încărcare se află bateria Li‑Po și dacă încărcătorul se află într‑o eroare termică sau de watchdog. Registrele încărcătorului se află la un decalaj de 0x80 în spațiul principal de adrese I²C al PF1550 (consultați §22.2 din fișa tehnică PF1550), așa că, de exemplu, CHG_INT_OK la adresa de încărcător 0x04 este citit din registrul 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)

Alte registre doar‑citire care merită analizate în fișa tehnică (toate la decalajul de încărcător 0x80): 0x80 CHG_INT (întreruperi memorate ale încărcătorului — indicatori de eroare), 0x86 VBUS_SNS (starea VBUS pe mai mulți biți, inclusiv OVLO / UVLO / DPM) și 0x88 BATT_SNS (prezența bateriei și starea de supracurent).

Wi‑Fi

Modulul Murata 1DX (CYW4343W) integrat pe placă este expus prin network — configurarea rețelei ca interfață de stație. Conectați antena furnizată la conectorul U.FL integrat pe placă înainte de a porni radioul:

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

Același Murata 1DX expune de asemenea Bluetooth LE 5.1. Folosiți aioble — BLE asincron pentru BLE compatibil cu asyncio — de exemplu, faceți publicitate ca periferic și așteptați conectarea unui dispozitiv central:

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)

Ediția LoRa a Vision Shield adaugă un modul LoRaWAN Murata CMWX1ZZABZ conectat la Portenta H7 prin UART. Modulul lora încapsulează firmware‑ul cu comenzi AT și acceptă conectarea OTAA sau ABP, uplink și 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()

Folosiți BAND_US915 / BAND_AS923 / BAND_AU915 etc. pentru regiuni din afara UE și comutați la lora.Lora.join_ABP() dacă serverul rețelei dvs. utilizează activarea ABP.

Atenționare

În timp ce modulul LoRa este utilizat, driverul revendică următorii pini ai anterului MKR ca linii de control pentru Murata CMWX1ZZABZ — aceștia nu pot fi utilizați:

Pin MKR

Motiv

D3

pinul BOOT al modulului LoRa

D5

pinul RST al modulului LoRa

Ethernet (Vision Shield)

Ediția Ethernet a Vision Shield adaugă o mufă RJ45 cu magnetice conectată la MAC‑ul Ethernet 10/100 al STM32H747 prin RMII. Conectați un cablu Ethernet, iar PHY‑ul apare ca o interfață LAN; DHCP rulează automat odată ce legătura este stabilită:

import network
import time

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

Card microSD (Vision Shield)

Când un card este introdus, acesta este montat automat la /sdcard și poate fi utilizat prin sistemul de fișiere obișnuit:

import os

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

Referință magistrale

GPIO

Folosiți machine.Pin pentru a citi sau a comanda oricare dintre pinii serigrafiati. Ieșirile sunt CMOS de 3,3 V și pot absorbi/furniza până la 20 mA per pin (140 mA în total pe întregul anter).

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

Orice pin de intrare poate de asemenea declanșa o întrerupere la tranzițiile de muchie:

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

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

UART

Magistrală

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

Magistrală

SCL

SDA

I2C3

D12

D11

from machine import I2C

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

Pad‑urile D11/D12 de pe anterul MKR și pinii SDA_EXT/SCL_EXT ai conectorului ESLOV ajung pe aceeași magistrală I²C 3 — consultați Conector ESLOV mai sus pentru pinout‑ul ESLOV.

Același hardware poate fi de asemenea utilizat în mod țintă (slave) prin machine.I2CTarget pentru a expune o regiune de memorie unui alt controler I²C:

from machine import I2CTarget

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

SPI

Magistrală

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 expune opt canale ADC pe 12 biți pe A0–A7. Toate sunt referențiate la 3,3 Vread_u16 returnează 0–65535 pe intervalul 0–3,3 V la pin:

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

Un singur canal DAC pe 12 biți este expus pe DAC1 (A6 / D21) prin pyb.DAC

from pyb import DAC

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

PWM

Pin

Temporizator / canal

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

Comandați oricare dintre ele prin machine.PWM

from machine import Pin, PWM

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

Notă

Mai mulți pini partajează canale de temporizator:

  • TIM1 CH1 se află pe D1 și D6.

  • TIM1 CH2 se află pe D2 și D14.

  • TIM8 CH3N se află pe D0 și D1.

Alegeți un singur consumator per canal de temporizator.

Atenționare

TIM1 este rezervat pentru ceasul principal al camerei atunci când Vision Shield este inițializat prin csi — senzori de camerăD1, D2, D6, D13 și D14 nu pot fi comandate prin PWM cât timp camera este activă.

Magistrale emulate software (bit‑banged)

machine.SoftI2C și machine.SoftSPI funcționează pe orice GPIO dacă aveți nevoie de o magistrală suplimentară.

Senzor termic (extern)

Firmware‑ul include driverul fir — driver pentru senzori termici (fir == far infrared) pentru imagistici termice conectate extern:

  • MLX90621 — matrice IR 16 × 4

  • MLX90640 — matrice IR 32 × 24

  • MLX90641 — matrice IR 16 × 12

  • AMG8833 — matrice IR 8 × 8

Conectați modulul la magistrala I²C a plăcii și citiți cadrele cu 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())

Driverul fir comunică cu senzorul doar prin I²C 3 — conectați modulul la D12 (SCL) și D11 (SDA).

Sincronizare

time

Modulul time acoperă întârzierile blocante, tick‑urile monotone și măsurarea timpului scurs:

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)

Temporizatoare virtuale

machine.Timer programează funcții de retroapelare (callback) periodice sau unice fără a consuma un slot de temporizator hardware. Transmiteți -1 ca id pentru a utiliza un temporizator virtual (software):

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

Valorile perioadei sunt în milisecunde. Apelați deinit() pentru a opri și a elibera slotul.

Ceas în timp real

machine.RTC păstrează ora de perete între resetări. Conectorul HD expune de asemenea un pad COINCELL care poate susține RTC‑ul de la o baterie CR2032 în caz de pierdere a alimentării:

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 resetează placa dacă aplicația se blochează. Odată pornit, nu poate fi oprit sau reconfigurat — alimentați‑l periodic în interiorul buclei dvs. principale:

from machine import WDT

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

Informații despre pornire și execuție

Actualizare firmware (DFU)

Portenta H7 folosește resetarea standard prin dublă apăsare de la Arduino pentru a intra în bootloader‑ul Arduino. Apăsați rapid butonul de resetare de două ori — placa se re‑enumeră prin USB ca dispozitiv DFU, iar OpenMV IDE poate scrie o nouă imagine de firmware.

Un script în execuție poate re‑intra în bootloader la cerere apelând machine.bootloader()

import machine

machine.bootloader()

Sistem de fișiere și ordinea de pornire

Firmware‑ul Portenta H7 montează până la trei sisteme de fișiere la pornire:

  • Memorie flash internă — montată întotdeauna la /flash. Conține implicit main.py și README.txt; creată la prima pornire.

  • Card microSD — dacă un Vision Shield este atașat și un card este introdus, acesta este montat la /sdcard.

  • ROMFS — sistem de fișiere doar‑citire, mapat în memorie, la /rom, montat automat de MicroPython la pornire.

După montare, directorul de lucru este setat la /sdcard când cardul este prezent, altfel la /flash. Interpretorul rulează apoi scripturi din acel director:

  • boot.py este executat la fiecare resetare soft (pornire la rece, Ctrl‑D din REPL sau ori de câte ori scriptul în execuție returnează).

  • main.py este executat doar la pornirea la rece, imediat după boot.py. Resetările soft ulterioare re‑execută boot.py, dar trec direct la REPL — pentru a re‑executa main.py trebuie să resetați complet placa.

Plasarea unui boot.py sau main.py pe cardul SD suprascrie copia din memoria flash fără a o atinge — ambele fișiere sunt căutate în directorul de pornire (/sdcard când cardul este montat, altfel /flash).

Fișierul main.py implicit livrat pe o placă proaspăt programată doar face să clipească canalul albastru al LED‑ului RGB de utilizator ca un semnal de funcționare (două pulsuri scurte, pauză scurtă), astfel încât să puteți spune că firmware‑ul a pornit corect fără niciun host atașat.

sys.path este extins pentru a include toate cele trei sisteme de fișiere și subdirectoarele lor lib/, astfel încât modulele importabile pot fi plasate în /flash/lib, /sdcard/lib sau /rom/lib.

Pentru a forța sistemul să ignore un card SD introdus (de exemplu pentru a rula main.py din memoria flash chiar și cu un card prezent), creați un fișier gol numit SKIPSD în rădăcina /flash.

Când este conectat prin USB, sistemul de fișiere de pornire (/sdcard dacă un card este prezent, altfel /flash) se enumeră de asemenea ca o unitate de stocare în masă USB pe host, permițându‑vă să editați direct boot.py, main.py și orice alte fișiere. Scoateți unitatea înainte de a reseta placa astfel încât host‑ul să golească scrierile sale din memoria cache.

Notă

Deoarece sistemul de operare tratează unitatea ca un dispozitiv de blocuri pasiv, fișierele create sau modificate de codul care rulează pe cameră nu vor apărea până când host‑ul nu remontează unitatea. Dacă atât sistemul de operare, cât și camera scriu pe același sistem de fișiere în același timp, sistemul de operare va câștiga și va suprascrie modificările făcute de cameră. Folosiți cardul SD pentru orice date pe care scriptul le scrie înapoi și remontați înainte de a citi acele fișiere de pe host.

Notă

Canalul roșu al LED‑ului RGB de utilizator se poate aprinde scurt în timp ce host‑ul citește de pe sau scrie pe unitatea de stocare în masă USB — acesta este un indicator de activitate condus de firmware, nu o eroare.

Dimensiuni de stocare

Portenta H7 este livrată cu:

  • /flash — sistem de fișiere FAT de 11 MB, citire/scriere.

  • /rom — ROMFS doar‑citire, mapat în memorie, de 4 MB, utilizat pentru a livra scripturi și modele ML care beneficiază de accesul mmap fără copiere.

  • /sdcard — dimensiunea completă a oricărui card microSD introdus într‑un Vision Shield (când este prezent), citire/scriere.

Indicator de eroare gravă (hard‑fault)

Dacă LED‑ul RGB de utilizator parcurge rapid toate culorile — suficient de rapid încât tinde să arate ca un LED alb scânteietor mai degrabă decât ca nuanțe distincte — firmware‑ul a întâlnit o eroare gravă (hard fault) irecuperabilă. Reprogramați firmware‑ul pentru a recupera; dacă reprogramarea nu ajută, este posibil ca placa să fie deteriorată fizic.

Biblioteci software

Consultați indexul de biblioteci pentru lista completă de module — inclusiv cele care sunt unice pentru versiunea Portenta H7.