Arduino Nicla Vision

Arduino Nicla Vision — це плата технічного зору розміром 22,86 × 22,86 мм, побудована на базі STMicroelectronics STM32H747AII6 — двоядерної SoC, що поєднує ядро Cortex‑M7 на 400 МГц і Cortex‑M4 на 200 МГц. Мікропрограма OpenMV працює виключно на ядрі M7. Плата об’єднує мікроконтролер із 2-мегапіксельним кольоровим CMOS-датчиком GC2145, 6-осьовим ІМП LSM6DSOX, MEMS-мікрофоном MP34DT06, далекоміром часу прольоту VL53L1CB, модулем Wi‑Fi + Bluetooth LE 5.1 та зарядним пристроєм/вимірювачем заряду батареї.

Arduino Nicla Vision

Повний даташит, фотографії та розміри наведено на сторінці продукту Arduino Nicla Vision.

Основні характеристики

  • STMicroelectronics STM32H747AII6 — двоядерна SoC: Cortex‑M7 (400 МГц) + Cortex‑M4 (200 МГц). Мікропрограма OpenMV працює лише на ядрі M7.

  • 2 МБ внутрішньої флеш-пам’яті і 16 МБ зовнішньої QSPI флеш-пам’яті (використовується для застосунку та ROMFS).

  • 1 МБ внутрішньої SRAM.

  • Апаратний кодек JPEG.

  • GC2145 — 2-мегапіксельний кольоровий CMOS-датчик.

  • Вбудований ІМП (акселерометр + гіроскоп LSM6DSOX), MEMS-мікрофон (MP34DT06JTR) та VL53L1CB — далекомір часу прольоту (до ~4 м).

  • Wi‑Fi b/g/n (2,4 ГГц) + Bluetooth LE 5.1 через модуль Murata 1DX (CYW4343W) — підключається до комплектної антени через вбудований роз’єм U.FL.

  • High‑speed USB (480 Мб/с) через Micro USB за допомогою зовнішнього ULPI PHY (USB3320C).

  • 13 користувацьких виводів на краєвих роз’ємах Arduino — чотири цифрові LPIO (D0D3), три аналогові входи 1,8 В (A0A2), пара I²C SCL/SDA та квартет SPI SCLK/CIPO/COPI/CS.

  • Підтримка акумулятора — роз’єм Li‑Po на зворотньому боці, зарядний пристрій типу BQ та вимірювач заряду MAX17262 на внутрішній шині PMIC.

  • 5-контактний роз’єм ESLOV на зворотній стороні для підключення розширень I²C без паяння.

Попередження

Цифрові виводи за замовчуванням мають рівень 3,3 В, але вони прокладені через програмно керовані перетворювачі рівнів (VDDIO_EXT), які можна перенастроїти на 1,8 В. Аналогові виводи (A0–A2) — лише 1,8 В — вони обходять перетворювачі рівнів і підключаються безпосередньо до мікроконтролера. Подача 3,3 В на A0–A2 пошкодить SoC.

Розпіновка

Arduino Nicla Vision Pinout

Довідник виводів

Тринадцять користувацьких виводів виведено на краєві роз’єми Arduino (J1 та J2). Додаткові сигнали налагодження, відновлення та PMIC виведено на тестові контактні майданчики на зворотній стороні плати.

Назва виводу

Довідка

Функція

D0

3,3 В

GPIO / LPIO0 (J1‑1)

D1

3,3 В

LPUART1 TX / TIM1 CH2 / LPIO1 (J2‑3)

D2

3,3 В

LPUART1 RX / TIM1 CH3 / LPIO2 (J2‑4)

D3

3,3 В

GPIO / LPIO3 (J2‑5)

A0

1,8 В

ADC1 channel 4 (J1‑8)

A1

1,8 В

ADC2 channel 2 (J1‑7)

A2

1,8 В

ADC3 channel 5 (J1‑2)

SCL

3,3 В

I2C1 SCL / UART4 RX / TIM4 CH3 (J2‑2)

