OpenMV Pure Thermal

OpenMV Pure Thermal là bo mạch chụp ảnh nhiệt đầy đủ chức năng, được xây dựng xung quanh vi điều khiển STMicroelectronics STM32H743 (Cortex‑M7 @ 480 MHz) với 64 MB SDRAM ngoài, 32 MB bộ nhớ flash QSPI, bộ mã hóa/giải mã JPEG phần cứng, màn hình cảm ứng điện dung IPS 4.3" 800×480, đầu ra HDMI, đế cắm cảm biến nhiệt FLIR® Lepton®, và camera ánh sáng khả kiến OV5640 5MP. Bo mạch còn tích hợp Wi‑Fi, khe microSD, máy đo khoảng cách laser, còi buzzer và đèn chiếu sáng trắng công suất cao.

OpenMV Pure Thermal

Để xem thông số kỹ thuật đầy đủ, ảnh chụp và kích thước, hãy truy cập trang sản phẩm OpenMV Pure Thermal.

Điểm nổi bật

  • STMicroelectronics STM32H743XI Cortex‑M7 ở 480 MHz.

  • Bộ mã hóa/giải mã JPEG phần cứng.

  • 64 MB SDRAM ngoài (~400 MB/s) cộng với 1 MB SRAM nội bộ.

  • 2 MB bộ nhớ flash nội bộ + 32 MB bộ nhớ flash QSPI ngoài (~50 MB/s đọc).

  • Cảm biến ánh sáng khả kiến màn trập cuộn OV5640 5MP.

  • Đế cắm FLIR® Lepton® — tương thích với mọi module Lepton 1/2/2.5/3/3.5, đo nhiệt độ từng điểm ảnh theo độ Celsius, hỗ trợ cả loại có và không có dữ liệu nhiệt độ.

  • Màn hình cảm ứng điện dung IPS 4.3" 800×480 (màu 24‑bit @ 60 Hz) hỗ trợ tối đa 5 điểm chạm.

  • Đầu ra HDMI qua bộ tuần tự hóa DVI TFP410 — hỗ trợ đến 1280×720 @ 60 Hz.

  • Wi‑Fi qua WINC1500; hỗ trợ MJPEG qua RTSP ngay khi sử dụng.

  • USB‑C tốc độ đầy đủ (12 Mb/s, giới hạn dòng điện 900 mA) — xuất hiện như VCP + USB mass storage trên máy tính, đồng thời hỗ trợ sạc pin.

  • Khe cắm microSD — SD đến 2 GB, SDHC đến 32 GB, SDXC đến 2 TB.

  • Máy đo khoảng cách laser VL53L1CX (đến ~4 m).

  • Còi Buzzer với âm lượng / tần số điều chỉnh bằng phần mềm.

  • Đèn LED chiếu sáng trắng công suất cao ngoài đèn LED trạng thái RGB cho người dùng.

  • Đầu nối pin LiPo với sạc USB ở 500 mA.

  • 10 chân (pin) I/O, chịu được 5 V với điện áp ra 3.3 V, 25 mA mỗi chân (120 mA tổng cộng), hỗ trợ ngắt. P6 không chịu được 5 V khi dùng ở chế độ ADC hoặc DAC.

  • Đầu nối ARM 10‑pin SWD cho việc gỡ lỗi bằng ST‑LINK / J‑Link.

  • Đầu nối Qwiic cho các ngoại vi I²C.

Ghi chú

Bo mạch có một khe ở cạnh dưới bên trái để lắp đai ốc tripod ¼"–20 tùy chọn. Khe này không được lắp sẵn từ nhà máy — hãy hàn một đai ốc vào khe nếu bạn muốn gắn bo mạch lên tripod camera tiêu chuẩn.

Sơ đồ chân

OpenMV Pure Thermal pinout

Bảng tham chiếu chân

Tên chân

Chức năng

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 kỹ thuật số

RESET

kéo xuống GND để khởi động lại bo mạch

SYN

chân đồng bộ khung hình — không kết nối

VIN

chân VIN của shield — không kết nối

BOOT0

kéo lên 3.3 V khi bật nguồn để vào chế độ DFU / ROM bootloader

BUZZER

còi piezo trên bo mạch (điều khiển bằng TIM2/PWM)

LED_RED

kênh đỏ của đèn LED trạng thái RGB (mức thấp kích hoạt)

LED_GREEN

kênh xanh lá của đèn LED trạng thái RGB (mức thấp kích hoạt)

LED_BLUE

