OpenMV Pure Thermal¶
O OpenMV Pure Thermal é uma placa de imagem térmica de sistema completo construída em torno do STMicroelectronics STM32H743 (Cortex‑M7 @ 480 MHz) com 64 MB de SDRAM externa, 32 MB de flash QSPI, um codec JPEG por hardware, um ecrã tátil IPS capacitivo de 4,3» 800×480, uma saída HDMI, um socket FLIR® Lepton® térmico e uma câmara de luz visível OV5640 de 5MP. Inclui também Wi‑Fi, um socket microSD, um telémetro laser, um buzzer e um iluminador branco de alta potência.
Para a ficha técnica completa, fotografias e dimensões, consulte a página do produto OpenMV Pure Thermal.
Destaques¶
STMicroelectronics STM32H743XI Cortex‑M7 a 480 MHz.
Codificador/descodificador JPEG por hardware.
64 MB de SDRAM externa (~400 MB/s) mais 1 MB de SRAM interna.
2 MB de flash interna + 32 MB de flash QSPI externa (~50 MB/s de leitura).
OV5640 sensor de luz visível de 5MP com obturador rolante.
Socket FLIR® Lepton® — aceita qualquer módulo Lepton 1/2/2,5/3/3,5, radiométrico ou não radiométrico, com temperatura por pixel em graus Celsius.
Ecrã tátil IPS capacitivo de 4,3» 800×480 (cor de 24 bits @ 60 Hz) com suporte de até 5 pontos de gesto.
Saída HDMI via serializador DVI TFP410 — até 1280×720 @ 60 Hz.
Wi‑Fi via WINC1500; MJPEG sobre RTSP suportado de raiz.
USB‑C de velocidade máxima (12 Mb/s, 900 mA com limitação de corrente) — aparece como VCP + armazenamento de massa USB no anfitrião e gere também o carregamento.
Socket microSD — SD até 2 GB, SDHC até 32 GB, SDXC até 2 TB.
Telémetro laser VL53L1CX (até ~4 m).
Buzzer com volume/frequência controlados por software.
Iluminador LED branco de alta potência além do LED de estado RGB de utilizador.
Conector de bateria LiPo com carregamento USB a 500 mA.
10 pinos de E/S, tolerantes a 5 V com saída de 3,3 V, 25 mA por pino (120 mA no total), com capacidade de interrupção. P6 não é tolerante a 5 V quando utilizado em modo ADC ou DAC.
Conector SWD ARM de 10 pinos para depuração com ST‑LINK / J‑Link.
Conector Qwiic para periféricos I²C.
Nota
A placa tem uma ranhura na extremidade inferior esquerda para uma porca de tripé ¼»–20 opcional. Não é montada de fábrica — solde-a na ranhura se pretender fixar a placa num tripé de câmara standard.
Pinout¶
Referência de pinos¶
Nome do pino |
Função |
|---|---|
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 |
E/S digital |
RESET |
ligar a GND para reiniciar a placa |
SYN |
pad de sincronização de fotograma — não ligado |
VIN |
pad VIN do shield — não ligado |
BOOT0 |
ligar a 3,3 V na ligação para DFU / bootloader ROM |
BUZZER |
buzzer piezo integrado (controlado por TIM2/PWM) |
LED_RED |
canal vermelho do LED de estado RGB (activo baixo) |
LED_GREEN |
canal verde do LED de estado RGB (activo baixo) |
LED_BLUE |
canal azul do LED de estado RGB (activo baixo) |
LED_WHITE |
LED iluminador branco de alta potência |
Nota
Os pads SYN e VIN no shield/header não têm ligação eléctrica no Pure Thermal — existem apenas para compatibilidade com o header. Alimente a placa através do USB‑C ou do conector de bateria LiPo integrado (ver Pinos de alimentação abaixo). Note também que o pad VIN está serigrafiado como VBAT na placa (um erro de etiquetagem) — a posição é o pino VIN standard do header OpenMV e não está ligado de qualquer forma.
Pinos de alimentação¶
3,3V — rail regulado de 3,3 V. Até 250 mA disponíveis para shields.
GND — massa comum.
O Pure Thermal é alimentado através de USB‑C ou do conector de bateria LiPo integrado. A porta USB‑C tem limitação de corrente a 900 mA no total e gere também o carregamento LiPo a 500 mA, pelo que ligar uma bateria juntamente com USB é suportado.
O botão de alimentação integrado comuta os rails do sistema ligado e desligado e funciona quer a placa esteja a ser alimentada por USB ou pela LiPo. Mantenha o botão premido durante alguns segundos para mudar de estado — um toque rápido é ignorado para evitar desligamentos acidentais.
A selecção da fonte segue duas regras simples:
A bateria só alimenta a placa quando a sua tensão está acima de 3 V. Abaixo desse limiar, o PMIC integrado desliga a bateria para a proteger de descarga excessiva.
Quando o USB está presente, o USB alimenta a placa e qualquer LiPo ligada carrega em segundo plano.
O conector LiPo também dispõe de protecção contra polaridade inversa, pelo que ligar a bateria ao contrário não danifica a placa.
Nota
A placa também encaminha a tensão da bateria e um sinal de detecção de corrente da bateria de volta para canais ADC do MCU, mas o suporte de firmware para ambos ainda não foi adicionado.
Pinos de recuperação e depuração¶
RESET — ligar a GND para reiniciar a placa. O Pure Thermal também tem um botão RESET dedicado na placa que faz o mesmo.
BOOT0 — ligar a 3,3 V ao ligar a placa para entrar no bootloader ROM do STM32 (modo DFU). O OpenMV IDE usa este modo para reflashear o bootloader integrado. Um botão BOOT0 dedicado na placa faz o mesmo — mantenha-o premido ao aplicar alimentação.
A placa expõe um header de depuração SWD (RST / SWCLK / SWDIO / SWO) junto ao header GPIO, compatível com adaptadores ST‑LINK e SEGGER J‑Link. Um conector SWD ARM de 10 pinos separado também está montado — transporta os mesmos sinais SWD (sem JTAG completo) mas no form factor standard de 10 pinos 0,05».
Nota
O pino de rastreio SWO é partilhado com o clock SPI do FLIR® Lepton® integrado. O SWO não pode ser usado ao mesmo tempo que o Lepton — escolha um ou outro.
Um terceiro conector PURE Modules Debug está montado na placa. Expõe um conjunto de sinais orientados para depuração (SWCLK, SWDIO, RST, SPI2_MISO, SPI2_MOSI, VBUS, 3,3 V, GND e dois pinos GPIO) para ligar módulos complementares. Os dois pinos GPIO neste conector são controlados por um bus I²C por software (bit-banged) em vez de um periférico de hardware.
Os três conectores de depuração (o header SWD em linha, o conector SWD ARM de 10 pinos e o conector PURE Modules Debug) têm referência a 3,3 V — certifique-se de que o seu adaptador de depuração está configurado para lógica de 3,3 V antes de ligar.
Periféricos integrados¶
LEDs¶
O Pure Thermal tem três LEDs na placa:
LED RGB de utilizador — controlável por software, exposto como
LED_RED,LED_GREENeLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
Iluminador branco — controlado através de
LED_WHITE.LED_WHITEestá ligado activo alto no hardware enquanto o firmware trata todos os outros LEDs integrados como activos baixos, por isso uselow()/high()em vez deon()/off()(que inverteriam o sentido):from machine import LED light = LED("LED_WHITE") light.low() # turn the white LED ON light.high() # turn the white LED OFF
LED de carregamento — controlado directamente pelo hardware de gestão de energia integrado, sem controlo por software. Funciona quer os rails do sistema estejam ligados ou desligados (ou seja, com o botão de alimentação em qualquer posição).
Cor
Significado
Azul
a carregar — ver errata: pode não se apagar quando o carregamento termina
Verde
carregamento completo — ver errata: pode não activar de forma fiável
Vermelho
bateria fraca (≤ 3,2 V, apenas quando não está activamente a carregar)
Buzzer¶
O buzzer piezo integrado está ligado a um canal de temporizador — controle-o com machine.PWM para tons com frequência (altura) e ciclo de trabalho (volume) controlados por 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()
Sensor de câmara¶
O OV5640 é o CSI principal no Pure Thermal — passe cid=csi.OV5640 para o endereçar explicitamente:
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()
O OV5640 tem um compressor JPEG integrado. Defina csi.CSI.pixformat como csi.JPEG e o sensor entrega fotogramas comprimidos directamente à câmara através do bus da câmara, o que torna práticas as capturas em alta resolução: csi.HD (1280×720), csi.FHD (1920×1080) e o 5MP completo csi.WQXGA2 (2592×1944) transmitem todos em JPEG. Ajuste a compressão com csi.CSI.quality (0-100, maior = fotogramas maiores, mais detalhe):
cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)
O OV5640 tem uma lente de autofoco com actuador de bobine de voz. Desencadeie uma passagem de autofoco única via csi.CSI.ioctl com csi.IOCTL_TRIGGER_AUTO_FOCUS — o sensor percorre o motor de foco uma vez e bloqueia no que estiver à sua frente:
cam.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)
Reemita o ioctl sempre que a cena mudar — o autofoco é de passagem única, não contínuo.
Nota
A saída STROBE do OV5640 (usada para flash sincronizado / iluminação IR) está ligada ao MCU no Pure Thermal, mas o suporte de firmware para tal ainda não foi adicionado.
Sensor de câmara térmica¶
O socket FLIR® Lepton® aparece como um segundo CSI na mesma API csi — sensores de câmara. Passe cid=csi.LEPTON para o endereçar e ignore o reset de 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()
Nota
A saída VSYNC do Lepton (um pulso por fotograma térmico) está ligada ao MCU no Pure Thermal, mas o suporte de firmware para tal ainda não foi adicionado.
Ambos os CSIs podem funcionar lado a lado. O exemplo abaixo obtém um fotograma de cor do OV5640 e um fotograma térmico do Lepton, e depois sobrepõe o Lepton sobre o fotograma de cor usando uma paleta Ironbow e uma máscara alfa que desvanece para transparente a baixa intensidade:
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,
)
Aprendizagem automática¶
ml — Machine Learning executa modelos TFLite quantizados no Cortex‑M7 com kernels CMSIS‑NN — rápido o suficiente para detectores compactos a alguns fotogramas por segundo. Os modelos no sistema de ficheiros só de leitura /rom carregam directamente da flash sem copiar para RAM. Aqui está um detector BlazeFace 128×128 que sobrepõe a face detectada e os seus seis pontos de referência em cada fotograma da câmara de luz visível:
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")
Telémetro laser¶
O telêmetro de tempo de voo ST VL53L1CX integrado está ligado ao bus I²C 2. Use o driver frozen vl53l1x — driver do sensor de distância ToF VL53L1X para obter leituras de distância até ~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)
Saída LCD¶
O LCD integrado de 4,3» é 800 × 480 (WVGA) e é controlado através da interface de visualização RGB do módulo display — controlador de ecrã — passe framesize=display.FWVGA para corresponder à sua resolução nativa:
import display
lcd = display.RGBDisplay(framesize=display.FWVGA, refresh=60)
lcd.backlight(True) # turn the LCD backlight on
lcd.write(img)
A retroiluminação está ligada a um GPIO, pelo que backlight() aceita True / False (ou qualquer valor de 0–100, onde 0 é desligado e qualquer valor não nulo é ligado):
lcd.backlight(False) # turn the backlight off
lcd.backlight(True) # back on
Ecrã tátil¶
O controlador táctil capacitivo é o FT5X06; posições multi-toque e eventos de gesto são expostos através de ft5x06 — Driver de Ecrã Tátil. Registe um callback para reagir a toques e leia os pontos activos dentro dele:
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)
Saída HDMI¶
O firmware também encaminha o buffer de fotograma do LCD para o serializador HDMI tfp410 — Controlador DVI/HDMI integrado, de modo a que um monitor externo espelhe o que está no LCD. Instancie tfp410.TFP410 para activar a saída HDMI:
import tfp410
hdmi = tfp410.TFP410()
Se apenas pretende saída HDMI e não se preocupa com o LCD integrado, desligue a retroiluminação e aumente a resolução do buffer de fotograma acima de WVGA. O TFP410 suporta até 1280×720 @ 60 Hz, por exemplo:
lcd = display.RGBDisplay(framesize=display.HD, refresh=60)
lcd.backlight(False) # the on‑board LCD can't render HD
hdmi = tfp410.TFP410()
O painel integrado está fixo a 800×480, por isso qualquer coisa acima de WVGA só é significativa no monitor HDMI externo.
Para saber quando um monitor HDMI foi ligado ou desligado, registe um callback de hot-plug no TFP410. O callback é activado com True ao ligar e False ao desligar:
def on_hotplug(connected):
print("HDMI", "connected" if connected else "disconnected")
hdmi.hotplug_callback(on_hotplug)
Pode também verificar o estado da ligação a qualquer momento com isconnected() (apenas quando nenhum callback está registado).
A porta HDMI também transporta os canais DDC (dados de visualização) e CEC (controlo de electrónica de consumo), expostos através da classe class DisplayData – Dados do Ecrã. Use-a para ler o bloco EDID do monitor ligado (para se adaptar à sua resolução nativa / taxa de actualização) ou para enviar/receber frames CEC para controlar outros dispositivos HDMI no mesmo cabo:
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¶
O Wi‑Fi funciona através de um módulo Microchip WINC1500, exposto através da interface class WINC – controlador do 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])
Nota
Devido a escassez de componentes, algumas unidades Pure Thermal foram expedidas sem o módulo WINC1500 montado. Se network.WINC lançar um erro ou nunca conectar, verifique a placa para um módulo Wi‑Fi em falta — o resto da câmara funciona exactamente da mesma forma sem ele.
Cartão microSD¶
Quando um cartão é inserido, é montado automaticamente em /sdcard e pode ser usado através do sistema de ficheiros regular:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Referência de buses¶
GPIO¶
Use machine.Pin para ler ou controlar qualquer um dos pinos serigrafiados. As saídas são CMOS de 3,3 V, tolerantes a 5 V no lado da entrada, e podem drenar/fornecer até 25 mA por pino (120 mA no total em todo o 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())
Qualquer pino de entrada também pode disparar uma interrupção em transições de flanco:
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")
O mesmo hardware também pode ser usado em modo alvo (escravo) através de machine.I2CTarget para expor uma região de memória a outro controlador I²C:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)
O conector Qwiic integrado expõe um destes buses I²C para módulos plug-and-play. A linha Qwiic tem mudança de nível para 5 V através de transistores de drenagem aberta, pelo que o bus está limitado ao modo standard (100 kHz) e modo rápido (400 kHz) apenas — não tente utilizar taxas superiores ao modo rápido através do header Qwiic.
O conector Qwiic fornece 5 V para alimentar os módulos ligados; não pode ser usado para alimentar o próprio Pure Thermal — alimente a placa através de USB‑C ou do conector de bateria 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 e DAC¶
P6 é o único pino analógico de utilizador. Pode ser usado como entrada ADC de 12 bits ou como saída DAC.
ADC — escala completa a 3,3 V no pino:
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 — através de
pyb.DAC. O valor de 8 bits cobre 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
Em modo ADC ou DAC, P6 é tolerante apenas a 3,3 V — não aplique 5 V.
PWM¶
Pino |
Temporizador / canal |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Nota
TIM1 está reservado pelo firmware para gerar o clock de pixel do sensor da câmara, pelo que os canais TIM1 que estão fisicamente em P0/P1/P2 não podem ser usados para PWM de utilizador sem quebrar a câmara.
TIM4 é partilhado com pyb.Servo — instanciar um servo reconfigura o temporizador inteiro para operação a 50 Hz, por isso não misture machine.PWM em P7/P8 com pyb.Servo no mesmo script.
Controle qualquer um deles via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Buses por software (bit-banged)¶
machine.SoftI2C e machine.SoftSPI funcionam em qualquer GPIO se precisar de um bus extra.
Sensor térmico (externo)¶
Para além do FLIR Lepton integrado, o firmware também inclui o driver fir — driver de sensor térmico (fir == infravermelho longínquo) para imagiadores térmicos I²C ligados externamente:
MLX90621 — array IR de 16 × 4
MLX90640 — array IR de 32 × 24
MLX90641 — array IR de 16 × 12
AMG8833 — array IR de 8 × 8
Ligue o módulo ao bus I²C da placa e leia fotogramas com 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())
O driver fir comunica com o sensor apenas através de I²C 2 — ligue o módulo a P4 (SCL) e P5 (SDA).
Temporização¶
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)
Temporizadores virtuais¶
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"))
Os valores de período estão em milissegundos. Chame deinit() para parar e libertar o slot.
Relógio de tempo real¶
from machine import RTC
rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0))
print(rtc.datetime())
Se uma bateria LiPo estiver ligada, o RTC mantém a hora mesmo enquanto os rails do sistema estão desligados (desactivados via o botão de alimentação integrado). Com apenas USB ligado, premir o botão de alimentação corta também a alimentação ao RTC — pelo que a hora do relógio não sobrevive a um ciclo de alimentação sem uma bateria ligada.
Watchdog¶
from machine import WDT
wdt = WDT(timeout=5_000)
while True:
# ...do work...
wdt.feed()
Informação de arranque e tempo de execução¶
Janela do bootloader USB¶
Em cada arranque, a câmara executa um bootloader curto (alguns segundos) que permite ao OpenMV IDE actualizar o firmware sem que o utilizador precise de entrar no modo DFU. Após o fim da janela, o bootloader passa o controlo para boot.py e depois para main.py.
Um script em execução pode re-entrar no bootloader a pedido chamando machine.bootloader().
Sistema de ficheiros e ordem de arranque¶
O firmware do Pure Thermal monta até três sistemas de ficheiros no arranque:
Flash interna — sempre montada em
/flash. Contémmain.pyeREADME.txtpor omissão; criada no primeiro arranque.Cartão microSD — se um cartão estiver inserido, é montado em
/sdcard.ROMFS — sistema de ficheiros só de leitura mapeado em memória em
/rom, usado para distribuir grandes recursos de dados (p. ex. modelos de IA) que beneficiam de acesso sem cópia. Montado automaticamente pelo MicroPython no arranque, antes de qualquer Python de utilizador ser executado.
Após a montagem, o directório de trabalho é definido como /sdcard quando o cartão está presente, caso contrário /flash. O interpretador executa então scripts a partir desse directório:
boot.pyé executado em cada reset por software.main.pyé executado apenas no arranque a frio, imediatamente apósboot.py.
Colocar um boot.py ou main.py no cartão SD substitui a cópia em flash sem a modificar.
Quando ligado via USB, o sistema de ficheiros de arranque (/sdcard se um cartão estiver presente, caso contrário /flash) também aparece como unidade de armazenamento de massa USB no anfitrião. Ejicte a unidade antes de reiniciar a câmara para que o anfitrião liberte as suas escritas em cache.
Nota
Os ficheiros criados ou modificados por código a correr na OpenMV Cam não aparecem no anfitrião até que a unidade seja remontada. Use o cartão SD para quaisquer dados que o script escreva, e remonte antes de ler esses ficheiros a partir do anfitrião.
Tamanhos de armazenamento¶
O Pure Thermal é fornecido com:
/flash— sistema de ficheiros FAT de 24 MB, leitura/escrita./rom— ROMFS de 8 MB só de leitura mapeado em memória, usado para distribuir scripts e modelos ML que beneficiam de acesso mmap sem cópia./sdcard— tamanho total do cartão microSD inserido (quando presente), leitura/escrita.
Indicador de falha grave¶
Se o LED RGB de utilizador estiver a ciclar rapidamente por todas as cores — rápido o suficiente para parecer um LED branco cintilante em vez de matizes distintos — o firmware atingiu uma falha grave irrecuperável. Reflasheie o firmware para recuperar.
Errata de hardware¶
Alguns peculiaridades ao nível da placa estão documentadas na errata de hardware do Pure Thermal. Pontos-chave a ter em atenção:
Interferência do conector da bateria — os componentes no PCB ficam directamente sob o conector da bateria LiPo, e a cunha saliente no conector do cabo da bateria pode enganchar neles ao remover o cabo, por vezes arrancando componentes da placa. Corte a cunha do conector do cabo com cortadores de ras antes da primeira utilização.
O RTC para enquanto a placa está desligada — a capacitância de carga no cristal de 32 kHz (Y2) é demasiado elevada. Remover C96 e C97 (o par flanqueando o cristal junto ao STM32) permite ao RTC continuar a funcionar com alimentação de reserva. A maioria das placas é expedida com estes condensadores já removidos; se o seu RTC perder a hora quando desligado, verifique essas posições. Ver issues GitHub #1536 e #1600 para o fio completo.
O LED indicador de carregamento fica azul — o carregador pode terminar o seu ciclo de carga entre 4,15 V e 4,19 V sem mudar o indicador de azul (a carregar) para verde (carregado). A bateria está ainda totalmente carregada neste caso; confie numa medição de tensão, não no LED.
A serigrafia etiqueta VIN como VBAT — o pad na posição VIN standard do header OpenMV está serigrafiado como
VBATno Pure Thermal. A etiqueta está errada, mas na prática não tem importância porque o pad não tem ligação eléctrica de qualquer forma.
Bibliotecas de software¶
Consulte o índice de biblioteca para a lista completa de módulos — incluindo quais são exclusivos da compilação Pure Thermal.