Arduino Nicla Vision

Arduino Nicla Vision este o placă de viziune artificială de 22,86 × 22,86 mm construită în jurul cipului STMicroelectronics STM32H747AII6 — un SoC dual-core care combină un Cortex-M7 la 400 MHz cu un Cortex-M4 la 200 MHz. Firmware-ul OpenMV rulează în întregime pe nucleul M7. Placa asociază microcontrolerul cu senzorul CMOS color GC2145 de 2 MP, un IMU pe 6 axe LSM6DSOX, un microfon MEMS MP34DT06, un telemetru time-of-flight VL53L1CB, Wi-Fi + Bluetooth LE 5.1 și un încărcător de baterie / indicator de încărcare (fuel gauge).

Arduino Nicla Vision

Pentru fișa tehnică completă, fotografii și dimensiuni consultați pagina produsului Arduino Nicla Vision.

Caracteristici principale

  • STMicroelectronics STM32H747AII6 dual Cortex-M7 (400 MHz) + Cortex-M4 (200 MHz). Firmware-ul OpenMV rulează doar pe nucleul M7.

  • 2 MB memorie flash internă plus 16 MB memorie flash externă QSPI (utilizată pentru aplicație + ROMFS).

  • 1 MB SRAM internă.

  • Codificator/decodificator JPEG hardware.

  • Senzor CMOS color GC2145 de 2 MP.

  • IMU integrat (accelerometru + giroscop LSM6DSOX), microfon MEMS (MP34DT06JTR) și telemetru time-of-flight VL53L1CB (până la ~4 m).

  • Wi-Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 prin modulul Murata 1DX (CYW4343W) — se conectează la antena furnizată printr-un conector U.FL integrat.

  • USB de mare viteză (480 Mb/s) prin Micro USB, printr-un PHY ULPI extern (USB3320C).

  • 13 pini de I/O utilizator pe conectorii laterali Arduino — patru LPIO digitale (D0D3), trei intrări analogice de 1,8 V (A0A2), perechea I²C SCL/SDA și cvartetul SPI SCLK/CIPO/COPI/CS.

  • Suport pentru baterie — conector Li-Po pe spate, încărcător de tip BQ și indicator de încărcare MAX17262 pe magistrala PMIC internă.

  • Conector ESLOV cu 5 pini pe spate pentru extindere I²C fără lipire.

Atenționare

Pinii digitali de utilizator sunt la 3,3 V în mod implicit, dar sunt direcționați prin convertoare de nivel programabile prin software (VDDIO_EXT) care pot fi reconfigurate la 1,8 V. Pinii analogici (A0–A2) sunt doar la 1,8 V — aceștia ocolesc convertoarele de nivel și se conectează direct la microcontroler. Aplicarea a 3,3 V pe A0–A2 va deteriora SoC-ul.

Configurația pinilor

Configurația pinilor Arduino Nicla Vision

Referință pini

Treisprezece pini de utilizator sunt expuși pe conectorii laterali Arduino (J1 și J2). Semnale suplimentare de depanare, recuperare și PMIC sunt direcționate către pad-uri de test pe spatele plăcii.

Nume pin

Referință

Funcție

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

trageți la GND (sau apăsați comutatorul integrat) pentru a reseta placa

LED_RED

3,3 V

canalul roșu al LED-ului RGB (activ la nivel scăzut)

LED_GREEN

3,3 V

canalul verde al LED-ului RGB (activ la nivel scăzut)

LED_BLUE

3,3 V

canalul albastru al LED-ului RGB (activ la nivel scăzut)

Notă

D0D3 și SCLK/CIPO/COPI/CS se află în spatele convertorului de nivel bidirecțional TXB0108 — acel component acceptă doar comandă GPIO de tip push-pull, așa că traficul de magistrală cu colector deschis (open-drain) (de exemplu, un 1-Wire sau I²C emulat software pe acei pini) nu va funcționa.

