OpenMV Pure Thermal

OpenMV Pure Thermal este o placă completă pentru imagistică termică construită în jurul cipului STMicroelectronics STM32H743 (Cortex‑M7 @ 480 MHz), cu 64 MB de SDRAM extern, 32 MB de memorie flash QSPI, un codec JPEG hardware, un ecran tactil capacitiv IPS de 4,3” cu rezoluția 800×480, o ieșire HDMI, un soclu termic FLIR® Lepton® și o cameră de lumină vizibilă OV5640 de 5MP. De asemenea, integrează Wi‑Fi, un soclu microSD, un telemetru laser, un buzzer și un iluminator alb de putere mare.

OpenMV Pure Thermal

Pentru fișa tehnică completă, fotografii și dimensiuni, consultați pagina de produs OpenMV Pure Thermal.

Caracteristici principale

  • STMicroelectronics STM32H743XI Cortex‑M7 la 480 MHz.

  • Encoder/decoder JPEG hardware.

  • 64 MB de SDRAM extern (~400 MB/s) plus 1 MB de SRAM intern.

  • 2 MB de memorie flash internă + 32 MB de memorie flash QSPI externă (citire ~50 MB/s).

  • Senzor de lumină vizibilă OV5640 de 5MP cu rolling‑shutter.

  • Soclu FLIR® Lepton® — acceptă orice modul Lepton 1/2/2.5/3/3.5, radiometric sau non‑radiometric, cu temperatura per pixel în grade Celsius.

  • Ecran tactil capacitiv IPS de 4,3” cu rezoluția 800×480 (culoare pe 24 de biți @ 60 Hz) cu suport pentru gesturi cu până la 5 puncte.

  • Ieșire HDMI prin serializatorul DVI TFP410 — până la 1280×720 @ 60 Hz.

  • Wi‑Fi prin WINC1500; MJPEG peste RTSP suportat din fabrică.

  • USB‑C full‑speed (12 Mb/s, limitat la 900 mA) — apare ca VCP + dispozitiv de stocare în masă USB pentru gazdă și gestionează și încărcarea.

  • Soclu microSD — SD până la 2 GB, SDHC până la 32 GB, SDXC până la 2 TB.

  • Telemetru laser VL53L1CX (până la ~4 m).

  • Buzzer cu volum / frecvență controlate prin software.

  • LED iluminator alb de putere mare pe lângă LED‑ul RGB de stare al utilizatorului.

  • Conector pentru baterie LiPo cu încărcare prin USB la 500 mA.

  • 10 pini I/O, tolerând 5 V cu ieșire de 3,3 V, 25 mA per pin (120 mA în total), capabili de întreruperi. P6 nu tolerează 5 V când este folosit în modul ADC sau DAC.

  • Conector ARM SWD cu 10 pini pentru depanare ST‑LINK / J‑Link.

  • Conector Qwiic pentru periferice I²C.

Notă

Placa are un slot pe marginea sa din stânga‑jos pentru o piuliță de trepied opțională ¼”–20. Nu este montată din fabrică — lipiți una în slot dacă doriți să montați placa pe un trepied standard de cameră.

Configurația pinilor

Configurația pinilor OpenMV Pure Thermal

Referință pini

Numele pinului

Funcție

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 digital

RESET

trageți la GND pentru a reseta placa

SYN

pad de sincronizare a cadrelor (frame‑sync) — neconectat

VIN

pad VIN al shield‑ului — neconectat

BOOT0

trageți la 3,3 V la pornire pentru bootloaderul DFU / ROM

BUZZER

buzzer piezo de pe placă (acționat de TIM2/PWM)

LED_RED

canalul roșu al LED‑ului RGB de stare (activ pe nivel jos)

LED_GREEN

canalul verde al LED‑ului RGB de stare (activ pe nivel jos)

LED_BLUE

canalul albastru al LED‑ului RGB de stare (activ pe nivel jos)

LED_WHITE

LED iluminator alb de putere mare

