OpenMV Pure Thermal

OpenMV Pure Thermal は、STMicroelectronics STM32H743(Cortex‑M7 @ 480 MHz)を中核に構築された統合型サーマルイメージングボードです。64 MB の外部 SDRAM、32 MB の QSPI フラッシュ、ハードウェア JPEG コーデック、4.3 インチ 800×480 IPS 静電容量式タッチスクリーン、HDMI 出力、FLIR® Lepton® サーマルソケット、そして 5MP の OV5640 可視光カメラを搭載しています。さらに Wi‑Fi、microSD ソケット、レーザー距離計、ブザー、高出力ホワイト照明も内蔵しています。

OpenMV Pure Thermal

完全なデータシート、写真、寸法については OpenMV Pure Thermal 製品ページ を参照してください。

主な特長

  • STMicroelectronics STM32H743XI Cortex‑M7、480 MHz 動作。

  • ハードウェア JPEG エンコーダー/デコーダー

  • 64 MB 外部 SDRAM(約 400 MB/s)に加え 1 MB 内蔵 SRAM

  • 2 MB 内蔵フラッシュ + 32 MB 外部 QSPI フラッシュ(読み出し約 50 MB/s)。

  • OV5640 5MP ローリングシャッター可視光センサー。

  • FLIR® Lepton® ソケット — ラジオメトリック/非ラジオメトリックを問わず、任意の Lepton 1/2/2.5/3/3.5 モジュールに対応し、ピクセルごとに摂氏での温度を取得できます。

  • 4.3 インチ 800×480 IPS 静電容量式タッチスクリーン(24 ビットカラー @ 60 Hz)で、最大 5 点までのジェスチャーをサポート。

  • TFP410 DVI シリアライザーによる HDMI 出力 — 最大 1280×720 @ 60 Hz。

  • WINC1500 による Wi‑Fi。RTSP 上の MJPEG を標準でサポート。

  • フルスピード USB‑C(12 Mb/s、900 mA 電流制限) — ホストには VCP + USB マスストレージとして認識され、充電も行います。

  • microSD ソケット — SD は最大 2 GB、SDHC は最大 32 GB、SDXC は最大 2 TB に対応。

  • VL53L1CX レーザー距離計(最大約 4 m)。

  • ソフトウェアで音量/周波数を制御できる ブザー

  • ユーザー RGB ステータス LED に加え、高出力ホワイト LED 照明

  • 500 mA での USB 充電に対応した LiPo バッテリーコネクタ

  • 10 本の I/O ピン。5 V トレラントで 3.3 V 出力、ピンあたり 25 mA(合計 120 mA)、割り込み対応。P6 は ADC または DAC モードで使用する場合 5 V トレラントでは ありません

  • ST‑LINK / J‑Link デバッグ用の ARM 10 ピン SWD コネクタ。

  • I²C ペリフェラル用の Qwiic コネクタ。

注釈

ボードの左下端には、オプションの ¼"–20 三脚ナット 用のスロットがあります。工場出荷時には取り付けられていません — 標準的なカメラ三脚にボードを取り付けたい場合は、スロットにはんだ付けしてください。

ピン配置

OpenMV Pure Thermal のピン配置

ピンリファレンス

ピン名

機能

P0

UART1 RX / SPI2 MOSI

P1

UART1 TX / SPI2 MISO

P2

SPI2 SCK / FDCAN2 TX

P3

SPI2 NSS (CS) / FDCAN2 RX

P4

I2C2 SCL / UART3 TX / TIM2 CH3

P5

I2C2 SDA / UART3 RX / TIM2 CH4

P6

ADC / DAC / TIM2 CH1

P7

I2C4 SCL / TIM4 CH1

P8

I2C4 SDA / TIM4 CH2

P9

デジタル I/O

RESET

GND に引き下げてボードをリセット

SYN

フレーム同期パッド — 未接続

VIN

シールド VIN パッド — 未接続

BOOT0

電源投入時に 3.3 V に引き上げると DFU / ROM ブートローダーに入る

BUZZER

オンボード圧電ブザー(TIM2/PWM 駆動)

LED_RED