SDA

3,3 В

I2C1 SDA / UART4 TX / TIM4 CH4 (J2‑1)

SCLK

3,3 В

SPI4 SCK / TIM1 CH3N (J1‑6)

CIPO

3,3 В

SPI4 MISO / TIM1 CH3 (J1‑5)

COPI

3,3 В

SPI4 MOSI / TIM1 CH4 (J1‑4)

CS

3,3 В

SPI4 NSS / TIM1 CH2 (J1‑3)

RESET

3,3 В

притягнути до GND (або натиснути кнопку на платі), щоб скинути плату

LED_RED

3,3 В

Червоний канал RGB-світлодіода (активний низький рівень)

LED_GREEN

3,3 В

Зелений канал RGB-світлодіода (активний низький рівень)

LED_BLUE

3,3 В

Синій канал RGB-світлодіода (активний низький рівень)

Примітка

D0D3 та SCLK/CIPO/COPI/CS розташовані за двонаправленим перетворювачем рівнів TXB0108 — він підтримує лише режим push‑pull для GPIO, тому відкритодрейнові сигнали шини (наприклад, бітбанг 1-Wire або I²C на цих виводах) не будуть працювати.

SCL/SDA розташовані за окремим перетворювачем NTS0304, що підтримує як push‑pull, так і відкритодрейновий режим — саме тому I²C 1 там працює.

Обидва перетворювачі орієнтовані на VDDIO_EXT (за замовчуванням 3,3 В від вбудованого PMIC), і їхня здатність до керування обмежена порівняно з прямим GPIO — вони розраховані на передачу сигналів, а не живлення навантажень.

Виводи живлення

Виводи краєвого роз’єму:

  • VIN (J2‑9) — основна системна шина 3,6–5 В. Тут PMIC отримує своє живлення.

  • VDDIO_EXT (J2‑7) — вихід шини перетворювача рівнів, 1,8 В або 3,3 В (за замовчуванням 3,3 В). Використовуйте для живлення зовнішніх периферійних пристроїв 1,8 В або 3,3 В, підключених до виводів LPIO/SPI/I²C, щоб вони мали той самий логічний рівень, що й роз’єми.

  • VBAT (J3‑2) — вхід батареї Li‑Po. Вбудований PMIC заряджає акумулятор від VIN та звітує про стан заряду через вимірювач заряду.

  • NTC (J3‑1) — необов’язковий вхід терморезистора Li‑Po.

  • GND (J2‑6) — спільна земля.

  • NC (J2‑8) — не підключено.

Тестові контактні майданчики на зворотній стороні плати:

  • +3V3 — основна шина 3,3 В.

  • D_P / D_N — пара диференціальних сигналів USB high‑speed (після PHY).

USB та роз’єм ESLOV обидва живлять VIN через пару ідеальних діодів LM66100 (по одному на кожне джерело), тому будь-яке джерело може самостійно живити плату, і вони ніколи не зворотно керують одне одним. Якщо ви зовнішньо подаєте VIN на J2‑9, це джерело має пріоритет — діоди просто перестають проводити від USB / ESLOV, як тільки зовнішня шина піднімається вище.

Тому плату можна живити будь-яким із таких способів:

  • Micro USB — 5 В на VIN через ідеальний діод USB-сторони.

  • Роз’єм ESLOV — до 5 В на виводі VESLOV J5, прокладено у VIN через ідеальний діод ESLOV-сторони (див. Роз’єм ESLOV).

  • Вивід VIN (J2‑9) — безпосередньо подати регульоване джерело живлення 3,6–5 В.

  • Акумулятор Li‑Po — підключити до роз’єму батареї J4 на зворотній стороні або до майданчиків VBAT/GND/NTC на J3/J2‑6. Не підключайте два акумулятори одночасно.

Роз’єм ESLOV

J5 на зворотній стороні плати — це 5-контактний роз’єм Molex ESLOV без паяння:

Контакт

Назва

