Arduino Portenta H7¶
Arduino Portenta H7 là bo mạch phát triển công nghiệp kích thước 66 × 25 mm được xây dựng xung quanh vi mạch STMicroelectronics STM32H747XI — một SoC lõi kép kết hợp Cortex‑M7 ở tốc độ 400 MHz với Cortex‑M4 ở tốc độ 200 MHz. Firmware OpenMV chạy hoàn toàn trên lõi M7 và được thiết kế để sử dụng với Portenta Vision Shield (phiên bản Ethernet hoặc LoRa), bổ sung camera Himax HM01B0 / HM0360, hai micro PDM và khe cắm microSD vào Portenta H7.
Để xem datasheet đầy đủ, ảnh và kích thước, hãy truy cập trang sản phẩm Arduino Portenta H7.
Tính năng nổi bật¶
STMicroelectronics STM32H747XI lõi kép Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). Firmware OpenMV chạy trên lõi M7; lõi M4 được truy xuất qua openamp cho giao tiếp liên lõi.
8 MB SDRAM ngoài cùng 2 MB flash nội và 16 MB flash QSPI ngoài.
Bộ mã hóa/giải mã JPEG phần cứng.
Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 qua module Murata 1DX (CYW4343W) — kết nối với ăng-ten đi kèm qua đầu nối U.FL trên bo.
USB‑C tốc độ cao (480 Mb/s).
22 chân I/O người dùng trên các header kiểu Arduino MKR phía trên — D0–D14 (số) và A0–A6 (tương tự).
Hai đầu nối mật độ cao 80 chân ở phía dưới cung cấp toàn bộ tài nguyên STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UART, thêm SPI/I²C/bộ định thời, v.v. Các shield như Vision Shield kết nối qua các đầu nối này.
JTAG / SWD có thể truy xuất qua đầu nối HD phía dưới để debug nâng cao.
Hỗ trợ pin — đầu nối JST Li‑Po 3,7 V cùng bộ sạc và bộ theo dõi pin tích hợp.
Sơ đồ chân¶
Tham chiếu chân¶
22 chân người dùng được truy xuất trên các header cạnh trên kiểu Arduino MKR — 15 chân số (D0-D14) và 7 chân tương tự (A0-A6). Nhiều chân SoC hơn có sẵn qua các đầu nối mật độ cao 80 chân phía dưới cho các shield; xem tài liệu sơ đồ chân đầy đủ PDF của Arduino để biết thêm.
Tên chân |
Tham chiếu |
Chức năng |
|---|---|---|
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 (dùng chung với A3 / A5) |
D9 |
3.3 V |
SPI2 SCK |
D10 |
3.3 V |
SPI2 MISO (dùng chung với 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 (chỉ tương tự) |
A1 |
3.3 V |
ADC12 IN1 (chỉ tương tự) |
A2 |
3.3 V |
ADC123 IN12 (chỉ tương tự; dùng chung với D10) |
A3 |
3.3 V |
ADC12 IN13 (chỉ tương tự; dùng chung với D8) |
A4 |
3.3 V |
ADC123 IN12 (dùng chung với D10) |
A5 |
3.3 V |
ADC12 IN13 (dùng chung với D8) |
A6 |
3.3 V |
DAC1 OUT1 / ADC12 IN18 |
A7 |
3.3 V |
TIM3 CH1 / ADC12 IN3 (không hiển thị trên header) |
D20 |
3.3 V |
bí danh của |
D21 |
3.3 V |
bí danh của |
RESET |
3.3 V |
nhấn công tắc trên bo hoặc kéo xuống GND để reset |
LED_RED |
3.3 V |
Kênh đỏ của LED RGB (tích cực mức thấp) |
LED_GREEN |
3.3 V |
Kênh xanh lá của LED RGB (tích cực mức thấp) |
LED_BLUE |
3.3 V |
Kênh xanh dương của LED RGB (tích cực mức thấp) |
Ghi chú
A0-A3 là các chân chỉ tương tự trên STM32H747 không có chức năng GPIO — hãy dùng chúng chỉ là đầu vào ADC. A2/A4 và A3/A5 dùng chung chân vật lý với D10 và D8 tương ứng, vì vậy bạn không thể dùng PWM hay SPI trên đó trong khi đọc chúng dạng tương tự. A7 nằm trên các đầu nối HD phía dưới.
Chân nguồn¶
Các chân header MKR:
VIN — đường nguồn hệ thống chính vào PMIC trên bo. Được cấp qua diode từ đường
+5V, chân MKRVIN, hoặc đầu nối HD 80 chân phía dưới.+5V — đường 5 V được cấp từ USB, đầu nối ESLOV, hoặc chân MKR
+5V.+3V3 — đường 3,3 V chính (đầu ra bộ chuyển đổi switching của PMIC).
AREF — điện áp tham chiếu tương tự cho các chân ADC. Mặc định là 3,3 V; kết nối ngoài để dùng điện áp tham chiếu khác.
GND — nối đất chung.
Đầu vào pin:
JST Li‑Po ở mặt trước bo chấp nhận pin Li‑Po 3,7 V. PMIC sạc pin khi có
+5VhoặcVIN.
Portenta H7 có thể được cấp nguồn qua bất kỳ đường nào sau đây:
USB‑C — cung cấp 5 V cho PMIC trên bo.
Đầu nối ESLOV — lên đến 5 V trên
VESLOV(xem Đầu nối ESLOV).Chân VIN — kết nối nguồn 5 V điều chỉnh trực tiếp.
Pin Li‑Po — kết nối với đầu nối JST ở mặt trước.
Đầu nối ESLOV¶
Ở bên cạnh bo có một đầu nối ESLOV 5 chân không cần hàn:
Chân |
Tên |
Chức năng |
|---|---|---|
1 |
VESLOV |
Đầu ra nguồn 5 V (cùng đường với |
2 |
INT |
Đầu vào ngắt ngoài trên |
3 |
SCL_EXT |
dùng chung với chân |
4 |
SDA_EXT |
dùng chung với chân |
5 |
GND |
nối đất chung |
SCL_EXT/SDA_EXT của ESLOV và D12/D11 của header MKR là cùng một chân — một bus I²C 3 được hiển thị trên hai đầu nối.
Mẹo
Dùng công cụ ước tính thời lượng pin để mô phỏng thời gian hoạt động của Portenta H7 trên pin với chu kỳ hoạt động / ngủ sâu nhất định.
Chân phục hồi và debug¶
RESET — vừa là chân được truy xuất trên header phía trên vừa là công tắc nhấn tạm thời bên cạnh bo, nối với đường NRST của SoC. Kéo xuống GND hoặc nhấn nút để reset.
Portenta H7 sử dụng nhấp đôi reset chuẩn của Arduino để vào bootloader Arduino. Nhấn nút reset nhanh hai lần — bo sẽ liệt kê lại qua USB như một thiết bị DFU và OpenMV IDE có thể nạp firmware mới.
Tín hiệu SWD của STM32 được truy xuất trên đầu nối HD J1 phía dưới:
J1‑73— NRSTJ1‑75— SWDIO (PA13)J1‑77— SWCLK (PA14)J1‑79— SWO (PB3)
Kết nối chúng qua Portenta Breakout, bộ debug chính thức của Arduino, hoặc carrier tùy chỉnh với header 1,27 mm. Tất cả tín hiệu debug đều tham chiếu 3,3 V.
Ghi chú
Khi Portenta Vision Shield được gắn vào, cùng các tín hiệu SWD/JTAG được dẫn lên header JTAG Cortex Debug ARM 20 chân chuẩn trên shield (bước 1,27 mm / 0,05″).
Ngoại vi tích hợp¶
LED¶
Portenta H7 có một LED RGB người dùng, có thể điều khiển bằng phần mềm qua machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
Một LED sạc màu cam riêng biệt cạnh đầu nối JST pin sáng khi bộ sạc tích hợp đang nạp dòng vào Li‑Po đã kết nối; nó không thể điều khiển bằng người dùng.
Cảm biến camera (Vision Shield)¶
Khi Portenta Vision Shield (phiên bản Ethernet hoặc LoRa) được gắn vào, cảm biến Himax được điều khiển qua module csi --- cảm biến camera
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()
Hỗ trợ hai phiên bản Vision Shield:
HM01B0 — 320 × 320 đơn sắc.
HM0360 — 640 × 480 đơn sắc.
Cảnh báo
Khi camera Vision Shield đang được khởi tạo, các chân header MKR sau bị firmware chiếm dụng và không thể sử dụng:
Chân MKR |
Lý do |
|---|---|
|
TIM1 CH1 — xung clock chính camera |
|
TIM1 CH1 (alt) — xung clock chính camera |
|
I²C 3 SDA — dùng chung với camera; bus vẫn có thể dùng nhưng tránh địa chỉ I²C của cảm biến ( |
|
I²C 3 SCL — dùng chung với camera; bus vẫn có thể dùng nhưng tránh địa chỉ I²C của cảm biến ( |
|
DCMI HSYNC — cũng vô hiệu hóa DAC |
|
DCMI PXCLK |
Học máy¶
ml --- Machine Learning chạy các mô hình TFLite lượng tử hóa trên Cortex‑M7 với các kernel CMSIS‑NN — đủ nhanh cho các bộ phát hiện nhỏ gọn ở vài khung hình mỗi giây. Các mô hình trên hệ thống tệp chỉ đọc /rom được tải trực tiếp từ flash mà không cần sao chép vào RAM. Đây là bộ phát hiện khuôn mặt BlazeFace 128×128 vẽ lớp phủ khuôn mặt và sáu điểm đặc trưng trên mỗi khung hình từ 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")
Lõi M4¶
Lõi Cortex‑M4 được truy xuất qua openamp cho giao tiếp liên lõi. Firmware OpenMV chạy chỉ trên M7; M4 không có runtime MicroPython riêng, vì vậy sử dụng nó có nghĩa là xây dựng firmware C riêng và tải từ hệ thống tệp qua openamp.RemoteProc. Firmware ví dụ dựng sẵn triển khai endpoint UART ảo có trong kho lưu trữ openamp_vuart — làm theo README của nó để build 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)
Trên thực tế, hỗ trợ này nên được coi là minh họa về giao diện openamp hơn là nền tảng lõi kép thực sự — M4 không thể reset độc lập với M7, vì vậy dừng M4 buộc khởi động lại toàn bộ hệ thống.
Micro (Vision Shield)¶
Vision Shield mang hai micro PDM được thu qua audio --- Mô-đun Âm thanh qua ngoại vi SAI4 của STM32. Mỗi bộ đệm đến dưới dạng PCM 16-bit có dấu bytearray, sẵn sàng đưa vào ulab/numpy để xử lý DSP — ví dụ, một bộ phát hiện độ to đơn giản:
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
Truyền channels=2 vào audio.init để nhận mẫu xen kẽ từ cả hai micro.
Đồng hồ đo pin¶
Đồng hồ đo ModelGauge m5 MAX17262 của Maxim theo dõi điện áp, dòng điện, nhiệt độ và trạng thái sạc của pin Li‑Po. Nó nằm trên I²C 1 tại địa chỉ 0x36.
MAX17262 có khả năng cảm biến dòng điện nội bộ, vì vậy thanh ghi dòng điện đọc trực tiếp bằng microamp mà không cần áp dụng hệ số Rsense ngoài. Đọc đồng hồ đo pin là vô hại — không có driver đi kèm, nhưng các thanh ghi được ghi lại trong datasheet MAX17262 có thể đọc trực tiếp:
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 là số bù hai: dương khi sạc, âm khi xả. TTE chỉ có nghĩa khi dòng điện âm; TTF chỉ khi dòng điện dương.
IC quản lý nguồn¶
PF1550 của NXP PMIC xử lý mọi bộ điều chỉnh điện áp trên Portenta H7 — đường +3V3 chính, đường lõi SoC / I/O +1V8, và bộ sạc Li‑Po. Nó nằm trên I²C 1 tại địa chỉ 0x08.
Cảnh báo
Đọc thanh ghi PMIC là an toàn; ghi vào chúng là nguy hiểm. Cấu hình sai bộ chuyển đổi buck hay cài đặt bộ sạc có thể gây hỏng vĩnh viễn bo, pin, hoặc cả hai. Hãy xem PMIC chỉ đọc trừ khi bạn biết chính xác mình đang làm gì.
Điều hữu ích nhất mà PMIC cho bạn biết mà đồng hồ đo pin không thể là máy trạng thái bộ sạc — liệu bo hiện đang chạy trên USB / ESLOV / VIN, giai đoạn nào của chu kỳ sạc Li‑Po, và liệu bộ sạc có đang ở trạng thái lỗi nhiệt hay watchdog không. Các thanh ghi bộ sạc nằm ở offset 0x80 trong không gian địa chỉ I²C chính của PF1550 (xem §22.2 của datasheet PF1550), vì vậy ví dụ CHG_INT_OK tại địa chỉ bộ sạc 0x04 được đọc từ thanh ghi 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)
Các thanh ghi chỉ đọc khác đáng xem trong datasheet (tất cả ở offset bộ sạc 0x80): 0x80 CHG_INT (các ngắt bộ sạc đã chốt — cờ lỗi), 0x86 VBUS_SNS (trạng thái VBUS nhiều bit bao gồm OVLO / UVLO / DPM), và 0x88 BATT_SNS (trạng thái hiện diện pin và quá dòng).
Wi‑Fi¶
Murata 1DX (CYW4343W) tích hợp trên bo được truy xuất qua network --- cấu hình mạng như một giao diện trạm. Kết nối ăng-ten đi kèm với đầu nối U.FL trên bo trước khi bật 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¶
Cùng Murata 1DX cũng cung cấp Bluetooth LE 5.1. Dùng aioble --- Async BLE cho BLE thân thiện với asyncio — ví dụ, quảng bá như một ngoại vi và chờ kết nối từ thiết bị trung tâm:
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)¶
Phiên bản LoRa của Vision Shield thêm module LoRaWAN Murata CMWX1ZZABZ kết nối với Portenta H7 qua UART. Module lora bọc firmware lệnh AT và hỗ trợ tham gia OTAA hoặc ABP, uplink và 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()
Dùng BAND_US915 / BAND_AS923 / BAND_AU915 v.v. cho các khu vực ngoài EU, và chuyển sang lora.Lora.join_ABP() nếu máy chủ mạng của bạn sử dụng kích hoạt ABP.
Cảnh báo
Khi module LoRa đang được sử dụng, driver chiếm dụng các chân header MKR sau làm đường điều khiển cho Murata CMWX1ZZABZ — chúng không thể sử dụng:
Chân MKR |
Lý do |
|---|---|
|
Chân BOOT của module LoRa |
|
Chân RST của module LoRa |
Ethernet (Vision Shield)¶
Phiên bản Ethernet của Vision Shield thêm đầu nối RJ45 có biến áp cách ly kết nối với MAC Ethernet 10/100 của STM32H747 qua RMII. Cắm cáp Ethernet và PHY xuất hiện như giao diện LAN; DHCP chạy tự động khi kết nối được thiết lập:
import network
import time
lan = network.LAN()
lan.active(True)
while not lan.isconnected():
time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])
Thẻ microSD (Vision Shield)¶
Khi thẻ được lắp vào, nó tự động được gắn kết tại /sdcard và có thể dùng qua hệ thống tệp thông thường:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Tham chiếu bus¶
GPIO¶
Dùng machine.Pin để đọc hoặc điều khiển bất kỳ chân nào trên silkscreen. Đầu ra là 3,3 V CMOS và có thể nhận/cấp đến 20 mA mỗi chân (140 mA tổng cộng trên toàn bộ 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())
Bất kỳ chân đầu vào nào cũng có thể kích hoạt ngắt khi chuyển cạnh:
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")
Các chân D11/D12 trên header MKR và các chân SDA_EXT/SCL_EXT của đầu nối ESLOV đều nằm trên cùng bus I²C 3 — xem Đầu nối ESLOV ở trên để biết sơ đồ chân ESLOV.
Cùng phần cứng cũng có thể được dùng ở chế độ mục tiêu (slave) qua machine.I2CTarget để hiển thị vùng bộ nhớ cho bộ điều khiển I²C khác:
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 cung cấp tám kênh ADC 12-bit trên A0–A7. Tất cả đều tham chiếu 3,3 V — read_u16 trả về 0–65535 trên dải 0–3,3 V tại chân:
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¶
Một kênh DAC 12-bit duy nhất được truy xuất trên DAC1 (A6 / D21) qua pyb.DAC
from pyb import DAC
dac = DAC("DAC1")
dac.write(int(0.5 * 255)) # 8‑bit output, ~1.65 V
PWM¶
Chân |
Bộ định thời / kênh |
|---|---|
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 |
Điều khiển bất kỳ chân nào trong số đó qua machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D4"), freq=1_000, duty_u16=32768)
Ghi chú
Một số chân dùng chung kênh bộ định thời:
TIM1 CH1 nằm trên
D1vàD6.TIM1 CH2 nằm trên
D2vàD14.TIM8 CH3N nằm trên
D0vàD1.
Chọn một đối tượng duy nhất cho mỗi kênh bộ định thời.
Cảnh báo
TIM1 được dành riêng cho xung clock chính camera khi Vision Shield được khởi tạo qua csi --- cảm biến camera — D1, D2, D6, D13, và D14 không thể dùng PWM khi camera đang hoạt động.
Bus bit-bang bằng phần mềm¶
machine.SoftI2C và machine.SoftSPI hoạt động trên bất kỳ GPIO nào nếu bạn cần thêm bus.
Cảm biến nhiệt (ngoài bo)¶
Firmware bao gồm driver fir --- trình điều khiển cảm biến nhiệt (fir == hồng ngoại xa) cho các thiết bị chụp ảnh nhiệt kết nối ngoài:
MLX90621 — mảng IR 16 × 4
MLX90640 — mảng IR 32 × 24
MLX90641 — mảng IR 16 × 12
AMG8833 — mảng IR 8 × 8
Kết nối module với bus I²C của bo và đọc khung hình bằng 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 chỉ giao tiếp với cảm biến qua I²C 3 — kết nối module với D12 (SCL) và D11 (SDA).
Định thời¶
time¶
Module time bao gồm trì hoãn chặn, tick đơn điệu và đo thời gian trôi qua:
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)
Bộ định thời ảo¶
machine.Timer lên lịch các hàm gọi lại định kỳ hoặc một lần mà không tiêu thụ khe cắm bộ định thời phần cứng. Truyền -1 làm id để dùng bộ định thời ảo (phần mềm):
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"))
Giá trị chu kỳ tính bằng mili giây. Gọi deinit() để dừng và giải phóng khe cắm.
Đồng hồ thời gian thực¶
machine.RTC giữ thời gian thực qua các lần reset. Đầu nối HD cũng có chân COINCELL có thể dự phòng RTC từ pin CR2032 khi mất nguồn:
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 reset bo nếu ứng dụng bị treo. Một khi đã khởi động, nó không thể dừng hay cấu hình lại — hãy feed nó định kỳ trong vòng lặp chính:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Thông tin khởi động và runtime¶
Cập nhật firmware (DFU)¶
Portenta H7 sử dụng nhấp đôi reset chuẩn của Arduino để vào bootloader Arduino. Nhấn nút reset nhanh hai lần — bo sẽ liệt kê lại qua USB như một thiết bị DFU và OpenMV IDE có thể nạp firmware mới.
Một tập lệnh đang chạy có thể vào lại bootloader theo yêu cầu bằng cách gọi machine.bootloader()
import machine
machine.bootloader()
Hệ thống tệp và thứ tự khởi động¶
Firmware Portenta H7 gắn kết tối đa ba hệ thống tệp khi khởi động:
Flash nội — luôn được gắn kết tại
/flash. Mặc định chứamain.pyvàREADME.txt; được tạo trong lần khởi động đầu tiên.Thẻ microSD — nếu Vision Shield được gắn và thẻ được lắp vào, nó được gắn kết tại
/sdcard.ROMFS — hệ thống tệp ánh xạ bộ nhớ chỉ đọc tại
/romđược MicroPython gắn kết tự động khi khởi động.
Sau khi gắn kết, thư mục làm việc được đặt thành /sdcard khi có thẻ, ngược lại là /flash. Trình thông dịch sau đó chạy các tập lệnh từ thư mục đó:
boot.pyđược thực thi trong mỗi lần reset mềm (khởi động lạnh,Ctrl‑Dtừ REPL, hoặc khi tập lệnh đang chạy trả về).main.pychỉ được thực thi khi khởi động lạnh, ngay sauboot.py. Các lần reset mềm tiếp theo chạy lạiboot.pynhưng chuyển thẳng đến REPL — để chạy lạimain.pybạn phải reset hoàn toàn bo.
Đặt boot.py hoặc main.py lên thẻ SD sẽ ghi đè bản sao trong flash mà không làm ảnh hưởng nó — cả hai tệp đều được tìm trong thư mục khởi động (/sdcard khi thẻ được gắn kết, ngược lại là /flash).
Tệp main.py mặc định được cài sẵn trên bo mới flash chỉ nhấp nháy kênh xanh dương của LED RGB người dùng như nhịp tim (hai xung ngắn, khoảng ngừng ngắn), để bạn biết firmware đã khởi động thành công mà không cần kết nối host.
sys.path được mở rộng để bao gồm cả ba hệ thống tệp và các thư mục con lib/ của chúng, vì vậy các module có thể nhập nằm trong /flash/lib, /sdcard/lib, hoặc /rom/lib.
Để buộc hệ thống bỏ qua thẻ SD đã lắp (ví dụ để chạy main.py trong flash ngay cả khi có thẻ), tạo một tệp rỗng tên SKIPSD ở thư mục gốc của /flash.
Khi kết nối qua USB, hệ thống tệp khởi động (/sdcard nếu có thẻ, ngược lại là /flash) cũng liệt kê như ổ đĩa lưu trữ USB trên host, cho phép bạn chỉnh sửa boot.py, main.py và các tệp khác trực tiếp. Eject ổ đĩa trước khi reset bo để host đẩy các ghi được cache.
Ghi chú
Vì hệ điều hành xử lý ổ đĩa như một thiết bị khối thụ động, các tệp được tạo hoặc sửa đổi bởi code chạy trên camera sẽ không hiển thị cho đến khi host gắn lại ổ đĩa. Nếu cả hệ điều hành và camera cùng ghi lên cùng một hệ thống tệp, hệ điều hành sẽ thắng và ghi đè các thay đổi từ camera. Dùng thẻ SD cho bất kỳ dữ liệu nào tập lệnh ghi lại, và gắn lại trước khi đọc các tệp đó từ host.
Ghi chú
Kênh đỏ của LED RGB người dùng có thể sáng thoáng trong khi host đang đọc từ hoặc ghi vào ổ đĩa lưu trữ USB — đây là chỉ báo hoạt động do firmware điều khiển, không phải lỗi.
Kích thước bộ nhớ¶
Portenta H7 được cung cấp kèm theo:
/flash— hệ thống tệp FAT 11 MB, đọc/ghi./rom— ROMFS ánh xạ bộ nhớ chỉ đọc 4 MB, dùng để cung cấp tập lệnh và mô hình ML hưởng lợi từ truy cập mmap sao chép bằng không./sdcard— toàn bộ dung lượng của thẻ microSD được lắp vào Vision Shield (khi có), đọc/ghi.
Chỉ báo hard‑fault¶
Nếu LED RGB người dùng đang chuyển đổi nhanh qua tất cả các màu — nhanh đến mức trông giống LED trắng nhấp nháy hơn là các màu riêng biệt — firmware đã gặp hard fault không thể phục hồi. Nạp lại firmware để khôi phục; nếu nạp lại không giúp được, bo có thể bị hỏng vật lý.
Thư viện phần mềm¶
Xem chỉ mục thư viện để có danh sách đầy đủ các module — bao gồm cả những module độc đáo với bản build Portenta H7.