RGB ステータス LED の赤チャンネル(アクティブロー)

LED_GREEN

RGB ステータス LED の緑チャンネル(アクティブロー)

LED_BLUE

RGB ステータス LED の青チャンネル(アクティブロー)

LED_WHITE

高出力ホワイト照明 LED

注釈

シールド/ヘッダー上の SYN および VIN パッドは、Pure Thermal では 電気的に接続されていません — ヘッダーの互換性のためだけに存在します。代わりに USB‑C またはオンボードの LiPo バッテリーコネクタを通じてボードに給電してください(下記の 電源ピン を参照)。なお、VIN パッドはボード上では VBAT とシルク印刷されています(ラベルの誤り) — この位置は標準的な OpenMV ヘッダーの VIN ピンであり、いずれにせよ接続されていません。

電源ピン

  • 3.3V — レギュレートされた 3.3 V 電源レール。シールド向けに最大 250 mA を供給可能。

  • GND — 共通グランド。

Pure Thermal は USB‑C またはオンボードの LiPo バッテリーコネクタ を通じて給電されます。USB‑C ポートは合計 900 mA に電流制限 されており、500 mA での LiPo 充電も行うため、USB と並行してバッテリーを接続することもサポートされています。

オンボードの 電源ボタン はシステム電源レールのオン/オフを切り替えるもので、ボードが USB または LiPo のいずれから給電されている場合でも動作します。状態を切り替えるには ボタンを数秒間長押し してください — 誤ったシャットダウンを防ぐため、短く押すだけでは無視されます。

電源の選択は次の 2 つの単純なルールに従います。

  • バッテリーは、その電圧が 3 V を超えている場合にのみボードに給電します。このしきい値を下回ると、オンボードの PMIC は過放電からバッテリーを保護するために切り離します。

  • USB が接続されている場合は USB がボードに給電 し、接続されている LiPo はバックグラウンドで充電されます。

LiPo コネクタには 逆電圧保護 も備わっているため、バッテリーを逆向きに接続してもボードは破損しません。

注釈

ボードは バッテリー電圧バッテリー電流センス 信号を MCU の ADC チャンネルにも配線していますが、いずれもファームウェアのサポートはまだ追加されていません。

リカバリーとデバッグピン

  • RESET — GND に引き下げてボードをリセットします。Pure Thermal にはボード上に同じ働きをする専用の RESET ボタン もあります。

  • BOOT0 — ボードに給電しながら 3.3 V に引き上げると、STM32 の ROM ブートローダー(DFU モード)に入ります。OpenMV IDE はこのモードを使ってオンボードのブートローダーを再書き込みします。ボード上の専用 BOOT0 ボタン も同じ働きをします — 電源を投入しながら押し続けてください。

ボードは GPIO ヘッダーの隣に SWD デバッグヘッダー(RST / SWCLK / SWDIO / SWO)を備えており、ST‑LINK や SEGGER J‑Link アダプターと互換性があります。別途 ARM 10 ピン SWD コネクタも取り付けられています — これは同じ SWD 信号(フル JTAG ではありません)を、標準的な 0.05 インチ 10 ピンのフォームファクタで提供します。

注釈

SWO トレースピンはオンボードの FLIR® Lepton® の SPI クロックと共有されています。SWO は Lepton と同時には使用できません — どちらか一方を選んでください。

ボードには 3 つ目の PURE Modules Debug コネクタも取り付けられています。これはコンパニオンモジュールを接続するためのデバッグ向け信号群(SWCLK、SWDIO、RST、SPI2_MISO、SPI2_MOSI、VBUS、3.3 V、GND、および 2 本の GPIO ピン)を引き出しています。このコネクタの 2 本の GPIO ピンは、ハードウェアペリフェラルではなく内部の ビットバング I²C バス によって駆動されます。

3 つのデバッグコネクタ(インライン SWD ヘッダー、ARM 10 ピン SWD コネクタ、PURE Modules Debug コネクタ)はすべて 3.3 V を基準にしています — 接続前にデバッグアダプターが 3.3 V ロジック用に設定されていることを確認してください。

オンボードペリフェラル

LED