SCL/SDA se află în spatele unui convertor separat NTS0304 care acceptă atât comandă push-pull, cât și open-drain, motiv pentru care I²C 1 funcționează acolo.

Ambele convertoare sunt raportate la VDDIO_EXT (3,3 V în mod implicit de la PMIC-ul integrat), iar puterea lor de comandă este limitată față de un GPIO direct — sunt proiectate pentru sarcini de nivel de semnal, nu pentru sarcini de putere.

Pini de alimentare

Pinii de pe conectorii laterali:

  • VIN (J2-9) — magistrala principală de sistem de 3,6 – 5 V. PMIC-ul își preia intrarea de aici.

  • VDDIO_EXT (J2-7) — ieșirea magistralei convertorului de nivel, 1,8 V sau 3,3 V (3,3 V în mod implicit). Utilizați-o pentru a alimenta periferice externe de 1,8 V sau 3,3 V conectate la pinii LPIO/SPI/I²C, astfel încât acestea să vorbească același nivel logic ca și conectorii.

  • VBAT (J3-2) — intrare pentru baterie Li-Po. PMIC-ul integrat încarcă celula de la VIN și raportează nivelul de încărcare prin indicatorul de încărcare (fuel gauge).

  • NTC (J3-1) — intrare opțională pentru termistorul Li-Po.

  • GND (J2-6) — masă comună.

  • NC (J2-8) — fără conexiune.

Pad-uri de test pe spatele plăcii:

  • +3V3 — magistrala principală de 3,3 V.

  • D_P / D_N — perechea de date USB de mare viteză (după PHY).

USB și conectorul ESLOV alimentează ambele VIN printr-o pereche de diode ideale LM66100 (câte una pentru fiecare sursă), astfel încât oricare dintre alimentări poate alimenta placa pe cont propriu, iar cele două nu se alimentează niciodată reciproc înapoi. Dacă alimentați extern VIN pe J2-9, aceasta are prioritate — diodele pur și simplu opresc conducția dinspre USB / ESLOV odată ce magistrala externă crește mai sus.

Prin urmare, placa poate fi alimentată prin oricare dintre aceste căi:

  • Micro USB — 5 V în VIN prin dioda ideală de pe partea USB.

  • Conector ESLOV — până la 5 V pe pinul VESLOV al J5, direcționat către VIN prin dioda ideală de pe partea ESLOV (consultați Conector ESLOV).

  • Pinul VIN (J2-9) — alimentați direct cu o sursă reglată de 3,6 – 5 V.

  • Baterie Li-Po — conectați la conectorul de baterie J4 de pe spate sau la pad-urile VBAT/GND/NTC de pe J3 / J2-6. Nu conectați două baterii simultan.

Conector ESLOV

J5 de pe spatele plăcii este un conector ESLOV Molex cu 5 pini, fără lipire:

Pin

Nume

Funcție

J5-1

VESLOV

intrare de alimentare (≤ 5 V) — combinată cu VIN printr-o diodă ideală LM66100

J5-2

INT

intrare de întrerupere externă pe PD9

J5-3

SCL_EXT

partajat cu pad-ul SCL al J2 — aceeași magistrală I²C 1 ca și conectorul de utilizator

J5-4

SDA_EXT

partajat cu pad-ul SDA al J2 — aceeași magistrală I²C 1 ca și conectorul de utilizator

J5-5

GND

masă comună

SCL_EXT/SDA_EXT ale ESLOV și SCL/SDA ale J2 sunt aceiași pini — o singură magistrală I²C 1 expusă pe doi conectori.

Sfat

Utilizați estimatorul duratei de viață a bateriei pentru a modela cât timp va funcționa Nicla Vision pe baterie pentru un anumit ciclu de funcționare activă / somn profund.

Pini de recuperare și depanare

  • RESET — atât un comutator momentan în partea de sus a plăcii, cât și un pad (J3-4 / pad de test P5) legat la linia NRST a SoC-ului. Trageți la GND pentru a reseta.

