Arduino Portenta H7

Arduino Portenta H7 — це промислова плата розробника розміром 66 × 25 мм, побудована на базі STMicroelectronics STM32H747XI — двоядерного SoC, що поєднує Cortex‑M7 на 400 МГц із Cortex‑M4 на 200 МГц. Мікропрограма OpenMV працює виключно на ядрі M7 і призначена для використання з Portenta Vision Shield (видання Ethernet або LoRa), яке додає до базового Portenta H7 камеру Himax HM01B0 / HM0360, два PDM‑мікрофони та слот microSD.

Arduino Portenta H7

Повну документацію, фотографії та розміри дивіться на сторінці продукту Arduino Portenta H7.

Основні характеристики

  • STMicroelectronics STM32H747XI — подвійне ядро Cortex‑M7 (400 МГц) + Cortex‑M4 (200 МГц). Мікропрограма OpenMV працює лише на ядрі M7; ядро M4 доступне через openamp для міжпроцесорного зв’язку.

  • 8 МБ зовнішньої SDRAM плюс 2 МБ внутрішньої флеш‑пам’яті та 16 МБ зовнішньої QSPI флеш‑пам’яті.

  • Апаратний кодек JPEG.

  • Wi‑Fi b/g/n (2,4 ГГц) + Bluetooth LE 5.1 через модуль Murata 1DX (CYW4343W) — підключається до антени, що постачається, через вбудований роз’єм U.FL.

  • High‑speed USB‑C (480 Мб/с).

  • 22 призначених для користувача виводи на верхніх роз’ємах стилю Arduino MKR — D0–D14 (цифрові) та A0–A6 (аналогові).

  • Два 80‑контактних роз’єми високої щільності знизу відкривають повний набір функцій STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UART, додаткові SPI/I²C/таймери тощо. Шилди, такі як Vision Shield, підключаються саме до цих роз’ємів.

  • JTAG / SWD виведені на нижні роз’єми HD для розширеного налагодження.

  • Підтримка акумулятора — роз’єм JST для Li‑Po 3,7 В, вбудований зарядний пристрій та монітор акумулятора.

Розпіновка

Arduino Portenta H7 Pinout

Довідник із виводів

22 призначених для користувача виводи розміщені на верхніх крайніх роз’ємах стилю Arduino MKR — 15 цифрових (D0-D14) та 7 аналогових (A0-A6). Значно більша кількість виводів SoC доступна через нижні 80‑контактні роз’єми високої щільності для роботи з шилдами; для відповідного відображення дивіться повну PDF‑схему Arduino.

Назва виводу

Довідка

Функція

D0

3,3 В

TIM8 CH3N

D1

3,3 В

TIM1 CH1 / SPI5 NSS

D2

3,3 В

TIM1 CH2 / SPI5 MISO

D3

3,3 В

GPIO

D4

3,3 В

TIM3 CH2 / TIM8 CH2 / USART6 RX

D5

3,3 В

TIM3 CH1 / TIM8 CH1 / USART6 TX

D6

3,3 В

TIM1 CH1 / I2C3 SCL

D7

3,3 В

TIM5 CH4 / SPI2 NSS

D8

3,3 В

SPI2 MOSI (спільний з A3 / A5)

D9

3,3 В

SPI2 SCK

D10

3,3 В

SPI2 MISO (спільний з A2 / A4)

D11

3,3 В

I2C3 SDA

D12

3,3 В

I2C3 SCL

D13

3,3 В

USART1 RX / TIM1 CH3

D14

3,3 В

USART1 TX / TIM1 CH2

A0

3,3 В

ADC12 IN0 (лише аналоговий)

A1

3,3 В

ADC12 IN1 (лише аналоговий)

A2

3,3 В

ADC123 IN12 (лише аналоговий; спільний з D10)

A3

3,3 В

ADC12 IN13 (лише аналоговий; спільний з D8)

A4

3,3 В