Notă

Pad‑urile SYN și VIN de pe shield/header nu au nicio conexiune electrică pe Pure Thermal — sunt prezente doar pentru compatibilitate cu header‑ul. Alimentați placa prin USB‑C sau prin conectorul de baterie LiPo de pe placă (vezi Pini de alimentare mai jos). De asemenea, rețineți că pad‑ul VIN este serigrafiat VBAT pe placă (o greșeală de etichetare) — poziția este pinul VIN standard al header‑ului OpenMV și nu este conectat în niciun caz.

Pini de alimentare

  • 3.3V — magistrala reglată de 3,3 V. Până la 250 mA disponibili pentru shield‑uri.

  • GND — masă comună.

Pure Thermal este alimentat prin USB‑C sau prin conectorul de baterie LiPo de pe placă. Portul USB‑C este limitat la 900 mA în total și gestionează și încărcarea LiPo la 500 mA, deci conectarea unei baterii în paralel cu USB este suportată.

Butonul de alimentare de pe placă comută magistralele sistemului între pornit și oprit și funcționează indiferent dacă placa este alimentată de la USB sau de la LiPo. Țineți butonul apăsat câteva secunde pentru a schimba starea — o apăsare scurtă este ignorată pentru a preveni oprirea accidentală.

Selectarea sursei urmează două reguli simple:

  • Bateria alimentează placa doar când tensiunea sa este peste 3 V. Sub acel prag, PMIC‑ul de pe placă deconectează bateria pentru a o proteja împotriva descărcării excesive.

  • Când USB este prezent, USB alimentează placa, iar orice LiPo atașat se încarcă în fundal.

Conectorul LiPo dispune și de protecție la tensiune inversă, astfel încât conectarea bateriei invers nu va deteriora placa.

Notă

Placa direcționează, de asemenea, tensiunea bateriei și un semnal de detectare a curentului bateriei înapoi către canalele ADC ale MCU‑ului, dar suportul firmware pentru oricare dintre acestea nu a fost adăugat încă.

Pini de recuperare și depanare

  • RESET — trageți la GND pentru a reseta placa. Pure Thermal are, de asemenea, un buton RESET dedicat pe placă care face același lucru.

  • BOOT0 — trageți la 3,3 V în timpul alimentării plăcii pentru a intra în bootloaderul ROM al STM32 (modul DFU). OpenMV IDE folosește acest mod pentru a reprograma bootloaderul de pe placă. Un buton BOOT0 dedicat pe placă face același lucru — țineți‑l apăsat în timp ce aplicați alimentarea.

Placa expune un header de depanare SWD (RST / SWCLK / SWDIO / SWO) lângă header‑ul GPIO, compatibil cu adaptoarele ST‑LINK și SEGGER J‑Link. Este montat și un conector separat ARM SWD cu 10 pini — acesta transportă aceleași semnale SWD (fără JTAG complet), dar în formatul standard de 0,05” cu 10 pini.

Notă

Pinul de urmărire SWO este partajat cu ceasul SPI al FLIR® Lepton® de pe placă. SWO nu poate fi folosit în același timp cu Lepton — alegeți unul sau celălalt.

Un al treilea conector PURE Modules Debug este montat pe placă. Acesta scoate la exterior câteva semnale orientate spre depanare (SWCLK, SWDIO, RST, SPI2_MISO, SPI2_MOSI, VBUS, 3,3 V, GND și doi pini GPIO) pentru atașarea modulelor companion. Cei doi pini GPIO de pe acest conector sunt acționați de o magistrală I²C bit‑banged internă, mai degrabă decât de un periferic hardware.

Toate cele trei conectoare de depanare (header‑ul SWD în linie, conectorul ARM SWD cu 10 pini și conectorul PURE Modules Debug) sunt raportate la 3,3 V — asigurați‑vă că adaptorul dvs. de depanare este configurat pentru logică de 3,3 V înainte de conectare.

Periferice de pe placă

LED‑uri

