OpenMV Pure Thermal

OpenMV Pure Thermal on täysjärjestelmäinen lämpökuvauskortti, joka on rakennettu STMicroelectronics STM32H743 -piirin (Cortex‑M7 @ 480 MHz) ympärille ja jossa on 64 MB ulkoista SDRAM-muistia, 32 MB QSPI flash-muistia, laitteistopohjainen JPEG-koodekki, 4,3” 800×480 IPS kapasitiivinen kosketusnäyttö, HDMI-lähtö, FLIR® Lepton® -lämpökamerakanta sekä 5MP OV5640 näkyvän valon kamera. Lisäksi siinä on Wi‑Fi, microSD-kortinlukija, laser-etäisyysmittari, summeri ja tehokas valkoinen valaisin.

OpenMV Pure Thermal

Täydellinen datalehti, valokuvat ja mitat löytyvät OpenMV Pure Thermal -tuotesivulta.

Kohokohdat

  • STMicroelectronics STM32H743XI Cortex‑M7 480 MHz.

  • Laitteistopohjainen JPEG-enkooderi/dekooderi.

  • 64 MB ulkoista SDRAM-muistia (~400 MB/s) ja 1 MB sisäistä SRAM-muistia.

  • 2 MB sisäistä flash-muistia + 32 MB ulkoista QSPI flash-muistia (~50 MB/s luku).

  • OV5640 5MP rolling‑shutter näkyvän valon sensori.

  • FLIR® Lepton® -kanta — hyväksyy minkä tahansa Lepton 1/2/2.5/3/3.5 -moduulin, radiometrisen tai ei-radiometrisen, pikselikohtaisella lämpötilalla celsiusasteina.

  • 4,3” 800×480 IPS kapasitiivinen kosketusnäyttö (24‑bittinen väri @ 60 Hz), jopa 5‑pisteen eletuella.

  • HDMI-lähtö TFP410 DVI-sarjamuuntimen kautta — jopa 1280×720 @ 60 Hz.

  • Wi‑Fi WINC1500:n kautta; MJPEG RTSP:n yli tuettu suoraan laatikosta.

  • Full‑speed USB‑C (12 Mb/s, 900 mA virtarajoitettu) — näkyy isäntäkoneelle VCP:nä + USB-massamuistina ja hoitaa myös lataamisen.

  • microSD-kortinlukija — SD jopa 2 GB, SDHC jopa 32 GB, SDXC jopa 2 TB.

  • VL53L1CX laser-etäisyysmittari (jopa ~4 m).

  • Summeri ohjelmistopohjaisesti säädettävällä äänenvoimakkuudella / taajuudella.

  • Tehokas valkoinen LED-valaisin käyttäjän RGB-tilan LEDin lisäksi.

  • LiPo-akkuliitin USB-latauksella 500 mA -teholla.

  • 10 I/O-nastaa, 5 V kestävät 3,3 V lähdöllä, 25 mA per nasta (120 mA yhteensä), keskeytyskykyiset. P6 ei kestä 5 V ADC- tai DAC-tilassa käytettäessä.

  • ARM 10‑nastainen SWD -liitin ST‑LINK / J‑Link -virheenkorjaukseen.

  • Qwiic-liitin I²C-oheislaitteille.

Muista

Kortin vasemmassa alareunassa on aukko valinnaiselle ¼”–20 jalustamutterille. Sitä ei ole asennettu tehtaalla — juota yksi aukkoon, jos haluat kiinnittää kortin tavalliseen kamerajalustaan.

Nastakartta

OpenMV Pure Thermal -nastakartta

Nastaviite

Nastan nimi

Toiminto

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

digitaalinen I/O

RESET

vedä GND:hen nollataksesi kortin

SYN

kehyssynkronointinasta — ei kytketty

VIN

shield VIN -nasta — ei kytketty

BOOT0

vedä 3,3 V:iin käynnistyksen yhteydessä DFU / ROM-käynnistyslatainta varten