ADC123 IN12 (спільний з D10)

A5

3,3 В

ADC12 IN13 (спільний з D8)

A6

3,3 В

DAC1 OUT1 / ADC12 IN18

A7

3,3 В

TIM3 CH1 / ADC12 IN3 (не виведений на роз’єми)

D20

3,3 В

псевдонім D8 / A3 / A5

D21

3,3 В

псевдонім A6 — DAC1 OUT1

RESET

3,3 В

натисніть бортовий перемикач або під’єднайте до GND для скидання

LED_RED

3,3 В

червоний канал RGB LED (активний низьким рівнем)

LED_GREEN

3,3 В

зелений канал RGB LED (активний низьким рівнем)

LED_BLUE

3,3 В

синій канал RGB LED (активний низьким рівнем)

Примітка

A0-A3 — це лише аналогові контактні площадки на STM32H747 без функції GPIO — використовуйте їх виключно як входи ADC. A2/A4 та A3/A5 спільні зі своїми фізичними виводами D10 та D8 відповідно, тому неможливо одночасно виводити PWM або SPI на них та читати їх як аналогові. A7 знаходиться на нижніх роз’ємах HD.

Виводи живлення

Виводи роз’єму MKR:

  • VIN — основна системна шина на вбудований PMIC. Подається через діод із шини +5V, виводу VIN MKR або нижніх 80‑контактних роз’ємів HD.

  • +5V — шина 5 В, яка живиться від USB, роз’єму ESLOV або самого виводу MKR +5V.

  • +3V3 — основна шина 3,3 В (вихід імпульсного регулятора PMIC).

  • AREF — опорна аналогова напруга для виводів ADC. За замовчуванням 3,3 В; підключіть зовнішнє джерело для використання іншого опорного значення.

  • GND — спільна земля.

Вхід акумулятора:

  • Li‑Po JST на передній частині плати приймає елемент Li‑Po 3,7 В. PMIC заряджає його за наявності +5V або VIN.

Portenta H7 може живитися через будь-який із цих шляхів:

  • USB‑C — подає 5 В на вбудований PMIC.

  • Роз’єм ESLOV — до 5 В на VESLOV (див. Роз’єм ESLOV).

  • Вивід VIN — подайте стабілізовані 5 В безпосередньо.

  • Акумулятор Li‑Po — підключіть до роз’єму JST спереду.

Роз’єм ESLOV

На боковій стороні плати розміщено 5‑контактний безпаяльний роз’єм ESLOV:

Вивід

Назва

Функція

1

VESLOV

Вихід живлення 5 В (та сама шина, що й +5V роз’єму MKR)

2

INT

вхід зовнішнього переривання на D7

3

SCL_EXT

спільний із контактною площадкою D12 роз’єму MKR — та сама шина I²C 3, що й на роз’ємі користувача

4

SDA_EXT

спільний із контактною площадкою D11 роз’єму MKR — та сама шина I²C 3, що й на роз’ємі користувача

5

GND

спільна земля

SCL_EXT/SDA_EXT роз’єму ESLOV та D12/D11 роз’єму MKR — це одні й ті ж виводи: один канал I²C 3, виведений на два роз’єми.

Порада

Скористайтеся калькулятором часу роботи від акумулятора, щоб змоделювати, скільки працюватиме Portenta H7 від акумулятора при заданому циклі активності / глибокого сну.

Виводи відновлення та налагодження

  • RESET — як виведений вивід на верхньому роз’ємі, так і моментальний перемикач на бічній стороні плати, підключений до лінії NRST SoC. Підключіть до GND або натисніть кнопку для скидання.

Portenta H7 використовує стандартне Arduino подвійне торкання кнопки скидання для входу в завантажувач Arduino. Швидко натисніть кнопку скидання двічі — плата повторно перелічиться через USB як пристрій DFU, і OpenMV IDE зможе прошити новий образ мікропрограми.