kênh xanh dương của đèn LED trạng thái RGB (mức thấp kích hoạt)

LED_WHITE

đèn LED chiếu sáng trắng công suất cao

Ghi chú

Các chân SYNVIN trên shield/header không có kết nối điện trên Pure Thermal — chúng chỉ có mặt để tương thích header. Cấp nguồn cho bo mạch qua USB‑C hoặc đầu nối pin LiPo trên bo (xem Chân nguồn bên dưới). Lưu ý rằng chân VIN được in lụa là VBAT trên bo mạch (lỗi ghi nhãn) — vị trí này là chân VIN tiêu chuẩn của header OpenMV và không có kết nối điện dù bằng cách nào.

Chân nguồn

  • 3.3V — đường điện 3.3 V đã ổn áp. Có thể cung cấp đến 250 mA cho shield.

  • GND — nối đất chung.

Pure Thermal được cấp nguồn qua USB‑C hoặc đầu nối pin LiPo trên bo. Cổng USB‑C được giới hạn dòng điện 900 mA tổng cộng và cũng xử lý việc sạc LiPo ở 500 mA, vì vậy có thể cắm pin cùng lúc với USB.

Nút nguồn trên bo mạch bật/tắt các đường điện của hệ thống và hoạt động cho dù bo mạch đang được cấp nguồn từ USB hay từ LiPo. Giữ nút trong vài giây để chuyển trạng thái — nhấn nhanh sẽ bị bỏ qua để tránh tắt nguồn không cố ý.

Việc chọn nguồn điện tuân theo hai quy tắc đơn giản:

  • Pin chỉ cấp nguồn cho bo khi điện áp pin trên 3 V. Dưới ngưỡng đó, PMIC trên bo ngắt kết nối pin để bảo vệ khỏi xả quá mức.

  • Khi có USB, USB cấp nguồn cho bo mạch và bất kỳ pin LiPo nào được kết nối sẽ sạc ở chế độ nền.

Đầu nối LiPo cũng có bảo vệ điện áp ngược, vì vậy cắm pin ngược sẽ không làm hỏng bo mạch.

Ghi chú

Bo mạch cũng định tuyến tín hiệu điện áp pincảm biến dòng điện pin đến các kênh ADC của MCU, nhưng hỗ trợ firmware cho cả hai tính năng này chưa được thêm vào.

Chân khôi phục và gỡ lỗi

  • RESET — kéo xuống GND để khởi động lại bo mạch. Pure Thermal cũng có một nút RESET chuyên dụng trên bo làm điều tương tự.

  • BOOT0 — kéo lên 3.3 V trong khi bật nguồn cho bo để vào ROM bootloader của STM32 (chế độ DFU). OpenMV IDE sử dụng chế độ này để nạp lại bootloader trên bo. Một nút BOOT0 chuyên dụng trên bo làm điều tương tự — giữ nút trong khi cấp nguồn.

Bo mạch cung cấp header gỡ lỗi SWD (RST / SWCLK / SWDIO / SWO) bên cạnh header GPIO, tương thích với ST‑LINK và bộ chuyển đổi SEGGER J‑Link. Một đầu nối ARM 10‑pin SWD riêng biệt cũng được lắp — nó mang các tín hiệu SWD tương tự (không có JTAG đầy đủ) nhưng ở dạng 10‑pin 0.05" tiêu chuẩn.

Ghi chú

Chân trace SWO được chia sẻ với xung nhịp SPI của FLIR® Lepton® trên bo. SWO không thể sử dụng cùng lúc với Lepton — chọn một trong hai.

Đầu nối PURE Modules Debug thứ ba được lắp trên bo. Nó cung cấp một số tín hiệu hướng gỡ lỗi (SWCLK, SWDIO, RST, SPI2_MISO, SPI2_MOSI, VBUS, 3.3 V, GND và hai chân GPIO) để gắn các module đồng hành. Hai chân GPIO trên đầu nối này được điều khiển bởi một bus I²C bit‑banged nội bộ thay vì ngoại vi phần cứng.

Tất cả ba đầu nối gỡ lỗi (header SWD nội tuyến, đầu nối ARM 10‑pin SWD và đầu nối PURE Modules Debug) đều tham chiếu đến 3.3 V — hãy đảm bảo bộ chuyển đổi gỡ lỗi của bạn được cấu hình cho logic 3.3 V trước khi kết nối.

Ngoại vi trên bo

Đèn LED