BUZZER

kortilla oleva pietsosummeri (TIM2/PWM-ohjattu)

LED_RED

RGB-tilan LEDin punainen kanava (aktiivinen matala)

LED_GREEN

RGB-tilan LEDin vihreä kanava (aktiivinen matala)

LED_BLUE

RGB-tilan LEDin sininen kanava (aktiivinen matala)

LED_WHITE

tehokas valkoinen valaisin-LED

Muista

Shieldin/header-liittimen SYN- ja VIN-nastoilla ei ole sähköistä kytkentää Pure Thermalissa — ne ovat olemassa vain header-yhteensopivuuden vuoksi. Syötä virtaa kortille sen sijaan USB‑C:n tai kortilla olevan LiPo-akkuliittimen kautta (katso Virtanastat alla). Huomaa myös, että VIN-nasta on merkitty silkkipainatuksella VBAT kortille (merkintävirhe) — kyseessä on tavallisen OpenMV-headerin VIN-nastan paikka, eikä sitä ole kytketty kummassakaan tapauksessa.

Virtanastat

  • 3.3V — säädelty 3,3 V kisko. Jopa 250 mA käytettävissä shieldeille.

  • GND — yhteinen maa.

Pure Thermalille syötetään virtaa USB‑C:n tai kortilla olevan LiPo-akkuliittimen kautta. USB‑C-portti on virtarajoitettu 900 mA:iin yhteensä ja hoitaa myös LiPo-lataamisen 500 mA -teholla, joten akun liittäminen USB:n rinnalle on tuettu.

Kortilla oleva virtapainike kytkee järjestelmäkiskot päälle ja pois, ja se toimii riippumatta siitä, syötetäänkö kortille virtaa USB:stä vai LiPosta. Pidä painiketta painettuna pari sekuntia vaihtaaksesi tilaa — nopea näpäytys jätetään huomiotta tahattoman sammutuksen estämiseksi.

Virtalähteen valinta noudattaa kahta yksinkertaista sääntöä:

  • Akku syöttää virtaa kortille vain, kun sen jännite on yli 3 V. Tämän kynnyksen alapuolella kortilla oleva PMIC kytkee akun irti suojatakseen sitä ylipurkautumiselta.

  • Kun USB on kytkettynä, USB syöttää virtaa kortille ja mahdollinen liitetty LiPo latautuu taustalla.

LiPo-liittimessä on myös käänteisjännitesuoja, joten akun liittäminen väärinpäin ei vahingoita korttia.

Muista

Kortti ohjaa myös akun jännitteen ja akun virranmittaussignaalin takaisin MCU:n ADC-kanaville, mutta laiteohjelmistotukea kummallekaan ei ole vielä lisätty.

Palautus- ja virheenkorjausnastat

  • RESET — vedä GND:hen nollataksesi kortin. Pure Thermalissa on myös oma RESET-painike kortilla, joka tekee saman asian.

  • BOOT0 — vedä 3,3 V:iin kortille virtaa syötettäessä siirtyäksesi STM32 ROM-käynnistyslataimeen (DFU-tila). OpenMV IDE käyttää tätä tilaa kortilla olevan käynnistyslataimen uudelleenohjelmointiin. Kortilla oleva oma BOOT0-painike tekee saman asian — pidä sitä painettuna virtaa kytkettäessä.

Kortilla on SWD-virheenkorjausheader (RST / SWCLK / SWDIO / SWO) GPIO-headerin vieressä, yhteensopiva ST‑LINK- ja SEGGER J‑Link -sovittimien kanssa. Lisäksi on asennettu erillinen ARM 10‑nastainen SWD -liitin — se kuljettaa samoja SWD-signaaleja (ei täyttä JTAG:ia) mutta standardissa 0,05” 10‑nastaisessa muotoilussa.

Muista