Сигнали SWD STM32 виведені на нижній роз’єм HD J1:

  • J1‑73 — NRST

  • J1‑75 — SWDIO (PA13)

  • J1‑77 — SWCLK (PA14)

  • J1‑79 — SWO (PB3)

Підключіть їх через Portenta Breakout, офіційний адаптер налагодження Arduino або власний носій із роз’ємом кроком 1,27 мм. Усі сигнали налагодження мають рівень 3,3 В.

Примітка

Коли підключено Portenta Vision Shield, ті самі сигнали SWD/JTAG маршрутизуються на стандартний 20‑контактний роз’єм налагодження ARM Cortex JTAG на шилді (крок 1,27 мм / 0,05″).

Периферійні пристрої на платі

Світлодіоди

Portenta H7 має один RGB LED для користувача, яким можна керувати програмно через machine.LED

from machine import LED

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

Окремий помаранчевий LED заряджання поряд із роз’ємом JST акумулятора світиться, коли вбудований зарядний пристрій подає струм у підключений Li‑Po; він не керується користувачем.

Датчик камери (Vision Shield)

Коли підключено Portenta Vision Shield (видання Ethernet або LoRa), датчик Himax керується через модуль csi — датчики камери

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

Підтримуються дві ревізії Vision Shield:

  • HM01B0 — монохромний 320 × 320.

  • HM0360 — монохромний 640 × 480.

Попередження

Поки камера Vision Shield ініціалізована, наступні виводи роз’єму MKR зайняті мікропрограмою і не можуть використовуватися:

Вивід MKR

Причина

D1

TIM1 CH1 — тактовий сигнал камери

D6

TIM1 CH1 (альт.) — тактовий сигнал камери

D11

I²C 3 SDA — спільний із камерою; шина доступна, але уникайте I²C адреси датчика (0x24)

D12

I²C 3 SCL — спільний із камерою; шина доступна, але уникайте I²C адреси датчика (0x24)

A6 / D21

DCMI HSYNC — також вимикає DAC

A7

DCMI PXCLK

Машинне навчання

ml — Машинне навчання запускає квантизовані моделі TFLite на Cortex‑M7 із ядрами CMSIS‑NN — достатньо швидко для компактних детекторів при кількох кадрах на секунду. Моделі у файловій системі /rom (лише для читання) завантажуються безпосередньо з флеш‑пам’яті без копіювання до RAM. Ось детектор облич BlazeFace 128×128, що накладає виявлене обличчя та шість його орієнтирів на кожен кадр із камери 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")

Ядро M4

Ядро Cortex‑M4 доступне через openamp для міжпроцесорного зв’язку. Мікропрограма OpenMV працює лише на M7; M4 не має власного середовища виконання MicroPython, тому його використання передбачає збірку окремого образу мікропрограми на C та його завантаження з файлової системи через openamp.RemoteProc. Готовий приклад мікропрограми, що реалізує віртуальний UART‑кінцевий пристрій, доступний у репозиторії openamp_vuart — дотримуйтесь README для збірки 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)

На практиці ця підтримка найкраще розглядається як демонстрація інтерфейсу openamp, а не як повноцінна двоядерна платформа — M4 не може бути скинутий незалежно від M7, тому зупинка M4 призводить до повного перезавантаження системи.

Мікрофон (Vision Shield)

Vision Shield містить два PDM‑мікрофони, захоплення яких здійснюється через audio — Аудіомодуль через периферійний пристрій SAI4 STM32. Кожен буфер надходить як bytearray зі знаковими 16‑бітними PCM‑даними, готовий для подачі до ulab/numpy для DSP — наприклад, простий детектор гучності:

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

Передайте channels=2 до audio.init, щоб отримувати перемежовані семпли з обох мікрофонів.

Лічильник заряду акумулятора

Лічильник заряду Maxim MAX17262 ModelGauge m5 відстежує напругу, струм, температуру та рівень заряду акумулятора Li‑Po. Він знаходиться на I²C 1 за адресою 0x36.