Функція

J5‑1

VESLOV

вхід живлення (≤ 5 В) — об’єднується у VIN через ідеальний діод LM66100

J5‑2

INT

зовнішній вхід переривання на PD9

J5‑3

SCL_EXT

спільний із майданчиком SCL на J2 — та сама шина I²C 1, що й у роз’ємі користувача

J5‑4

SDA_EXT

спільний із майданчиком SDA на J2 — та сама шина I²C 1, що й у роз’ємі користувача

J5‑5

GND

спільна земля

SCL_EXT/SDA_EXT ESLOV та SCL/SDA J2 — це ті самі виводи, тобто одна шина I²C 1, виведена на два роз’єми.

Порада

Використовуйте оцінювач ресурсу батареї, щоб змоделювати, як довго Nicla Vision працюватиме від батареї при заданому циклі активності / глибокого сну.

Виводи відновлення та налагодження

  • RESET — кнопка миттєвого натискання на верхній стороні плати та майданчик (J3‑4 / тестовий майданчик P5), підключені до лінії NRST SoC. Притягніть до GND для скидання.

Nicla Vision використовує стандартне подвійне натискання на скидання Arduino для входу в завантажувач Arduino — швидко натисніть кнопку скидання двічі, і плата перерахується як DFU-пристрій. OpenMV IDE використовує цей режим для перепрошивки мікропрограми.

Сигнали SWD STM32 виведено на зворотній стороні плати через рядок тестових майданчиків між двома роз’ємами J2. Припаяйте роз’єм 2,54 мм (100 міл) до них, щоб підключити адаптер ST‑LINK або J‑Link:

  • P1 / P2 — внутрішня шина I²C PMIC на PF0 (SDA) та PF1 (SCL). Це machine.I2C(2) на Nicla Vision, яка несе трафік PMIC, вимірювача заряду та ToF.

  • P3 — TMS / SWDIO (PA13)

  • P4 — TCK / SWCLK (PA14)

  • P5 — NRST

  • P6 — TDO / SWO (PB3)

  • P7 — шина +1V8 (джерело живлення I/O SoC — також правильний опорний рівень для адаптера налагодження).

  • P8VOTP_PMICлише для заводського програмування. Залиште непідключеним.

Усі сигнали налагодження мають опорний рівень 1,8 В — кільце I/O STM32H747 на цій платі живиться від шини +1V8. Перед підключенням налаштуйте адаптер налагодження на логічний рівень 1,8 В.

Вбудовані периферійні пристрої

Світлодіоди

Nicla Vision має один користувацький RGB-світлодіод, керованим програмно через machine.LED

from machine import LED

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

Окремий DL2 CHARGE LED збоку плати безпосередньо підключено до виходу CHGB PMIC — він світиться під час заряджання акумулятора Li‑Po від USB / ESLOV / VIN і не піддається програмному управлінню.

Датчик камери

GC2145 керується через модуль csi — датчики камери

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

Коли ви запитуєте малий розмір кадру, драйвер GC2145 вирізає пропорційно мале вікно зчитування з датчика — за замовчуванням співвідношення масштабування від зчитування до виходу обмежене значенням 3x для підтримки частоти кадрів. csi.IOCTL_SET_FOV_WIDE підвищує це обмеження до 5x, тобто драйвер захоплює з ширшої ділянки датчика при потоковій передачі малих роздільних здатностей. Результат — помітно ширше поле зору при малих розмірах кадру, ціною деякої пропускної здатності:

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

Ядро M4

Ядро Cortex‑M4 доступне через openamp для міжпроцесорного зв’язку. Мікропрограма OpenMV працює лише на M7; M4 не має власного середовища виконання MicroPython, тому його використання означає збірку окремого образу мікропрограми на C та завантаження його з файлової системи через openamp.RemoteProc. Попередньо зібраний приклад мікропрограми, що реалізує віртуальний UART-кінцевий пристрій, доступний у репозиторії openamp_vuart — дотримуйтесь README для збірки 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)