Pure Thermal にはボード上に 3 つの LED があります。

  • ユーザー RGB LED — ソフトウェアで制御可能で、LED_REDLED_GREENLED_BLUE として公開されています:

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • ホワイト照明LED_WHITE を通じて駆動されます。LED_WHITE はハードウェア上で アクティブハイ で配線されていますが、ファームウェアは他のすべてのオンボード LED をアクティブローとして扱うため、on() / off()(意味が反転してしまいます)ではなく low() / high() を使用してください:

    from machine import LED
    
    light = LED("LED_WHITE")
    light.low()    # turn the white LED ON
    light.high()   # turn the white LED OFF
    
  • 充電 LED — オンボードの電源管理ハードウェアによって直接駆動され、ソフトウェアによる制御はできません。システム電源レールのオン/オフにかかわらず(つまり電源ボタンがどちらの位置にあっても)動作します。

    意味

    充電中 — エラッタを参照: 充電完了時に消灯しないことがあります

    充電完了 — エラッタを参照: 確実にトリガーされないことがあります

    バッテリー残量低下(≤ 3.2 V、充電中でない場合のみ)

ブザー

オンボードの圧電ブザーはタイマーチャンネルに配線されています — ソフトウェアで周波数(音程)とデューティサイクル(音量)を制御したトーンを鳴らすには、machine.PWM で駆動してください:

import time
from machine import Pin, PWM

beep = PWM(Pin("BUZZER"), freq=2_000, duty_u16=32768)   # ~50% duty
time.sleep_ms(500)                                      # sound for 0.5 s
beep.deinit()

カメラセンサー

OV5640 は Pure Thermal のメイン CSI です — 明示的に指定するには cid=csi.OV5640 を渡してください:

import csi

cam = csi.CSI(cid=csi.OV5640)
cam.reset(hard=True)
cam.pixformat(csi.RGB565)
cam.framesize(csi.WVGA)
cam.snapshot(time=2000)       # let auto‑exposure settle

while True:
    img = cam.snapshot()

OV5640 にはオンボードの JPEG コンプレッサーが搭載されています。csi.CSI.pixformatcsi.JPEG に設定すると、センサーは圧縮済みフレームをカメラバス経由でそのままカメラに送るため、高解像度のキャプチャが実用的になります。csi.HD(1280×720)、csi.FHD(1920×1080)、フル 5MP の csi.WQXGA2(2592×1944)はいずれも JPEG としてストリーミングされます。圧縮は csi.CSI.quality(0〜100、値が大きいほどフレームが大きくなり、より詳細になります)で調整してください:

cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)

OV5640 にはボイスコイルアクチュエーター式オートフォーカスレンズが搭載されています。csi.IOCTL_TRIGGER_AUTO_FOCUS を指定して csi.CSI.ioctl を呼び出すと、1 回分のオートフォーカスがトリガーされます — センサーはフォーカスモーターを 1 回スイープし、目の前にあるものにピントを合わせます:

cam.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)

シーンが変わるたびに ioctl を再発行してください — オートフォーカスは連続ではなくワンショットです。

注釈

OV5640 の STROBE 出力(同期フラッシュ/IR 照明に使用)は Pure Thermal では MCU に配線されていますが、ファームウェアのサポートはまだ追加されていません。

サーマルカメラセンサー

FLIR® Lepton® ソケットは、同じ csi --- カメラセンサー API 上で 2 つ目の CSI として現れます。指定するには cid=csi.LEPTON を渡し、ハードウェアリセットをスキップしてください:

import csi

lepton = csi.CSI(cid=csi.LEPTON)
lepton.reset(hard=False)
lepton.pixformat(csi.GRAYSCALE)
lepton.framesize(csi.QVGA)

while True:
    img = lepton.snapshot()

注釈

Lepton の VSYNC 出力(サーマルフレームごとに 1 パルス)は Pure Thermal では MCU に配線されていますが、ファームウェアのサポートはまだ追加されていません。

両方の CSI を並行して動作させることができます。以下の例では、OV5640 からカラーフレームを、Lepton からサーマルフレームを取得し、Ironbow パレットと、低強度で透明にフェードするアルファマスクを使って、Lepton をカラーフレームの上にオーバーレイしています:

import csi
import image
import math

alpha_pal = image.Image(256, 1, image.GRAYSCALE)
for i in range(256):
    alpha_pal[i] = int(math.pow((i / 255), 2) * 255)

csi0 = csi.CSI()
csi0.reset(hard=True)
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.WVGA)

csi1 = csi.CSI(cid=csi.LEPTON)
csi1.reset(hard=False)
csi1.pixformat(csi.GRAYSCALE)
csi1.framesize(csi.QVGA)

img1 = image.Image(csi1.width(), csi1.height(), csi1.pixformat())

while True:
    img0 = csi0.snapshot()
    csi1.snapshot(blocking=False, image=img1)
    img0.draw_image(
        img1, 0, 0,
        color_palette=image.PALETTE_IRONBOW,
        alpha_palette=alpha_pal,
        hint=image.BILINEAR,
    )

機械学習

ml --- 機械学習CMSIS‑NN カーネルを用いて量子化済み TFLite モデルを Cortex‑M7 上で実行します — コンパクトな検出器を毎秒数フレームで動かせる程度に高速です。読み取り専用の /rom ファイルシステム上のモデルは、RAM にコピーすることなくフラッシュから直接ロードされます。以下は、可視光カメラからの各フレームに検出した顔とその 6 つのランドマークをオーバーレイする 128×128 BlazeFace 検出器の例です:

import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace

# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))

# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)

clock = time.clock()
while True:
    clock.tick()
    img = csi0.snapshot()

    # faces is a list of ((x, y, w, h), score, keypoints) tuples
    for r, score, keypoints in model.predict([img]):
        ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)

        # keypoints is a ndarray of shape (6, 2)
        # 0 - right eye (x, y)
        # 1 - left eye (x, y)
        # 2 - nose (x, y)
        # 3 - mouth (x, y)
        # 4 - right ear (x, y)
        # 5 - left ear (x, y)
        ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))

    print(clock.fps(), "fps")

レーザー距離計

オンボードの ST VL53L1CX Time‑of‑Flight 距離計は I²C バス 2 に配線されています。最大約 4 m までの距離測定値を取得するには、フリーズ済みの vl53l1x --- VL53L1X ToF 距離センサードライバ ドライバを使用してください:

import time
from machine import I2C
import vl53l1x

bus = I2C(2)
tof = vl53l1x.VL53L1X(bus)

while True:
    print("Distance:", tof.read(), "mm")
    time.sleep_ms(100)

LCD 出力

4.3 インチのオンボード LCD は 800 × 480(WVGA)で、display --- ディスプレイドライバ モジュールの RGB ディスプレイインターフェースを通じて駆動されます — ネイティブ解像度に合わせるには framesize=display.FWVGA を渡してください:

import display

lcd = display.RGBDisplay(framesize=display.FWVGA, refresh=60)
lcd.backlight(True)           # turn the LCD backlight on
lcd.write(img)

バックライトは GPIO に配線されているため、backlight()True / False(または任意の 0〜100 の値。0 はオフ、0 以外はすべてオン)を受け付けます:

lcd.backlight(False)           # turn the backlight off
lcd.backlight(True)            # back on

タッチスクリーン

静電容量式タッチコントローラーは FT5X06 です。マルチタッチの位置やジェスチャーイベントは ft5x06 --- タッチスクリーンドライバー を通じて公開されます。コールバックを登録してタッチに反応し、その中でアクティブなポイントを読み取ってください:

import ft5x06

touch = ft5x06.FT5X06()

def on_touch(n):
    for i in range(n):
        x = touch.get_point_x(i)
        y = touch.get_point_y(i)
        print("touch", i, "at", x, y)

    gesture = touch.get_gesture()
    if gesture != ft5x06.GESTURE_NONE:
        print("gesture:", gesture)

touch.touch_callback(on_touch)

HDMI 出力

ファームウェアは LCD フレームバッファをオンボードの tfp410 --- DVI/HDMI コントローラ HDMI シリアライザーにも分配するため、外部モニターは LCD の表示内容をミラーリングします。HDMI 出力を有効にするには tfp410.TFP410 をインスタンス化してください:

import tfp410

hdmi = tfp410.TFP410()

HDMI 出力のみが必要でオンボード LCD は不要な場合は、バックライトをオフにしてフレームバッファ解像度を WVGA 以上に引き上げてください。TFP410 は最大 1280×720 @ 60 Hz をサポートするので、たとえば次のようにします:

lcd = display.RGBDisplay(framesize=display.HD, refresh=60)
lcd.backlight(False)         # the on‑board LCD can't render HD
hdmi = tfp410.TFP410()

オンボードパネルは 800×480 に固定されているため、WVGA を超える設定は外部 HDMI モニターでのみ意味を持ちます。

HDMI モニターが接続または取り外されたことを検知するには、TFP410 にホットプラグコールバックを登録してください。コールバックは接続時に True、切断時に False で発火します:

def on_hotplug(connected):
    print("HDMI", "connected" if connected else "disconnected")

hdmi.hotplug_callback(on_hotplug)

接続状態は isconnected() を使っていつでもポーリングすることもできます(コールバックが登録されていない場合のみ)。

HDMI ポートは DDC(ディスプレイデータ)および CEC(家電制御)チャンネルも搬送し、これらは class DisplayData -- ディスプレイデータ クラスを通じて公開されます。接続されたモニターの EDID ブロックを読み取って(そのネイティブ解像度/リフレッシュレートに合わせられるように)したり、同じ線上の他の HDMI デバイスを制御するための CEC フレームを送受信したりするのに使用してください:

from display import DisplayData

dd = DisplayData(cec=True, ddc=True)

edid = dd.display_id()        # EDID bytes from the monitor
print(len(edid), "byte EDID")

# Send a CEC "image view on" command (opcode 0x04) from address 1 to address 0
dd.send_frame(0, 1, b"\x04")

# ...or wait for an incoming CEC frame addressed to us (logical address 1)
src, data = dd.receive_frame(1, timeout=5_000)
print("CEC from", src, ":", data)

Wi‑Fi

Wi‑Fi は Microchip WINC1500 モジュール上で動作し、class WINC -- WiFi シールドドライバ インターフェースを通じて公開されます:

import network, time

wlan = network.WINC()
wlan.connect("ssid", "password")
while not wlan.isconnected():
    time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])

注釈

部品不足のため、一部の Pure Thermal ユニットは WINC1500 モジュールが実装されないまま出荷されましたnetwork.WINC がエラーを発生させたり、接続できない場合は、ボードに Wi‑Fi モジュールが欠けていないか確認してください — カメラの他の部分は、それがなくてもまったく同じように動作します。

microSD カード

カードが挿入されると /sdcard に自動的にマウントされ、通常のファイルシステムを通じて使用できます:

import os

for entry in os.listdir("/sdcard"):
    print(entry)

バスリファレンス

GPIO

シルク印刷された任意のピンを読み取ったり駆動したりするには machine.Pin を使用してください。出力は 3.3 V CMOS で、入力側は 5 V トレラント であり、ピンあたり最大 25 mA(ヘッダー全体で合計 120 mA)をシンク/ソースできます。

from machine import Pin

out = Pin("P0", Pin.OUT)
out.on()
out.off()
out.value(1)

inp = Pin("P1", Pin.IN, Pin.PULL_UP)
print(inp.value())

任意の入力ピンは、エッジ遷移で割り込みを発生させることもできます:

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

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

UART

バス

TX

RX

UART1

P1

P0

UART3

P4

P5

from machine import UART

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

I²C

バス

SCL

SDA

I2C2

P4

P5

I2C4

P7

P8

from machine import I2C

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

同じハードウェアは、machine.I2CTarget を通じてターゲット(スレーブ)モードで使用し、別の I²C コントローラーにメモリ領域を公開することもできます:

from machine import I2CTarget

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

オンボードの Qwiic コネクタは、これらの I²C バスの 1 つをプラグアンドプレイモジュール用に引き出しています。Qwiic ラインはオープンドレイントランジスタを通じて 5 V にレベルシフトされているため、バスは 標準モード(100 kHz)ファストモード(400 kHz) のみに制限されます — Qwiic ヘッダーでファストモードプラスやそれ以上のレートを動かそうとしないでください。