SWO-jäljitysnasta on jaettu kortilla olevan FLIR® Lepton®:n SPI-kellon kanssa. SWO:ta ei voi käyttää samaan aikaan Leptonin kanssa — valitse jompikumpi.

Kortille on asennettu kolmas PURE Modules Debug -liitin. Se haaroittaa kourallisen virheenkorjaussuuntautuneita signaaleja (SWCLK, SWDIO, RST, SPI2_MISO, SPI2_MOSI, VBUS, 3,3 V, GND sekä kaksi GPIO-nastaa) lisämoduulien kytkemistä varten. Tämän liittimen kahta GPIO-nastaa ohjaa sisäinen bit‑banged I²C-väylä laitteistopohjaisen oheislaitteen sijaan.

Kaikki kolme virheenkorjausliitintä (linjassa oleva SWD-header, ARM 10‑nastainen SWD-liitin ja PURE Modules Debug -liitin) viittaavat 3,3 V:iin — varmista, että virheenkorjaussovittimesi on määritetty 3,3 V logiikalle ennen kytkemistä.

Kortilla olevat oheislaitteet

LEDit

Pure Thermalissa on kolme LEDiä kortilla:

  • Käyttäjän RGB-LED — ohjelmistopohjaisesti ohjattava, esitelty muodossa LED_RED, LED_GREEN ja LED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • Valkoinen valaisin — ohjataan LED_WHITE:n kautta. LED_WHITE on kytketty laitteistossa aktiivisena korkeana, kun taas laiteohjelmisto käsittelee kaikkia muita kortilla olevia LEDejä aktiivisina matalina, joten käytä low() / high() mieluummin kuin on() / off() (jotka kääntäisivät merkityksen):

    from machine import LED
    
    light = LED("LED_WHITE")
    light.low()    # turn the white LED ON
    light.high()   # turn the white LED OFF
    
  • Lataus-LED — ohjataan suoraan kortilla olevalla virranhallintalaitteistolla, ei ohjelmisto-ohjausta. Se toimii riippumatta siitä, ovatko järjestelmäkiskot päällä vai pois (eli virtapainikkeen ollessa kummassa tahansa asennossa).

    Väri

    Merkitys

    Sininen

    lataa — katso errata: ei välttämättä sammu, kun lataus on valmis

    Vihreä

    lataus valmis — katso errata: ei välttämättä laukea luotettavasti

    Punainen

    akku vähissä (≤ 3,2 V, vain kun ei aktiivisesti ladata)

Summeri

Kortilla oleva pietsosummeri on kytketty ajastinkanavaan — ohjaa sitä machine.PWM:llä äänille, joiden taajuus (sävelkorkeus) ja pulssisuhde (äänenvoimakkuus) ovat ohjelmistopohjaisesti säädettävissä:

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

Kamerasensori

OV5640 on Pure Thermalin ensisijainen CSI — välitä cid=csi.OV5640 osoittaaksesi sen eksplisiittisesti:

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:ssä on kortilla oleva JPEG-pakkain. Aseta csi.CSI.pixformat arvoon csi.JPEG, niin sensori toimittaa pakatut kehykset suoraan kameralle kameraväylän yli, mikä tekee korkearesoluutioisista kaappauksista käytännöllisiä: csi.HD (1280×720), csi.FHD (1920×1080) ja täysi 5MP csi.WQXGA2 (2592×1944) kaikki striimaavat JPEG-muodossa. Säädä pakkausta arvolla csi.CSI.quality (0-100, korkeampi = suurempia kehyksiä, enemmän yksityiskohtia):

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

OV5640:ssä on äänikäämitoimilaitteella varustettu autofokus-linssi. Käynnistä yksittäinen autofokus-ajo csi.CSI.ioctl:n kautta arvolla csi.IOCTL_TRIGGER_AUTO_FOCUS — sensori pyyhkäisee tarkennusmoottoria kerran ja lukittuu siihen, mitä edessä onkin:

cam.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)

Anna ioctl uudelleen aina kun näkymä muuttuu — autofokus on kertaluonteinen, ei jatkuva.

