Arduino Portenta H7

Arduino Portenta H7 adalah papan pengembangan industri berukuran 66 × 25 mm yang dibangun di sekitar STMicroelectronics STM32H747XI — SoC dual‑core yang menggabungkan Cortex‑M7 pada 400 MHz dengan Cortex‑M4 pada 200 MHz. Firmware OpenMV berjalan sepenuhnya pada inti M7 dan dirancang untuk digunakan bersama Portenta Vision Shield (edisi Ethernet atau LoRa), yang menambahkan kamera Himax HM01B0 / HM0360, dua mikrofon PDM, dan slot microSD ke Portenta H7 dasar.

Arduino Portenta H7

Untuk datasheet lengkap, foto, dan dimensi, lihat halaman produk Arduino Portenta H7.

Sorotan

  • STMicroelectronics STM32H747XI dual Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). Firmware OpenMV berjalan hanya pada inti M7; inti M4 diekspos melalui openamp untuk Komunikasi Antar‑Prosesor.

  • 8 MB SDRAM eksternal ditambah 2 MB flash internal dan 16 MB flash QSPI eksternal.

  • Encoder/decoder JPEG berbasis hardware.

  • Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 melalui modul Murata 1DX (CYW4343W) — terhubung ke antena yang disertakan melalui konektor U.FL yang terpasang di papan.

  • USB‑C berkecepatan tinggi (480 Mb/dtk).

  • 22 pin I/O pengguna pada header atas bergaya Arduino MKR — D0–D14 (digital) ditambah A0–A6 (analog).

  • Dua konektor high‑density 80 pin di bagian bawah mengekspos seluruh fabric STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UART, SPI/I²C/timer tambahan, dan sebagainya. Shield seperti Vision Shield terhubung ke konektor ini.

  • JTAG / SWD yang tersedia pada konektor HD bawah untuk debug tingkat lanjut.

  • Dukungan baterai — konektor JST Li‑Po 3,7 V beserta pengisi daya dan monitor baterai yang terintegrasi.

Pinout

Arduino Portenta H7 Pinout

Referensi pin

22 pin pengguna diekspos pada header tepi atas bergaya Arduino MKR — 15 digital (D0-D14) ditambah 7 analog (A0-A6). Lebih banyak pin SoC tersedia melalui konektor high‑density 80 pin bagian bawah untuk pekerjaan dengan shield; lihat PDF pinout lengkap Arduino untuk pemetaan tersebut.

Nama pin

Referensi

Fungsi

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 (bersama dengan A3 / A5)

D9

3,3 V

SPI2 SCK

D10

3,3 V