Qwiic コネクタは、接続されたモジュールに給電するために 5 V を 出力 します。これを使って Pure Thermal 本体に給電することはできません — 代わりに USB‑C または LiPo バッテリーコネクタを通じてボードに給電してください。

SPI

バス

MOSI

MISO

SCK

CS

SPI2

P0

P1

P2

P3

from machine import SPI
from machine import Pin

spi = SPI(2, baudrate=10_000_000)
cs = Pin("P3", Pin.OUT, value=1)   # CS is not driven by the SPI peripheral

cs.value(0)
spi.write(b"hello")
cs.value(1)

CAN (FDCAN)

バス

TX

RX

FDCAN2

P2

P3

from machine import CAN

can = CAN(2, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())

ADC と DAC

P6 は唯一のユーザーアナログピンです。12 ビット ADC 入力または DAC 出力のいずれかとして使用できます。

  • ADC — ピンで 3.3 V のときフルスケール:

    from machine import ADC
    import time
    
    adc = ADC("P6")
    while True:
        voltage = adc.read_u16() * 3.3 / 65535
        print(voltage)
        time.sleep_ms(100)
    
  • DACpyb.DAC を通じて使用します。8 ビット値は 0〜3.3 V をカバーします:

    from pyb import DAC
    
    dac = DAC("P6")
    voltage = 1.65
    dac.write(int(voltage / 3.3 * 255))
    

ADC または DAC モードでは、P6 は 3.3 V トレラントのみです — 5 V を供給しないでください

PWM

ピン

タイマー / チャンネル

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM2 CH1

P7

TIM4 CH1

P8

TIM4 CH2

注釈

TIM1 はファームウェアによって予約 されており、カメラセンサーのピクセルクロックを生成するために使われます。そのため、物理的に P0/P1/P2 上にある TIM1 チャンネルは、カメラを壊さずにユーザー PWM として使うことはできません。

TIM4 は pyb.Servo と共有 されています — サーボをインスタンス化するとタイマー全体が 50 Hz 動作に再構成されるため、同じスクリプト内で P7/P8 上の machine.PWMpyb.Servo を混在させないでください。

いずれも machine.PWM を通じて駆動してください:

from machine import Pin, PWM

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

ソフトウェアビットバングバス

追加のバスが必要な場合、machine.SoftI2Cmachine.SoftSPI は任意の GPIO 上で動作します。

サーマルセンサー(オフボード)

オンボードの FLIR Lepton に加えて、ファームウェアには外部配線された I²C サーマルイメージャー用の 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 2 経由でのみ通信します — モジュールを P4(SCL)と P5(SDA)に配線してください。

タイミング

time

import time

time.sleep(1)
time.sleep_ms(500)
time.sleep_us(10)

start = time.ticks_ms()
elapsed = time.ticks_diff(time.ticks_ms(), start)

仮想タイマー

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() を呼び出してください。

リアルタイムクロック

from machine import RTC

rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0))
print(rtc.datetime())

LiPo バッテリーが接続されている場合、RTC はシステム電源レールがオフのとき(オンボードの電源ボタンで電源を切ったとき)でも時刻を保持します。USB のみを接続している状態では、電源ボタンを押すと RTC への電源も切れてしまうため、バッテリーを接続せずに電源を入れ直すと実時刻は保持されません。

ウォッチドッグ

from machine import WDT

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

ブートおよびランタイム情報

USB ブートローダーウィンドウ

電源投入のたびに、カメラは短いブートローダー(数秒間)を実行します。これにより、ユーザーが DFU モードに入ることなく OpenMV IDE がファームウェアを更新できます。このウィンドウが終了すると、ブートローダーは制御を boot.py に、続いて main.py に引き渡します。

実行中のスクリプトは、machine.bootloader() を呼び出すことで、オンデマンドでブートローダーに再び入ることができます。

ファイルシステムとブート順序

