Arduino Nicla Vision¶
O Arduino Nicla Vision é uma placa de visão por computador de 22,86 × 22,86 mm construída em torno do STMicroelectronics STM32H747AII6 — 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. A placa combina o MCU com o sensor CMOS a cores GC2145 de 2 MP, um IMU de 6 eixos LSM6DSOX, um microfone MEMS MP34DT06, um sensor de distância por tempo de voo VL53L1CB, Wi‑Fi + Bluetooth LE 5.1 e um carregador de bateria / medidor de carga.
Para ficha de dados completa, fotografias e dimensões, consulte a página do produto Arduino Nicla Vision.
Destaques¶
STMicroelectronics STM32H747AII6 Cortex‑M7 duplo (400 MHz) + Cortex‑M4 (200 MHz). O firmware OpenMV corre apenas no núcleo M7.
2 MB de flash interno mais 16 MB de flash QSPI externo (usado para a aplicação + ROMFS).
1 MB de SRAM interno.
Codificador/descodificador JPEG por hardware.
Sensor CMOS a cores GC2145 de 2 MP.
IMU integrado (acelerómetro + giroscópio LSM6DSOX), microfone MEMS (MP34DT06JTR) e sensor de distância por tempo de voo VL53L1CB (até ~4 m).
Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 através do módulo Murata 1DX (CYW4343W) — liga-se à antena fornecida através de um conector U.FL integrado.
USB de alta velocidade (480 Mb/s) através de Micro USB com um PHY ULPI externo (USB3320C).
13 pinos de I/O de utilizador nos conectores de aresta Arduino — quatro LPIOs digitais (
D0–D3), três entradas analógicas de 1,8 V (A0–A2), o par I²CSCL/SDA, e o quarteto SPISCLK/CIPO/COPI/CS.Suporte de bateria — conector Li‑Po na parte posterior, carregador BQ e medidor de carga MAX17262 através do barramento PMIC interno.
Conector ESLOV de 5 pinos na parte posterior para expansão I²C sem solda.
Aviso
Os pinos digitais de utilizador são 3,3 V por defeito, mas passam por conversores de nível programáveis por software (VDDIO_EXT) que podem ser reconfigurados para 1,8 V. Os pinos analógicos (A0–A2) são apenas 1,8 V — contornam os conversores de nível e ligam-se diretamente ao MCU. Aplicar 3,3 V em A0–A2 danificará o SoC.
Diagrama de pinos¶
Referência de pinos¶
Treze pinos de utilizador estão expostos nos conectores de aresta Arduino (J1 e J2). Sinais adicionais de depuração, recuperação e PMIC estão encaminhados para pontos de teste na parte posterior da placa.
Nome do pino |
Referência |
Função |
|---|---|---|
D0 |
3,3 V |
GPIO / LPIO0 (J1‑1) |
D1 |
3,3 V |
LPUART1 TX / TIM1 CH2 / LPIO1 (J2‑3) |
D2 |
3,3 V |
LPUART1 RX / TIM1 CH3 / LPIO2 (J2‑4) |
D3 |
3,3 V |
GPIO / LPIO3 (J2‑5) |
A0 |
1,8 V |
ADC1 canal 4 (J1‑8) |
A1 |
1,8 V |
ADC2 canal 2 (J1‑7) |
A2 |
1,8 V |
ADC3 canal 5 (J1‑2) |
SCL |
3,3 V |
I2C1 SCL / UART4 RX / TIM4 CH3 (J2‑2) |
SDA |
3,3 V |
I2C1 SDA / UART4 TX / TIM4 CH4 (J2‑1) |
SCLK |
3,3 V |
SPI4 SCK / TIM1 CH3N (J1‑6) |
CIPO |
3,3 V |
SPI4 MISO / TIM1 CH3 (J1‑5) |
COPI |
3,3 V |
SPI4 MOSI / TIM1 CH4 (J1‑4) |
CS |
3,3 V |
SPI4 NSS / TIM1 CH2 (J1‑3) |
RESET |
3,3 V |
ligar a GND (ou premir o interruptor integrado) para repor a placa |
LED_RED |
3,3 V |
Canal vermelho do LED RGB (ativo a nível baixo) |
LED_GREEN |
3,3 V |
Canal verde do LED RGB (ativo a nível baixo) |
LED_BLUE |
3,3 V |
Canal azul do LED RGB (ativo a nível baixo) |
Nota
D0–D3 e SCLK/CIPO/COPI/CS estão atrás do conversor de nível bidirecional TXB0108 — esse componente suporta apenas o modo GPIO push‑pull, pelo que o tráfego de barramento em coletor aberto (por exemplo, 1‑Wire emulado por software ou I²C nesses pinos) não funcionará.
SCL/SDA estão atrás de um conversor NTS0304 separado que suporta tanto o modo push‑pull como coletor aberto, razão pela qual o I²C 1 funciona nesse local.
Ambos os conversores estão referenciados a VDDIO_EXT (3,3 V por defeito a partir do PMIC integrado), e a sua força de condução é limitada em comparação com um GPIO direto — são concebidos para níveis de sinal, não para cargas de potência.
Pinos de alimentação¶
Pinos do conector de aresta:
VIN (J2‑9) — rail principal do sistema de 3,6 – 5 V. O PMIC recebe a sua entrada aqui.
VDDIO_EXT (J2‑7) — saída do rail do conversor de nível, 1,8 V ou 3,3 V (3,3 V por defeito). Use-o para alimentar periféricos externos de 1,8 V ou 3,3 V ligados aos pinos LPIO/SPI/I²C, para que falem o mesmo nível lógico que os conectores.
VBAT (J3‑2) — entrada de bateria Li‑Po. O PMIC integrado carrega a célula a partir de VIN e reporta o estado de carga através do medidor de carga.
NTC (J3‑1) — entrada opcional para termístor Li‑Po.
GND (J2‑6) — massa comum.
NC (J2‑8) — sem ligação.
Pontos de teste na parte posterior da placa:
+3V3 — rail principal de 3,3 V.
D_P / D_N — par de dados USB de alta velocidade (pós-PHY).
O USB e o conector ESLOV alimentam ambos VIN através de um par de díodos ideais LM66100 (um por fonte), pelo que qualquer das fontes pode alimentar a placa de forma independente e as duas nunca se alimentam mutuamente na direção errada. Se conduzir VIN externamente em J2‑9, isso tem precedência — os díodos simplesmente deixam de conduzir a partir de USB / ESLOV quando o rail externo sobe mais alto.
A placa pode, portanto, ser alimentada por qualquer um destes caminhos:
Micro USB — 5 V para VIN através do díodo ideal do lado USB.
Conector ESLOV — até 5 V no pino
VESLOVde J5, encaminhados para VIN através do díodo ideal do lado ESLOV (ver Conector ESLOV).Pino VIN (J2‑9) — aplique diretamente uma tensão regulada de 3,6 – 5 V.
Bateria Li‑Po — ligue ao conector de bateria J4 na parte posterior ou aos pontos VBAT/GND/NTC em J3 / J2‑6. Não ligue duas baterias simultaneamente.
Conector ESLOV¶
J5 na parte posterior da placa é um conector ESLOV Molex de 5 pinos sem solda:
Pino |
Nome |
Função |
|---|---|---|
J5‑1 |
VESLOV |
entrada de alimentação (≤ 5 V) — combinada em |
J5‑2 |
INT |
entrada de interrupção externa em |
J5‑3 |
SCL_EXT |
partilhado com o ponto |
J5‑4 |
SDA_EXT |
partilhado com o ponto |
J5‑5 |
GND |
massa comum |
SCL_EXT/SDA_EXT do ESLOV e SCL/SDA de J2 são os mesmos pinos — um barramento I²C 1 exposto em dois conectores.
Dica
Use o estimador de autonomia de bateria para modelar quanto tempo o Nicla Vision funcionará com uma bateria para um determinado ciclo de trabalho ativo / sono profundo.
Pinos de recuperação e depuração¶
RESET — tanto um interruptor momentâneo no topo da placa como um ponto (J3‑4 / ponto de teste P5) ligado à linha NRST do SoC. Ligar a GND para repor.
O Nicla Vision utiliza o duplo toque de reset padrão do Arduino para entrar no bootloader do Arduino — prima o botão de reset rapidamente duas vezes e a placa enumera-se como um dispositivo DFU. O OpenMV IDE utiliza este modo para reflashear o firmware.
Os sinais SWD do STM32 estão expostos na parte posterior da placa através de uma fila de pontos de teste entre os dois conectores J2. Solde um conector de 2,54 mm (100 mil) neles para ligar um adaptador ST‑LINK ou J‑Link:
P1 / P2 — barramento I²C PMIC interno em PF0 (SDA) e PF1 (SCL). Este é
machine.I2C(2)no Nicla Vision e transporta o tráfego do PMIC, medidor de carga e ToF.P3 — TMS / SWDIO (PA13)
P4 — TCK / SWCLK (PA14)
P5 — NRST
P6 — TDO / SWO (PB3)
P7 — rail +1V8 (a alimentação de I/O do SoC — também a referência correta para o adaptador de depuração).
P8 —
VOTP_PMIC— apenas para programação de fábrica. Deve ser deixado desligado.
Todos os sinais de depuração são referenciados a 1,8 V — o anel de I/O do STM32H747 nesta placa funciona a partir do rail +1V8. Configure o seu adaptador de depuração para lógica de 1,8 V antes de ligar.
Periféricos integrados¶
LEDs¶
O Nicla Vision tem um único LED RGB de utilizador, controlável por software através de machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
Um LED DL2 CHARGE separado na lateral da placa está ligado diretamente à saída CHGB do PMIC — acende enquanto uma bateria Li‑Po está a ser carregada a partir de USB / ESLOV / VIN e não é controlável pelo utilizador.
Sensor de câmara¶
O GC2145 é controlado através do módulo csi — sensores de câmara
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
Quando solicita um tamanho de fotograma pequeno, o controlador GC2145 recorta uma janela de leitura proporcionalmente pequena do sensor — por defeito a relação de redução de leitura para saída está limitada a 3x para manter a taxa de fotogramas elevada. csi.IOCTL_SET_FOV_WIDE aumenta esse limite para 5x, o que significa que o controlador lê a partir de uma área mais ampla do sensor quando transmite resoluções pequenas. O resultado é um campo de visão visivelmente mais amplo em tamanhos de fotograma pequenos, à custa de algum débito:
cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE) # returns the current setting
Núcleo M4¶
O núcleo Cortex‑M4 é exposto através de openamp para comunicação entre processadores. O firmware OpenMV corre apenas no M7; o M4 não tem runtime MicroPython próprio, pelo que utilizá-lo implica construir uma imagem de firmware C separada e carregá-la a partir do sistema de ficheiros via openamp.RemoteProc. O 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 reposto independentemente do M7, pelo que parar o M4 força um reinício completo do sistema.
Microfone¶
O microfone PDM MP34DT06JTR integrado é capturado através de audio — Módulo de Áudio através do periférico DFSDM do STM32. Cada buffer chega como um bytearray PCM de 16 bits com sinal, pronto para ser processado com ulab/numpy para DSP — por exemplo, um detetor de volume 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
IMU¶
O acelerómetro + giroscópio LSM6DSOX integrado é exposto através de imu — sensor imu
import imu
import time
while True:
print(imu.acceleration_mg()) # (x, y, z) in milli‑g
print(imu.angular_rate_mdps()) # (x, y, z) in milli‑deg/s
time.sleep_ms(100)
O IMU está ligado a um barramento SPI interno dedicado (SPI5), pelo que não interfere com o SPI4 de utilizador exposto nos conectores.
Sensor de distância por tempo de voo¶
O sensor de distância por tempo de voo ST VL53L1CB integrado encontra-se no barramento I²C PMIC interno (I²C 2). Use o controlador frozen vl53l1x — driver do sensor de distância ToF VL53L1X para obter leituras de distância até ~4 m:
import time
from machine import I2C
import vl53l1x
bus = I2C(2) # internal bus (PMIC / fuel gauge / ToF)
tof = vl53l1x.VL53L1X(bus)
while True:
print("Distance:", tof.read(), "mm")
time.sleep_ms(100)
Medidor de carga de bateria¶
O medidor de carga ModelGauge m5 Maxim MAX17262 monitoriza a tensão, corrente, temperatura e estado de carga da bateria Li‑Po. Encontra-se em I²C 2 no endereço 0x36.
O MAX17262 tem deteção de corrente interna, pelo que o registo de corrente lê diretamente em microamperes sem fator Rsense externo a aplicar. Ler o medidor de carga é inofensivo — não há nenhum controlador incluído, mas os registos documentados na ficha 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(2)
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 de 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 PMIC NXP MC34PF1550A0EP gere todos os reguladores no Nicla Vision — o rail principal +3V3, o rail de núcleo / I/O +1V8 do SoC, VDDIO_EXT para os conversores de nível e o carregador Li‑Po. Encontra-se em I²C 2 no endereço 0x08.
Aviso
Ler registos 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 só de leitura, a não ser que saiba exatamente o que está a fazer.
A coisa mais útil que o PMIC lhe diz e que o medidor de carga não pode é a máquina de estados do carregador — se a placa está atualmente a funcionar com USB / ESLOV / VIN, em que fase do ciclo de carga se encontra o Li‑Po e se o carregador está com uma falha térmica ou de watchdog. Os registos do carregador residem num deslocamento de 0x80 no espaço de endereços I²C principal do PF1550 (ver §22.2 da ficha de dados 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(2)
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/ESLOV/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 só de leitura que vale a pena consultar na ficha de dados (todos com deslocamento de carregador 0x80): 0x80 CHG_INT (interrupções de carregador latched — flags de falha), 0x86 VBUS_SNS (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 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 aioble — BLE Assíncrono para BLE compatível com asyncio — por exemplo, anunciar como periférico e aguardar a ligação de um dispositivo central:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="Nicla-Vision")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
Referência de barramento¶
GPIO¶
Use machine.Pin para ler ou controlar qualquer um dos pinos marcados na serigrafia. As saídas são CMOS de 3,3 V (VDDIO_EXT por defeito) e os conversores de nível limitam a força de condução por pino a alguns miliamperes — são concebidos para níveis de sinal, não para cargas de potência.
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 aresta:
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 |
|---|---|---|
UART4 |
SDA |
SCL |
from machine import UART
uart = UART(4, baudrate=115200)
uart.write("hello")
uart.read(5)
Nota
O UART4 partilha os seus pinos com I²C 1 — os mesmos pontos SDA/SCL transportam ambos os barramentos. Escolha UART ou I²C, não ambos, nesses pinos.
A serigrafia D1/D2 também indica UART_TX/UART_RX, mas neste firmware esses pinos estão encaminhados para LPUART1, não para machine.UART. O próprio machine.UART(1) está reservado para o controlador Bluetooth integrado e não está acessível nos conectores.
I²C¶
Barramento |
SCL |
SDA |
|---|---|---|
I2C1 |
SCL |
SDA |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Os pontos SCL/SDA em J2 e os pinos SCL_EXT/SDA_EXT do conector ESLOV chegam ao mesmo barramento I²C 1 — veja Conector ESLOV acima para o diagrama de pinos ESLOV.
O mesmo hardware também pode ser usado no modo destino (escravo) através de machine.I2CTarget para expor uma região de memória a outro controlador I²C:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
SPI¶
Barramento |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI4 |
COPI |
CIPO |
SCLK |
CS |
from machine import SPI
from machine import Pin
spi = SPI(4, baudrate=10_000_000)
cs = Pin("CS", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
ADC¶
O Nicla Vision expõe três canais ADC de 12 bits em A0, A1 e A2. Todos os três são referenciados a 1,8 V — read_u16 devolve 0–65535 para 0–1,8 V no pino:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
Aviso
As entradas ADC do Nicla Vision são referenciadas a 1,8 V (e não têm conversor de nível à frente do SoC). Aplicar um sinal de 3,3 V irá saturar o conversor e pode danificar o pino — divida tensões mais altas externamente.
PWM¶
Pino |
Temporizador / canal |
|---|---|
D1 |
TIM1 CH2 |
D2 |
TIM1 CH3 |
SCL |
TIM4 CH3, TIM16 CH1 |
SDA |
TIM4 CH4, TIM17 CH1 |
SCLK |
TIM1 CH3N |
CIPO |
TIM1 CH3 |
COPI |
TIM1 CH4 |
CS |
TIM1 CH2 |
Controle qualquer deles através de machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D1"), freq=1_000, duty_u16=32768)
Nota
Vários pinos partilham canais TIM1:
TIM1 CH2 está em
D1eCS.TIM1 CH3 está em
D2eCIPO;SCLKproduz o complemento invertido (TIM1 CH3N) do mesmo canal.TIM1 CH4 está apenas em
COPI.
Escolha um utilizador por canal de temporizador. Os pinos do quarteto SPI (SCLK/CIPO/COPI/CS) também não podem ser controlados por PWM enquanto machine.SPI(4) os estiver a usar.
Barramentos emulados por software¶
machine.SoftI2C e machine.SoftSPI funcionam em qualquer GPIO se precisar de um barramento adicional.
Sensor térmico (externo)¶
O firmware inclui o controlador fir — driver de sensor térmico (fir == infravermelho longínquo) para imagiadores térmicos ligados externamente:
MLX90621 — matriz IR de 16 × 4
MLX90640 — matriz IR de 32 × 24
MLX90641 — matriz IR de 16 × 12
AMG8833 — matriz IR de 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 controlador fir comunica com o sensor apenas através de I²C 1 — ligue o módulo aos pontos SCL / SDA da serigrafia.
Temporização¶
time¶
O módulo time abrange 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 únicos sem consumir um slot de temporizador de hardware. Passe -1 como id para usar 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 estão em milissegundos. Chame deinit() para parar e libertar o slot.
Relógio de tempo real¶
machine.RTC mantém a hora do relógio entre reinícios:
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 repõe a placa se a aplicação ficar bloqueada. 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ção de arranque e runtime¶
Atualização de firmware (DFU)¶
O Nicla Vision utiliza o duplo toque de reset padrão do Arduino para entrar no bootloader do Arduino. Prima rapidamente o botão de reset duas vezes — a placa re-enumera-se 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 a pedido, chamando machine.bootloader()
import machine
machine.bootloader()
Sistema de ficheiros e ordem de arranque¶
O firmware do Nicla Vision monta até dois sistemas de ficheiros no arranque:
Flash interno — montado sempre em
/flash. Contémmain.pyeREADME.txtpor defeito; criado no primeiro arranque.ROMFS — sistema de ficheiros mapeado em memória, só de leitura, em
/rom, montado automaticamente pelo MicroPython no arranque.
Após a montagem, o diretório de trabalho é definido como /flash. O interpretador executa então scripts a partir 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. Resets suaves subsequentes re-executamboot.pymas vão diretamente para o REPL — para re-executarmain.pyé necessário reiniciar completamente a placa.
O main.py predefinido enviado numa placa recém-gravada apenas pisca o canal azul do LED RGB de utilizador como batimento cardíaco (dois pulsos curtos, pausa curta), para que possa confirmar que o firmware arrancou corretamente sem nenhum host ligado.
sys.path é expandido para incluir ambos os sistemas de ficheiros e os seus subdiretórios lib/, pelo que os módulos importáveis podem residir em /flash/lib ou /rom/lib.
Quando ligada via USB, /flash também é enumerada como uma unidade de armazenamento de massa USB no host, permitindo editar boot.py, main.py e quaisquer outros ficheiros diretamente. Ejete a unidade antes de reiniciar a câmara para que o host descarregue as suas escritas em cache.
Nota
Como o sistema operativo trata a unidade como um dispositivo de bloco passivo, os ficheiros criados ou modificados por código a correr na câmara não serão visíveis até que o host remonte a unidade. Se o SO e a câmara escreverem no mesmo sistema de ficheiros ao mesmo tempo, o SO ganhará e sobreporá as alterações feitas pela câmara. Use o cartão SD para quaisquer dados que o script escreva de volta 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 lê ou escreve na unidade de armazenamento de massa USB — este é um indicador de atividade controlado pelo firmware, não uma falha.
Tamanhos de armazenamento¶
O Nicla Vision é fornecido com:
/flash— sistema de ficheiros FAT de 11 MB, leitura/escrita./rom— ROMFS de 4 MB mapeado em memória, só de leitura, usado para incluir scripts e modelos de ML que beneficiam de acesso mmap de cópia zero.
Indicador de falha grave¶
Se o LED RGB de utilizador estiver a percorrer rapidamente todas as cores — suficientemente rápido para parecer um LED branco a piscar em vez de tonalidades distintas — o firmware encontrou uma falha grave 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 da compilação para o Nicla Vision.