Muista

OV5640:n STROBE-lähtö (käytetään synkronoituun salamaan / IR-valaistukseen) on kytketty MCU:hun Pure Thermalissa, mutta laiteohjelmistotukea sille ei ole vielä lisätty.

Lämpökamerasensori

FLIR® Lepton® -kanta näkyy toisena CSI:nä samassa csi — kennot -rajapinnassa. Välitä cid=csi.LEPTON osoittaaksesi sen, ja ohita laitteiston nollaus:

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

Muista

Leptonin VSYNC-lähtö (yksi pulssi per lämpökehys) on kytketty MCU:hun Pure Thermalissa, mutta laiteohjelmistotukea sille ei ole vielä lisätty.

Molemmat CSI:t voivat toimia rinnakkain. Alla oleva esimerkki noutaa värikehyksen OV5640:stä ja lämpökehyksen Leptonista, ja sitten asettaa Leptonin värikehyksen päälle käyttäen Ironbow-palettia ja alfamaskia, joka häipyy läpinäkyväksi matalalla intensiteetillä:

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

Koneoppiminen

ml — Koneoppiminen ajaa kvantisoituja TFLite-malleja Cortex‑M7:lla CMSIS‑NN-ytimillä — riittävän nopeasti kompakteille tunnistimille muutamalla kehyksellä sekunnissa. Vain luku -tilaisessa /rom-tiedostojärjestelmässä olevat mallit latautuvat suoraan flash-muistista kopioimatta RAM-muistiin. Tässä on 128×128 BlazeFace-tunnistin, joka asettaa tunnistetut kasvot ja niiden kuusi maamerkkiä jokaisen näkyvän valon kameran kehyksen päälle:

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

Laser-etäisyysmittari

Kortilla oleva ST VL53L1CX lentoajan etäisyysmittari on kytketty I²C-väylään 2. Käytä jäädytettyä vl53l1x — VL53L1X ToF-etäisyyssensorin ajuri -ajuria etäisyyslukemien saamiseksi jopa ~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)

LCD-lähtö

Kortilla oleva 4,3” LCD on 800 × 480 (WVGA) ja sitä ohjataan display — näyttöajuri -moduulin RGB-näyttörajapinnan kautta — välitä framesize=display.FWVGA vastaamaan sen natiiviresoluutiota:

import display

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

Taustavalo on kytketty GPIO:hon, joten backlight() hyväksyy True / False (tai minkä tahansa 0–100 arvon, jossa 0 on pois ja mikä tahansa nollasta poikkeava on päällä):

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

Kosketusnäyttö

Kapasitiivinen kosketusohjain on FT5X06; monikosketuksen sijainnit ja eletapahtumat esitellään ft5x06 — kosketusnäytön ajuri:n kautta. Rekisteröi takaisinkutsu reagoidaksesi kosketuksiin ja lue aktiiviset pisteet sen sisällä:

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-lähtö

Laiteohjelmisto haaroittaa myös LCD:n kehyspuskurin kortilla olevaan tfp410 — DVI/HDMI-ohjain HDMI-sarjamuuntimeen, joten ulkoinen näyttö peilaa sen, mitä LCD:llä on. Instantioi tfp410.TFP410 ottaaksesi HDMI-lähdön käyttöön:

import tfp410

hdmi = tfp410.TFP410()

Jos haluat vain HDMI-lähdön etkä välitä kortilla olevasta LCD:stä, sammuta taustavalo ja nosta kehyspuskurin resoluutio WVGA:n yläpuolelle. TFP410 tukee jopa 1280×720 @ 60 Hz, joten esimerkiksi:

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

Kortilla oleva paneeli on kiinteä 800×480, joten kaikki WVGA:n yläpuolella on merkityksellistä vain ulkoisessa HDMI-näytössä.