SPI2 MISO (bersama dengan 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 (hanya analog)

A1

3,3 V

ADC12 IN1 (hanya analog)

A2

3,3 V

ADC123 IN12 (hanya analog; bersama dengan D10)

A3

3,3 V

ADC12 IN13 (hanya analog; bersama dengan D8)

A4

3,3 V

ADC123 IN12 (bersama dengan D10)

A5

3,3 V

ADC12 IN13 (bersama dengan D8)

A6

3,3 V

DAC1 OUT1 / ADC12 IN18

A7

3,3 V

TIM3 CH1 / ADC12 IN3 (tidak diekspos pada header)

D20

3,3 V

alias dari D8 / A3 / A5

D21

3,3 V

alias dari A6 — DAC1 OUT1

RESET

3,3 V

tekan tombol yang terpasang di papan atau tarik ke GND untuk reset

LED_RED

3,3 V

Saluran merah LED RGB (aktif rendah)

LED_GREEN

3,3 V

Saluran hijau LED RGB (aktif rendah)

LED_BLUE

3,3 V

Saluran biru LED RGB (aktif rendah)

Catatan

A0-A3 adalah pad hanya analog pada STM32H747 tanpa fungsi GPIO — gunakan hanya sebagai input ADC. A2/A4 dan A3/A5 berbagi pin fisik dengan D10 dan D8 masing-masing, sehingga Anda tidak dapat menggunakan PWM atau SPI pada pin tersebut saat membacanya sebagai analog. A7 berada pada konektor HD bawah.

Pin daya

Pin header MKR:

  • VIN — rel sistem utama ke PMIC yang terpasang. Diberi daya melalui dioda dari rel +5V, pin MKR VIN, atau konektor HD 80‑pin bawah.

  • +5V — rel 5 V yang diberi daya dari USB, konektor ESLOV, atau pin MKR +5V itu sendiri.

  • +3V3 — rel utama 3,3 V (keluaran regulator switching PMIC).

  • AREF — referensi tegangan analog untuk pin ADC. Default 3,3 V; hubungkan secara eksternal untuk menggunakan referensi yang berbeda.

  • GND — ground bersama.

Input baterai:

  • Li‑Po JST di bagian depan papan menerima sel Li‑Po 3,7 V. PMIC mengisinya kapan pun +5V atau VIN tersedia.

Portenta H7 dapat diberi daya melalui salah satu jalur berikut:

  • USB‑C — menyuplai 5 V ke PMIC yang terpasang.

  • Konektor ESLOV — hingga 5 V pada VESLOV (lihat Konektor ESLOV).

  • Pin VIN — hubungkan suplai 5 V yang diregulasi secara langsung.

  • Baterai Li‑Po — hubungkan ke JST di bagian depan.

Konektor ESLOV

Di sisi papan terdapat konektor ESLOV 5 pin bebas solder:

Pin

Nama

Fungsi

1

VESLOV

Keluaran daya 5 V (rel yang sama dengan header MKR +5V)

2

INT

input interupsi eksternal pada D7

3

SCL_EXT

bersama dengan pad header MKR D12 — bus I²C 3 yang sama dengan header pengguna

4

SDA_EXT

bersama dengan pad header MKR D11 — bus I²C 3 yang sama dengan header pengguna

5

GND

ground bersama

SCL_EXT/SDA_EXT ESLOV dan D12/D11 header MKR adalah pin yang sama — satu bus I²C 3 yang diekspos pada dua konektor.

Tip

Gunakan estimator masa pakai baterai untuk memodelkan berapa lama Portenta H7 dapat berjalan dengan baterai untuk siklus aktif / tidur‑dalam tertentu.

Pin pemulihan dan debug

  • RESET — baik pin yang diekspos pada header atas maupun tombol sesaat di sisi papan, terhubung ke jalur NRST SoC. Tarik ke GND atau tekan tombol untuk reset.

Portenta H7 menggunakan ketukan reset ganda standar Arduino untuk masuk ke bootloader Arduino. Tekan tombol reset dua kali dengan cepat — papan akan mengenumerasi ulang melalui USB sebagai perangkat DFU dan OpenMV IDE dapat memflash citra firmware baru.

Sinyal SWD STM32 diekspos pada konektor HD J1 bagian bawah:

  • J1‑73 — NRST

  • J1‑75 — SWDIO (PA13)

  • J1‑77 — SWCLK (PA14)

  • J1‑79 — SWO (PB3)

Sambungkan melalui Portenta Breakout, adapter debug Arduino resmi, atau carrier kustom dengan header 1,27 mm. Semua sinyal debug bereferensi 3,3 V.

Catatan

Ketika Portenta Vision Shield terpasang, sinyal SWD/JTAG yang sama diarahkan ke header JTAG debug ARM Cortex 20 pin standar pada shield (pitch 1,27 mm / 0,05″).

Periferal bawaan

LED

The Portenta H7 has a single user RGB LED, software‑controllable through machine.LED:

from machine import LED

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

LED charge oranye terpisah di sebelah JST baterai menyala saat pengisi daya terintegrasi mengalirkan arus ke Li‑Po yang terhubung; LED ini tidak dapat dikontrol pengguna.

Sensor kamera (Vision Shield)

Dengan Portenta Vision Shield (edisi Ethernet atau LoRa) terpasang, sensor Himax dikendalikan melalui modul csi --- sensor kamera

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

Dua revisi Vision Shield didukung:

  • HM01B0 — 320 × 320 monokrom.

  • HM0360 — 640 × 480 monokrom.

Peringatan

Saat kamera Vision Shield diinisialisasi, pin header MKR berikut diklaim oleh firmware dan tidak dapat digunakan:

Pin MKR

Alasan

D1

TIM1 CH1 — clock master kamera

D6

TIM1 CH1 (alt) — clock master kamera

D11

I²C 3 SDA — bersama dengan kamera; bus dapat digunakan tetapi hindari alamat I²C sensor (0x24)

D12

I²C 3 SCL — bersama dengan kamera; bus dapat digunakan tetapi hindari alamat I²C sensor (0x24)

A6 / D21

DCMI HSYNC — juga menonaktifkan DAC

A7

DCMI PXCLK

Machine learning

ml --- Machine Learning menjalankan model TFLite terkuantisasi pada Cortex‑M7 dengan kernel CMSIS‑NN — cukup cepat untuk detektor kompak pada beberapa bingkai per detik. Model pada filesystem read-only /rom dimuat langsung dari flash tanpa menyalin ke RAM. Berikut adalah detektor BlazeFace 128×128 yang melapisi wajah yang terdeteksi dan enam landmark‑nya pada setiap bingkai dari kamera 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")

Inti M4

Inti Cortex‑M4 diekspos melalui openamp untuk komunikasi antar‑prosesor. Firmware OpenMV berjalan hanya pada M7; M4 tidak memiliki runtime MicroPython sendiri, sehingga menggunakannya berarti membangun citra firmware C terpisah dan memuatnya dari filesystem melalui openamp.RemoteProc. Firmware contoh yang telah dibangun sebelumnya yang mengimplementasikan endpoint UART virtual tersedia di repositori openamp_vuart — ikuti README‑nya untuk membangun 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)