Pure Thermal のファームウェアは、起動時に最大 3 つのファイルシステムをマウントします:

  • 内蔵フラッシュ — 常に /flash にマウントされます。デフォルトでは main.pyREADME.txt を保持し、初回起動時に作成されます。

  • microSD カード — カードが挿入されている場合、/sdcard にマウントされます。

  • ROMFS/rom にある読み取り専用のメモリマップ型ファイルシステムで、ゼロコピーアクセスの恩恵を受ける大容量データアセット(AI モデルなど)を配布するために使用されます。ユーザー Python が実行される前に、起動時に MicroPython によって自動的にマウントされます。

マウント後、カードが存在する場合は作業ディレクトリが /sdcard に、それ以外の場合は /flash に設定されます。インタープリタは次に、そのディレクトリからスクリプトを実行します:

  • boot.pyすべての ソフトリセット時に実行されます。

  • main.pyコールドブート時のみboot.py の直後に実行されます。

SD カードに boot.py または main.py を置くと、フラッシュ内のコピーには手を加えずにそれを上書きします。

USB 経由で接続されると、ブートファイルシステム(カードがある場合は /sdcard、それ以外は /flash)もホスト上で USB マスストレージドライブとして列挙されます。カメラをリセットする前にドライブを取り出して ホストがキャッシュした書き込みをフラッシュできるようにしてください。

注釈

OpenMV Cam 上で実行されているコードによって作成または変更されたファイルは、ドライブを再マウントするまでホスト上に表示されません。スクリプトが書き戻すデータには SD カードを使用し、ホストからそれらのファイルを読む前に再マウントしてください。

ストレージサイズ

Pure Thermal には次のものが付属します:

  • /flash24 MB の FAT ファイルシステム、読み書き可能。

  • /rom8 MB の読み取り専用メモリマップ型 ROMFS。ゼロコピー mmap アクセスの恩恵を受けるスクリプトや ML モデルを配布するために使用されます。

  • /sdcard — 挿入された microSD カードの全容量(存在する場合)、読み書き可能。

ハードフォールトインジケーター

ユーザー RGB LED がすべての色を高速で循環している場合 — 個別の色合いというよりは きらめくホワイト LED のように見えるほど速い場合 — ファームウェアが回復不能なハードフォールトに陥っています。回復するにはファームウェアを再書き込みしてください。

ハードウェアエラッタ

ボードレベルの細かな注意点がいくつか Pure Thermal ハードウェアエラッタ に記載されています。把握しておくべき主な項目は次のとおりです:

  • バッテリーコネクタの干渉 — PCB 上の部品が LiPo バッテリーコネクタの真下に位置しており、バッテリーケーブルのプラグから突き出たくさび部分がケーブルを抜く際にそれらに引っかかり、ボードから部品を引き剥がしてしまうことがあります。初回使用前に、ニッパーでケーブルプラグのくさびを切り落としてください。

  • ボードの電源オフ中に RTC が停止する — 32 kHz クリスタル(Y2)の負荷容量が高すぎます。C96 と C97(STM32 の隣でクリスタルを挟む 1 対)を取り外すと、RTC はバックアップ電源で動作し続けます。ほとんどのボードはこれらのコンデンサがすでに取り外された状態で出荷されています。プラグを抜くと RTC が時刻を失う場合は、それらの位置を確認してください。詳しいスレッドについては GitHub の issue #1536#1600 を参照してください。

  • 充電インジケーター LED が青のままになる — 充電器は、インジケーターを青(充電中)から緑(充電完了)に切り替えることなく、4.15 V から 4.19 V の間のどこかで充電サイクルを終了することがあります。この場合でもバッテリーは完全に充電されています。LED ではなく電圧測定を信頼してください。

  • シルク印刷が VIN を VBAT と誤表記 — 標準的な OpenMV ヘッダーの VIN 位置にあるパッドは、Pure Thermal では VBAT とシルク印刷されています。ラベルは誤りですが、このパッドはいずれにせよ 電気的に接続されていない ため、実用上は問題ありません。

ソフトウェアライブラリ

モジュールの完全な一覧(Pure Thermal ビルド固有のものを含む)については ライブラリインデックス を参照してください。