Tietääksesi milloin HDMI-näyttö on kytketty tai irrotettu, rekisteröi hot‑plug-takaisinkutsu TFP410:lle. Takaisinkutsu laukeaa arvolla True kytkettäessä ja False irrotettaessa:

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

hdmi.hotplug_callback(on_hotplug)

Voit myös kysellä kytkentätilaa milloin tahansa isconnected():lla (vain kun takaisinkutsua ei ole rekisteröity).

HDMI-portti kuljettaa myös DDC (näyttödata)- ja CEC (kuluttajaelektroniikan ohjaus) -kanavia, jotka esitellään luokka DisplayData – näyttödata -luokan kautta. Käytä sitä liitetyn näytön EDID-lohkon lukemiseen (jotta voit mukautua sen natiiviresoluutioon / virkistystaajuuteen) tai CEC-kehysten lähettämiseen/vastaanottamiseen muiden samassa johdossa olevien HDMI-laitteiden ohjaamiseksi:

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 toimii Microchip WINC1500 -moduulin yli, joka esitellään class WINC – WiFi-lisäkortin ajuri -rajapinnan kautta:

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

Muista

Osapulan vuoksi jotkin Pure Thermal -yksiköt toimitettiin ilman asennettua WINC1500-moduulia. Jos network.WINC nostaa virheen tai ei koskaan yhdistä, tarkista kortilta puuttuva Wi‑Fi-moduuli — kameran loppuosa toimii täsmälleen samalla tavalla ilman sitä.

microSD-kortti

Kun kortti asetetaan, se liitetään automaattisesti kohtaan /sdcard ja on käytettävissä tavallisen tiedostojärjestelmän kautta:

import os

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

Väyläviite

GPIO

Käytä machine.Pin:ä lukeaksesi tai ohjataksesi mitä tahansa silkkipainettua nastaa. Lähdöt ovat 3,3 V CMOS, 5 V kestäviä sisääntulopuolella ja voivat upottaa/syöttää jopa 25 mA per nasta (120 mA yhteensä koko headerin yli).

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

Mikä tahansa sisääntulonasta voi myös laukaista keskeytyksen reunasiirtymissä:

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

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

UART

Väylä

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

Väylä

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

Samaa laitteistoa voidaan käyttää myös kohde (slave) -tilassa machine.I2CTarget:n kautta muistialueen esittelemiseksi toiselle I²C-ohjaimelle:

from machine import I2CTarget

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

Kortilla oleva Qwiic-liitin haaroittaa yhden näistä I²C-väylistä plug-and-play-moduuleille. Qwiic-linja on tasonsiirretty 5 V:iin avoimen kollektorin transistoreilla, joten väylä on rajoitettu vain standarditilaan (100 kHz) ja nopeaan tilaan (400 kHz) — älä yritä ajaa fast-mode-plus- tai korkeampia nopeuksia Qwiic-headerin läpi.

Qwiic-liitin antaa ulos 5 V kytkettyjen moduulien syöttämiseksi; sitä ei voi käyttää itse Pure Thermalin syöttämiseen — syötä virtaa kortille sen sijaan USB‑C:n tai LiPo-akkuliittimen kautta.

SPI

Väylä

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)

Väylä

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 ja DAC

P6 on ainoa käyttäjän analoginen nasta. Sitä voidaan käyttää joko 12‑bittisenä ADC-sisääntulona tai DAC-lähtönä.

  • ADC — täysi asteikko 3,3 V:ssa nastassa:

    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:n kautta. 8‑bittinen arvo kattaa 0–3,3 V:

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

ADC- tai DAC-tilassa P6 kestää vain 3,3 V — älä syötä siihen 5 V.

PWM

Nasta

Ajastin / kanava

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM2 CH1

P7

TIM4 CH1

P8

TIM4 CH2

Muista

TIM1 on varattu laiteohjelmiston toimesta kamerasensorin pikselikellon generointiin, joten TIM1-kanavia, jotka ovat fyysisesti nastoissa P0/P1/P2, ei voi käyttää käyttäjän PWM:ään kameraa rikkomatta.