Nicla Vision folosește resetarea cu dublă apăsare (double-tap reset) standard de la Arduino pentru a intra în bootloader-ul Arduino — apăsați rapid butonul de resetare de două ori, iar placa se enumeră ca dispozitiv DFU. OpenMV IDE folosește acest mod pentru a reflasha firmware-ul.

Semnalele SWD ale STM32 sunt expuse pe spatele plăcii printr-un rând de pad-uri de test între cele două conectoare J2. Lipiți un conector de 2,54 mm (100-mil) în ele pentru a atașa un adaptor ST-LINK sau J-Link:

  • P1 / P2 — magistrala I²C PMIC internă pe PF0 (SDA) și PF1 (SCL). Aceasta este machine.I2C(2) pe Nicla Vision și transportă traficul PMIC, indicatorului de încărcare și ToF.

  • P3 — TMS / SWDIO (PA13)

  • P4 — TCK / SWCLK (PA14)

  • P5 — NRST

  • P6 — TDO / SWO (PB3)

  • P7 — magistrala +1V8 (alimentarea de I/O a SoC-ului — de asemenea, referința corectă pentru adaptorul de depanare).

  • P8VOTP_PMICdoar pentru programarea din fabrică. Trebuie lăsat neconectat.

Toate semnalele de depanare sunt raportate la 1,8 V — inelul de I/O al STM32H747 de pe această placă funcționează de la magistrala +1V8. Setați adaptorul de depanare pentru logică de 1,8 V înainte de conectare.

Periferice integrate

LED-uri

Nicla Vision are un singur LED RGB de utilizator, controlabil prin software prin machine.LED

from machine import LED

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

Un LED separat DL2 CHARGE de pe lateralul plăcii este conectat direct la ieșirea CHGB a PMIC-ului — acesta se aprinde în timp ce o baterie Li-Po este încărcată de la USB / ESLOV / VIN și nu este controlabil de utilizator.

Senzor de cameră

GC2145 este comandat prin modulul csi — senzori de cameră

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

Când cereți o dimensiune mică a cadrului, driverul GC2145 decupează o fereastră de citire proporțional mai mică din senzor — în mod implicit, raportul de reducere de la citire la ieșire este limitat la 3x pentru a menține rata de cadre ridicată. csi.IOCTL_SET_FOV_WIDE ridică această limită la 5x, ceea ce înseamnă că driverul preia dintr-o zonă mai largă a senzorului atunci când transmite rezoluții mici. Rezultatul este un câmp vizual vizibil mai larg la dimensiuni mici de cadru, cu prețul unei anumite pierderi de debit:

cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE)  # returns the current setting

Nucleul M4

Nucleul Cortex-M4 este expus prin openamp pentru comunicarea inter-procesor. Firmware-ul OpenMV rulează doar pe M7; M4 nu are propriul runtime MicroPython, așa că utilizarea sa înseamnă construirea unei imagini de firmware C separate și încărcarea acesteia din sistemul de fișiere prin openamp.RemoteProc. Firmware-ul exemplu precompilat care implementează un punct final UART virtual este disponibil în depozitul openamp_vuart — urmați README-ul acestuia pentru a construi 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)

În practică, acest suport este cel mai bine tratat ca o demonstrație a interfeței openamp, mai degrabă decât ca o platformă dual-core funcțională — M4 nu poate fi resetat independent de M7, așa că oprirea M4 forțează o repornire completă a sistemului.

Microfon

Microfonul PDM integrat MP34DT06JTR este capturat prin audio — Modulul Audio peste periferia DFSDM a STM32. Fiecare tampon (buffer) ajunge ca un bytearray PCM pe 16 biți cu semn, gata de a fi alimentat în ulab/numpy pentru DSP — de exemplu, un detector simplu de intensitate sonoră:

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

Accelerometrul + giroscopul integrat LSM6DSOX este expus prin imu — senzor 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)

IMU-ul este conectat la o magistrală SPI internă dedicată (SPI5), astfel încât nu intră în conflict cu SPI4 de utilizator scos pe conectori.