Pure Thermal are trei LED‑uri pe placă:

  • LED RGB de utilizator — controlabil prin software, expus ca LED_RED, LED_GREEN și LED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • Iluminator alb — acționat prin LED_WHITE. LED_WHITE este conectat activ pe nivel înalt în hardware, în timp ce firmware‑ul tratează orice alt LED de pe placă ca activ pe nivel jos, deci folosiți low() / high() în loc de on() / off() (care ar inversa logica):

    from machine import LED
    
    light = LED("LED_WHITE")
    light.low()    # turn the white LED ON
    light.high()   # turn the white LED OFF
    
  • LED de încărcare — acționat direct de hardware‑ul de gestionare a alimentării de pe placă, fără control software. Funcționează indiferent dacă magistralele sistemului sunt pornite sau oprite (adică cu butonul de alimentare în oricare poziție).

    Culoare

    Semnificație

    Albastru

    se încarcă — vezi errata: este posibil să nu se stingă când încărcarea se finalizează

    Verde

    încărcare completă — vezi errata: este posibil să nu se declanșeze fiabil

    Roșu

    baterie scăzută (≤ 3,2 V, doar când nu se încarcă activ)

Buzzer

Buzzer‑ul piezo de pe placă este conectat la un canal de temporizator — acționați‑l cu machine.PWM pentru tonuri cu frecvență (înălțime) și factor de umplere (volum) controlate prin software:

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

Senzor de cameră

OV5640 este CSI‑ul principal de pe Pure Thermal — transmiteți cid=csi.OV5640 pentru a‑l adresa explicit:

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 are un compresor JPEG pe cip. Setați csi.CSI.pixformat la csi.JPEG și senzorul livrează cadre comprimate direct către cameră prin magistrala camerei, ceea ce face practice capturile la rezoluție mare: csi.HD (1280×720), csi.FHD (1920×1080) și întregul csi.WQXGA2 de 5MP (2592×1944) sunt toate transmise ca JPEG. Reglați compresia cu csi.CSI.quality (0-100, mai mare = cadre mai mari, mai multe detalii):

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

OV5640 are o lentilă cu autofocus acționată de o bobină vocală (voice‑coil). Declanșați o singură trecere de autofocus prin csi.CSI.ioctl cu csi.IOCTL_TRIGGER_AUTO_FOCUS — senzorul baleiează motorul de focalizare o dată și se fixează pe orice se află în fața sa:

cam.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)

Reemiteți ioctl‑ul de fiecare dată când scena se schimbă — autofocus‑ul este o singură dată, nu continuu.

Notă

Ieșirea STROBE a OV5640 (folosită pentru bliț / iluminare IR sincronizată) este conectată la MCU pe Pure Thermal, dar suportul firmware pentru aceasta nu a fost adăugat încă.

Senzor de cameră termică

Soclul FLIR® Lepton® apare ca un al doilea CSI pe aceeași API csi — senzori de cameră. Transmiteți cid=csi.LEPTON pentru a‑l adresa și omiteți resetarea hardware:

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

Notă

Ieșirea VSYNC a Lepton (un puls per cadru termic) este conectată la MCU pe Pure Thermal, dar suportul firmware pentru aceasta nu a fost adăugat încă.

Ambele CSI‑uri pot funcționa în paralel. Exemplul de mai jos preia un cadru color de la OV5640 și un cadru termic de la Lepton, apoi suprapune Lepton peste cadrul color folosind o paletă Ironbow și o mască alfa care se estompează spre transparent la intensitate scăzută:

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

Învățare automată

ml — Învățare automată rulează modele TFLite cuantizate pe Cortex‑M7 cu kerneluri CMSIS‑NN — suficient de rapid pentru detectoare compacte la câteva cadre pe secundă. Modelele de pe sistemul de fișiere read‑only /rom se încarcă direct din memoria flash fără copiere în RAM. Iată un detector BlazeFace de 128×128 care suprapune fața detectată și cele șase repere ale sale pe fiecare cadru de la camera de lumină vizibilă:

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