TIM4 on jaettu pyb.Servo:n kanssa — servon instantiointi konfiguroi koko ajastimen uudelleen 50 Hz toimintaan, joten älä sekoita machine.PWM:ää nastoissa P7/P8 ja pyb.Servo:a samassa skriptissä.

Ohjaa mitä tahansa niistä machine.PWM:n kautta:

from machine import Pin, PWM

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

Ohjelmistopohjaiset bit‑banged-väylät

machine.SoftI2C ja machine.SoftSPI toimivat millä tahansa GPIO:lla, jos tarvitset ylimääräisen väylän.

Lämpösensori (kortin ulkopuolinen)

Kortilla olevan FLIR Leptonin lisäksi laiteohjelmisto sisältää myös fir — lämpösensorin ajuri (fir == far infrared) -ajurin ulkoisesti kytketyille I²C-lämpökuvaimille:

  • MLX90621 — 16 × 4 IR-matriisi

  • MLX90640 — 32 × 24 IR-matriisi

  • MLX90641 — 16 × 12 IR-matriisi

  • AMG8833 — 8 × 8 IR-matriisi

Kytke moduuli kortin I²C-väylään ja lue kehyksiä komennoilla 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-ajuri kommunikoi sensorin kanssa vain I²C 2:n yli — kytke moduuli nastoihin P4 (SCL) ja P5 (SDA).

Ajoitus

aika

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)

Virtuaaliajastimet

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

Jaksoarvot ovat millisekunteina. Kutsu deinit() pysäyttääksesi ja vapauttaaksesi paikan.

Reaaliaikakello

from machine import RTC

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

Jos LiPo-akku on kytketty, RTC pitää aikaa myös järjestelmäkiskojen ollessa pois päältä (sammutettuna kortilla olevalla virtapainikkeella). Pelkkä USB kytkettynä virtapainikkeen painaminen katkaisee virran myös RTC:ltä — joten seinäkelloaika ei säily virtasyklin yli ilman kytkettyä akkua.

Vahtikoira

from machine import WDT

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

Käynnistys- ja ajonaikaiset tiedot

USB-käynnistyslataimen ikkuna

Joka käynnistyksessä kamera ajaa lyhyen käynnistyslataimen (muutaman sekunnin), joka antaa OpenMV IDE:n päivittää laiteohjelmiston ilman, että käyttäjän tarvitsee siirtyä DFU-tilaan. Ikkunan päätyttyä käynnistyslatain luovuttaa ohjauksen tiedostolle boot.py ja sitten main.py.

Ajossa oleva skripti voi palata käynnistyslataimeen pyynnöstä kutsumalla machine.bootloader().

Tiedostojärjestelmä ja käynnistysjärjestys

Pure Thermalin laiteohjelmisto liittää käynnistyksessä jopa kolme tiedostojärjestelmää:

  • Sisäinen flash-muisti — aina liitetty kohtaan /flash. Sisältää oletuksena main.py:n ja README.txt:n; luodaan aivan ensimmäisellä käynnistyksellä.

  • microSD-kortti — jos kortti on asetettu, se liitetään kohtaan /sdcard.

  • ROMFS — vain luku -tilainen, muistiin mapattu tiedostojärjestelmä kohdassa /rom, jota käytetään suurten data-aineistojen (esim. AI-mallien) toimittamiseen, jotka hyötyvät zero-copy-pääsystä. MicroPython liittää sen automaattisesti käynnistyksen yhteydessä, ennen kuin mikään käyttäjän Python ajetaan.

Liittämisen jälkeen työhakemistoksi asetetaan /sdcard, kun kortti on läsnä, muuten /flash. Tulkki ajaa sitten skriptejä kyseisestä hakemistosta:

  • boot.py suoritetaan jokaisen pehmeän nollauksen yhteydessä.

  • main.py suoritetaan vain kylmäkäynnistyksessä, heti boot.py:n jälkeen.