MAX17262 має внутрішнє вимірювання струму, тому регістр струму безпосередньо видає значення в мікроамперах без необхідності застосовувати зовнішній коефіцієнт Rsense. Читання лічильника заряду є безпечним — драйвер не постачається, але регістри, задокументовані в даташиті MAX17262, можна читати безпосередньо:

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 є знаковим доповненням до двох: позитивний при заряджанні, негативний при розряджанні. TTE має сенс лише коли струм від’ємний; TTF — лише коли струм додатний.

Мікросхема управління живленням

NXP PF1550 PMIC керує всіма регуляторами Portenta H7 — основною шиною +3V3, шиною ядра/I/O +1V8 SoC та зарядним пристроєм Li‑Po. Вона знаходиться на I²C 1 за адресою 0x08.

Попередження

Читання регістрів PMIC є безпечним; запис до них — небезпечний. Неправильне налаштування знижувального регулятора або параметрів зарядного пристрою може назавжди пошкодити плату, акумулятор або обидва. Вважайте PMIC доступним лише для читання, якщо ви точно не знаєте, що робите.

Найкорисніша інформація, яку PMIC повідомляє на відміну від лічильника заряду — це автомат станів зарядного пристрою: чи працює плата від USB / ESLOV / VIN, на якій стадії циклу заряджання знаходиться Li‑Po, і чи виник тепловий збій або збій сторожового таймера. Регістри зарядного пристрою знаходяться зі зсувом 0x80 у просторі основних I²C‑адрес PF1550 (див. §22.2 даташита PF1550), тому, наприклад, CHG_INT_OK за адресою зарядного пристрою 0x04 зчитується з регістра 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)

Інші регістри лише для читання, на які варто звернути увагу в даташиті (всі зі зсувом зарядного пристрою 0x80): 0x80 CHG_INT (зафіксовані переривання зарядного пристрою — прапорці помилок), 0x86 VBUS_SNS (багатобітний стан VBUS, включаючи OVLO / UVLO / DPM) та 0x88 BATT_SNS (наявність акумулятора та стан перевантаження по струму).

Wi‑Fi

Вбудований Murata 1DX (CYW4343W) доступний через network — налаштування мережі як інтерфейс станції. Підключіть антену, що постачається, до вбудованого роз’єму 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

Той самий Murata 1DX також надає Bluetooth LE 5.1. Використовуйте aioble — Async BLE для асинхронного BLE через asyncio — наприклад, оголосіть себе як периферійний пристрій і чекайте підключення центрального пристрою:

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 Vision Shield додає модуль LoRaWAN Murata CMWX1ZZABZ, підключений до Portenta H7 через UART. Модуль lora обгортає AT‑командну мікропрограму і підтримує приєднання OTAA або ABP, висхідний та низхідний канали:

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

Використовуйте BAND_US915 / BAND_AS923 / BAND_AU915 тощо для не‑EU регіонів і перейдіть на lora.Lora.join_ABP(), якщо ваш мережевий сервер використовує активацію ABP.

Попередження

Поки модуль LoRa використовується, драйвер займає наступні виводи роз’єму MKR як лінії керування для Murata CMWX1ZZABZ — вони не можуть використовуватися:

Вивід MKR

Причина

D3

Вивід BOOT модуля LoRa

D5

Вивід RST модуля LoRa

Ethernet (Vision Shield)

Видання Ethernet Vision Shield додає роз’єм RJ45 з трансформаторами, підключений до MAC Ethernet 10/100 STM32H747 через RMII. Підключіть кабель Ethernet, і PHY з’явиться як інтерфейс LAN; DHCP запускається автоматично після встановлення з’єднання:

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

Коли карта вставлена, вона монтується автоматично в /sdcard і доступна через звичайну файлову систему:

import os

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

Довідник із шин

GPIO