Telemetru time-of-flight

Telemetrul time-of-flight ST VL53L1CB integrat se află pe magistrala I²C internă a PMIC-ului (I²C 2). Utilizați driverul înghețat vl53l1x — Driver pentru senzorul de distanță ToF VL53L1X pentru a obține citiri de distanță de până la ~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)

Indicator de încărcare a bateriei

Indicatorul de încărcare (fuel gauge) Maxim MAX17262 ModelGauge m5 urmărește tensiunea, curentul, temperatura și nivelul de încărcare ale bateriei Li-Po. Se află pe I²C 2 la adresa 0x36.

MAX17262 are detectare internă a curentului, așa că registrul de curent se citește direct în microamperi, fără niciun factor Rsense extern de aplicat. Citirea indicatorului de încărcare este inofensivă — nu există un driver livrat, dar registrele documentate în fișa tehnică MAX17262 pot fi citite direct:

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 este în complement față de doi cu semn: pozitiv în timpul încărcării, negativ în timpul descărcării. TTE are sens doar când curentul este negativ; TTF doar când curentul este pozitiv.

Circuit de gestionare a energiei (PMIC)

PMIC-ul NXP MC34PF1550A0EP gestionează fiecare regulator de pe Nicla Vision — magistrala principală +3V3, magistrala +1V8 a nucleului / I/O a SoC-ului, VDDIO_EXT către convertoarele de nivel și încărcătorul Li-Po. Se află pe I²C 2 la adresa 0x08.

Atenționare

Citirea registrelor PMIC este în regulă; scrierea în ele este periculoasă. Configurarea greșită a unui regulator buck sau a unei setări de încărcător poate deteriora permanent placa, bateria sau ambele. Tratați PMIC-ul ca fiind doar pentru citire, cu excepția cazului în care știți exact ce faceți.

Cel mai util lucru pe care PMIC-ul ți-l spune și pe care indicatorul de încărcare nu îl poate spune este mașina de stări a încărcătorului — dacă placa rulează în prezent pe USB / ESLOV / VIN, în ce etapă a ciclului de încărcare se află bateria Li-Po și dacă încărcătorul este într-o eroare termică sau de watchdog. Registrele încărcătorului se află la un offset de 0x80 în spațiul principal de adrese I²C al PF1550 (consultați §22.2 din fișa tehnică PF1550), așa că, de exemplu, CHG_INT_OK la adresa de încărcător 0x04 se citește din registrul 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)

Alte registre doar pentru citire care merită consultate în fișa tehnică (toate la offset-ul de încărcător 0x80): 0x80 CHG_INT (întreruperi de încărcător memorate (latched) — indicatori de eroare), 0x86 VBUS_SNS (starea VBUS pe mai mulți biți, incluzând OVLO / UVLO / DPM) și 0x88 BATT_SNS (prezența bateriei și starea de supracurent).

Wi-Fi

Modulul Murata 1DX (CYW4343W) integrat este expus prin network — configurarea rețelei ca interfață de stație. Conectați antena furnizată la conectorul U.FL integrat înainte de a activa radioul:

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

Același Murata 1DX expune și Bluetooth LE 5.1. Utilizați aioble — BLE asincron pentru BLE compatibil cu asyncio — de exemplu, anunțarea ca periferic și așteptarea conectării unui dispozitiv 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())

Referință magistrale

GPIO

Utilizați machine.Pin pentru a citi sau comanda oricare dintre pinii inscripționați pe placă. Ieșirile sunt CMOS de 3,3 V (implicit VDDIO_EXT), iar convertoarele de nivel limitează puterea de comandă per pin la câțiva miliamperi — sunt proiectate pentru sarcini de nivel de semnal, nu pentru sarcini de putere.

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

Orice pin de intrare poate, de asemenea, declanșa o întrerupere la tranzițiile de muchie:

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

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

UART

Magistrală

TX

RX

UART4