Telemetru laser

Telemetrul time‑of‑flight ST VL53L1CX de pe placă este conectat la magistrala I²C 2. Folosiți driverul înghețat vl53l1x — Driver pentru senzorul de distanță ToF VL53L1X pentru a obține citiri ale distanței până la ~4 m:

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)

Ieșire LCD

Ecranul LCD de 4,3” de pe placă are 800 × 480 (WVGA) și este acționat prin interfața de afișare RGB a modulului display — driver de afișaj — transmiteți framesize=display.FWVGA pentru a se potrivi cu rezoluția sa nativă:

import display

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

Iluminarea de fundal este conectată la un GPIO, deci backlight() acceptă True / False (sau orice valoare 0–100, unde 0 este oprit și orice valoare diferită de zero este pornit):

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

Ecran tactil

Controlerul de atingere capacitivă este FT5X06; pozițiile multi‑touch și evenimentele de gesturi sunt expuse prin ft5x06 — Driver pentru ecran tactil. Înregistrați o funcție de retroapelare (callback) pentru a reacționa la atingeri și citiți punctele active în interiorul ei:

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)

Ieșire HDMI

Firmware‑ul direcționează, de asemenea, framebuffer‑ul LCD către serializatorul HDMI tfp410 — Controler DVI/HDMI de pe placă, astfel încât un monitor extern oglindește ceea ce este pe LCD. Instanțiați tfp410.TFP410 pentru a activa ieșirea HDMI:

import tfp410

hdmi = tfp410.TFP410()

Dacă doriți doar ieșire HDMI și nu vă interesează LCD‑ul de pe placă, opriți iluminarea de fundal și măriți rezoluția framebuffer‑ului peste WVGA. TFP410 suportă până la 1280×720 @ 60 Hz, deci de exemplu:

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

Panoul de pe placă este fixat la 800×480, deci orice valoare peste WVGA are sens doar pe monitorul HDMI extern.

Pentru a ști când un monitor HDMI a fost conectat sau deconectat, înregistrați o funcție de retroapelare hot‑plug pe TFP410. Funcția de retroapelare se declanșează cu True la conectare și False la deconectare:

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

hdmi.hotplug_callback(on_hotplug)

De asemenea, puteți interoga starea conexiunii în orice moment cu isconnected() (doar când nu este înregistrată nicio funcție de retroapelare).

Portul HDMI transportă, de asemenea, canalele DDC (date de afișare) și CEC (consumer electronics control), expuse prin clasa class DisplayData – Date de afișaj. Folosiți‑o pentru a citi blocul EDID al monitorului atașat (astfel încât să vă puteți adapta la rezoluția / rata de reîmprospătare nativă a acestuia) sau pentru a trimite/primi cadre CEC pentru controlarea altor dispozitive HDMI de pe același fir:

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 rulează printr‑un modul Microchip WINC1500, expus prin interfața class WINC – driver pentru shield 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])

Notă

Din cauza lipsei de componente, unele unități Pure Thermal au fost livrate fără modulul WINC1500 montat. Dacă network.WINC generează o eroare sau nu se conectează niciodată, verificați placa pentru un modul Wi‑Fi lipsă — restul camerei funcționează exact la fel și fără el.

Card microSD

Când un card este introdus, acesta este montat automat la /sdcard și poate fi folosit prin sistemul de fișiere obișnuit:

import os

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

Referință magistrale

GPIO

Folosiți machine.Pin pentru a citi sau acționa oricare dintre pinii serigrafiați. Ieșirile sunt CMOS de 3,3 V, tolerante la 5 V pe partea de intrare și pot absorbi/furniza până la 25 mA per pin (120 mA în total pe întregul header).

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

Orice pin de intrare poate, de asemenea, declanșa o întrerupere la tranzițiile de muchie:

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

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

UART

Magistrală

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

Magistrală

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