На практиці цю підтримку краще розглядати як демонстрацію інтерфейсу openamp, а не як повноцінну двоядерну платформу — M4 не можна скинути незалежно від M7, тому зупинка M4 примушує виконати повне перезавантаження системи.

Мікрофон

Вбудований PDM-мікрофон MP34DT06JTR захоплюється через audio — Аудіомодуль за допомогою периферійного пристрою DFSDM STM32. Кожен буфер надходить у вигляді знакового 16-бітного PCM bytearray, готового для подачі в ulab/numpy для ЦОС — наприклад, простий детектор гучності:

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

ІМП

Вбудований акселерометр + гіроскоп LSM6DSOX доступний через imu — датчик 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)

ІМП підключено до виділеної внутрішньої шини SPI (SPI5), тому він не конкурує з SPI4 користувача, виведеним на роз’єми.

Далекомір часу прольоту

Вбудований далекомір часу прольоту ST VL53L1CB розташований на внутрішній шині I²C PMIC (I²C 2). Використовуйте заморожений драйвер vl53l1x — драйвер датчика відстані VL53L1X ToF для отримання показань відстані до ~4 м:

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)

Вимірювач заряду батареї

Вимірювач заряду Maxim MAX17262 ModelGauge m5 відстежує напругу, струм, температуру та стан заряду акумулятора Li‑Po. Він розташований на I²C 2 за адресою 0x36.

MAX17262 має внутрішнє вимірювання струму, тому регістр струму безпосередньо повертає значення в мікроамперах без зовнішнього коефіцієнта Rsense. Зчитування вимірювача заряду є безпечним — драйвер не постачається, але регістри, задокументовані в даташиті MAX17262, можна зчитувати безпосередньо:

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 — знакове доповнення до двох: позитивне під час заряджання, від’ємне під час розряджання. TTE має сенс лише при від’ємному струмі; TTF — лише при позитивному.

Мікросхема управління живленням

PMIC NXP MC34PF1550A0EP керує кожним регулятором на Nicla Vision — основною шиною +3V3, шиною ядра/I-O +1V8 SoC, VDDIO_EXT для перетворювачів рівнів та зарядним пристроєм Li‑Po. Він розташований на I²C 2 за адресою 0x08.

Попередження

Зчитування регістрів PMIC є безпечним; запис до них — небезпечним. Неправильне налаштування buck-регулятора або параметрів зарядного пристрою може назавжди пошкодити плату, акумулятор або обидва. Ставтеся до PMIC як до пристрою лише для читання, якщо не знаєте точно, що робите.

Найкорисніше, що PMIC повідомляє на відміну від вимірювача заряду — це кінцевий автомат зарядного пристрою — чи плата наразі живиться від USB / ESLOV / VIN, на якому етапі циклу заряджання перебуває Li‑Po, і чи є теплова або сторожова несправність зарядного пристрою. Регістри зарядного пристрою знаходяться зі зміщенням 0x80 у просторі основних I²C-адрес PF1550 (див. §22.2 даташиту PF1550), тому, наприклад, CHG_INT_OK за адресою зарядного пристрою 0x04 зчитується з регістра 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)

Інші регістри лише для читання, варті уваги в даташиті (всі зі зміщенням зарядного пристрою 0x80): 0x80 CHG_INT (залатчені переривання зарядного пристрою — прапори несправностей), 0x86 VBUS_SNS (стан VBUS з кількома бітами, включно з OVLO / UVLO / DPM) та 0x88 BATT_SNS (наявність батареї та стан перевищення струму).

Wi‑Fi

Вбудований Murata 1DX (CYW4343W) доступний через network — налаштування мережі як інтерфейс станції. Підключіть комплектну антену до вбудованого роз’єму U.FL перед увімкненням радіо:

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

Той самий Murata 1DX також надає Bluetooth LE 5.1. Використовуйте aioble — Async BLE для asyncio-сумісного BLE — наприклад, оголошуйте себе як периферійний пристрій і очікуйте підключення центрального пристрою:

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