boot.py:n tai main.py:n pudottaminen SD-kortille ohittaa flash-muistissa olevan kopion koskematta siihen.

Kun yhdistettynä USB:n yli, käynnistystiedostojärjestelmä (/sdcard jos kortti on läsnä, muuten /flash) luetteloituu myös USB-massamuistiasemana isäntäkoneella. Poista asema turvallisesti ennen kameran nollaamista, jotta isäntä huuhtelee välimuistissa olevat kirjoitukset.

Muista

OpenMV Camilla ajettavan koodin luomat tai muokkaamat tiedostot eivät näy isäntäkoneella ennen kuin asema on liitetty uudelleen. Käytä SD-korttia kaikkeen dataan, jota skripti kirjoittaa takaisin, ja liitä uudelleen ennen kuin luet noita tiedostoja isäntäkoneelta.

Tallennustilan koot

Pure Thermal toimitetaan seuraavilla:

  • /flash24 MB FAT-tiedostojärjestelmä, luku/kirjoitus.

  • /rom8 MB vain luku -tilainen muistiin mapattu ROMFS, jota käytetään skriptien ja ML-mallien toimittamiseen, jotka hyötyvät zero-copy-mmap-pääsystä.

  • /sdcard — asetetun microSD-kortin täysi koko (kun läsnä), luku/kirjoitus.

Vakavan virheen ilmaisin

Jos käyttäjän RGB-LED kiertää nopeasti kaikkien värien läpi — riittävän nopeasti, että se yleensä näyttää tuikkivalta valkoiselta LEDiltä erillisten sävyjen sijaan — laiteohjelmisto on osunut palautumattomaan vakavaan virheeseen. Ohjelmoi laiteohjelmisto uudelleen palautuaksesi.

Laitteiston errata

Kourallinen kortintasoisia erikoisuuksia on dokumentoitu Pure Thermal -laitteiston eratassa. Keskeiset huomioitavat kohdat:

  • Akkuliittimen häiriö — PCB:llä olevat komponentit sijaitsevat suoraan LiPo-akkuliittimen alla, ja akkukaapelin pistokkeen ulkoneva kiila voi tarttua niihin kaapelia irrotettaessa, joskus repien osia irti kortilta. Leikkaa kiila pois kaapelin pistokkeesta sivuleikkureilla ennen ensimmäistä käyttöä.

  • RTC pysähtyy kortin ollessa sammutettuna — 32 kHz kiteen (Y2) kuormituskapasitanssi on liian korkea. C96:n ja C97:n (kiteen kummallakin puolella STM32:n vieressä oleva pari) poistaminen antaa RTC:n jatkaa toimintaa varavirralla. Useimmat kortit toimitetaan näiden kondensaattoreiden jo poistettuina; jos RTC:si menettää ajan irrotettaessa, tarkista nuo paikat. Katso GitHub-asiat #1536 ja #1600 koko keskustelu varten.

  • Latauksen ilmaisin-LED pysyy sinisenä — laturi saattaa lopettaa latausjaksonsa missä tahansa 4,15 V:n ja 4,19 V:n välillä kääntämättä ilmaisinta sinisestä (lataa) vihreäksi (ladattu). Akku on tässä tapauksessa silti täysin ladattu; luota jännitemittaukseen, ei LEDiin.

  • Silkkipainatus merkitsee VIN:n väärin VBAT:ksi — tavallisen OpenMV-headerin VIN-paikassa oleva nasta on merkitty silkkipainatuksella VBAT Pure Thermalissa. Merkintä on väärä, mutta sillä ei ole käytännössä väliä, koska nastalla ei ole sähköistä kytkentää kummassakaan tapauksessa.

Ohjelmistokirjastot

Katso kirjastohakemisto täydellistä moduulilistaa varten — mukaan lukien ne, jotka ovat ainutlaatuisia Pure Thermal -koonnokselle.