Використовуйте machine.Pin для читання або керування будь-яким із виводів з шовкографії. Виходи — CMOS 3,3 В із можливістю поглинання/видачі до 20 мА на вивід (140 мА сумарно по всьому роз’єму).

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

Будь-який вхідний вивід може також генерувати переривання на перепадах:

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

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

UART

Шина

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

Шина

SCL

SDA

I2C3

D12

D11

from machine import I2C

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

Контактні площадки D11/D12 на роз’ємі MKR та виводи SDA_EXT/SCL_EXT роз’єму ESLOV знаходяться на одній шині I²C 3 — дивіться Роз’єм ESLOV вище для розпіновки ESLOV.

Ту саму апаратуру можна також використовувати в режимі ведомого (target) через machine.I2CTarget для надання доступу до області пам’яті іншому I²C контролеру:

from machine import I2CTarget

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

SPI

Шина

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 виводить вісім 12‑бітних каналів ADC на A0–A7. Всі прив’язані до 3,3 Вread_u16 повертає 0–65535 для напруги 0–3,3 В на виводі:

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

Один 12‑бітний канал DAC виводиться на DAC1 (A6 / D21) через pyb.DAC

from pyb import DAC

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

PWM

Вивід

Таймер / канал

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

Керуйте будь-яким із них через machine.PWM

from machine import Pin, PWM

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

Примітка

Кілька виводів спільно використовують канали таймерів:

  • TIM1 CH1 знаходиться на D1 та D6.

  • TIM1 CH2 знаходиться на D2 та D14.

  • TIM8 CH3N знаходиться на D0 та D1.

Вибирайте одного споживача на канал таймера.

Попередження

TIM1 зарезервований для тактового сигналу камери, коли Vision Shield ініціалізований через csi — датчики камериD1, D2, D6, D13 та D14 не можуть отримувати сигнал PWM, поки камера активна.

Програмні шини з побітовою передачею

machine.SoftI2C та machine.SoftSPI працюють на будь-якому GPIO, якщо потрібна додаткова шина.

Тепловий датчик (зовнішній)

Мікропрограма включає драйвер fir — драйвер теплового датчика (fir == далекий інфрачервоний діапазон) для зовнішньо підключених теплових імаджерів:

  • MLX90621 — масив ІЧ 16 × 4

  • MLX90640 — масив ІЧ 32 × 24

  • MLX90641 — масив ІЧ 16 × 12

  • AMG8833 — масив ІЧ 8 × 8

Підключіть модуль до шини I²C плати та зчитуйте кадри за допомогою 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())

Драйвер fir спілкується з датчиком лише через I²C 3 — підключіть модуль до D12 (SCL) та D11 (SDA).

Синхронізація

час

Модуль time охоплює блокуючі затримки, монотонні тики та вимірювання часу:

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)

Віртуальні таймери

machine.Timer планує періодичні або одноразові зворотні виклики без використання апаратного слоту таймера. Передайте -1 як ідентифікатор для використання віртуального (програмного) таймера:

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

Значення періоду задаються в мілісекундах. Викличте deinit(), щоб зупинити і звільнити слот.

Годинник реального часу

machine.RTC зберігає астрономічний час між скиданнями. Роз’єм HD також виводить контактну площадку COINCELL, яка може живити RTC від CR2032 при відключеному живленні:

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

Сторожовий таймер

machine.WDT скидає плату, якщо застосунок завис. Після запуску його неможливо зупинити або перепрограмувати — підживлюйте його periodically всередині головного циклу:

from machine import WDT

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

Інформація про завантаження та виконання

Оновлення мікропрограми (DFU)

Portenta H7 використовує стандартне Arduino подвійне торкання кнопки скидання для входу в завантажувач Arduino. Швидко натисніть кнопку скидання двічі — плата повторно перелічиться через USB як пристрій DFU, і OpenMV IDE зможе прошити новий образ мікропрограми.

Запущений скрипт може повторно увійти в завантажувач на вимогу, викликавши machine.bootloader()

