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‑осевым IMU LSM6DSOX, MEMS‑микрофоном MP34DT06, дальномером VL53L1CB на основе времени пролёта (time‑of‑flight), модулем Wi‑Fi + Bluetooth LE 5.1, а также зарядным устройством / индикатором заряда батареи.
Полный datasheet, фотографии и габариты см. на странице продукта Arduino Nicla Vision.
Ключевые особенности¶
STMicroelectronics STM32H747AII6 — двухъядерный Cortex‑M7 (400 МГц) + Cortex‑M4 (200 МГц). Прошивка OpenMV работает только на ядре M7.
2 МБ внутренней флеш‑памяти плюс 16 МБ внешней QSPI‑флеш (используется для приложения + ROMFS).
1 МБ внутренней SRAM.
Аппаратный кодер/декодер JPEG.
GC2145 — 2‑мегапиксельный цветной CMOS‑датчик.
Встроенный IMU (акселерометр + гироскоп LSM6DSOX), MEMS‑микрофон (MP34DT06JTR) и дальномер VL53L1CB на основе времени пролёта (time‑of‑flight) (до ~4 м).
Wi‑Fi b/g/n (2,4 ГГц) + Bluetooth LE 5.1 через модуль Murata 1DX (CYW4343W) — подключается к прилагаемой антенне через встроенный разъём U.FL.
Высокоскоростной USB (480 Мбит/с) через Micro USB с внешним ULPI PHY (USB3320C).
13 пользовательских выводов ввода‑вывода на краевых разъёмах Arduino — четыре цифровых LPIO (
D0–D3), три аналоговых входа на 1,8 В (A0–A2), пара I²CSCL/SDAи четвёрка SPISCLK/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 (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 канал 4 (J1‑8) |
A1 |
1,8 В |
ADC2 канал 2 (J1‑7) |
A2 |
1,8 В |
ADC3 канал 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‑светодиода (активный низкий уровень) |
Примечание
D0–D3 и SCLK/CIPO/COPI/CS подключены через двунаправленный преобразователь уровня TXB0108 — эта микросхема поддерживает только двухтактный (push‑pull) режим работы GPIO, поэтому трафик шины с открытым стоком (например, программно реализованный 1‑Wire или I²C на этих выводах) работать не будет.
SCL/SDA подключены через отдельный преобразователь NTS0304, который поддерживает как двухтактный (push‑pull), так и с открытым стоком (open‑drain) режим, поэтому 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 (после 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‑контактный беспаечный ESLOV‑разъём Molex:
Вывод |
Имя |
Функция |
|---|---|---|
J5‑1 |
VESLOV |
вход питания (≤ 5 В) — объединяется (OR) с |
J5‑2 |
INT |
вход внешнего прерывания на |
J5‑3 |
SCL_EXT |
разделяется с площадкой |
J5‑4 |
SDA_EXT |
разделяется с площадкой |
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 двойной сброс (double‑tap reset) для входа в загрузчик Arduino — быстро нажмите кнопку сброса дважды, и плата определится как DFU‑устройство. OpenMV IDE использует этот режим для перепрошивки.
Сигналы SWD STM32 выведены на обратной стороне платы через ряд контактных площадок между двумя разъёмами J2. Впаяйте в них штыревой разъём с шагом 2,54 мм (100 mil), чтобы подключить адаптер ST‑LINK или J‑Link:
P1 / P2 — внутренняя шина I²C PMIC на PF0 (SDA) и PF1 (SCL). На Nicla Vision это
machine.I2C(2), по которой идёт трафик PMIC, индикатора заряда и ToF.P3 — TMS / SWDIO (PA13)
P4 — TCK / SWCLK (PA14)
P5 — NRST
P6 — TDO / SWO (PB3)
P7 — шина +1V8 (питание ввода‑вывода SoC — также правильное опорное напряжение для отладочного адаптера).
P8 —
VOTP_PMIC— только для заводского программирования. Должен оставаться неподключённым.
Все отладочные сигналы привязаны к 1,8 В — кольцо ввода‑вывода 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 сбоку платы подключён напрямую к выходу 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 — Модуль Audio посредством периферийного устройства DFSDM STM32. Каждый буфер приходит как 16‑битный знаковый PCM bytearray, готовый к передаче в ulab/numpy для DSP — например, простой детектор громкости:
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¶
Встроенный акселерометр + гироскоп 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)
IMU подключён к выделенной внутренней шине SPI (SPI5), поэтому он не конкурирует с пользовательским SPI4, выведенным на разъёмы.
Дальномер на основе времени пролёта¶
Встроенный дальномер ST VL53L1CB на основе времени пролёта (time‑of‑flight) находится на внутренней шине I²C PMIC (I²C 2). Используйте встроенный драйвер vl53l1x — Драйвер датчика расстояния ToF VL53L1X для получения измерений расстояния до ~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. Чтение индикатора заряда безвредно — драйвер не поставляется, но регистры, описанные в datasheet 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, шиной ядра / ввода‑вывода SoC +1V8, VDDIO_EXT для преобразователей уровня и зарядным устройством Li‑Po. Он находится на шине I²C 2 по адресу 0x08.
Предупреждение
Чтение регистров PMIC безопасно; запись в них опасна. Неправильная настройка понижающего регулятора или параметров зарядного устройства может необратимо повредить плату, батарею или и то, и другое. Относитесь к PMIC как к доступному только для чтения, если только вы точно не знаете, что делаете.
Самое полезное, что PMIC сообщает в отличие от индикатора заряда, — это конечный автомат зарядного устройства: работает ли плата сейчас от USB / ESLOV / VIN, на какой стадии цикла заряда находится Li‑Po и нет ли у зарядного устройства теплового или сторожевого (watchdog) сбоя. Регистры зарядного устройства располагаются со смещением 0x80 в основном адресном пространстве I²C PF1550 (см. §22.2 datasheet 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)
Другие доступные только для чтения регистры, на которые стоит взглянуть в datasheet (все со смещением зарядного устройства 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 — асинхронный 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 == far infrared, дальний инфракрасный) для внешне подключённых тепловизоров:
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 в качестве id, чтобы использовать виртуальный (программный) таймер:
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"))
Значения периода указываются в миллисекундах. Вызовите 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 двойной сброс (double‑tap reset) для входа в загрузчик 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 поставляется с:
/flash— файловая система FAT объёмом 11 МБ, чтение/запись./rom— отображённая в память ROMFS объёмом 4 МБ, доступная только для чтения, используется для поставки скриптов и ML‑моделей, которым выгоден доступ через mmap без копирования (zero‑copy).
Индикатор аппаратного сбоя¶
Если пользовательский RGB‑светодиод быстро перебирает все цвета — настолько быстро, что это, как правило, выглядит как мерцающий белый светодиод, а не как отдельные оттенки — прошивка столкнулась с неустранимым аппаратным сбоем (hard fault). Перепрошейте прошивку для восстановления; если перепрошивка не помогает, плата может быть физически повреждена.
Программные библиотеки¶
См. индекс библиотек для полного списка модулей — включая те, что уникальны для сборки Nicla Vision.