Pure Thermal có ba đèn LED trên bo:

  • Đèn LED RGB cho người dùng — điều khiển bằng phần mềm, được cung cấp dưới dạng LED_RED, LED_GREENLED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • Đèn chiếu sáng trắng — điều khiển qua LED_WHITE. LED_WHITE được đấu dây mức cao kích hoạt trong phần cứng trong khi firmware xử lý mọi đèn LED trên bo khác là mức thấp kích hoạt, vì vậy hãy dùng low() / high() thay vì on() / off() (vì chúng sẽ đảo chiều kích hoạt):

    from machine import LED
    
    light = LED("LED_WHITE")
    light.low()    # turn the white LED ON
    light.high()   # turn the white LED OFF
    
  • Đèn LED sạc — được điều khiển trực tiếp bởi phần cứng quản lý nguồn trên bo, không có điều khiển phần mềm. Nó hoạt động cho dù các đường điện hệ thống bật hay tắt (tức là với nút nguồn ở vị trí nào).

    Màu sắc

    Ý nghĩa

    Xanh dương

    đang sạc — xem errata: có thể không tắt khi sạc xong

    Xanh lá

    sạc đầy — xem errata: có thể không kích hoạt đáng tin cậy

    Đỏ

    pin yếu (≤ 3.2 V, chỉ khi không đang sạc tích cực)

Còi Buzzer

Còi piezo trên bo được đấu dây vào một kênh bộ định thời — điều khiển nó bằng machine.PWM để tạo âm thanh với tần số (cao độ) và chu kỳ nhiệm vụ (âm lượng) điều chỉnh bằng phần mềm:

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

Cảm biến camera

OV5640 là CSI chính trên Pure Thermal — truyền cid=csi.OV5640 để định địa chỉ nó một cách tường minh:

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 có bộ nén JPEG tích hợp. Đặt csi.CSI.pixformat thành csi.JPEG và cảm biến gửi trực tiếp các khung hình nén đến cam qua bus camera, giúp việc chụp ảnh độ phân giải cao trở nên thực tế: csi.HD (1280×720), csi.FHD (1920×1080) và 5MP đầy đủ csi.WQXGA2 (2592×1944) đều truyền dưới dạng JPEG. Điều chỉnh nén bằng csi.CSI.quality (0-100, cao hơn = khung hình lớn hơn, chi tiết hơn):

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

OV5640 có ống kính lấy nét tự động dùng cơ cấu cuộn dây. Kích hoạt một lần lấy nét tự động qua csi.CSI.ioctl với csi.IOCTL_TRIGGER_AUTO_FOCUS — cảm biến quét motor lấy nét một lần và khóa vào vật thể trước mặt:

cam.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)

Phát lại ioctl bất cứ khi nào cảnh thay đổi — lấy nét tự động là một lần, không liên tục.

Ghi chú

Đầu ra STROBE của OV5640 (dùng cho đèn flash đồng bộ / chiếu sáng IR) được đấu dây vào MCU trên Pure Thermal, nhưng hỗ trợ firmware cho nó chưa được thêm vào.

Cảm biến camera nhiệt

Đế cắm FLIR® Lepton® xuất hiện như một CSI thứ hai trên cùng API csi --- cảm biến camera. Truyền cid=csi.LEPTON để định địa chỉ nó, và bỏ qua việc khởi động lại phần cứng:

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

Ghi chú

Đầu ra VSYNC của Lepton (một xung mỗi khung hình nhiệt) được đấu dây vào MCU trên Pure Thermal, nhưng hỗ trợ firmware cho nó chưa được thêm vào.

Cả hai CSI đều có thể chạy song song. Ví dụ dưới đây lấy một khung hình màu từ OV5640 và một khung hình nhiệt từ Lepton, sau đó phủ Lepton lên trên khung hình màu bằng bảng màu Ironbow và một mặt nạ alpha mờ dần đến trong suốt ở cường độ thấp:

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

Học máy

ml --- Machine Learning chạy các mô hình TFLite đã lượng hóa trên Cortex‑M7 với nhân CMSIS‑NN — đủ nhanh cho các bộ phát hiện nhỏ gọn ở vài khung hình mỗi giây. Các mô hình trên hệ thống tệp chỉ đọc /rom tải trực tiếp từ bộ nhớ flash mà không cần sao chép vào RAM. Đây là bộ phát hiện BlazeFace 128×128 phủ khuôn mặt được phát hiện và sáu điểm đặc trưng lên mỗi khung hình từ camera ánh sáng khả kiến:

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

Máy đo khoảng cách laser