Dalam praktiknya, dukungan ini sebaiknya diperlakukan sebagai demonstrasi antarmuka openamp daripada platform dual‑core yang berfungsi penuh — M4 tidak dapat direset secara independen dari M7, sehingga menghentikan M4 memaksa reboot sistem penuh.

Mikrofon (Vision Shield)

Vision Shield membawa dua mikrofon PDM yang ditangkap melalui audio --- Modul Audio melalui periferal SAI4 STM32. Setiap buffer tiba sebagai PCM 16-bit bertanda bytearray, siap untuk dimasukkan ke ulab/numpy untuk DSP — misalnya, detektor kenyaringan sederhana:

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

Berikan channels=2 ke audio.init untuk menerima sampel yang diinterleave dari kedua mikrofon.

Fuel gauge baterai

Fuel gauge Maxim MAX17262 ModelGauge m5 melacak tegangan, arus, suhu, dan status pengisian baterai Li‑Po. Perangkat ini berada pada I²C 1 di alamat 0x36.

MAX17262 memiliki penginderaan arus internal, sehingga register arus dapat dibaca langsung dalam mikroamp tanpa perlu menerapkan faktor Rsense eksternal. Membaca fuel gauge tidak berbahaya — tidak ada driver yang disertakan, tetapi register yang didokumentasikan dalam datasheet MAX17262 dapat dibaca langsung:

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 adalah komplemen dua bertanda: positif saat mengisi, negatif saat menguras. TTE hanya bermakna ketika arus negatif; TTF hanya ketika arus positif.

IC manajemen daya

NXP PF1550 PMIC menangani setiap regulator pada Portenta H7 — rel utama +3V3, rel inti SoC / I/O +1V8, dan pengisi daya Li‑Po. Perangkat ini berada pada I²C 1 di alamat 0x08.

Peringatan

Membaca register PMIC tidak masalah; menulis ke register tersebut berbahaya. Kesalahan konfigurasi regulator buck atau pengaturan pengisi daya dapat merusak papan, baterai, atau keduanya secara permanen. Perlakukan PMIC sebagai hanya‑baca kecuali Anda benar‑benar tahu apa yang Anda lakukan.

Hal paling berguna yang diberitahu PMIC kepada Anda yang tidak bisa dilakukan oleh fuel gauge adalah mesin status pengisi daya — apakah papan saat ini berjalan pada USB / ESLOV / VIN, tahap siklus pengisian apa yang sedang dilalui Li‑Po, dan apakah pengisi daya dalam kondisi fault termal atau watchdog. Register pengisi daya berada pada offset 0x80 dalam ruang alamat I²C utama PF1550 (lihat §22.2 dari datasheet PF1550), sehingga misalnya CHG_INT_OK pada alamat pengisi daya 0x04 dibaca dari register 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)

Register hanya‑baca lain yang layak dilihat dalam datasheet (semua pada offset pengisi daya 0x80): 0x80 CHG_INT (interupsi pengisi daya yang dikunci — flag fault), 0x86 VBUS_SNS (status VBUS multi‑bit termasuk OVLO / UVLO / DPM), dan 0x88 BATT_SNS (keberadaan baterai dan status arus lebih).

Wi‑Fi

Murata 1DX (CYW4343W) bawaan diekspos melalui network --- konfigurasi jaringan sebagai antarmuka station. Sambungkan antena yang disertakan ke konektor U.FL yang terpasang sebelum mengaktifkan radio:

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 yang sama juga mengekspos Bluetooth LE 5.1. Gunakan aioble --- Async BLE untuk BLE yang ramah asyncio — misalnya, iklankan sebagai periferal dan tunggu central untuk terhubung:

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)

Edisi LoRa Vision Shield menambahkan modul LoRaWAN Murata CMWX1ZZABZ yang dihubungkan ke Portenta H7 melalui UART. Modul lora membungkus firmware perintah AT dan mendukung join OTAA atau ABP, uplink, dan 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()