import machine

machine.bootloader()

Файлова система та порядок завантаження

Мікропрограма Portenta H7 монтує до трьох файлових систем при завантаженні:

  • Внутрішня флеш‑пам’ять — завжди монтується в /flash. За замовчуванням містить main.py та README.txt; створюється при першому завантаженні.

  • Карта microSD — якщо підключено Vision Shield і вставлено карту, вона монтується в /sdcard.

  • ROMFS — файлова система лише для читання, відображена в пам’ять за адресою /rom, монтується автоматично MicroPython при запуску.

Після монтування робочий каталог встановлюється в /sdcard, якщо карта присутня, інакше — /flash. Потім інтерпретатор запускає скрипти з цього каталогу:

  • boot.py виконується при кожному м’якому скиданні (холодне завантаження, Ctrl‑D з REPL або при поверненні запущеного скрипту).

  • main.py виконується лише при холодному завантаженні, одразу після boot.py. Подальші м’які скидання повторно запускають boot.py, але переходять прямо до REPL — щоб повторно запустити main.py, необхідно повністю скинути плату.

Перенесення boot.py або main.py на SD‑карту перевизначає копію у флеш‑пам’яті, не зачіпаючи її — обидва файли шукаються в каталозі завантаження (/sdcard, якщо карта змонтована, інакше /flash).

За замовчуванням main.py на щойно прошитій платі лише блимає синім каналом RGB LED як серцебиття (два коротких спалаху, коротка пауза), щоб ви могли переконатися, що мікропрограма завантажилась успішно без підключеного хоста.

sys.path розширений для включення всіх трьох файлових систем та їхніх підкаталогів lib/, тому модулі, що імпортуються, можуть знаходитися в /flash/lib, /sdcard/lib або /rom/lib.

Щоб змусити систему ігнорувати вставлену SD‑карту (наприклад, для запуску main.py з флеш‑пам’яті навіть за наявності карти), створіть порожній файл з іменем SKIPSD у корені /flash.

Під час підключення через USB файлова система завантаження (/sdcard, якщо карта присутня, інакше /flash) також перелічується як USB‑накопичувач на хості, дозволяючи редагувати boot.py, main.py та будь-які інші файли безпосередньо. Від’єднайте накопичувач перед скиданням плати, щоб хост вивантажив кешовані записи.

Примітка

Оскільки ОС розглядає накопичувач як пасивний блоковий пристрій, файли, створені або змінені кодом, що виконується на камері, не з’являться, поки хост не перемонтує накопичувач. Якщо ОС і камера одночасно записують в одну файлову систему, ОС перемагає і перезаписує зміни, зроблені камерою. Використовуйте SD‑карту для будь-яких даних, які скрипт записує назад, і перемонтуйте перед читанням цих файлів з хоста.

Примітка

Червоний канал RGB LED може короткочасно засвічуватися, поки хост читає або записує на USB‑накопичувач — це індикатор активності мікропрограми, а не збій.

Розміри сховищ

Portenta H7 постачається з:

  • /flash — файлова система FAT 11 МБ, читання/запис.

  • /rom — ROMFS лише для читання, відображений у пам’ять розміром 4 МБ, призначений для скриптів та моделей ML, що отримують користь від доступу через mmap без копіювання.

  • /sdcard — повний розмір будь-якої вставленої в Vision Shield карти microSD (за наявності), читання/запис.

Індикатор апаратного збою

Якщо RGB LED для користувача швидко циклічно перебирає всі кольори — достатньо швидко, що виглядає скоріше як мерехтливий білий LED, ніж окремі відтінки — мікропрограма зазнала невідновного апаратного збою. Перепрошуйте мікропрограму для відновлення; якщо перепрошивання не допомагає, плата може бути фізично пошкоджена.

Програмні бібліотеки

Дивіться індекс бібліотек для повного списку модулів — включаючи ті, що є унікальними для збірки Portenta H7.