Același hardware poate fi folosit, de asemenea, în modul target (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(2, addr=0x42, mem=buf)

Conectorul Qwiic de pe placă scoate la exterior una dintre aceste magistrale I²C pentru module plug‑and‑play. Linia Qwiic este nivelată la 5 V prin tranzistoare open‑drain, deci magistrala este limitată doar la modul standard (100 kHz) și modul rapid (400 kHz) — nu încercați să rulați fast‑mode‑plus sau rate mai mari prin header‑ul Qwiic.

Conectorul Qwiic furnizează 5 V pentru alimentarea modulelor atașate; nu poate fi folosit pentru a alimenta Pure Thermal însuși — alimentați placa prin USB‑C sau prin conectorul de baterie LiPo.

SPI

Magistrală

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)

Magistrală

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 și DAC

P6 este singurul pin analogic al utilizatorului. Poate fi folosit fie ca intrare ADC pe 12 biți, fie ca ieșire DAC.

  • ADC — scală completă la 3,3 V la pin:

    from machine import ADC
    import time
    
    adc = ADC("P6")
    while True:
        voltage = adc.read_u16() * 3.3 / 65535
        print(voltage)
        time.sleep_ms(100)
    
  • DAC — prin pyb.DAC. Valoarea pe 8 biți acoperă 0–3,3 V:

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

În modul ADC sau DAC, P6 este tolerant doar la 3,3 V — nu îl alimentați cu 5 V.

PWM

Pin

Temporizator / canal

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM2 CH1

P7

TIM4 CH1

P8

TIM4 CH2

Notă

TIM1 este rezervat de firmware pentru a genera ceasul de pixeli al senzorului de cameră, deci canalele TIM1 care sunt fizic pe P0/P1/P2 nu pot fi folosite pentru PWM de utilizator fără a defecta camera.

TIM4 este partajat cu pyb.Servo — instanțierea unui servo reconfigurează întregul temporizator pentru funcționare la 50 Hz, deci nu amestecați machine.PWM pe P7/P8 cu pyb.Servo în același script.

Acționați oricare dintre acestea prin machine.PWM

from machine import Pin, PWM

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

Magistrale bit‑banged prin software

machine.SoftI2C și machine.SoftSPI funcționează pe orice GPIO dacă aveți nevoie de o magistrală suplimentară.

Senzor termic (extern plăcii)

Pe lângă FLIR Lepton de pe placă, firmware‑ul include, de asemenea, driverul fir — driver pentru senzori termici (fir == far infrared) pentru camere termice I²C conectate 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 cadrele 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 2 — conectați modulul la P4 (SCL) și P5 (SDA).

Temporizare

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)

Temporizatoare virtuale

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

from machine import RTC

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

Dacă o baterie LiPo este conectată, RTC‑ul ține evidența timpului chiar și în timp ce magistralele sistemului sunt oprite (alimentarea fiind întreruptă prin butonul de alimentare de pe placă). Cu doar USB conectat, apăsarea butonului de alimentare întrerupe și alimentarea RTC‑ului — deci ora reală nu va supraviețui unui ciclu de alimentare fără o baterie atașată.

Watchdog

from machine import WDT

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

Informații despre pornire și execuție

Fereastra bootloaderului USB

La fiecare pornire, camera rulează un scurt bootloader (câteva secunde) care permite OpenMV IDE să actualizeze firmware‑ul fără ca utilizatorul să fie nevoit să intre în modul DFU. După expirarea ferestrei, bootloaderul predă controlul către boot.py și apoi main.py.

Un script în execuție poate reintra în bootloader la cerere apelând machine.bootloader().

Sistemul de fișiere și ordinea de pornire

Firmware‑ul Pure Thermal montează până la trei sisteme de fișiere la pornire:

  • Memoria flash internă — întotdeauna montată la /flash. Conține implicit main.py și README.txt; creată la prima pornire.

  • Card microSD — dacă un card este introdus, acesta este montat la /sdcard.

  • ROMFS — sistem de fișiere read‑only, mapat în memorie, la /rom, folosit pentru a livra resurse mari de date (de ex. modele AI) care beneficiază de acces zero‑copy. Montat automat de MicroPython la pornire, înainte de a rula orice cod Python al utilizatorului.

