Arduino Portenta H7¶
O Arduino Portenta H7 é uma placa de desenvolvimento industrial de 66 × 25 mm construída em torno do STMicroelectronics STM32H747XI — um SoC dual‑core que combina um Cortex‑M7 a 400 MHz com um Cortex‑M4 a 200 MHz. O firmware OpenMV roda inteiramente no núcleo M7 e foi projetado para ser usado com o Portenta Vision Shield (edição Ethernet ou LoRa), que adiciona uma câmera Himax HM01B0 / HM0360, dois microfones PDM e um slot microSD ao Portenta H7 básico.
Para a folha de dados completa, fotos e dimensões, consulte a página do produto Arduino Portenta H7.
Destaques¶
STMicroelectronics STM32H747XI dual Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). O firmware OpenMV roda apenas no núcleo M7; o núcleo M4 é exposto através do openamp para Comunicação Inter‑Processadores.
8 MB de SDRAM externa mais 2 MB de flash interna e 16 MB de flash QSPI externa.
Codificador/decodificador JPEG por hardware.
Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 via o módulo Murata 1DX (CYW4343W) — conecta-se à antena fornecida através de um conector U.FL integrado.
USB‑C de alta velocidade (480 Mb/s).
22 pinos de I/O de usuário nos headers superiores estilo Arduino MKR — D0–D14 (digitais) mais A0–A6 (analógicos).
Dois conectores de alta densidade de 80 pinos na parte inferior expõem todo o fabric do STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UARTs, SPI/I²C/timers adicionais, e assim por diante. Shields como o Vision Shield se encaixam nesses conectores.
JTAG / SWD disponibilizados nos conectores HD inferiores para depuração avançada.
Suporte a bateria — conector JST para Li‑Po de 3,7 V mais carregador e monitor de bateria integrados.
Pinagem¶
Referência de pinos¶
22 pinos de usuário são expostos nos headers de borda superior estilo Arduino MKR — 15 digitais (D0-D14) mais 7 analógicos (A0-A6). Muitos outros pinos do SoC estão disponíveis através dos conectores de alta densidade de 80 pinos inferiores para trabalho com shields; consulte o PDF de pinagem completa da Arduino para esse mapeamento.
Nome do pino |
Referência |
Função |
|---|---|---|
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 (compartilhado com A3 / A5) |
D9 |
3,3 V |
SPI2 SCK |
D10 |
3,3 V |
SPI2 MISO (compartilhado com 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 (apenas analógico) |
A1 |
3,3 V |
ADC12 IN1 (apenas analógico) |
A2 |
3,3 V |
ADC123 IN12 (apenas analógico; compartilhado com D10) |
A3 |
3,3 V |
ADC12 IN13 (apenas analógico; compartilhado com D8) |
A4 |
3,3 V |
ADC123 IN12 (compartilhado com D10) |
A5 |
3,3 V |
ADC12 IN13 (compartilhado com D8) |
A6 |
3,3 V |
DAC1 OUT1 / ADC12 IN18 |
A7 |
3,3 V |
TIM3 CH1 / ADC12 IN3 (não exposto nos headers) |
D20 |
3,3 V |
alias de |
D21 |
3,3 V |
alias de |
RESET |
3,3 V |
pressione o botão integrado ou puxe para GND para reiniciar |
LED_RED |
3,3 V |
canal vermelho do LED RGB (ativo em nível baixo) |
LED_GREEN |
3,3 V |
canal verde do LED RGB (ativo em nível baixo) |
LED_BLUE |
3,3 V |
canal azul do LED RGB (ativo em nível baixo) |
Nota
A0-A3 são pads apenas analógicos no STM32H747 sem função GPIO — trate-os apenas como entradas de ADC. A2/A4 e A3/A5 compartilham seus pinos físicos com D10 e D8 respectivamente, então você não pode acionar PWM ou SPI neles enquanto os lê como analógicos. A7 fica nos conectores HD inferiores.
Pinos de alimentação¶
Pinos do header MKR:
VIN — barramento principal do sistema para o PMIC integrado. Alimentado via um diodo a partir do barramento
+5V, do pino MKRVINou dos conectores HD inferiores de 80 pinos.+5V — barramento de 5 V alimentado pelo USB, pelo conector ESLOV ou pelo próprio pino MKR
+5V.+3V3 — barramento principal de 3,3 V (saída do regulador chaveado do PMIC).
AREF — referência de tensão analógica para os pinos do ADC. O padrão é 3,3 V; acione externamente para usar uma referência diferente.
GND — terra comum.
Entrada de bateria:
JST Li‑Po na frente da placa aceita uma célula Li‑Po de 3,7 V. O PMIC a carrega sempre que
+5VouVINestiver presente.
O Portenta H7 pode ser alimentado através de qualquer um destes caminhos:
USB‑C — fornece 5 V ao PMIC integrado.
Conector ESLOV — até 5 V em
VESLOV(consulte Conector ESLOV).Pino VIN — acione uma fonte regulada de 5 V diretamente.
Bateria Li‑Po — conecte ao JST na frente.
Conector ESLOV¶
Na lateral da placa há um conector ESLOV de 5 pinos sem solda:
Pino |
Nome |
Função |
|---|---|---|
1 |
VESLOV |
saída de alimentação de 5 V (mesmo barramento do |
2 |
INT |
entrada de interrupção externa em |
3 |
SCL_EXT |
compartilhado com o pad |
4 |
SDA_EXT |
compartilhado com o pad |
5 |
GND |
terra comum |
Os SCL_EXT/SDA_EXT do ESLOV e os D12/D11 do header MKR são os mesmos pinos — um barramento I²C 3 exposto em dois conectores.
Dica
Use o estimador de vida útil da bateria para modelar por quanto tempo o Portenta H7 funcionará com uma bateria para um determinado ciclo de trabalho ativo / deep-sleep.
Pinos de recuperação e depuração¶
RESET — tanto um pino exposto no header superior quanto um botão momentâneo na lateral da placa, ligados à linha NRST do SoC. Puxe para GND ou pressione o botão para reiniciar.
O Portenta H7 usa o reset por toque duplo padrão da Arduino para entrar no bootloader da Arduino. Pressione rapidamente o botão de reset duas vezes — a placa é re‑enumerada via USB como um dispositivo DFU e o OpenMV IDE pode gravar uma nova imagem de firmware.
Os sinais SWD do STM32 são expostos no conector HD J1 inferior:
J1‑73— NRSTJ1‑75— SWDIO (PA13)J1‑77— SWCLK (PA14)J1‑79— SWO (PB3)
Conecte-os via um Portenta Breakout, o adaptador de depuração oficial da Arduino ou uma placa portadora personalizada com um header de 1,27 mm. Todos os sinais de depuração são referenciados a 3,3 V.
Nota
Quando o Portenta Vision Shield está conectado, os mesmos sinais SWD/JTAG são roteados até o header JTAG ARM Cortex Debug de 20 pinos padrão no shield (passo de 1,27 mm / 0,05″).
Periféricos integrados¶
LEDs¶
O Portenta H7 tem um único LED RGB de usuário, controlável por software através do machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
Um LED de carga laranja separado, ao lado do JST da bateria, acende quando o carregador integrado está fornecendo corrente a uma Li‑Po conectada; ele não é controlável pelo usuário.
Sensor de câmera (Vision Shield)¶
Com o Portenta Vision Shield (edição Ethernet ou LoRa) conectado, o sensor Himax é controlado através do módulo csi — sensores de câmera
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()
Duas revisões do Vision Shield são suportadas:
HM01B0 — monocromático 320 × 320.
HM0360 — monocromático 640 × 480.
Aviso
Enquanto a câmera do Vision Shield está inicializada, os seguintes pinos do header MKR são reservados pelo firmware e não podem ser usados:
Pino MKR |
Motivo |
|---|---|
|
TIM1 CH1 — clock mestre da câmera |
|
TIM1 CH1 (alt) — clock mestre da câmera |
|
I²C 3 SDA — compartilhado com a câmera; o barramento é utilizável, mas evite o endereço I²C do sensor ( |
|
I²C 3 SCL — compartilhado com a câmera; o barramento é utilizável, mas evite o endereço I²C do sensor ( |
|
DCMI HSYNC — também desabilita o DAC |
|
DCMI PXCLK |
Aprendizado de máquina¶
O ml — Aprendizado de Máquina executa modelos TFLite quantizados no Cortex‑M7 com kernels CMSIS‑NN — rápido o suficiente para detectores compactos a alguns quadros por segundo. Modelos no sistema de arquivos somente leitura /rom carregam diretamente da flash sem copiar para a RAM. Aqui está um detector BlazeFace de 128×128 sobrepondo o rosto detectado e seus seis pontos de referência em cada quadro da câmera do 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")
Núcleo M4¶
O núcleo Cortex‑M4 é exposto através do openamp para comunicação inter‑processadores. O firmware OpenMV roda apenas no M7; o M4 não tem runtime MicroPython próprio, então usá-lo significa compilar uma imagem de firmware C separada e carregá-la a partir do sistema de arquivos via openamp.RemoteProc. Um firmware de exemplo pré‑compilado que implementa um endpoint UART virtual está disponível no repositório openamp_vuart — siga seu README para compilar o 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)
Na prática, esse suporte é melhor tratado como uma demonstração da interface openamp do que como uma plataforma dual‑core funcional — o M4 não pode ser reiniciado independentemente do M7, então parar o M4 força uma reinicialização completa do sistema.
Microfone (Vision Shield)¶
O Vision Shield possui dois microfones PDM capturados através do audio — Módulo de Áudio pelo periférico SAI4 do STM32. Cada buffer chega como PCM de 16 bits com sinal em um bytearray, pronto para alimentar o ulab/numpy para DSP — por exemplo, um detector de intensidade sonora simples:
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
Passe channels=2 para audio.init para receber amostras intercaladas de ambos os microfones.
Medidor de carga da bateria¶
O medidor de carga Maxim MAX17262 ModelGauge m5 acompanha a tensão, corrente, temperatura e estado de carga da bateria Li‑Po. Ele fica no I²C 1 no endereço 0x36.
O MAX17262 tem detecção de corrente interna, então o registrador de corrente é lido diretamente em microamperes, sem fator de Rsense externo a aplicar. Ler o medidor de carga é inofensivo — não há driver fornecido, mas os registradores documentados na folha de dados do MAX17262 podem ser lidos diretamente:
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 é um complemento de dois com sinal: positivo durante a carga, negativo durante a descarga. TTE só é significativo quando a corrente é negativa; TTF só quando a corrente é positiva.
CI de gerenciamento de energia¶
O PMIC NXP PF1550 gerencia todos os reguladores do Portenta H7 — o barramento principal +3V3, o barramento +1V8 do núcleo / I/O do SoC e o carregador Li‑Po. Ele fica no I²C 1 no endereço 0x08.
Aviso
Ler registradores do PMIC é seguro; escrever neles é perigoso. Configurar incorretamente um regulador buck ou uma definição do carregador pode danificar permanentemente a placa, a bateria, ou ambos. Trate o PMIC como somente leitura, a menos que você saiba exatamente o que está fazendo.
A coisa mais útil que o PMIC informa e que o medidor de carga não pode é a máquina de estados do carregador — se a placa está atualmente funcionando com USB / ESLOV / VIN, em que estágio do ciclo de carga a Li‑Po está e se o carregador está em uma falha térmica ou de watchdog. Os registradores do carregador ficam em um offset de 0x80 no espaço de endereços I²C principal do PF1550 (consulte §22.2 da folha de dados do PF1550), então, por exemplo, o CHG_INT_OK no endereço de carregador 0x04 é lido do registrador 0x84 do PMIC:
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)
Outros registradores somente leitura que vale a pena consultar na folha de dados (todos no offset de carregador 0x80): 0x80 CHG_INT (interrupções do carregador travadas — flags de falha), 0x86 VBUS_SNS (o estado VBUS de múltiplos bits, incluindo OVLO / UVLO / DPM) e 0x88 BATT_SNS (presença da bateria e estado de sobrecorrente).
Wi‑Fi¶
O Murata 1DX (CYW4343W) integrado é exposto via network — configuração de rede como uma interface de estação. Conecte a antena fornecida ao conector U.FL integrado antes de ativar o rádio:
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¶
O mesmo Murata 1DX também expõe Bluetooth LE 5.1. Use o aioble — BLE Assíncrono para BLE amigável a asyncio — por exemplo, anuncie como periférico e aguarde a conexão de um 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)¶
A edição LoRa do Vision Shield adiciona um módulo LoRaWAN Murata CMWX1ZZABZ conectado ao Portenta H7 via UART. O módulo lora encapsula o firmware de comandos AT e suporta join OTAA ou ABP, uplink e 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()
Use BAND_US915 / BAND_AS923 / BAND_AU915 etc. para regiões fora da UE, e mude para lora.Lora.join_ABP() se o seu servidor de rede usar ativação ABP.
Aviso
Enquanto o módulo LoRa está em uso, o driver reserva os seguintes pinos do header MKR como linhas de controle para o Murata CMWX1ZZABZ — eles não podem ser usados:
Pino MKR |
Motivo |
|---|---|
|
pino BOOT do módulo LoRa |
|
pino RST do módulo LoRa |
Ethernet (Vision Shield)¶
A edição Ethernet do Vision Shield adiciona um conector RJ45 com magnetics conectado ao MAC Ethernet 10/100 do STM32H747 via RMII. Conecte um cabo Ethernet e o PHY aparece como uma interface LAN; o DHCP roda automaticamente assim que o link é estabelecido:
import network
import time
lan = network.LAN()
lan.active(True)
while not lan.isconnected():
time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])
Cartão microSD (Vision Shield)¶
Quando um cartão é inserido, ele é montado automaticamente em /sdcard e fica utilizável através do sistema de arquivos normal:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Referência de barramentos¶
GPIO¶
Use machine.Pin para ler ou acionar qualquer um dos pinos serigrafados. As saídas são CMOS de 3,3 V e podem drenar/fornecer até 20 mA por pino (140 mA no total em todo o 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())
Qualquer pino de entrada também pode disparar uma interrupção em transições de borda:
def handler(pin):
print("triggered:", pin)
Pin("D1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Barramento |
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¶
Barramento |
SCL |
SDA |
|---|---|---|
I2C3 |
D12 |
D11 |
from machine import I2C
i2c = I2C(3, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Os pads D11/D12 no header MKR e os pinos SDA_EXT/SCL_EXT do conector ESLOV ficam no mesmo barramento I²C 3 — consulte Conector ESLOV acima para a pinagem do ESLOV.
O mesmo hardware também pode ser usado no modo target (escravo) através do machine.I2CTarget para expor uma região de memória a outro controlador I²C:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(3, addr=0x42, mem=buf)
SPI¶
Barramento |
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¶
O Portenta H7 expõe oito canais de ADC de 12 bits em A0–A7. Todos são referenciados a 3,3 V — read_u16 retorna de 0 a 65535 ao longo de 0 a 3,3 V no pino:
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¶
Um único canal de DAC de 12 bits é exposto em DAC1 (A6 / D21) através do pyb.DAC
from pyb import DAC
dac = DAC("DAC1")
dac.write(int(0.5 * 255)) # 8‑bit output, ~1.65 V
PWM¶
Pino |
Timer / 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 |
Acione qualquer um deles via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D4"), freq=1_000, duty_u16=32768)
Nota
Vários pinos compartilham canais de timer:
TIM1 CH1 está em
D1eD6.TIM1 CH2 está em
D2eD14.TIM8 CH3N está em
D0eD1.
Escolha um consumidor por canal de timer.
Aviso
TIM1 é reservado para o clock mestre da câmera quando o Vision Shield é inicializado através do csi — sensores de câmera — D1, D2, D6, D13 e D14 não podem ser acionados por PWM enquanto a câmera está ativa.
Barramentos por bit‑banging em software¶
O machine.SoftI2C e o machine.SoftSPI funcionam em qualquer GPIO caso você precise de um barramento extra.
Sensor térmico (externo)¶
O firmware inclui o driver fir — driver de sensor térmico (fir == far infrared) para imageadores térmicos conectados externamente:
MLX90621 — array IR de 16 × 4
MLX90640 — array IR de 32 × 24
MLX90641 — array IR de 16 × 12
AMG8833 — array IR de 8 × 8
Conecte o módulo ao barramento I²C da placa e leia quadros com 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())
O driver fir só se comunica com o sensor pelo I²C 3 — conecte o módulo a D12 (SCL) e D11 (SDA).
Temporização¶
time¶
O módulo time cobre atrasos bloqueantes, ticks monotônicos e medição de tempo decorrido:
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)
Timers virtuais¶
O machine.Timer agenda callbacks periódicos ou únicos sem consumir um slot de timer de hardware. Passe -1 como id para usar um timer virtual (de 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"))
Os valores de período são em milissegundos. Chame deinit() para parar e liberar o slot.
Relógio de tempo real¶
O machine.RTC mantém a hora do relógio de parede ao longo de reinicializações. O conector HD também expõe um pad COINCELL que pode alimentar o RTC a partir de uma CR2032 em caso de perda de energia:
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¶
O machine.WDT reinicia a placa se a aplicação travar. Uma vez iniciado, ele não pode ser parado ou reconfigurado — alimente-o periodicamente dentro do seu loop principal:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Informações de boot e tempo de execução¶
Atualização de firmware (DFU)¶
O Portenta H7 usa o reset por toque duplo padrão da Arduino para entrar no bootloader da Arduino. Pressione rapidamente o botão de reset duas vezes — a placa é re‑enumerada via USB como um dispositivo DFU e o OpenMV IDE pode gravar uma nova imagem de firmware.
Um script em execução pode re‑entrar no bootloader sob demanda chamando machine.bootloader()
import machine
machine.bootloader()
Sistema de arquivos e ordem de boot¶
O firmware do Portenta H7 monta até três sistemas de arquivos no boot:
Flash interna — sempre montada em
/flash. Contémmain.pyeREADME.txtpor padrão; criada no primeiro boot.Cartão microSD — se um Vision Shield estiver conectado e um cartão inserido, ele é montado em
/sdcard.ROMFS — sistema de arquivos somente leitura, mapeado em memória em
/rom, montado automaticamente pelo MicroPython na inicialização.
Após a montagem, o diretório de trabalho é definido como /sdcard quando o cartão está presente, caso contrário /flash. O interpretador então executa scripts a partir desse diretório:
boot.pyé executado em cada soft reset (cold boot,Ctrl‑Ddo REPL ou sempre que o script em execução retorna).main.pyé executado apenas no cold boot, imediatamente após oboot.py. Soft resets subsequentes re‑executam oboot.pymas vão direto para o REPL — para re‑executar omain.pyvocê precisa reiniciar completamente a placa.
Colocar um boot.py ou main.py no cartão SD substitui a cópia na flash sem tocá-la — ambos os arquivos são procurados no diretório de boot (/sdcard quando o cartão está montado, caso contrário /flash).
O main.py padrão fornecido em uma placa recém‑gravada apenas pisca o canal azul do LED RGB de usuário como um heartbeat (dois pulsos curtos, pequeno intervalo), para que você possa saber que o firmware inicializou corretamente sem nenhum host conectado.
O sys.path é estendido para incluir todos os três sistemas de arquivos e seus subdiretórios lib/, então módulos importáveis podem ficar em /flash/lib, /sdcard/lib ou /rom/lib.
Para forçar o sistema a ignorar um cartão SD inserido (por exemplo, para executar o main.py da flash mesmo com um cartão presente), crie um arquivo vazio chamado SKIPSD na raiz de /flash.
Quando conectado via USB, o sistema de arquivos de boot (/sdcard se um cartão estiver presente, caso contrário /flash) também é enumerado como uma unidade de armazenamento em massa USB no host, permitindo que você edite boot.py, main.py e quaisquer outros arquivos diretamente. Ejete a unidade antes de reiniciar a placa para que o host descarregue suas escritas em cache.
Nota
Como o SO trata a unidade como um dispositivo de bloco passivo, arquivos criados ou modificados por código em execução na câmera não aparecerão até que o host remonte a unidade. Se tanto o SO quanto a câmera escreverem no mesmo sistema de arquivos ao mesmo tempo, o SO vencerá e sobrescreverá as alterações feitas pela câmera. Use o cartão SD para quaisquer dados que o script grave de volta, e remonte antes de ler esses arquivos a partir do host.
Nota
O canal vermelho do LED RGB de usuário pode acender brevemente enquanto o host está lendo ou gravando na unidade de armazenamento em massa USB — isso é um indicador de atividade controlado pelo firmware, não uma falha.
Tamanhos de armazenamento¶
O Portenta H7 vem com:
/flash— sistema de arquivos FAT de 11 MB, leitura/escrita./rom— ROMFS somente leitura mapeado em memória de 4 MB, usado para fornecer scripts e modelos de ML que se beneficiam de acesso mmap com zero cópia./sdcard— tamanho completo de qualquer cartão microSD inserido em um Vision Shield (quando presente), leitura/escrita.
Indicador de hard fault¶
Se o LED RGB de usuário estiver ciclando rapidamente por todas as cores — rápido o suficiente para parecer um LED branco cintilante em vez de tons distintos — o firmware atingiu um hard fault irrecuperável. Regrave o firmware para recuperar; se a regravação não ajudar, a placa pode estar fisicamente danificada.
Bibliotecas de software¶
Consulte o índice de bibliotecas para a lista completa de módulos — incluindo quais são exclusivos do build do Portenta H7.