Gunakan BAND_US915 / BAND_AS923 / BAND_AU915 dll. untuk wilayah non-EU, dan beralih ke lora.Lora.join_ABP() jika server jaringan Anda menggunakan aktivasi ABP.

Peringatan

Saat modul LoRa sedang digunakan, driver mengklaim pin header MKR berikut sebagai jalur kontrol untuk Murata CMWX1ZZABZ — pin tersebut tidak dapat digunakan:

Pin MKR

Alasan

D3

Pin BOOT modul LoRa

D5

Pin RST modul LoRa

Ethernet (Vision Shield)

Edisi Ethernet Vision Shield menambahkan jack RJ45 dengan magnetics yang dihubungkan ke MAC Ethernet 10/100 STM32H747 melalui RMII. Sambungkan kabel Ethernet dan PHY muncul sebagai antarmuka LAN; DHCP berjalan otomatis setelah tautan aktif:

import network
import time

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

kartu microSD (Vision Shield)

Ketika kartu dimasukkan, kartu tersebut dipasang secara otomatis di /sdcard dan dapat digunakan melalui sistem file biasa:

import os

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

Referensi bus

GPIO

Gunakan machine.Pin untuk membaca atau menggerakkan salah satu pin yang tercetak. Keluaran adalah CMOS 3,3 V dan dapat sink/source hingga 20 mA per pin (140 mA total di seluruh header).

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

Pin input mana pun juga dapat memicu interupsi pada transisi tepi:

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

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

UART

Bus

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

Bus

SCL

SDA

I2C3

D12

D11

from machine import I2C

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

Pad D11/D12 pada header MKR dan pin SDA_EXT/SCL_EXT konektor ESLOV berada pada bus I²C 3 yang sama — lihat Konektor ESLOV di atas untuk pinout ESLOV.

Hardware yang sama juga dapat digunakan dalam mode target (slave) melalui machine.I2CTarget untuk mengekspos wilayah memori ke kontroler I²C lain:

from machine import I2CTarget

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

SPI

Bus

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 mengekspos delapan saluran ADC 12‑bit pada A0–A7. Semua bereferensi 3,3 Vread_u16 mengembalikan 0–65535 pada 0–3,3 V di 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

Satu saluran DAC 12‑bit diekspos pada DAC1 (A6 / D21) melalui pyb.DAC

from pyb import DAC

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

PWM

Pin

Timer / saluran

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

Gerakkan salah satunya melalui machine.PWM

from machine import Pin, PWM

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

Catatan

Beberapa pin berbagi saluran timer:

  • TIM1 CH1 ada pada D1 dan D6.

  • TIM1 CH2 ada pada D2 dan D14.

  • TIM8 CH3N ada pada D0 dan D1.

Pilih satu pengguna per saluran timer.

Peringatan

TIM1 dicadangkan untuk clock master kamera saat Vision Shield diinisialisasi melalui csi --- sensor kameraD1, D2, D6, D13, dan D14 tidak dapat digerakkan dengan PWM selama kamera aktif.

Bus bit‑bang perangkat lunak

machine.SoftI2C dan machine.SoftSPI bekerja pada GPIO mana pun jika Anda membutuhkan bus tambahan.

Sensor termal (di luar papan)

Firmware menyertakan driver fir --- driver sensor termal (fir == far infrared) untuk imager termal yang dihubungkan secara eksternal:

  • MLX90621 — array IR 16 × 4

  • MLX90640 — array IR 32 × 24

  • MLX90641 — array IR 16 × 12

  • AMG8833 — array IR 8 × 8

Hubungkan modul ke bus I²C papan dan baca bingkai dengan 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())

Driver fir hanya berkomunikasi dengan sensor melalui I²C 3 — hubungkan modul ke D12 (SCL) dan D11 (SDA).

Waktu

time

Modul time mencakup penundaan pemblokiran, tik monotonis, dan pengukuran waktu yang berlalu:

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)

Timer virtual

machine.Timer menjadwalkan callback periodik atau satu‑kali tanpa menggunakan slot timer hardware. Berikan -1 sebagai id untuk menggunakan timer virtual (perangkat lunak):

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

Nilai periode dalam milidetik. Panggil deinit() untuk menghentikan dan melepaskan slot.

Real‑time clock

machine.RTC menjaga waktu jam dinding di seluruh reset. Konektor HD juga mengekspos pad COINCELL yang dapat membackup RTC dari CR2032 saat kehilangan daya:

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 mereset papan jika aplikasi hang. Setelah dimulai, tidak dapat dihentikan atau dikonfigurasi ulang — umpan secara berkala di dalam loop utama Anda:

from machine import WDT

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

Info boot dan runtime

Pembaruan firmware (DFU)

Portenta H7 menggunakan ketukan reset ganda standar Arduino untuk masuk ke bootloader Arduino. Tekan tombol reset dua kali dengan cepat — papan akan mengenumerasi ulang melalui USB sebagai perangkat DFU dan OpenMV IDE dapat memflash citra firmware baru.

Skrip yang sedang berjalan dapat masuk kembali ke bootloader sesuai permintaan dengan memanggil machine.bootloader()

import machine

machine.bootloader()

Sistem file dan urutan boot

Firmware Portenta H7 memasang hingga tiga filesystem saat boot:

  • Flash internal — selalu dipasang di /flash. Berisi main.py dan README.txt secara default; dibuat pada boot pertama.

  • Kartu microSD — jika Vision Shield terpasang dan kartu dimasukkan, kartu dipasang di /sdcard.

  • ROMFS — filesystem read-only yang dipetakan memori di /rom yang dipasang secara otomatis oleh MicroPython saat startup.

Setelah pemasangan, direktori kerja diatur ke /sdcard ketika kartu ada, jika tidak ke /flash. Interpreter kemudian menjalankan skrip dari direktori tersebut:

  • boot.py dieksekusi pada setiap soft reset (cold boot, Ctrl‑D dari REPL, atau kapan pun skrip yang berjalan kembali).

  • main.py dieksekusi hanya pada cold boot, segera setelah boot.py. Soft reset berikutnya menjalankan kembali boot.py tetapi langsung ke REPL — untuk menjalankan kembali main.py Anda harus mereset penuh papan.

Menjatuhkan boot.py atau main.py ke kartu SD menggantikan salinan di flash tanpa menyentuhnya — kedua file dicari di direktori boot (/sdcard ketika kartu dipasang, jika tidak /flash).

main.py default yang dikirim pada papan yang baru diflash hanya berkedip saluran biru LED RGB pengguna sebagai heartbeat (dua pulsa pendek, jeda pendek), sehingga Anda dapat mengetahui firmware booted dengan bersih tanpa host yang terhubung.

sys.path diperluas untuk menyertakan ketiga filesystem dan subdirektori lib/‑nya, sehingga modul yang dapat diimpor dapat berada di /flash/lib, /sdcard/lib, atau /rom/lib.

Untuk memaksa sistem mengabaikan kartu SD yang dimasukkan (misalnya untuk menjalankan main.py flash meskipun ada kartu), buat file kosong bernama SKIPSD di root /flash.

Saat terhubung melalui USB, filesystem boot (/sdcard jika kartu ada, jika tidak /flash) juga mengenumerasi sebagai drive USB mass‑storage di host, memungkinkan Anda mengedit boot.py, main.py, dan file lain secara langsung. Eject drive sebelum mereset papan agar host membilas penulisan yang di‑cache.

Catatan

Karena OS memperlakukan drive sebagai perangkat blok pasif, file yang dibuat atau dimodifikasi oleh kode yang berjalan di kamera tidak akan muncul sampai host me‑remount drive. Jika OS dan kamera menulis ke filesystem yang sama secara bersamaan, OS akan menang dan menimpa perubahan yang dibuat oleh kamera. Gunakan kartu SD untuk data apa pun yang ditulis kembali oleh skrip, dan remount sebelum membaca file tersebut dari host.

Catatan

Saluran merah LED RGB pengguna mungkin menyala sebentar saat host membaca dari atau menulis ke drive USB mass‑storage — ini adalah indikator aktivitas yang digerakkan firmware, bukan fault.

Ukuran penyimpanan

Portenta H7 dikirim dengan:

  • /flash — filesystem FAT 11 MB, baca/tulis.

  • /rom — ROMFS yang dipetakan memori hanya‑baca 4 MB, digunakan untuk mengirimkan skrip dan model ML yang mendapat manfaat dari akses mmap tanpa salinan.

  • /sdcard — ukuran penuh kartu microSD apa pun yang dimasukkan ke Vision Shield (jika ada), baca/tulis.

Indikator hard‑fault

Jika LED RGB pengguna bersiklus cepat melalui semua warna — cukup cepat sehingga cenderung terlihat seperti LED putih berkedip daripada warna yang berbeda — firmware telah mengalami hard fault yang tidak dapat dipulihkan. Reflash firmware untuk memulihkan; jika reflashing tidak membantu, papan mungkin rusak secara fisik.

Pustaka perangkat lunak

Lihat indeks pustaka untuk daftar lengkap modul — termasuk mana yang unik untuk build Portenta H7.