SDA

SCL

from machine import UART

uart = UART(4, baudrate=115200)
uart.write("hello")
uart.read(5)

Notă

UART4 își partajează pinii cu I²C 1 — aceleași pad-uri SDA/SCL transportă ambele magistrale. Alegeți UART sau I²C, nu ambele, pe acei pini.

Inscripția D1/D2 indică și UART_TX/UART_RX, dar pe acest firmware acei pini sunt direcționați către LPUART1, nu către machine.UART. machine.UART(1) în sine este rezervat pentru controlerul Bluetooth de pe cip și nu este accesibil pe conectori.

I²C

Magistrală

SCL

SDA

I2C1

SCL

SDA

from machine import I2C

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

Pad-urile SCL/SDA de pe J2 și pinii SCL_EXT/SDA_EXT ai conectorului ESLOV ajung pe aceeași magistrală I²C 1 — consultați Conector ESLOV de mai sus pentru configurația pinilor ESLOV.

Același hardware poate fi utilizat și în modul țintă (slave) prin machine.I2CTarget pentru a expune o regiune de memorie unui alt controler I²C:

from machine import I2CTarget

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

SPI

Magistrală

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

Nicla Vision expune trei canale ADC pe 12 biți pe A0, A1 și A2. Toate trei sunt raportate la 1,8 Vread_u16 returnează 0–65535 pe intervalul 0–1,8 V la pin:

from machine import ADC
import time

adc = ADC("A0")
while True:
    voltage = adc.read_u16() * 1.8 / 65535
    print(voltage)
    time.sleep_ms(100)

Atenționare

Intrările ADC ale Nicla Vision sunt raportate la 1,8 V (și nu au niciun convertor de nivel în fața SoC-ului). Aplicarea unui semnal de 3,3 V va satura convertorul și poate deteriora pinul — divizați extern tensiunile mai mari.

PWM

Pin

Temporizator / 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

Comandați oricare dintre ele prin machine.PWM

from machine import Pin, PWM

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

Notă

Mai mulți pini partajează canalele TIM1:

  • TIM1 CH2 se află pe D1 și CS.

  • TIM1 CH3 se află pe D2 și CIPO; SCLK emite complementul inversat (TIM1 CH3N) al aceluiași canal.

  • TIM1 CH4 se află doar pe COPI.

Alegeți un singur consumator per canal de temporizator. Pinii cvartetului SPI (SCLK/CIPO/COPI/CS) nu pot fi nici comandați prin PWM în timp ce machine.SPI(4) îi utilizează.

Magistrale emulate software (bit-banged)

machine.SoftI2C și machine.SoftSPI funcționează pe orice GPIO dacă aveți nevoie de o magistrală suplimentară.

Senzor termic (extern)

Firmware-ul include driverul fir — driver pentru senzori termici (fir == far infrared) pentru camere termice cablate extern:

  • MLX90621 — matrice IR de 16 × 4

  • MLX90640 — matrice IR de 32 × 24

  • MLX90641 — matrice IR de 16 × 12

  • AMG8833 — matrice IR de 8 × 8

Conectați modulul la magistrala I²C a plăcii și citiți cadre cu 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())

Driverul fir comunică cu senzorul doar prin I²C 1 — conectați modulul la pad-urile SCL / SDA inscripționate pe placă.

Temporizare

time

Modulul time acoperă întârzieri cu blocare, tact-uri monotone și măsurarea timpului scurs:

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)

Temporizatoare virtuale

machine.Timer programează funcții de retroapelare (callback) periodice sau unice fără a consuma un slot de temporizator hardware. Transmiteți -1 ca id pentru a utiliza un temporizator 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"))

Valorile perioadei sunt în milisecunde. Apelați deinit() pentru a opri și elibera slotul.

Ceas în timp real

machine.RTC păstrează ora reală (wall-clock) de-a lungul resetărilor:

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 resetează placa dacă aplicația se blochează. Odată pornit, nu poate fi oprit sau reconfigurat — alimentați-l periodic în interiorul buclei principale:

from machine import WDT

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

Informații despre pornire și runtime

Actualizare firmware (DFU)

Nicla Vision folosește resetarea cu dublă apăsare (double-tap reset) standard de la Arduino pentru a intra în bootloader-ul Arduino. Apăsați rapid butonul de resetare de două ori — placa se reenumeră prin USB ca dispozitiv DFU și OpenMV IDE poate flasha o nouă imagine de firmware.

Un script în execuție poate reintra în bootloader la cerere apelând machine.bootloader()

import machine

machine.bootloader()

Sistem de fișiere și ordinea de pornire

Firmware-ul Nicla Vision montează până la două sisteme de fișiere la pornire:

  • Memoria flash internă — întotdeauna montată la /flash. Conține main.py și README.txt în mod implicit; creată la prima pornire.

  • ROMFS — sistem de fișiere doar pentru citire, mapat în memorie la /rom, montat automat de MicroPython la pornire.

După montare, directorul de lucru este setat la /flash. Interpretorul rulează apoi scripturile din acel director:

  • boot.py este executat la fiecare resetare soft (pornire la rece, Ctrl‑D din REPL sau ori de câte ori scriptul în execuție revine).

  • main.py este executat doar la pornirea la rece, imediat după boot.py. Resetările soft ulterioare reexecută boot.py, dar trec direct la REPL — pentru a reexecuta main.py trebuie să resetați complet placa.

main.py-ul implicit livrat pe o placă proaspăt flashată doar clipește canalul albastru al LED-ului RGB de utilizator ca un puls de viață (heartbeat) (două impulsuri scurte, pauză scurtă), astfel încât să puteți spune că firmware-ul a pornit corect, fără niciun host atașat.

sys.path este extins pentru a include ambele sisteme de fișiere și subdirectoarele lor lib/, astfel încât modulele importabile pot fi în /flash/lib sau /rom/lib.

Când este conectat prin USB, /flash se enumeră, de asemenea, ca o unitate de stocare în masă USB pe host, permițându-vă să editați boot.py, main.py și orice alte fișiere direct. Ejectați unitatea înainte de a reseta camera, astfel încât host-ul să golească scrierile sale memorate în cache.

Notă

Deoarece sistemul de operare tratează unitatea ca un dispozitiv de bloc pasiv, fișierele create sau modificate de codul care rulează pe cameră nu vor apărea până când host-ul nu remontează unitatea. Dacă atât sistemul de operare, cât și camera scriu pe același sistem de fișiere în același timp, sistemul de operare va câștiga și va suprascrie modificările făcute de cameră. Utilizați cardul SD pentru orice date pe care scriptul le scrie înapoi și remontați înainte de a citi acele fișiere de pe host.

Notă

Canalul roșu al LED-ului RGB de utilizator se poate aprinde scurt în timp ce host-ul citește de pe sau scrie pe unitatea de stocare în masă USB — acesta este un indicator de activitate controlat de firmware, nu o eroare.

Dimensiuni de stocare

Nicla Vision este livrată cu:

  • /flash — sistem de fișiere FAT de 11 MB, citire/scriere.

  • /rom — ROMFS de 4 MB, doar pentru citire, mapat în memorie, utilizat pentru a livra scripturi și modele ML care beneficiază de acces mmap zero-copy.

Indicator de eroare gravă (hard-fault)

Dacă LED-ul RGB de utilizator parcurge rapid toate culorile — suficient de rapid încât tinde să arate ca un LED alb sclipitor mai degrabă decât nuanțe distincte — firmware-ul a întâmpinat o eroare gravă irecuperabilă (hard fault). Reflashați firmware-ul pentru a recupera; dacă reflasharea nu ajută, placa poate fi deteriorată fizic.

Biblioteci software

Consultați indexul de biblioteci pentru lista completă a modulelor — inclusiv care dintre ele sunt unice pentru versiunea Nicla Vision.