Bộ đo khoảng cách thời gian bay ST VL53L1CX trên bo được đấu dây vào bus I²C 2. Sử dụng driver đóng băng vl53l1x --- Driver cảm biến đo khoảng cách ToF VL53L1X để lấy số đo khoảng cách đến ~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)

Đầu ra LCD

LCD trên bo 4.3" là 800 × 480 (WVGA) và được điều khiển qua giao diện màn hình RGB của module display --- trình điều khiển màn hình — truyền framesize=display.FWVGA để khớp với độ phân giải gốc của nó:

import display

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

Đèn nền được đấu dây vào GPIO, vì vậy backlight() chấp nhận True / False (hoặc bất kỳ giá trị 0–100 nào, trong đó 0 là tắt và bất kỳ giá trị khác không nào là bật):

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

Màn hình cảm ứng

Bộ điều khiển cảm ứng điện dung là FT5X06; vị trí đa điểm chạm và sự kiện cử chỉ được cung cấp qua ft5x06 --- Trình Điều Khiển Màn Hình Cảm Ứng. Đăng ký hàm gọi lại để phản hồi các lần chạm và đọc các điểm đang kích hoạt bên trong nó:

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)

Đầu ra HDMI

Firmware cũng phát rộng bộ đệm khung hình LCD ra bộ tuần tự hóa HDMI tfp410 --- Bộ điều khiển DVI/HDMI trên bo, vì vậy một màn hình ngoài phản chiếu những gì hiển thị trên LCD. Khởi tạo tfp410.TFP410 để bật đầu ra HDMI:

import tfp410

hdmi = tfp410.TFP410()

Nếu bạn chỉ muốn đầu ra HDMI và không quan tâm đến LCD trên bo, hãy tắt đèn nền và tăng độ phân giải bộ đệm khung hình lên trên WVGA. TFP410 hỗ trợ đến 1280×720 @ 60 Hz, vì vậy ví dụ:

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

Màn hình trên bo được cố định ở 800×480, vì vậy bất cứ thứ gì trên WVGA chỉ có nghĩa trên màn hình HDMI ngoài.

Để biết khi nào màn hình HDMI được cắm vào hoặc rút ra, hãy đăng ký hàm gọi lại hot‑plug trên TFP410. Hàm gọi lại kích hoạt với True khi kết nối và False khi ngắt kết nối:

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

hdmi.hotplug_callback(on_hotplug)

Bạn cũng có thể thăm dò trạng thái kết nối bất kỳ lúc nào bằng isconnected() (chỉ khi không có hàm gọi lại nào được đăng ký).

Cổng HDMI cũng mang các kênh DDC (dữ liệu màn hình) và CEC (điều khiển điện tử tiêu dùng), được cung cấp qua lớp class DisplayData -- Dữ liệu màn hình. Sử dụng nó để đọc khối EDID của màn hình được kết nối (để bạn có thể thích ứng với độ phân giải gốc / tốc độ làm mới của nó) hoặc để gửi/nhận các khung CEC để điều khiển các thiết bị HDMI khác trên cùng dây:

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 chạy qua module Microchip WINC1500, được cung cấp qua giao diện class WINC -- trình điều khiển 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])

Ghi chú

Do thiếu linh kiện, một số đơn vị Pure Thermal đã được giao hàng mà không lắp module WINC1500. Nếu network.WINC báo lỗi hoặc không bao giờ kết nối, hãy kiểm tra bo mạch xem có thiếu module Wi‑Fi không — phần còn lại của camera hoạt động hoàn toàn giống nhau mà không có nó.

Thẻ microSD

Khi thẻ được cắm vào, nó sẽ được gắn kết tự động tại /sdcard và có thể sử dụng qua hệ thống tệp thông thường:

import os

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

Tham chiếu bus

GPIO

Sử dụng machine.Pin để đọc hoặc điều khiển bất kỳ chân nào được in lụa. Đầu ra là CMOS 3.3 V, chịu được 5 V ở phía đầu vào, và có thể nhận/cấp đến 25 mA mỗi chân (120 mA tổng cộng trên toàn bộ 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())

Bất kỳ chân đầu vào nào cũng có thể kích hoạt ngắt trên các chuyển tiếp cạnh:

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

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

UART

Bus

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

Bus

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

Phần cứng tương tự cũng có thể được sử dụng ở chế độ target (slave) qua machine.I2CTarget để cung cấp một vùng bộ nhớ cho một bộ điều khiển I²C khác:

from machine import I2CTarget

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

Đầu nối Qwiic trên bo cung cấp một trong các bus I²C này cho các module cắm và chạy. Đường Qwiic được chuyển mức lên 5 V qua transistor open‑drain, vì vậy bus bị giới hạn ở chế độ tiêu chuẩn (100 kHz)chế độ nhanh (400 kHz) — đừng cố chạy fast‑mode‑plus hoặc tốc độ cao hơn qua header Qwiic.

Đầu nối Qwiic xuất 5 V để cấp nguồn cho các module được kết nối; nó không thể được dùng để cấp nguồn cho Pure Thermal — cấp nguồn cho bo qua USB‑C hoặc đầu nối pin LiPo.

SPI

Bus

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)

Bus

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 và DAC

P6 là chân analog duy nhất cho người dùng. Nó có thể được sử dụng như đầu vào ADC 12‑bit hoặc đầu ra DAC.

  • ADC — toàn thang đo ở 3.3 V tại chân:

    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 — qua pyb.DAC. Giá trị 8‑bit bao phủ 0–3.3 V:

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

Trong chế độ ADC hoặc DAC, P6 chỉ chịu được 3.3 V — không cấp 5 V vào đây.

PWM

Chân

Bộ định thời / kênh

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM2 CH1

P7

TIM4 CH1

P8

TIM4 CH2

Ghi chú

TIM1 được firmware dự trữ để tạo xung nhịp điểm ảnh cho cảm biến camera, vì vậy các kênh TIM1 ở trên P0/P1/P2 không thể dùng cho PWM người dùng mà không làm hỏng camera.

TIM4 được chia sẻ với pyb.Servo — khởi tạo một servo sẽ cấu hình lại toàn bộ bộ định thời cho hoạt động 50 Hz, vì vậy đừng kết hợp machine.PWM trên P7/P8 với pyb.Servo trong cùng một tập lệnh.

Điều khiển bất kỳ chân nào trong số đó qua machine.PWM

from machine import Pin, PWM

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

Bus bit‑bang phần mềm

machine.SoftI2Cmachine.SoftSPI hoạt động trên bất kỳ GPIO nào nếu bạn cần thêm bus.

Cảm biến nhiệt (ngoài bo)

Ngoài FLIR Lepton trên bo, firmware còn bao gồm driver fir --- trình điều khiển cảm biến nhiệt (fir == hồng ngoại xa) cho các cảm biến nhiệt I²C được đấu dây ngoài:

  • MLX90621 — mảng IR 16 × 4

  • MLX90640 — mảng IR 32 × 24

  • MLX90641 — mảng IR 16 × 12

  • AMG8833 — mảng IR 8 × 8

Đấu dây module vào bus I²C của bo và đọc khung hình bằng 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())

Driver fir chỉ giao tiếp với cảm biến qua I²C 2 — đấu dây module vào P4 (SCL) và P5 (SDA).

Thời gian

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)

Bộ định thời ảo

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

Giá trị chu kỳ tính bằng mili giây. Gọi deinit() để dừng và giải phóng slot.

Đồng hồ thời gian thực

from machine import RTC

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

Nếu pin LiPo được kết nối, RTC giữ thời gian ngay cả khi các đường điện hệ thống bị tắt (tắt nguồn qua nút nguồn trên bo). Khi chỉ có USB được cắm, nhấn nút nguồn cắt nguồn điện cho RTC cũng vậy — vì vậy thời gian tường không thể tồn tại qua một chu kỳ nguồn mà không có pin được kết nối.

Watchdog

from machine import WDT

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

Thông tin khởi động và thời gian chạy

Cửa sổ bootloader USB

Mỗi lần bật nguồn, camera chạy một bootloader ngắn (vài giây) cho phép OpenMV IDE cập nhật firmware mà người dùng không cần vào chế độ DFU. Sau khi cửa sổ hết hạn, bootloader chuyển sang boot.py và sau đó là main.py.

Một tập lệnh đang chạy có thể vào lại bootloader theo yêu cầu bằng cách gọi machine.bootloader().

Hệ thống tệp và thứ tự khởi động

Firmware Pure Thermal gắn kết đến ba hệ thống tệp khi khởi động:

  • Bộ nhớ flash nội bộ — luôn được gắn kết tại /flash. Chứa main.pyREADME.txt theo mặc định; được tạo ở lần khởi động đầu tiên.

  • Thẻ microSD — nếu có thẻ được cắm vào thì nó sẽ được gắn kết tại /sdcard.

  • ROMFS — hệ thống tệp ánh xạ bộ nhớ chỉ đọc tại /rom được dùng để cung cấp các tài nguyên dữ liệu lớn (ví dụ: mô hình AI) được hưởng lợi từ truy cập zero‑copy. Được MicroPython gắn kết tự động khi khởi động, trước khi bất kỳ Python người dùng nào chạy.

