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 de núcleo duplo que combina um Cortex‑M7 a 400 MHz com um Cortex‑M4 a 200 MHz. O firmware OpenMV corre inteiramente no núcleo M7 e foi concebido para ser utilizado com o Portenta Vision Shield (edição Ethernet ou LoRa), que adiciona uma câmara Himax HM01B0 / HM0360, dois microfones PDM e um slot microSD à base Portenta H7.
Para a ficha técnica completa, fotografias e dimensões, consulte a página de produto do Arduino Portenta H7.
Destaques¶
STMicroelectronics STM32H747XI com Cortex‑M7 duplo (400 MHz) + Cortex‑M4 (200 MHz). O firmware OpenMV corre apenas no núcleo M7; o núcleo M4 é exposto através do openamp para comunicação entre processadores.
8 MB de SDRAM externa mais 2 MB de flash interna e 16 MB de flash QSPI externa.
Codificador/descodificador JPEG por hardware.
Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 através do módulo Murata 1DX (CYW4343W) — liga à antena fornecida via um conector U.FL na placa.
USB‑C de alta velocidade (480 Mb/s).
22 pinos de E/S de utilizador nos cabeçalhos superiores estilo Arduino MKR — D0–D14 (digital) mais A0–A6 (analógico).
Dois conectores de alta densidade de 80 pinos na parte inferior expõem todo o tecido do STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, UARTs, SPI/I²C/temporizadores adicionais, entre outros. Shields como o Vision Shield ligam-se a estes conectores.
JTAG / SWD disponível nos conectores HD inferiores para depuração avançada.
Suporte a bateria — conector JST Li‑Po de 3,7 V mais carregador e monitor de bateria integrados.
Pinout¶
Referência de pinos¶
22 pinos de utilizador são expostos nos cabeçalhos da aresta superior estilo Arduino MKR — 15 digitais (D0-D14) mais 7 analógicos (A0-A6). Muitos mais pinos do SoC estão disponíveis através dos conectores de alta densidade de 80 pinos inferiores para uso com shields; consulte o PDF de pinout completo do 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 (partilhado com A3 / A5) |
D9 |
3,3 V |
SPI2 SCK |
D10 |
3,3 V |
SPI2 MISO (partilhado 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; partilhado com D10) |
A3 |
3,3 V |
ADC12 IN13 (apenas analógico; partilhado com D8) |
A4 |
3,3 V |
ADC123 IN12 (partilhado com D10) |
A5 |
3,3 V |
ADC12 IN13 (partilhado com D8) |
A6 |
3,3 V |
DAC1 OUT1 / ADC12 IN18 |
A7 |
3,3 V |
TIM3 CH1 / ADC12 IN3 (não exposto nos cabeçalhos) |
D20 |
3,3 V |
alias de |
D21 |
3,3 V |
alias de |
RESET |
3,3 V |
premir o interruptor integrado ou ligar a GND para reiniciar |
LED_RED |
3,3 V |
Canal vermelho do LED RGB (activo em baixo) |
LED_GREEN |
3,3 V |
Canal verde do LED RGB (activo em baixo) |
LED_BLUE |
3,3 V |
Canal azul do LED RGB (activo em baixo) |
Nota
A0-A3 são pads apenas analógicos no STM32H747 sem função GPIO — trate-os apenas como entradas ADC. A2/A4 e A3/A5 partilham os seus pinos físicos com D10 e D8 respectivamente, pelo que não é possível acionar PWM ou SPI nesses pinos enquanto se fazem leituras analógicas. A7 encontra-se nos conectores HD inferiores.
Pinos de alimentação¶
Pinos do cabeçalho MKR:
VIN — rail principal do sistema para o PMIC integrado. Alimentado via díodo a partir do rail
+5V, do pinoVINMKR, ou dos conectores HD de 80 pinos inferiores.+5V — rail de 5 V alimentado por USB, pelo conector ESLOV, ou pelo próprio pino
+5VMKR.+3V3 — rail principal de 3,3 V (saída do regulador comutado do PMIC).
AREF — referência de tensão analógica para os pinos ADC. Por defeito 3,3 V; aplique externamente para utilizar uma referência diferente.
GND — massa comum.
Entrada de bateria:
Li‑Po JST na face frontal da placa aceita uma célula Li‑Po de 3,7 V. O PMIC carrega-a sempre que
+5VouVINestão presentes.
O Portenta H7 pode ser alimentado por qualquer um destes caminhos:
USB‑C — fornece 5 V ao PMIC integrado.
Conector ESLOV — até 5 V em
VESLOV(ver Conector ESLOV).Pino VIN — aplique diretamente uma fonte regulada de 5 V.
Bateria Li‑Po — ligue ao JST na parte frontal.
Conector ESLOV¶
Na lateral da placa encontra-se um conector ESLOV de 5 pinos sem soldadura:
Pino |
Nome |
Função |
|---|---|---|
1 |
VESLOV |
Saída de 5 V (mesmo rail que o |
2 |
INT |
entrada de interrupção externa em |
3 |
SCL_EXT |
partilhado com o pad |
4 |
SDA_EXT |
partilhado com o pad |
5 |
GND |
massa comum |
SCL_EXT/SDA_EXT do ESLOV e D12/D11 do cabeçalho MKR são os mesmos pinos — um único barramento I²C 3 exposto em dois conectores.
Dica
Utilize o estimador de autonomia de bateria para modelar durante quanto tempo o Portenta H7 funcionará com uma bateria para um dado ciclo de trabalho activo / sono profundo.
Pinos de recuperação e depuração¶
RESET — tanto um pino exposto no cabeçalho superior como um interruptor momentâneo na lateral da placa, ligado à linha NRST do SoC. Ligue a GND ou pressione o botão para reiniciar.
O Portenta H7 utiliza o duplo toque no reset padrão do Arduino para entrar no bootloader do Arduino. Prima rapidamente o botão de reset duas vezes — a placa reenumera sobre USB como dispositivo DFU e o OpenMV IDE pode instalar uma nova imagem de firmware.
Os sinais SWD do STM32 estão expostos no conector HD J1 inferior:
J1‑73— NRSTJ1‑75— SWDIO (PA13)J1‑77— SWCLK (PA14)J1‑79— SWO (PB3)
Ligue-os através de um Portenta Breakout, do adaptador de depuração oficial do Arduino, ou de um carrier personalizado com um cabeçalho de 1,27 mm. Todos os sinais de depuração têm referência a 3,3 V.
Nota
Quando o Portenta Vision Shield está ligado, os mesmos sinais SWD/JTAG são encaminhados para o cabeçalho padrão JTAG ARM Cortex Debug de 20 pinos no shield (passo de 1,27 mm / 0,05″).
Periféricos integrados¶
LEDs¶
O Portenta H7 possui um único LED RGB de utilizador, 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 junto ao JST da bateria acende quando o carregador integrado está a fornecer corrente a uma célula Li‑Po ligada; não é controlável pelo utilizador.
Sensor de câmara (Vision Shield)¶
Com o Portenta Vision Shield (edição Ethernet ou LoRa) ligado, o sensor Himax é controlado através do módulo csi — sensores de câmara
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()
São suportadas duas revisões do Vision Shield:
HM01B0 — 320 × 320 monocromático.
HM0360 — 640 × 480 monocromático.
Aviso
Enquanto a câmara do Vision Shield está inicializada, os seguintes pinos do cabeçalho MKR são utilizados pelo firmware e não podem ser usados:
Pino MKR |
Motivo |
|---|---|
|
TIM1 CH1 — relógio mestre da câmara |
|
TIM1 CH1 (alt) — relógio mestre da câmara |
|
I²C 3 SDA — partilhado com a câmara; o barramento é utilizável mas evite o endereço I²C do sensor ( |
|
I²C 3 SCL — partilhado com a câmara; o barramento é utilizável mas evite o endereço I²C do sensor ( |
|
DCMI HSYNC — também desativa o DAC |
|
DCMI PXCLK |
Aprendizagem automática¶
ml — Machine Learning corre modelos TFLite quantizados no Cortex‑M7 com kernels CMSIS‑NN — rápido o suficiente para detetores compactos a alguns fotogramas por segundo. Os modelos no sistema de ficheiros apenas de leitura /rom carregam diretamente a partir da flash sem cópia para RAM. Aqui está um detetor BlazeFace de 128×128 que sobrepõe a face detetada e os seus seis pontos de referência em cada fotograma da câmara 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 entre processadores. O firmware OpenMV corre apenas no M7; o M4 não possui um runtime MicroPython próprio, pelo que a sua utilização implica construir uma imagem de firmware C separada e carregá-la a partir do sistema de ficheiros via openamp.RemoteProc. Firmware de exemplo pré-compilado que implementa um endpoint UART virtual está disponível no repositório openamp_vuart — siga o seu README para compilar 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, este suporte é melhor tratado como uma demonstração da interface openamp do que como uma plataforma de núcleo duplo funcional — o M4 não pode ser reiniciado independentemente do M7, pelo que 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 sobre o periférico SAI4 do STM32. Cada buffer chega como bytearray PCM de 16 bits com sinal, pronto para ser processado com ulab/numpy para DSP — por exemplo, um simples detetor de intensidade sonora:
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 a audio.init para receber amostras intercaladas de ambos os microfones.
Medidor de carga da bateria¶
O medidor de carga Maxim MAX17262 ModelGauge m5 rastreia a tensão, corrente, temperatura e estado de carga da bateria Li‑Po. Encontra-se no I²C 1 com endereço 0x36.
O MAX17262 possui deteção de corrente interna, pelo que o registo de corrente lê diretamente em microamperes sem necessidade de aplicar um fator Rsense externo. Ler o medidor de carga é inócuo — não existe driver incluído, mas os registos documentados na ficha técnica 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 é complemento para dois com sinal: positivo durante a carga, negativo durante a descarga. TTE só é significativo quando a corrente é negativa; TTF apenas quando a corrente é positiva.
CI de gestão de energia¶
O PF1550 da NXP gere todos os reguladores do Portenta H7 — o rail principal +3V3, o rail de núcleo/E/S +1V8 do SoC, e o carregador Li‑Po. Encontra-se no I²C 1 com endereço 0x08.
Aviso
Ler registos do PMIC é seguro; escrever neles é perigoso. Configurar incorretamente um regulador buck ou as definições do carregador pode danificar permanentemente a placa, a bateria, ou ambos. Trate o PMIC como apenas de leitura a menos que saiba exatamente o que está a fazer.
A informação mais útil que o PMIC fornece e que o medidor de carga não fornece é a máquina de estados do carregador — se a placa está a funcionar com USB / ESLOV / VIN, em que fase do ciclo de carga se encontra a Li‑Po, e se o carregador está num estado de falha térmica ou watchdog. Os registos do carregador encontram-se num deslocamento de 0x80 no espaço de endereços I²C principal do PF1550 (ver §22.2 da ficha técnica do PF1550), pelo que, por exemplo, CHG_INT_OK no endereço do carregador 0x04 é lido do registo 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)
Outros registos apenas de leitura que vale a pena consultar na ficha técnica (todos com deslocamento de carregador 0x80): 0x80 CHG_INT (interrupções do carregador latched — flags de falha), 0x86 VBUS_SNS (o estado VBUS multi-bit incluindo OVLO / UVLO / DPM), e 0x88 BATT_SNS (presença de bateria e estado de sobrecorrente).
Wi‑Fi¶
O Murata 1DX (CYW4343W) integrado é exposto via network — configuração de rede como interface de estação. Ligue a antena fornecida ao conector U.FL da placa 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 compatível com asyncio — por exemplo, anunciar como periférico e aguardar a ligaçã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 Murata CMWX1ZZABZ LoRaWAN ligado ao Portenta H7 via UART. O módulo lora encapsula o firmware de comandos AT e suporta adesão 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 cabeçalho MKR como linhas de controlo para o Murata CMWX1ZZABZ — não podem ser utilizados:
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 uma ficha RJ45 com magnéticos ligada ao MAC Ethernet 10/100 do STM32H747 via RMII. Ligue um cabo Ethernet e o PHY aparece como interface LAN; o DHCP corre automaticamente assim que a ligação é estabelecida:
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, é montado automaticamente em /sdcard e é utilizável através do sistema de ficheiros regular:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Referência de barramentos¶
GPIO¶
Use o machine.Pin para ler ou acionar qualquer um dos pinos identificados na serigrafía. As saídas são CMOS de 3,3 V e podem absorver/fornecer até 20 mA por pino (140 mA no total por todo o cabeçalho).
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 flanco:
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 cabeçalho MKR e os pinos SDA_EXT/SCL_EXT do conector ESLOV estão no mesmo barramento I²C 3 — ver Conector ESLOV acima para o pinout do ESLOV.
O mesmo hardware também pode ser utilizado em 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 ADC de 12 bits em A0–A7. Todos têm referência a 3,3 V — read_u16 retorna 0–65535 para 0–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 DAC de 12 bits está 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 |
Temporizador / 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 através do machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D4"), freq=1_000, duty_u16=32768)
Nota
Vários pinos partilham canais de temporizador:
TIM1 CH1 está em
D1eD6.TIM1 CH2 está em
D2eD14.TIM8 CH3N está em
D0eD1.
Escolha um único utilizador por canal de temporizador.
Aviso
TIM1 está reservado para o relógio mestre da câmara quando o Vision Shield é inicializado através do csi — sensores de câmara — D1, D2, D6, D13 e D14 não podem ser acionados por PWM enquanto a câmara está activa.
Barramentos por software (bit-banging)¶
machine.SoftI2C e machine.SoftSPI funcionam em qualquer GPIO se necessitar de um barramento adicional.
Sensor térmico (externo)¶
O firmware inclui o driver fir — driver de sensor térmico (fir == infravermelho longínquo) para imagiologistas térmicos ligados externamente:
MLX90621 — matriz IR 16 × 4
MLX90640 — matriz IR 32 × 24
MLX90641 — matriz IR 16 × 12
AMG8833 — matriz IR 8 × 8
Ligue o módulo ao barramento I²C da placa e leia fotogramas 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 comunica com o sensor apenas via I²C 3 — ligue 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)
Temporizadores virtuais¶
machine.Timer agenda callbacks periódicos ou de disparo único sem consumir um slot de temporizador de hardware. Passe -1 como id para utilizar um temporizador virtual (software):
from machine import Timer
one_shot = Timer(-1)
one_shot.init(period=5_000, mode=Timer.ONE_SHOT,
callback=lambda t: print("once"))
periodic = Timer(-1)
periodic.init(period=2_000, mode=Timer.PERIODIC,
callback=lambda t: print("tick"))
Os valores de período são em milissegundos. Chame deinit() para parar e libertar o slot.
Relógio em tempo real¶
machine.RTC mantém a hora do relógio de parede entre reinicializações. O conector HD também expõe um pad COINCELL que pode alimentar o RTC a partir de um CR2032 durante perdas 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¶
machine.WDT reinicia a placa se a aplicação ficar suspensa. Uma vez iniciado não pode ser parado nem reconfigurado — alimente-o periodicamente dentro do seu ciclo principal:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Informações de arranque e runtime¶
Atualização de firmware (DFU)¶
O Portenta H7 utiliza o duplo toque no reset padrão do Arduino para entrar no bootloader do Arduino. Prima rapidamente o botão de reset duas vezes — a placa reenumera sobre USB como dispositivo DFU e o OpenMV IDE pode instalar uma nova imagem de firmware.
Um script em execução pode voltar ao bootloader a pedido chamando machine.bootloader()
import machine
machine.bootloader()
Sistema de ficheiros e ordem de arranque¶
O firmware do Portenta H7 monta até três sistemas de ficheiros no arranque:
Flash interna — montada sempre em
/flash. Contémmain.pyeREADME.txtpor defeito; criada no primeiro arranque.Cartão microSD — se um Vision Shield estiver ligado e um cartão inserido, é montado em
/sdcard.ROMFS — sistema de ficheiros mapeado em memória apenas de leitura em
/rom, montado automaticamente pelo MicroPython no arranque.
Após a montagem, o diretório de trabalho é definido como /sdcard quando o cartão está presente, caso contrário /flash. O interpretador executa então scripts desse diretório:
boot.pyé executado em cada reset suave (arranque a frio,Ctrl‑Dno REPL, ou sempre que o script em execução termina).main.pyé executado apenas no arranque a frio, imediatamente apósboot.py. Os resets suaves subsequentes executam novamenteboot.pymas vão directamente para o REPL — para voltar a executarmain.pytem de reiniciar completamente a placa.
Colocar um boot.py ou main.py no cartão SD substitui a cópia na flash sem a alterar — ambos os ficheiros são procurados no diretório de arranque (/sdcard quando o cartão está montado, caso contrário /flash).
O main.py predefinido fornecido numa placa recém-instalada faz piscar o canal azul do LED RGB de utilizador como batimento cardíaco (dois pulsos curtos, intervalo curto), para poder verificar que o firmware arrancou corretamente sem nenhum host ligado.
sys.path é estendido para incluir os três sistemas de ficheiros e os seus subdiretórios lib/, pelo que os módulos importáveis podem residir 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 ficheiro vazio chamado SKIPSD na raiz de /flash.
Quando ligado via USB, o sistema de ficheiros de arranque (/sdcard se houver cartão presente, caso contrário /flash) também é enumerado como unidade de armazenamento em massa USB no host, permitindo editar boot.py, main.py e quaisquer outros ficheiros diretamente. Ejete a unidade antes de reiniciar a placa para que o host descarregue as escritas em cache.
Nota
Como o SO trata a unidade como um dispositivo de bloco passivo, os ficheiros criados ou modificados por código a correr na câmara não aparecerão até o host remontar a unidade. Se tanto o SO como a câmara escreverem no mesmo sistema de ficheiros ao mesmo tempo, o SO prevalecerá e sobreporá as alterações feitas pela câmara. Utilize o cartão SD para quaisquer dados que o script escreva, e remonte antes de ler esses ficheiros a partir do host.
Nota
O canal vermelho do LED RGB de utilizador pode acender brevemente enquanto o host está a ler ou escrever na unidade de armazenamento em massa USB — é um indicador de actividade controlado pelo firmware, não uma falha.
Tamanhos de armazenamento¶
O Portenta H7 é fornecido com:
/flash— sistema de ficheiros FAT de 11 MB, leitura/escrita./rom— ROMFS apenas de leitura mapeada em memória de 4 MB, utilizado para distribuir scripts e modelos ML que beneficiam de acesso mmap sem cópia./sdcard— tamanho completo do cartão microSD inserido num Vision Shield (quando presente), leitura/escrita.
Indicador de hard fault¶
Se o LED RGB de utilizador estiver a ciclar rapidamente por todas as cores — rápido o suficiente para parecer um LED branco a tremeluzir em vez de matizes distintas — o firmware atingiu um hard fault irrecuperável. Reinstale o firmware para recuperar; se a reinstalação não resolver, 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 da compilação para o Portenta H7.