Arduino Nicla Vision¶
Arduino Nicla Vision は、STMicroelectronics STM32H747AII6 を中心に構築された 22.86 × 22.86 mm のマシンビジョン基板です。STM32H747AII6 は、400 MHz の Cortex‑M7 と 200 MHz の Cortex‑M4 を組み合わせたデュアルコア SoC です。OpenMV ファームウェアは完全に M7 コア上で動作します。この基板は、MCU に GC2145 2 MP カラー CMOS センサー、LSM6DSOX 6 軸 IMU、MP34DT06 MEMS マイク、VL53L1CB time‑of‑flight 距離センサー、Wi‑Fi + Bluetooth LE 5.1、およびバッテリー充電器 / 残量計を組み合わせています。
完全なデータシート、写真、寸法については、Arduino Nicla Vision 製品ページ を参照してください。
主な特徴¶
STMicroelectronics STM32H747AII6 デュアル Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz)。OpenMV ファームウェアは M7 コアのみで動作します。
2 MB の内蔵フラッシュ に加えて 16 MB の外部 QSPI フラッシュ(アプリケーション + ROMFS に使用)。
1 MB の内蔵 SRAM。
ハードウェア JPEG エンコーダ/デコーダ。
GC2145 2 MP カラー CMOS センサー。
オンボード IMU(LSM6DSOX 加速度センサー + ジャイロスコープ)、MEMS マイク(MP34DT06JTR)、および VL53L1CB time‑of‑flight 距離センサー(最大約 4 m)。
Murata 1DX (CYW4343W) モジュールを介した Wi‑Fi b/g/n(2.4 GHz)+ Bluetooth LE 5.1 — オンボードの U.FL コネクタ を介して付属のアンテナに接続します。
外部 ULPI PHY (USB3320C) を介して Micro USB 上で動作する High‑speed USB(480 Mb/s)。
Arduino エッジヘッダ上の 13 個のユーザー I/O ピン — 4 つのデジタル LPIO(
D0–D3)、3 つの 1.8 V アナログ入力(A0–A2)、SCL/SDAの I²C ペア、およびSCLK/CIPO/COPI/CSの SPI 4 本セット。バッテリーサポート — 背面の Li‑Po コネクタ、BQ 系の充電器、および内部 PMIC バス経由の MAX17262 残量計。
背面のはんだ付け不要な I²C 拡張用 5 ピン ESLOV コネクタ。
警告
ユーザーの デジタルピンはデフォルトで 3.3 V ですが、ソフトウェアでプログラム可能なレベルシフタ(VDDIO_EXT)を介して配線されており、1.8 V に再設定できます。アナログピン (A0–A2) は 1.8 V 専用 で、レベルシフタをバイパスして MCU に直接接続されています。A0–A2 に 3.3 V を入力すると SoC が損傷します。
ピン配置¶
ピンリファレンス¶
13 個のユーザーピンが Arduino エッジヘッダ(J1 および J2)に引き出されています。追加のデバッグ、リカバリ、PMIC 信号は基板背面のテストパッドに配線されています。
ピン名 |
リファレンス |
機能 |
|---|---|---|
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 channel 4 (J1‑8) |
A1 |
1.8 V |
ADC2 channel 2 (J1‑7) |
A2 |
1.8 V |
ADC3 channel 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 |
GND に引き下げる(またはオンボードスイッチを押す)と基板がリセットされます |
LED_RED |
3.3 V |
RGB LED の赤チャンネル(アクティブロー) |
LED_GREEN |
3.3 V |
RGB LED の緑チャンネル(アクティブロー) |
LED_BLUE |
3.3 V |
RGB LED の青チャンネル(アクティブロー) |
注釈
D0–D3 および SCLK/CIPO/COPI/CS は TXB0108 双方向レベルシフタの背後にあります。この部品は プッシュプル GPIO ドライブのみをサポートするため、オープンドレインのバス通信(例えばこれらのピン上でのビットバンギングによる 1‑Wire や I²C)は機能しません。
SCL/SDA は別の NTS0304 シフタの背後にあり、プッシュプルとオープンドレイン の両方のドライブをサポートします。そのため I²C 1 がそこで動作します。
どちらのシフタも VDDIO_EXT(デフォルトではオンボード PMIC からの 3.3 V)を基準としており、直接の GPIO に比べてドライブ強度は制限されています。これらは電力負荷ではなく信号レベル向けに設計されています。
電源ピン¶
エッジヘッダのピン:
VIN (J2‑9) — メインの 3.6 – 5 V システムレール。PMIC はここから入力を取得します。
VDDIO_EXT (J2‑7) — レベルシフタレールの 出力 で、1.8 V または 3.3 V(デフォルトは 3.3 V)。LPIO/SPI/I²C ピンに接続された外部の 1.8 V または 3.3 V ペリフェラルに給電して、ヘッダと同じ論理レベルで通信できるようにするために使用します。
VBAT (J3‑2) — Li‑Po バッテリー入力。オンボード PMIC は VIN からセルを充電し、残量計を通じて充電状態を報告します。
NTC (J3‑1) — オプションの Li‑Po サーミスタ入力。
GND (J2‑6) — 共通グランド。
NC (J2‑8) — 未接続。
基板背面のテストパッド:
+3V3 — メインの 3.3 V レール。
D_P / D_N — USB high‑speed データペア(PHY 後段)。
USB と ESLOV コネクタはどちらも一対の LM66100 理想ダイオード(ソースごとに 1 つ)を介して VIN に給電するため、どちらの電源でも単独で基板に給電でき、両者が互いに逆給電することはありません。J2‑9 で VIN を外部から駆動すると、それが優先されます。外部レールが高くなると、ダイオードは単純に USB / ESLOV からの導通を停止します。
したがって、基板は次のいずれかの経路で給電できます:
Micro USB — USB 側の理想ダイオードを介して VIN に 5 V を供給。
ESLOV コネクタ — J5 の
VESLOVピンに最大 5 V を供給し、ESLOV 側の理想ダイオードを介して VIN に配線します(ESLOV コネクタ を参照)。VIN ピン (J2‑9) — 安定化された 3.6 – 5 V 電源を直接供給します。
Li‑Po バッテリー — 背面の J4 バッテリーコネクタ または J3 / J2‑6 の VBAT/GND/NTC パッドに接続します。2 つのバッテリーを同時に接続しないでください。
ESLOV コネクタ¶
基板背面の J5 は 5 ピンの Molex はんだ付け不要 ESLOV コネクタです:
ピン |
名前 |
機能 |
|---|---|---|
J5‑1 |
VESLOV |
電源入力(≤ 5 V)— LM66100 理想ダイオードを介して |
J5‑2 |
INT |
|
J5‑3 |
SCL_EXT |
J2 の |
J5‑4 |
SDA_EXT |
J2 の |
J5‑5 |
GND |
共通グランド |
ESLOV の SCL_EXT/SDA_EXT と J2 の SCL/SDA は同じピンです — 2 つのコネクタに引き出された 1 つの I²C 1 バスです。
Tip
バッテリー寿命推定ツール を使用すると、特定のアクティブ / ディープスリープのデューティサイクルで Nicla Vision がバッテリーでどれくらいの時間動作するかをモデル化できます。
リカバリおよびデバッグピン¶
RESET — 基板上面のモーメンタリスイッチと、SoC の NRST ラインに接続されたパッド(J3‑4 / テストパッド P5)の両方です。GND に引き下げるとリセットされます。
Nicla Vision は、Arduino のブートローダに入るために Arduino 標準の ダブルタップリセット を使用します。リセットボタンを素早く 2 回押すと、基板が DFU デバイスとして列挙されます。OpenMV IDE はこのモードを使用してファームウェアを再書き込みします。
STM32 の SWD 信号は、2 つの J2 ヘッダの間にある一列のテストパッドを通じて基板背面に引き出されています。2.54 mm (100‑mil) ヘッダをはんだ付けして、ST‑LINK または J‑Link アダプタを接続します:
P1 / P2 — PF0 (SDA) と PF1 (SCL) 上の内部 PMIC I²C バス。これは Nicla Vision 上の
machine.I2C(2)で、PMIC、残量計、ToF の通信を担います。P3 — TMS / SWDIO (PA13)
P4 — TCK / SWCLK (PA14)
P5 — NRST
P6 — TDO / SWO (PB3)
P7 — +1V8 レール(SoC の I/O 電源 — デバッグアダプタの正しい基準でもあります)。
P8 —
VOTP_PMIC— 工場プログラミング専用。未接続のままにする必要があります。
すべてのデバッグ信号は 1.8 V 基準 です。この基板上の STM32H747 の I/O リングは +1V8 レールから動作します。接続する前にデバッグアダプタを 1.8 V ロジックに設定してください。
オンボードペリフェラル¶
LED¶
Nicla Vision には単一のユーザー RGB LED があり、machine.LED を通じてソフトウェアで制御できます:
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
基板側面の別個の DL2 CHARGE LED は PMIC の CHGB 出力に直接配線されています。USB / ESLOV / VIN から Li‑Po バッテリーが充電されている間に点灯し、ユーザーが制御することはできません。
カメラセンサー¶
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 ドライバはセンサーから比例的に小さな読み出しウィンドウをクロップします。デフォルトでは、読み出しから出力へのダウンスケール比はフレームレートを維持するために 3 倍に制限されています。csi.IOCTL_SET_FOV_WIDE はその上限を 5 倍に引き上げます。これは、小さい解像度でストリーミングする際にドライバがセンサーのより広い領域から取り込むことを意味します。その結果、いくらかのスループットを犠牲にして、小さなフレームサイズで明らかに広い視野が得られます:
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 を停止するとシステム全体の再起動が強制されます。
マイク¶
オンボードの MP34DT06JTR PDM マイクは、STM32 の DFSDM ペリフェラルを介して audio --- オーディオモジュール を通じてキャプチャされます。各バッファは符号付き 16 ビット PCM の bytearray として届き、DSP 用に 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
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 と競合しません。
Time‑of‑flight 距離センサー¶
オンボードの ST VL53L1CB time‑of‑flight 距離センサーは内部 PMIC I²C バス (I²C 2) 上にあります。フリーズされた vl53l1x --- VL53L1X ToF 距離センサードライバ ドライバを使用して最大約 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)
バッテリー残量計¶
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 は符号付き 2 の補数です。充電中は正、放電中は負になります。TTE は電流が負のときのみ意味を持ち、TTF は電流が正のときのみ意味を持ちます。
電源管理 IC¶
NXP MC34PF1550A0EP PMIC は、Nicla Vision のすべてのレギュレータを処理します。+3V3 メインレール、+1V8 SoC コア / I/O レール、レベルシフタへの VDDIO_EXT、および Li‑Po 充電器です。これは I²C 2 上のアドレス 0x08 にあります。
警告
PMIC レジスタの読み取りは問題ありませんが、書き込みは危険です。 バックレギュレータや充電器の設定を誤ると、基板、バッテリー、またはその両方が恒久的に損傷する可能性があります。何をしているのか正確に分かっている場合を除き、PMIC は読み取り専用として扱ってください。
残量計では分からない PMIC が教えてくれる最も有用な情報は 充電器のステートマシン です。基板が現在 USB / ESLOV / VIN のどれで動作しているか、Li‑Po が充電サイクルのどの段階にあるか、そして充電器がサーマルフォルトやウォッチドッグフォルトの状態にあるかどうかです。充電器レジスタは PF1550 のメイン I²C アドレス空間のオフセット 0x80 にあります(PF1550 データシート の §22.2 を参照)。したがって、例えば充電器アドレス 0x04 の CHG_INT_OK は 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(OVLO / UVLO / DPM を含むマルチビットの VBUS 状態)、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 も公開します。asyncio フレンドリーな BLE には aioble --- 非同期 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 V 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 とも書かれていますが、このファームウェアではこれらのピンは machine.UART ではなく LPUART1 に配線されています。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")
J2 の SCL/SDA パッドと ESLOV コネクタの SCL_EXT/SDA_EXT ピンは同じ I²C 1 バスに接続されています。ESLOV のピン配置については上記の ESLOV コネクタ を参照してください。
同じハードウェアは、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 は、A0、A1、A2 に 3 つの 12 ビット ADC チャンネルを公開しています。3 つすべてが 1.8 V 基準 です。read_u16 はピンでの 0–1.8 V の範囲にわたって 0–65535 を返します:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
警告
Nicla Vision の ADC 入力は 1.8 V 基準 です(そして SoC の前段にレベルシフタはありません)。3.3 V の信号を入力するとコンバータが飽和し、ピンが損傷する可能性があります。より高い電圧は外部で分圧してください。
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のみにあります。
タイマーチャンネルごとに 1 つのコンシューマを選択してください。SPI の 4 本セットのピン(SCLK/CIPO/COPI/CS)は、machine.SPI(4) がそれらを使用している間は PWM 駆動もできません。
ソフトウェアビットバンギングバス¶
追加のバスが必要な場合、machine.SoftI2C と machine.SoftSPI は任意の GPIO で動作します。
サーマルセンサー(オフボード)¶
ファームウェアには、外部配線されたサーマルイメージャ用の fir --- 熱センサードライバー(fir == 遠赤外線) ドライバが含まれています:
MLX90621 — 16 × 4 IR アレイ
MLX90640 — 32 × 24 IR アレイ
MLX90641 — 16 × 12 IR アレイ
AMG8833 — 8 × 8 IR アレイ
モジュールを基板の 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 は、ハードウェアタイマーのスロットを消費せずに周期的またはワンショットのコールバックをスケジュールします。仮想(ソフトウェア)タイマーを使用するには、id として -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"))
周期の値はミリ秒単位です。スロットを停止して解放するには 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 標準の ダブルタップリセット を使用します。リセットボタンを素早く 2 回押すと、基板が USB 経由で DFU デバイスとして再列挙され、OpenMV IDE が新しいファームウェアイメージを書き込めるようになります。
実行中のスクリプトは、machine.bootloader() を呼び出すことで、オンデマンドでブートローダに再突入できます:
import machine
machine.bootloader()
ファイルシステムとブート順序¶
Nicla Vision のファームウェアは、ブート時に最大 2 つのファイルシステムをマウントします:
内蔵フラッシュ — 常に
/flashにマウントされます。デフォルトでmain.pyとREADME.txtを保持し、最初のブート時に作成されます。ROMFS — 読み取り専用のメモリマップトファイルシステムで、起動時に MicroPython によって
/romに自動的にマウントされます。
マウント後、作業ディレクトリは /flash に設定されます。インタプリタはその後、そのディレクトリからスクリプトを実行します:
boot.pyは すべての ソフトリセット時(コールドブート、REPL からのCtrl‑D、または実行中のスクリプトが戻ったときなど)に実行されます。main.pyは コールドブート時のみ、boot.pyの直後に実行されます。その後のソフトリセットではboot.pyが再実行されますが、そのまま REPL に移行します。main.pyを再実行するには基板を完全にリセットする必要があります。
新しく書き込まれた基板に付属するデフォルトの main.py は、ユーザー RGB LED の 青 チャンネルをハートビートとして点滅させるだけです(短いパルス 2 回、短い間隔)。これにより、ホストを接続しなくてもファームウェアが正常にブートしたことが分かります。
sys.path は両方のファイルシステムとそれぞれの lib/ サブディレクトリを含むように拡張されるため、インポート可能なモジュールは /flash/lib または /rom/lib に配置できます。
USB 経由で接続すると、/flash はホスト上で USB マスストレージドライブとしても列挙され、boot.py、main.py、その他のファイルを直接編集できます。カメラをリセットする前にドライブを取り出して ホストがキャッシュされた書き込みをフラッシュするようにしてください。
注釈
OS はドライブをパッシブなブロックデバイスとして扱うため、カメラ上で実行されるコードによって作成または変更されたファイルは、ホストがドライブを再マウントするまで表示されません。OS とカメラの両方が同じファイルシステムに同時に書き込むと、OS が優先され、カメラによる変更を上書きします。スクリプトが書き戻すデータには SD カードを使用し、ホストからそれらのファイルを読み取る前に再マウントしてください。
注釈
ホストが USB マスストレージドライブから読み取りまたは書き込みを行っている間、ユーザー RGB LED の 赤 チャンネルが短時間点灯することがあります。これはファームウェア駆動のアクティビティインジケータであり、障害ではありません。
ストレージサイズ¶
Nicla Vision には以下が付属します:
/flash— 11 MB の FAT ファイルシステム、読み書き可能。/rom— 4 MB の読み取り専用メモリマップト ROMFS で、ゼロコピーの mmap アクセスの恩恵を受けるスクリプトや ML モデルを出荷するために使用されます。
ハードフォルトインジケータ¶
ユーザー RGB LED がすべての色を高速に循環している場合 — 個別の色相というより きらめく白い LED のように見えるほど速い場合 — ファームウェアは回復不能なハードフォルトに陥っています。回復するにはファームウェアを再書き込みしてください。再書き込みしても改善しない場合、基板が物理的に損傷している可能性があります。
ソフトウェアライブラリ¶
モジュールの完全なリスト(Nicla Vision ビルドに固有のものを含む)については、ライブラリインデックス を参照してください。