Sau khi gắn kết, thư mục làm việc được đặt thành /sdcard khi thẻ có mặt, ngược lại là /flash. Trình thông dịch sau đó chạy các tập lệnh từ thư mục đó:

  • boot.py được thực thi mỗi lần khởi động lại mềm.

  • main.py chỉ được thực thi trong lần khởi động lạnh, ngay sau boot.py.

Đặt boot.py hoặc main.py vào thẻ SD sẽ ghi đè bản sao trong flash mà không chạm vào nó.

Khi kết nối qua USB, hệ thống tệp khởi động (/sdcard nếu có thẻ, ngược lại là /flash) cũng được liệt kê như ổ đĩa USB mass‑storage trên máy tính. Eject ổ đĩa trước khi khởi động lại camera để máy tính xả các lần ghi đã được đệm.

Ghi chú

Các tệp được tạo hoặc sửa đổi bởi mã chạy trên OpenMV Cam sẽ không hiển thị trên máy tính cho đến khi ổ đĩa được gắn lại. Sử dụng thẻ SD cho bất kỳ dữ liệu nào mà tập lệnh ghi lại, và gắn lại trước khi đọc các tệp đó từ máy tính.

Kích thước lưu trữ

Pure Thermal đi kèm với:

  • /flash — Hệ thống tệp FAT 24 MB, đọc/ghi.

  • /rom — ROMFS ánh xạ bộ nhớ chỉ đọc 8 MB, dùng để cung cấp các tập lệnh và mô hình ML được hưởng lợi từ truy cập mmap zero‑copy.

  • /sdcard — kích thước đầy đủ của thẻ microSD được cắm vào (khi có), đọc/ghi.

Chỉ báo hard‑fault

Nếu đèn LED RGB người dùng đang chạy nhanh qua tất cả các màu — nhanh đến mức nó có xu hướng trông giống đèn LED trắng nhấp nháy hơn là các màu riêng biệt — firmware đã gặp hard fault không thể phục hồi. Nạp lại firmware để khôi phục.

Lỗi phần cứng

Một số vấn đề ở cấp độ bo mạch được ghi lại trong Lỗi phần cứng Pure Thermal. Các vấn đề chính cần lưu ý:

  • Nhiễu loạn đầu nối pin — các linh kiện trên PCB nằm ngay dưới đầu nối pin LiPo, và miếng chêm nhô ra trên phích cắm dây pin có thể vướng vào chúng khi rút cáp, đôi khi kéo các linh kiện ra khỏi bo. Cắt bỏ miếng chêm trên phích cắm cáp bằng kéo cắt phẳng trước khi sử dụng lần đầu.

  • RTC dừng khi bo mạch bị tắt nguồn — điện dung tải trên tinh thể 32 kHz (Y2) quá cao. Tháo C96 và C97 (cặp tụ điện hai bên tinh thể gần STM32) cho phép RTC tiếp tục chạy trên nguồn dự phòng. Hầu hết các bo được giao với các tụ này đã được tháo; nếu RTC của bạn mất thời gian khi rút phích cắm, hãy kiểm tra những vị trí đó. Xem các vấn đề GitHub #1536#1600 để biết toàn bộ nội dung thảo luận.

  • Đèn LED chỉ thị sạc vẫn xanh dương — bộ sạc có thể kết thúc chu kỳ sạc ở bất kỳ đâu trong khoảng 4.15 V đến 4.19 V mà không chuyển chỉ thị từ xanh dương (đang sạc) sang xanh lá (đã sạc đầy). Pin vẫn được sạc đầy trong trường hợp này; tin vào phép đo điện áp, không phải đèn LED.

  • Nhãn in lụa ghi nhầm VIN thành VBAT — chân ở vị trí VIN của header OpenMV tiêu chuẩn được in lụa là VBAT trên Pure Thermal. Nhãn sai, nhưng điều đó không quan trọng trong thực tế vì chân này không có kết nối điện dù bằng cách nào.

Thư viện phần mềm

Xem danh mục thư viện để biết danh sách đầy đủ các module — bao gồm cả những module chỉ có trong bản build Pure Thermal.