După montare, directorul de lucru este setat la /sdcard când cardul este prezent, altfel /flash. Interpretorul rulează apoi scripturile din acel director:

  • boot.py este executat la fiecare resetare soft.

  • main.py este executat doar la pornirea la rece, imediat după boot.py.

Plasarea unui boot.py sau main.py pe cardul SD suprascrie copia din memoria flash fără a o atinge.

Când este conectat prin USB, sistemul de fișiere de pornire (/sdcard dacă un card este prezent, altfel /flash) se enumeră, de asemenea, ca o unitate de stocare în masă USB pe gazdă. Ejectați unitatea înainte de a reseta camera pentru ca gazda să golească scrierile sale din cache.

Notă

Fișierele create sau modificate de codul care rulează pe OpenMV Cam nu vor apărea pe gazdă până când unitatea nu este remontată. Folosiți cardul SD pentru orice date pe care scriptul le scrie înapoi și remontați înainte de a citi acele fișiere de pe gazdă.

Dimensiuni de stocare

Pure Thermal este livrat cu:

  • /flash — sistem de fișiere FAT de 24 MB, citire/scriere.

  • /rom — ROMFS read‑only mapat în memorie de 8 MB, folosit pentru a livra scripturi și modele ML care beneficiază de acces mmap zero‑copy.

  • /sdcard — dimensiunea completă a oricărui card microSD introdus (când este prezent), citire/scriere.

Indicator de eroare gravă (hard‑fault)

Dacă LED‑ul RGB al utilizatorului parcurge rapid toate culorile — suficient de rapid încât tinde să arate ca un LED alb pâlpâind mai degrabă decât nuanțe distincte — firmware‑ul a întâmpinat o eroare gravă (hard fault) nerecuperabilă. Reprogramați firmware‑ul pentru a recupera.

Errata hardware

Câteva particularități la nivel de placă sunt documentate în errata hardware Pure Thermal. Aspecte cheie de care trebuie să fiți conștienți:

  • Interferența conectorului de baterie — componente de pe PCB se află direct sub conectorul de baterie LiPo, iar pana proeminentă de pe mufa cablului bateriei se poate agăța de ele când cablul este scos, uneori smulgând piese de pe placă. Tăiați pana de pe mufa cablului cu un clește de tăiat la ras înainte de prima utilizare.

  • RTC‑ul se oprește în timp ce placa este oprită — capacitanța de sarcină pe cristalul de 32 kHz (Y2) este prea mare. Eliminarea C96 și C97 (perechea care flanchează cristalul lângă STM32) permite RTC‑ului să continue să funcționeze pe alimentarea de rezervă. Majoritatea plăcilor sunt livrate cu acești condensatori deja eliminați; dacă RTC‑ul dvs. pierde ora când este deconectat, verificați acele poziții. Vezi problemele GitHub #1536 și #1600 pentru firul complet.

  • LED‑ul indicator de încărcare rămâne albastru — încărcătorul își poate încheia ciclul de încărcare oriunde între 4,15 V și 4,19 V fără a comuta indicatorul de la albastru (se încarcă) la verde (încărcat). Bateria este totuși complet încărcată în acest caz; aveți încredere într‑o măsurătoare de tensiune, nu în LED.

  • Serigrafia etichetează greșit VIN ca VBAT — pad‑ul din poziția VIN standard a header‑ului OpenMV este serigrafiat VBAT pe Pure Thermal. Eticheta este greșită, dar nu contează în practică deoarece pad‑ul nu are nicio conexiune electrică în niciun caz.

Biblioteci software

Consultați indexul bibliotecii pentru lista completă de module — inclusiv care dintre ele sunt unice pentru versiunea Pure Thermal.