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).
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 (
D0–D3), trei intrări analogice de 1,8 V (A0–A2), perechea I²CSCL/SDAși cvartetul SPISCLK/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¶
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ă
D0–D3 ș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
VESLOVal 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 |
J5-2 |
INT |
intrare de întrerupere externă pe |
J5-3 |
SCL_EXT |
partajat cu pad-ul |
J5-4 |
SDA_EXT |
partajat cu pad-ul |
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).
P8 —
VOTP_PMIC— doar 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 V — read_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șiCS.TIM1 CH3 se află pe
D2șiCIPO;SCLKemite 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ținemain.pyșiREADME.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.pyeste executat la fiecare resetare soft (pornire la rece,Ctrl‑Ddin REPL sau ori de câte ori scriptul în execuție revine).main.pyeste executat doar la pornirea la rece, imediat dupăboot.py. Resetările soft ulterioare reexecutăboot.py, dar trec direct la REPL — pentru a reexecutamain.pytrebuie 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.