Довідник шин

GPIO

Використовуйте machine.Pin для зчитування або керування будь-яким із пронумерованих виводів. Виходи є 3,3 В CMOS (за замовчуванням VDDIO_EXT), а перетворювачі рівнів обмежують здатність до керування кожного виводу кількома міліамперами — вони розраховані на передачу сигналів, а не живлення навантажень.

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

Будь-який вхідний вивід також може генерувати переривання за фронтами:

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

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

UART

Шина

TX

RX

UART4

SDA

SCL

from machine import UART

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

Примітка

UART4 ділить свої виводи з I²C 1 — ті самі майданчики SDA/SCL несуть обидві шини. Вибирайте або UART, або I²C — не обидва — на цих виводах.

Шовкографія D1/D2 також містить написи UART_TX/UART_RX, але в цій мікропрограмі ці виводи прокладено до LPUART1, а не до machine.UART. Сам machine.UART(1) зарезервований для вбудованого контролера Bluetooth і недоступний на роз’ємах.

I²C

Шина

SCL

SDA

I2C1

SCL

SDA

from machine import I2C

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

Майданчики SCL/SDA на J2 та виводи SCL_EXT/SDA_EXT роз’єму ESLOV підключаються до тієї самої шини I²C 1 — див. Роз’єм ESLOV вище для розпіновки ESLOV.

Те саме апаратне забезпечення також можна використовувати в режимі ведений (slave) через machine.I2CTarget, щоб надати іншому I²C-контролеру доступ до ділянки пам’яті:

from machine import I2CTarget

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

SPI

Шина

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 виводить три 12-бітні ADC канали на A0, A1 та A2. Усі три мають опорний рівень 1,8 Вread_u16 повертає 0–65535 для діапазону 0–1,8 В на виводі:

from machine import ADC
import time

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

Попередження

Аналогові входи ADC Nicla Vision мають опорний рівень 1,8 В (і не мають перетворювача рівнів перед SoC). Подача сигналу 3,3 В призведе до насичення перетворювача та може пошкодити вивід — зменшуйте вищі напруги зовнішнім дільником.

PWM

Контакт

Таймер / канал

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

Керуйте будь-яким із них через machine.PWM

from machine import Pin, PWM

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

Примітка

Кілька виводів поділяють канали TIM1:

  • TIM1 CH2 — на D1 та CS.

  • TIM1 CH3 — на D2 та CIPO; SCLK виводить інвертований сигнал (TIM1 CH3N) того самого каналу.

  • TIM1 CH4 — лише на COPI.

Вибирайте одного споживача на канал таймера. Виводи квартету SPI (SCLK/CIPO/COPI/CS) також не можна керувати як PWM, поки їх використовує machine.SPI(4).

Програмні бітбанг-шини

machine.SoftI2C та machine.SoftSPI працюють на будь-якому GPIO, якщо потрібна додаткова шина.

Тепловий датчик (зовнішній)

Мікропрограма включає драйвер fir — драйвер теплового датчика (fir == далекий інфрачервоний діапазон) для зовнішньо підключених теплових імаджерів:

  • MLX90621 — ІЧ-масив 16 × 4

  • MLX90640 — ІЧ-масив 32 × 24

  • MLX90641 — ІЧ-масив 16 × 12

  • AMG8833 — ІЧ-масив 8 × 8

Підключіть модуль до шини I²C плати та зчитуйте кадри за допомогою 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())

Драйвер fir спілкується з датчиком лише через I²C 1 — підключіть модуль до майданчиків SCL / SDA із шовкографії.

Час

time

Модуль time охоплює блокуючі затримки, монотонні тіки та вимірювання минулого часу:

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)

Віртуальні таймери

machine.Timer планує циклічні або одноразові зворотні виклики без використання слота апаратного таймера. Передайте -1 як ідентифікатор для використання віртуального (програмного) таймера:

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

