OpenMV Cam RT1062¶
OpenMV Cam RT1062 是一款围绕 NXP i.MX RT1062(Cortex‑M7 @ 600 MHz)打造的低功耗机器视觉开发板。该板将 USB‑C 高速网络、Wi‑Fi/蓝牙和 10/100 以太网与一块安装在可拆卸载板上的 OV5640 500 万像素传感器相结合。该摄像头在深度睡眠时仅从 LiPo 电池汲取约 30 µA 电流,因此非常适合电池供电的项目。
完整的数据手册、照片和尺寸信息请参见 OpenMV Cam RT1062 产品页面。
主要特性¶
NXP i.MX RT1062 Cortex‑M7,主频 600 MHz。
32 MB 外部 SDRAM(16 位 @ 160 MHz,320 MB/s)外加 1 MB 内部 SRAM 和 16 MB QSPI flash(133 MHz 4 位 SDR,读取 66 MB/s);R6+ 上配有 4 KB EEPROM。
OV5640 500 万像素卷帘快门传感器。
板载 IMU(12 位三轴加速度计,±2/4/8 g)。
高速 USB‑C(480 Mb/s,1.5 A 电流限制)、10/100 Mb/s 以太网(通过扩展板支持 PoE)、Wi‑Fi a/b/g/n + 蓝牙 5.1(芯片天线或 U.FL 选项)。
microSD 插槽 —— SD 最大 2 GB,SDHC 最大 32 GB,SDXC 最大 2 TB。
LiPo 充电器(R6+ 上 500 mA,R4/R5 上 100 mA)、带备用电池焊盘的 RTC。深度睡眠时电池汲取 ~30 µA。
14 个 I/O 引脚,全部为 3.3 V 输出 / 3.3 V 耐受,每个引脚 4 mA,支持中断。
用户 RGB LED、用户 SW 按钮、硬件电源按钮(深度睡眠 / 唤醒状态机),以及一个用于充电 / USB / VIN 供电的独立状态 LED。
警告
RT1062 的 I/O 引脚 不耐受 5 V。请勿将本设备直接连接到 Arduino Mega 这样的 5 V MCU。只能通过 VIN 为该板供电。
引脚分布¶
引脚参考¶
引脚名称 |
功能 |
|---|---|
P0 |
SPI1 MOSI / PWM2 B3 |
P1 |
SPI1 MISO / CAN0 TX |
P2 |
SPI1 SCLK / PWM2 B3 |
P3 |
SPI1 SS / CAN0 RX |
P4 |
I2C1 SCL / UART1 TX / PWM1 X2 |
P5 |
I2C1 SDA / UART1 RX / PWM1 X3 |
P6 |
ADC |
P7 |
PWM2 A0 |
P8 |
PWM2 B0 |
P9 |
PWM1 A3 |
P10 |
PWM1 B3 / 帧同步 I/O |
P11 |
唤醒(低电平有效,连接到 GND 以唤醒) |
P12 |
RESET —— 拉至 GND 以复位开发板(不是 GPIO) |
P13 |
数字 I/O |
P14 |
数字 I/O |
ON/OFF |
复制硬件电源按钮功能的排针焊盘(低电平有效) |
SW |
用户按钮(低电平有效) |
ST |
VIN 供电时为低,USB 供电时为高 |
CHG |
低电平有效;外接 LiPo 电池充电时为低 |
PG |
低电平有效;存在 VIN 或 USB 供电时为低 |
LED_RED |
RGB LED 红色通道(低电平有效) |
LED_GREEN |
RGB LED 绿色通道(低电平有效) |
LED_BLUE |
RGB LED 蓝色通道(低电平有效) |
备注
P10 帧同步线是一条共享总线。 它同时连接到 MCU、摄像头传感器的触发 / 曝光引脚以及用户排针。方向由应用程序定义 —— 取决于传感器的配置方式,MCU、传感器或外部信号都可以驱动它。请确保同一时刻只有一个驱动源处于激活状态。
备注
ON/OFF 和 P11 以始终供电的 RAW 电源轨为参考(而非受控的 3.3 V 电源轨),因此在开发板其余部分处于深度睡眠 / 低功耗模式时它们仍然有效。两个输入均为低电平有效。
这些引脚经过电平转换器,因此可以挂载在 RAW 电源轨上。如果你确实需要在 ON/OFF 或 P11 上获得 3.3 V 直连的 GPIO 行为(例如在不经过转换器的情况下由 3.3 V MCU 驱动它们),开发板提供了上拉和 0 欧姆跳线焊盘,可以让你绕过转换器。这是一项高级硬件改造 —— 大多数用户应保持原样不动。
备注
P13 和 P14 默认是普通 GPIO,没有特殊功能。可以通过重新回流焊接开发板背面的 0 欧姆电阻焊桥,将这些焊盘选择性地重新布线到其他信号:
P13 ↔ CHG 状态 / JTAG TRSTB
P14 ↔ ST 状态 / JTAG TDI
大多数用户不会动这些跳线 —— 除非你确实需要电源管理回读或 JTAG,否则请将它们保持为 GPIO 默认设置。
电源引脚¶
3.3V —— 已稳压的 3.3 V 电源轨。在 RT1062 上仅为输出 —— 不要向此引脚馈入外部电源。可为扩展板提供最高 1 A 电流。
VIN —— 5 V 输入。为开发板和板载 LiPo 充电器供电。
RAW —— 输入/输出,始终供电(3.6 V – 5 V)。承载当前激活的电源(VIN、USB 或外接电池),也可用作输入。向其馈入电源时必须通过串联二极管驱动 RAW —— 否则电流将回流到 VIN/USB,并损坏供电或板载保护电路。
GND —— 公共地。
备注
板载电源管理芯片会自动选取 USB 或 VIN 中电压较高者为开发板和电池充电器供电。如果接有 LiPo 电池,它会用剩余的余量进行充电;当 VIN/USB 电压下降或被拔出时,控制器会回退到电池以保持开发板运行。
备注
开发板背面有用于外接 3.3 V RTC 备用电池的焊盘。将一枚纽扣电池接到这些焊盘上,可在开发板其余部分断电时保持 RTC 运行。
小技巧
使用 电池续航估算器 来对给定的激活 / 深度睡眠占空比下 RT1062 的电池续航时间进行建模。
以太网引脚¶
RT1062 在 GPIO 排针旁边的专用焊盘上引出了 10/100 Mb/s 以太网 PHY 的 MDI 差分对。MDI 引脚不能直接接到 RJ45 —— PHY 与线缆之间必须有以太网磁性元件(隔离变压器,可内置于 magjack 或位于扩展板上)。OpenMV PoE 扩展板已包含这些元件;如果你自行设计接口,请使用集成磁性元件的 RJ45 或外置变压器。
ETH_LED —— 链路/活动 LED。链路连通时为低电平有效;有流量时闪烁。
ETH_TXP / ETH_TXN —— 发送差分对。
ETH_RXP / ETH_RXN —— 接收差分对。
备注
排针还引出了四个丝印为 Reserved 的焊盘。它们的封装与 OpenMV N6 上的千兆以太网差分对(DC P/N 和 DD P/N)兼容,因此同一块以太网 / PoE 扩展板可以插到任一开发板上。RT1062 的 PHY 仅支持 10/100 Mb/s,因此这四个焊盘没有电气连接 —— 请保持其悬空。
恢复与调试引脚¶
RESET —— 拉至 GND 以复位开发板。释放后让 MCU 正常启动。
SBL —— 在为开发板上电时拉至 3.3 V,以进入 ROM 引导加载程序(Serial Boot Loader)模式。OpenMV IDE 使用此模式来重新刷写板载引导加载程序。
板上装有专用的 ARM 10 针 SWD/JTAG 排针,兼容 ST‑LINK 和 SEGGER J‑Link 适配器。
备注
RT1062 默认仅通过此连接器引出 SWD 调试。完整的 JTAG 在开箱即用时不可用。
板载外设¶
LED¶
RT1062 有两个 RGB LED:
用户 RGB LED —— 软件可控,以
LED_RED、LED_GREEN和LED_BLUE形式引出:from machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
电源 LED —— 由板载电源管理硬件直接驱动,无软件控制。可用它一眼读出供电状态。
运行时:
通道
含义
蓝色
VIN 正在为开发板供电(USB 供电时熄灭)
绿色
存在 USB 或 VIN 供电
红色
正在为外接 LiPo 电池充电
在深度睡眠时,所有通道均熄灭,红色除外 —— 当 LiPo 仍在充电时它会保持点亮。
电源状态引脚¶
来自板载电源管理芯片的三个低电平有效状态输入:
PG —— 存在 VIN 或 USB 供电时为低。始终连接。
ST —— 开发板以 VIN 运行时为低,以 USB 供电运行时为高。默认未连接。
CHG —— 外接 LiPo 电池充电时为低。默认未连接。
from machine import Pin
power_ok = not Pin("PG", Pin.IN).value()
摄像头传感器¶
OV5640 通过 csi --- 摄像头传感器 模块驱动:
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
OV5640 内置 JPEG 压缩器。将 csi.CSI.pixformat 设为 csi.JPEG,传感器便会通过摄像头总线直接向相机传送压缩帧,这使得高分辨率拍摄变得可行:csi.HD(1280×720)、csi.FHD(1920×1080)以及完整的 500 万像素 csi.WQXGA2(2592×1944)都能以 JPEG 形式流式传输。可用 csi.CSI.quality(0-100,越高 = 帧越大、细节越多)调节压缩:
cam.pixformat(csi.JPEG)
cam.framesize(csi.WQXGA2)
cam.quality(90)
传感器位于一个可拆卸模块上 —— 可将其更换为任意其他 OpenMV 摄像头模块(全局快门、热成像、更高分辨率等),而无需更改开发板的其余部分。
机器学习¶
ml --- 机器学习 使用 CMSIS‑NN 内核在 Cortex‑M7 上运行量化的 TFLite 模型 —— 速度足以让紧凑型检测器达到每秒几帧。位于只读 /rom 文件系统上的模型可直接从 flash 加载,无需复制到 RAM。下面是一个 128×128 BlazeFace 检测器,它在每一帧上叠加检测到的人脸及其六个特征点:
import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace
# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))
# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# faces is a list of ((x, y, w, h), score, keypoints) tuples
for r, score, keypoints in model.predict([img]):
ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)
# keypoints is a ndarray of shape (6, 2)
# 0 - right eye (x, y)
# 1 - left eye (x, y)
# 2 - nose (x, y)
# 3 - mouth (x, y)
# 4 - right ear (x, y)
# 5 - left ear (x, y)
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
print(clock.fps(), "fps")
IMU¶
RT1062 固件没有将板载加速度计接入 imu --- imu 传感器 模块。请改为通过内部 I²C 总线直接与它通信 —— 该芯片位于地址 0x15,从寄存器 0x03 起依次封装三个有符号 12 位加速度通道外加一个 8 位温度字节:
import machine
import time
ADDR = 0x15
DATA_REG = 0x03
LSB_PER_G = 1024.0 # ±2 g range
def s12(hi, lo):
v = ((hi << 8) | lo) >> 4
return v - 0x1000 if v & 0x800 else v
bus = machine.I2C(2)
print("Devices on I²C2:", bus.scan())
while True:
d = bus.readfrom_mem(ADDR, DATA_REG, 7)
x = s12(d[0], d[1]) / LSB_PER_G
y = s12(d[2], d[3]) / LSB_PER_G
z = s12(d[4], d[5]) / LSB_PER_G
temp_c = d[6] * 0.586 + 25.0
print("x=%+.2fg y=%+.2fg z=%+.2fg T=%.1f°C" % (x, y, z, temp_c))
time.sleep_ms(100)
EEPROM¶
R6 及更新的开发板在与加速度计相同的内部总线上配有一颗通用的 4 KB I²C EEPROM。(更早的版本没有 —— 在 R4/R5 上调用这些代码片段会因缺少 I²C 应答而超时。)使用标准的 machine.I2C readfrom_mem / writeto_mem API 并配合 16 位存储器地址:
import machine
import time
EEPROM_ADDR = 0x50 # default address
PAGE_SIZE = 32 # bytes per page (both read and write)
EEPROM_SIZE = 4096
bus = machine.I2C(2)
# Dump the entire 4 KB one page at a time
data = bytearray()
for offset in range(0, EEPROM_SIZE, PAGE_SIZE):
data += bus.readfrom_mem(EEPROM_ADDR, offset, PAGE_SIZE, addrsize=16)
print(len(data), "bytes")
# Write a small payload back at offset 0 (fits in one page)
bus.writeto_mem(EEPROM_ADDR, 0, b"hello, world", addrsize=16)
time.sleep_ms(10) # ~5 ms write cycle after each page
# Read it back
print(bus.readfrom_mem(EEPROM_ADDR, 0, 12, addrsize=16))
读取和写入都必须保持在 32 字节的页内。请将任何更大的传输拆分为每页一次调用,并在连续写入之间加上约 5 ms 的写周期延时。
Wi‑Fi¶
板载的 CYW43 系列模块通过 network --- 网络配置 以 station 接口形式引出。连接后,ipconfig("addr4") 返回 (ip, netmask) 元组:
import network, time
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])
蓝牙¶
同一无线模块还提供蓝牙 5.1。使用 aioble --- 异步 BLE 实现对 asyncio 友好的 BLE —— 例如,作为外设广播并等待中心设备连接:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="OpenMV-RT1062")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
以太网¶
当 RJ45(带磁性元件)连接到 MDI 焊盘后,10/100 PHY 会作为 LAN 接口出现。链路连通后会自动运行 DHCP:
import network, time
lan = network.LAN()
lan.active(True)
while not lan.isconnected():
time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])
microSD 卡¶
插入卡后,它会自动挂载到 /sdcard,并可通过常规文件系统使用:
import os
for entry in os.listdir("/sdcard"):
print(entry)
总线参考¶
GPIO¶
使用 machine.Pin 读取或驱动任意带丝印的引脚。输出为 3.3 V CMOS,每个引脚可灌入/拉出最高 4 mA。
from machine import Pin
out = Pin("P0", Pin.OUT)
out.on()
out.off()
out.value(1)
inp = Pin("P1", Pin.IN, Pin.PULL_UP)
print(inp.value())
任意输入引脚还可在边沿跳变时触发中断:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
总线 |
TX |
RX |
|---|---|---|
UART1 |
P4 |
P5 |
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
总线 |
SCL |
SDA |
|---|---|---|
I2C1 |
P4 |
P5 |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
通过 machine.I2CTarget,同一硬件也可用于目标(从机)模式,向另一个 I²C 控制器开放一段存储区域:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
SPI¶
总线 |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI1 |
P0 |
P1 |
P2 |
P3 |
from machine import SPI
from machine import Pin
spi = SPI(1, 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¶
总线 |
TX |
RX |
|---|---|---|
CAN1 |
P1 |
P3 |
备注
固件 v5.0.0 在此开发板上尚不支持 CAN。
from machine import CAN
can = CAN(1, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())
ADC¶
唯一的用户 ADC 引脚是 P6,满量程约为 3.3 V:
from machine import ADC
import time
adc = ADC("P6")
while True:
voltage = adc.read_u16() * 3.3 / 65535
print(voltage)
time.sleep_ms(100)
PWM¶
引脚 |
FlexPWM 通道 |
|---|---|
P0 |
PWM2 B3 |
P2 |
PWM2 B3 |
P4 |
PWM1 X2 |
P5 |
PWM1 X3 |
P7 |
PWM2 A0 |
P8 |
PWM2 B0 |
P9 |
PWM1 A3 |
P10 |
PWM1 B3 |
通过 machine.PWM 驱动其中任意一个:
from machine import Pin, PWM
pwm = PWM(Pin("P9"), freq=1_000, duty_u16=32768)
软件位拨总线¶
machine.SoftI2C 和 machine.SoftSPI 可在任意 GPIO 上工作,以备你需要额外的总线时使用。
热成像传感器(板外)¶
固件包含用于外接热成像仪的 fir --- 热成像传感器驱动(fir == 远红外) 驱动:
MLX90621 —— 16 × 4 红外阵列
MLX90640 —— 32 × 24 红外阵列
MLX90641 —— 16 × 12 红外阵列
AMG8833 —— 8 × 8 红外阵列
将模块接到开发板的 I²C 总线,并用 fir.init() + fir.snapshot() 读取帧:
import time
import image
import fir
fir.init() # auto‑detects the sensor
clock = time.clock()
while True:
clock.tick()
try:
img = fir.snapshot(x_scale=5, y_scale=5,
color_palette=image.PALETTE_IRONBOW,
hint=image.BICUBIC,
copy_to_fb=True)
except OSError:
continue
print(clock.fps())
fir 驱动仅通过 I²C 4 与传感器通信 —— 请将模块接到 P4(SCL)和 P5(SDA)。
定时¶
time¶
time 模块涵盖阻塞延时、单调计时和耗时测量:
import time
time.sleep(1) # seconds
time.sleep_ms(500)
time.sleep_us(10)
start = time.ticks_ms()
# ...do work...
elapsed = time.ticks_diff(time.ticks_ms(), start)
虚拟定时器¶
machine.Timer 可在不占用硬件定时器槽的情况下调度周期性或一次性回调。将 -1 作为 id 传入即可使用虚拟(软件)定时器:
from machine import Timer
one_shot = Timer(-1)
one_shot.init(period=5_000, mode=Timer.ONE_SHOT,
callback=lambda t: print("once"))
periodic = Timer(-1)
periodic.init(period=2_000, mode=Timer.PERIODIC,
callback=lambda t: print("tick"))
周期值以毫秒为单位。调用 deinit() 可停止并释放该槽。
实时时钟¶
machine.RTC 可在复位之间,以及(在后部焊盘接上可选的 3.3 V 备用电池后,参见 电源引脚)在完全断电之间保持挂钟时间:
from machine import RTC
rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0)) # Y, M, D, weekday, h, m, s, subsec
print(rtc.datetime())
RTC 在深度睡眠期间也会继续运行,因此你可以将其用作 machine.deepsleep() 的唤醒源。
看门狗¶
machine.WDT 会在应用程序卡死时复位开发板。一旦启动便无法停止或重新配置 —— 请在主循环内定期对其喂狗:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
启动与运行时信息¶
USB 引导加载程序窗口¶
每次上电时,摄像头都会运行一段短暂的引导加载程序(几秒钟),让 OpenMV IDE 无需用户进入 DFU 模式即可更新固件。窗口期结束后,引导加载程序会移交给 boot.py,然后是 main.py。
正在运行的脚本可以通过调用 machine.bootloader() 按需重新进入引导加载程序:
import machine
machine.bootloader()
文件系统与启动顺序¶
RT1062 固件在启动时最多挂载三个文件系统:
内部 flash —— 始终挂载在
/flash。默认保存main.py和README.txt;在首次启动时创建。microSD 卡 —— 如果插入了卡,它会挂载在
/sdcard。ROMFS —— 位于
/rom的只读、内存映射文件系统,用于装载受益于零拷贝访问的大型数据资源(例如 AI 模型)。由 MicroPython 在启动时、在任何用户 Python 运行之前自动挂载。
挂载完成后,当存在卡时工作目录被设为 /sdcard,否则为 /flash。然后解释器会从该目录运行脚本:
boot.py在每次软复位时执行(冷启动、从 REPL 按Ctrl‑D,或每当正在运行的脚本返回时)。main.py仅在冷启动时执行,紧接在boot.py之后。后续的软复位会重新运行boot.py,但会直接进入 REPL —— 要重新运行main.py,你必须完全复位开发板。
将 boot.py 或 main.py 放到 SD 卡上,会覆盖 flash 中的副本而不触碰它 —— 这两个文件都在启动目录中查找(挂载了卡时为 /sdcard,否则为 /flash)。
刚刷写好的开发板上随附的默认 main.py 只是将用户 RGB LED 的蓝色通道作为心跳进行闪烁(两次短脉冲,短间隔),这样你无需连接任何主机即可判断固件已正常启动。
sys.path 被扩展以包含全部三个文件系统及其 lib/ 子目录,因此可导入的模块可以存放在 /flash/lib、/sdcard/lib 或 /rom/lib 中。
若要强制系统忽略已插入的 SD 卡(例如即使存在卡也运行 flash 中的 main.py),请在 /flash 根目录创建一个名为 SKIPSD 的空文件。
通过 USB 连接时,启动文件系统(存在卡时为 /sdcard,否则为 /flash)也会在主机上枚举为一个 USB 大容量存储驱动器,让你可以直接编辑 boot.py、main.py 及任何其他文件。在复位摄像头前请先弹出驱动器,以便主机刷新其缓存的写入。
备注
由于操作系统将该驱动器视为被动的块设备,由 OpenMV Cam 上运行的代码创建或修改的文件,在主机重新挂载该驱动器之前不会显示。如果操作系统和 OpenMV Cam 同时写入同一文件系统,操作系统会占上风并覆盖摄像头所做的更改。脚本写回的任何数据请使用 SD 卡,并在从主机读取这些文件前重新挂载。
备注
当主机正在从 USB 大容量存储驱动器读取或向其写入时,用户 RGB LED 的红色通道可能会短暂点亮 —— 这是固件驱动的活动指示,而非故障。
存储容量¶
RT1062 随附:
/flash—— 4 MB FAT 文件系统,可读写。/rom—— 8 MB 只读内存映射 ROMFS,用于装载受益于零拷贝 mmap 访问的脚本和 ML 模型。/sdcard—— 已插入的 microSD 卡(如果存在)的完整容量,可读写。
硬故障指示¶
如果用户 RGB LED 在所有颜色之间快速循环 —— 快到看起来更像一颗闪烁的白色 LED 而非各自分明的色调 —— 那么固件已遇到不可恢复的硬故障。重新刷写固件即可恢复;如果重新刷写也无济于事,开发板可能已物理损坏。
软件库¶
完整的模块列表(包括哪些是 RT1062 构建版本独有的)请参见 库索引。