Значення periodу задаються в мілісекундах. Викличте deinit(), щоб зупинити та звільнити слот.

Годинник реального часу

machine.RTC зберігає час настінного годинника між скиданнями:

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

Сторожовий таймер

machine.WDT скидає плату, якщо застосунок зависає. Після запуску його не можна зупинити чи перенастроїти — підгодовуйте його циклічно у своєму головному циклі:

from machine import WDT

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

Інформація про завантаження та виконання

Оновлення мікропрограми (DFU)

Nicla Vision використовує стандартне подвійне натискання на скидання Arduino для входу в завантажувач Arduino. Швидко натисніть кнопку скидання двічі — плата повторно перерахується через USB як DFU-пристрій, і OpenMV IDE зможе прошити новий образ мікропрограми.

Запущений скрипт може повторно увійти в завантажувач на вимогу, викликавши machine.bootloader()

import machine

machine.bootloader()

Файлова система та порядок завантаження

Мікропрограма Nicla Vision монтує до двох файлових систем при завантаженні:

  • Внутрішня флеш-пам’ять — завжди монтується як /flash. За замовчуванням містить main.py та README.txt; створюється під час першого завантаження.

  • ROMFS — файлова система лише для читання з відображенням у пам’ять за адресою /rom, яка автоматично монтується MicroPython при запуску.

Після монтування робоча тека встановлюється на /flash. Потім інтерпретатор виконує скрипти з цієї теки:

  • boot.py виконується при кожному м’якому скиданні (холодне завантаження, Ctrl‑D з REPL або щоразу, коли запущений скрипт повертається).

  • main.py виконується лише при холодному завантаженні, відразу після boot.py. Подальші м’які скидання повторно запускають boot.py, але потрапляють безпосередньо до REPL — щоб повторно виконати main.py, необхідно повністю скинути плату.

Стандартний main.py на щойно прошитій платі просто блимає синім каналом RGB-світлодіода користувача як сигнал серцебиття (два короткі імпульси, коротка пауза), щоб можна було переконатися, що мікропрограма завантажилася без підключеного хоста.

sys.path розширено для включення обох файлових систем та їхніх підтек lib/, тому імпортовані модулі можуть перебувати в /flash/lib або /rom/lib.

При підключенні через USB /flash також перераховується як USB-накопичувач на хості, дозволяючи редагувати boot.py, main.py та будь-які інші файли безпосередньо. Від’єднайте диск перед скиданням камери, щоб хост записав свої кешовані зміни.

Примітка

Оскільки ОС розглядає диск як пасивний блоковий пристрій, файли, створені або змінені кодом, що виконується на камері, не з’являться до повторного монтування диска хостом. Якщо ОС і камера одночасно записують ту саму файлову систему, ОС матиме перевагу і перезапише зміни, зроблені камерою. Використовуйте SD-карту для будь-яких даних, які скрипт записує назад, і перемонтуйте перед зчитуванням цих файлів з хоста.

Примітка

Червоний канал RGB-світлодіода користувача може ненадовго засвітитися, поки хост читає з або записує на USB-накопичувач — це індикатор активності, керований мікропрограмою, а не несправність.

Розміри сховища

Nicla Vision постачається з:

  • /flash11 МБ файлова система FAT, читання/запис.

  • /rom4 МБ ROMFS лише для читання з відображенням у пам’ять, використовується для постачання скриптів та моделей МН, що виграють від доступу mmap без копіювання.

Індикатор апаратного збою

Якщо RGB-світлодіод користувача швидко циклічно перебирає всі кольори — настільки швидко, що це виглядає як миготливий білий LED, а не окремі відтінки — мікропрограма зіткнулася з невідновлюваним апаратним збоєм. Перепрошийте мікропрограму для відновлення; якщо перепрошивка не допомагає, плата може бути фізично пошкоджена.

Програмні бібліотеки

Повний перелік модулів, включно з тими, що унікальні для збірки Nicla Vision, наведено в індексі бібліотек.