OpenMV AE3¶
OpenMV AE3 je postaven kolem čipu Alif Ensemble E3 — dvoujádrového SoC ARM Cortex‑M55 (400MHz HP jádro + 160MHz HE jádro) se dvěma integrovanými NPU (400MHz / 204 GOPS HP NPU + 160MHz / 46 GOPS HE NPU). Deska kombinuje NPU se senzorem PAG7936 s globální závěrkou a rozlišením 1 MP, vysokorychlostním USB‑C, Wi‑Fi, Bluetooth 5.1, IMU LSM6DSM, mikrofonem a 8×8 time‑of‑flight dálkoměrem VL53L8CX, vše na desce o rozměrech 30 × 30 mm.
Kompletní datasheet, fotografie a rozměry najdete na produktové stránce OpenMV AE3.
Hlavní vlastnosti¶
Alif Ensemble E3 — dvojité ARM Cortex‑M55 se 128bitovým SIMD Helium, 400MHz HP jádro + 160MHz HE jádro (~640 / ~256 DMIPS, CoreMark 1748 / 752).
Dvě NPU: 400MHz / 204 GOPS HP NPU + 160MHz / 46 GOPS HE NPU pro AI/ML — spouští detekci objektů YOLO souběžně s dalšími úlohami.
Hardwarové 2D GPU pro škálování.
13,5 MB interní SRAM plus 5,5 MB integrované MRAM a 32 MB externí oktální flash paměti (100 MHz 8bitová DDR, čtení 200 MB/s).
4 KB zálohovací RAM s integrovaným RTC.
PAG7936 barevný senzor 1 MP s globální závěrkou.
Integrované IMU (akcelerometr + gyroskop LSM6DSM), mikrofon a 8×8 time‑of‑flight senzor VL53L8CX (až 4 m).
Vysokorychlostní USB‑C (480 Mb/s) s EMI filtrací a TVS ochranou, Wi‑Fi a/b/g/n + Bluetooth 5.1 (čipová anténa nebo varianta U.FL).
10 uživatelských I/O pinů — P0–P3 na bočních konektorech, P4–P5 na konektoru Qwiic a P6–P9 na B2B konektoru na zadní straně. Na B2B konektor jsou vyvedeny také další ladicí a obnovovací linky.
Všechny piny mají výstup 3,3 V / toleranci 3,3 V, 25 mA na pin, s podporou přerušení. Vstupy ADC jsou vztažené k 1,8 V.
Uživatelská RGB LED, uživatelské tlačítko, obnovovací přepínač, konektor Qwiic.
80 µA v hlubokém spánku při 3,3 V (24 mA v klidu, 50–60 mA při činnosti).
Varování
I/O piny AE3 nejsou tolerantní k 5 V. Nepřipojujte zařízení přímo k 5V MCU, jako je Arduino Mega — pro jakýkoli 5V signál použijte převodník úrovní.
Pinout¶
Přehled pinů¶
AE3 vyvádí 10 uživatelských pinů na bočních konektorech (P0–P9). Další signály — včetně JTAG a obnovovací linky — jsou vyvedeny na B2B (board‑to‑board) konektor na zadní straně desky pro shieldy a nosné desky.
Název pinu |
Reference |
Funkce |
|---|---|---|
P0 |
3,3 V |
SPI0 MOSI / I2C2 SCL / UART4 TX / TIM0 T1 / PDM D3 |
P1 |
3,3 V |
SPI0 MISO / I2C2 SDA / UART4 RX / TIM0 T0 |
P2 |
3,3 V |
SPI0 SCLK / LPI2C SDA / UART5 TX / TIM1 T1 |
P3 |
3,3 V |
SPI0 SS / LPI2C SCL / UART5 RX / TIM1 T0 / PDM C3 |
P4 |
3,3 V |
I2C1 SCL / UART1 TX / TIM2 T1 / PDM C0 / CAN TX |
P5 |
3,3 V |
I2C1 SDA / UART1 RX / TIM2 T0 / PDM D0 / CAN RX |
P6 |
1,8 V |
I2C1 SDA / UART3 CTS / TIM9 T0 (pouze B2B) |
P7 |
1,8 V |
I2C1 SCL / UART3 RTS / TIM9 T1 (pouze B2B) |
P8 |
1,8 V |
I3C SDA / UART3 RX / TIM5 T0 / ADC ch S10 (pouze B2B) |
P9 |
1,8 V |
I3C SCL / UART3 TX / TIM5 T1 / ADC ch S11 (pouze B2B) |
P10 |
1,8 V |
GPIO / JTAG TCK (pouze B2B) |
P11 |
1,8 V |
GPIO / JTAG TDO (pouze B2B) |
P13 |
1,8 V |
GPIO / JTAG TMS (pouze B2B) |
P14 |
1,8 V |
GPIO / JTAG TDI (pouze B2B) |
RESET |
3,3 V |
stáhněte na GND pro reset desky |
SW |
3,3 V |
uživatelské tlačítko (aktivní v nule) |
LED_RED |
3,3 V |
červený kanál RGB LED (aktivní v nule) |
LED_GREEN |
3,3 V |
zelený kanál RGB LED (aktivní v nule) |
LED_BLUE |
3,3 V |
modrý kanál RGB LED (aktivní v nule) |
Poznámka
P0–P5 jsou na bočních konektorech (vztažené k 3,3 V); P6–P9 jsou vyvedeny pouze na B2B konektoru na zadní straně desky a jsou vztažené k 1,8 V. Přivedení 3,3 V na pin vztažený k 1,8 V poškodí SoC — ujistěte se, že každý signál připojený k B2B konektoru má úroveň 1,8 V.
Napájecí piny¶
3.3V — hlavní napájecí větev AE3. Stejná 3,3V větev je vyvedena na pájecí plošky GPIO konektoru, na konektor Qwiic a na B2B konektor na zadní straně desky.
1.8V — vyvedeno na B2B konektor pouze jako výstup. Slouží k napájení periferií s logikou 1,8 V na B2B nosné desce; nenapájejte tento pin z vnějšku desky.
GND — společná zem.
AE3 nemá pin VIN ani nabíječku LiPo. Lze ji napájet jednou ze tří cest:
USB‑C — regulátor na desce sníží 5 V z USB na 3,3 V a přivede je na 3,3V větev.
Konektor Qwiic — přiveďte stabilizovaných 3,3 V na konektor Qwiic a napájejte desku z modulu Qwiic.
GPIO konektor / B2B 3,3V plošky — přiveďte stabilizovaných 3,3 V na kteroukoli z 3,3V plošek na I/O konektoru nebo na B2B konektoru.
Regulátor USB napájí větev přes ideální diodu, takže externí 3,3V zdroje na straně Qwiic / GPIO / B2B mohou napájet desku i při stále připojeném USB, aniž by zpětně napájely USB regulátor.
Tip
Použijte odhad výdrže baterie k modelování toho, jak dlouho AE3 vydrží na baterii při daném pracovním cyklu činnost / hluboký spánek.
Piny pro obnovení a ladění¶
RESET — stáhněte na GND pro reset desky. Uvolnění umožní SoC normální spuštění.
Na přední (kamerové) straně desky, v levém dolním rohu se nachází obnovovací přepínač. Pokud je aktivován, vynutí vyvedení SE UART AE3 přes USB, aby OpenMV IDE mohlo přeflashovat bootloader na desce. Stejný režim obnovení lze spustit i vzdáleně stažením pinu RECOVERY na B2B konektoru do nuly.
AE3 podporuje ladění jak přes SWD, tak plné JTAG:
1,8V SWD konektor na boku desky je určen pro kabel Tag-Connect ECV3-06-CTX a vyvádí čtyři SWD signály (TCK / TMS / TDO / RSTN) plus GND.
B2B konektor na zadní straně desky vyvádí stejné ladicí piny (P10 = TCK, P11 = TDO, P13 = TMS, P14 = TDI) plus systémový RSTN a samostatný JTAG RSTN. Tyto piny lze použít buď pro SWD (TCK + TMS), nebo plné JTAG; linka JTAG RSTN je potřeba pouze v režimu plného JTAG.
Všechny ladicí signály jsou vztažené k 1,8 V — před připojením se ujistěte, že je váš ladicí adaptér nakonfigurován pro logiku 1,8 V.
Periferie na desce¶
LED¶
AE3 má jednu uživatelskou RGB LED, softwarově ovladatelnou přes machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
Senzor kamery¶
PAG7936 je řízen přes modul csi — kamerové senzory
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.HD) # 1280×800
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
PAG7936 podporuje spouštěný (triggered) režim — integrace pixelů je přesně sladěna s každým voláním csi.CSI.snapshot, nikoli s volně běžícím snímkovým hodinovým signálem, což je užitečné pro synchronizaci snímání s externí událostí nebo jiným senzorem. Povolte jej přes csi.CSI.ioctl pomocí csi.IOCTL_SET_TRIGGERED_MODE. Snímková frekvence klesne zhruba na polovinu volně běžícího režimu, protože vyčítání už není zřetězeno s integrací dalšího snímku:
cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)
NPU¶
Dvě integrovaná NPU AE3 (400MHz / 204 GOPS HP NPU + 160MHz / 46 GOPS HE NPU) jsou přístupná přes modul ml — Strojové učení. Modely uložené na souborovém systému /rom určeném pouze pro čtení se načítají přímo z flash paměti bez kopírování do RAM, takže i velké detektory se pohodlně vejdou vedle živého framebufferu. Spusťte detektor YOLOv8 na každém snímku a vykreslete predikce na živý obraz:
import csi
import time
import ml
from ml.postprocessing.ultralytics import YoloV8
# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
# Load YOLO V8 model from ROM FS.
model = ml.Model("/rom/yolov8n_192.tflite", postprocess=YoloV8(threshold=0.4))
print(model)
# Visualization parameters.
n = len(model.labels)
model_class_colors = [
(int(255 * i // n), int(255 * (n - i - 1) // n), 255)
for i in range(n)
]
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# boxes is a list of list per class of ((x, y, w, h), score) tuples
boxes = model.predict([img])
# Draw bounding boxes around the detected objects
for i, class_detections in enumerate(boxes):
rects = [r for r, score in class_detections]
labels = [model.labels[i] for j in range(len(rects))]
colors = [model_class_colors[i] for j in range(len(rects))]
ml.utils.draw_predictions(img, rects, labels, colors, format=None)
print(clock.fps(), "fps")
HE jádro¶
AE3 obsahuje dvě jádra Cortex‑M55 v jednom MCU: vysoce výkonné (HP) jádro, které spouští hlavní instanci MicroPython, kameru, HP NPU, USB atd.; a vysoce úsporné (HE) jádro, které pracuje s mnohem nižší spotřebou a zavádí vlastní malou instanci MicroPython. Obě jádra sdílejí sběrnici zpráv Open-AMP / RPMsg, takže HP jádro může předávat Python funkce HE jádru, získávat zpět výsledky a udržovat obě poloviny oddělené.
Nejjednodušším vstupním bodem je dekorátor @openamp.async_remote. Ten serializuje Python funkci, odešle ji na HE jádro a HE jádro ji spustí jako asyncio úlohu. Po registraci úloh vytvořte instanci openamp.RemoteProc s flash adresou HE firmwaru a zavolejte rproc.start() pro spuštění druhého jádra. Bez callbacku je výstup print() dekorované funkce předáván přes výchozí endpoint na stdout HP jádra — užitečné pro „hello world“:
import time
import openamp
@openamp.async_remote
async def task1(ept):
import asyncio
while True:
print("Hello from the HE core!")
await asyncio.sleep(1)
# Boot the HE core. This runs the registered tasks.
rproc = openamp.RemoteProc(0x80320000)
rproc.start()
while True:
print("Hello from the HP core!")
time.sleep(1)
Pro obousměrnou komunikaci předejte dekorátoru callback. Callback běží na HP jádru pokaždé, když HE úloha zavolá ept.send()
import time
import openamp
def task_callback(src_addr, data):
print("HP received:", data.decode())
@openamp.async_remote(task_callback)
async def task1(ept):
import asyncio
count = 0
while True:
ept.send(f"count = {count}")
count += 1
await asyncio.sleep(1)
rproc = openamp.RemoteProc(0x80320000)
rproc.start()
while True:
time.sleep(1)
HE jádro má vlastní HE NPU (160 MHz, 46 GOPS), takže může spouštět druhý ML model paralelně s tím, čím je zaneprázdněno HP NPU na HP jádru. Užitečné rozdělení je umístit malý vždy zapnutý spouštěcí / klasifikační model na stranu HE a nechat HP jádro reagovat, jen když je označeno něco zajímavého — rozpoznávání klíčových slov z mikrofonu na desce se hodí dobře, protože je kontinuální, s nízkou šířkou pásma a HE jádro zůstává na mnohem nižší spotřebě než HP. Zamrazený pomocník ml.apps.MicroSpeech rozpoznává „Yes“ a „No“ rovnou po vybalení — řekněte tato slova nahlas a zřetelně do mikrofonu na desce pro spuštění detekce:
import time
import openamp
def task_callback(src_addr, data):
print("Heard:", data.decode())
@openamp.async_remote(task_callback)
async def task1(ept):
from ml.apps import MicroSpeech
speech = MicroSpeech(gain_db=24)
while True:
label, scores = speech.listen(timeout=0, threshold=0.70)
if label:
ept.send(label)
rproc = openamp.RemoteProc(0x80320000)
rproc.start()
while True:
time.sleep(1)
Pro bohatší rozdělení spusťte BlazeFace na HP NPU, zatímco HE jádro na pozadí zpracovává rozpoznávání klíčových slov — HP smyčka překryje nejnovější slyšené klíčové slovo na snímek z kamery:
import csi
import time
import openamp
import ml
from ml.postprocessing.mediapipe import BlazeFace
label = None
label_ticks = 0
LABEL_HOLD_MS = 2000
def task_callback(src_addr, data):
global label, label_ticks
label = data.decode()
label_ticks = time.ticks_ms()
@openamp.async_remote(task_callback)
async def task1(ept):
from ml.apps import MicroSpeech
speech = MicroSpeech(gain_db=24)
while True:
l, scores = speech.listen(timeout=0, threshold=0.70)
if l:
ept.send(l)
# Start the HE core before initializing the camera on the HP core.
rproc = openamp.RemoteProc(0x80320000)
rproc.start()
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))
model = ml.Model("/rom/blazeface_front_128.tflite",
postprocess=BlazeFace(threshold=0.4))
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
for r, score, keypoints in model.predict([img]):
ml.utils.draw_predictions(img, [r], ("face",),
((0, 0, 255),), format=None)
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
if label is not None:
if time.ticks_diff(time.ticks_ms(), label_ticks) < LABEL_HOLD_MS:
img.draw_string((4, 4), f"Heard: {label}",
color=(255, 0, 0), scale=2)
else:
label = None
print(clock.fps(), "fps")
HE jádro se dobře hodí pro vždy zapnuté nebo nízkofrekvenční úlohy, u nichž nechcete, aby soupeřily s pipeline kamera/NPU na straně HP — drobné ML inference, lehký DSP nad daty z mikrofonu nebo IMU a podobné úlohy na pozadí.
Několik omezení, která je třeba mít na paměti:
Při ovládání periferií z HE jádra se držte mikrofonu a IMU — na ty je strana HE navržena. Každou periferii může v daném okamžiku vlastnit pouze jedno jádro, takže pro ni vyberte HP nebo HE a držte se toho po celou dobu běhu skriptu.
Tělo každé úlohy
@openamp.async_remotese musí serializovat do méně než 500 bajtů mpy bytecode — funkci udržujte malou a náročnější logiku vyčleňte do samostatných knihovních modulů, které se zamrazí do firmwaru.Importy uvnitř předané funkce vidí pouze moduly, které existují na souborovém systému HE jádra. HE jádro má vlastní ROMFS
/rom— oddělený od/romHP jádra — takže moduly a ML modely, které chcete mít k dispozici na HE, musí být zapečené do ROMFS obrazu na straně HE, ne do toho na straně HP.
Mikrofon¶
Mikrofon na desce je snímán přes audio — Modul Audio. Každý buffer přichází jako 16bitový PCM bytearray se znaménkem, což usnadňuje jeho předání do ulab/numpy pro rychlý DSP. Jednoduchý detektor hlasitosti — vypíše zprávu pokaždé, když efektivní hodnota (RMS) hlasitosti překročí práh:
import audio
from ulab import numpy as np
def loudness(pcmbuf):
samples = np.array(np.frombuffer(pcmbuf, dtype=np.int16), dtype=np.float)
rms = np.sqrt(np.mean(samples ** 2))
if rms > 10000:
print("Loud!", int(rms))
audio.init(channels=1, frequency=16000, gain_db=24)
audio.start_streaming(loudness)
while True:
pass
IMU¶
Akcelerometr + gyroskop LSM6DSM na desce je přístupný přes imu — imu senzor
import imu
import time
while True:
print(imu.acceleration_mg()) # (x, y, z) in milli‑g
print(imu.angular_rate_mdps()) # (x, y, z) in milli‑deg/s
time.sleep_ms(100)
Time‑of‑flight senzor¶
AE3 nese 8×8 vícezónový time‑of‑flight senzor VL53L8CX, který vrací až 64 měření vzdálenosti na snímek s maximálním dosahem ~4 m. Je přístupný přes modul tof — ovladač time-of-flight senzoru — zavoláním tof.init() spustíte senzor a tof.read_depth() získá snímek hloubky jako plochý seznam měření v milimetrech (jedno na zónu):
import tof
tof.init()
while True:
depth, depth_min, depth_max = tof.read_depth()
print("min:", depth_min, "mm max:", depth_max, "mm")
Pole hloubky lze také vykreslit přes barevný snímek z hlavního senzoru — tof.draw_depth() jej namaluje na existující image.Image, zatímco tof.snapshot() vrátí čerstvě vykreslený hloubkový obraz:
import image
import tof
import csi
# Bring up the VL53L8CX time-of-flight sensor.
tof.init()
# Configure the main camera at VGA RGB565.
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.VGA)
# Off-screen framebuffer used to compose the camera frame and the
# up-scaled depth heat-map side by side before pushing the result
# back to the live preview.
b = image.Image(640, 480, image.RGB565)
while True:
# Grab a colour frame from the main camera.
img = cam.snapshot()
try:
# Capture TOF data [depth map, min distance, max distance].
# vflip / hmirror align the ToF orientation with the camera.
depth, dmin, dmax = tof.read_depth(vflip=True, hmirror=True)
# Zones with no return read back as 0.0 — clamp them to the
# frame's max distance so the colour palette doesn't show
# them as "closest".
for i in range(0, len(depth)):
if depth[i] == 0.0:
depth[i] = dmax
except RuntimeError:
# The sensor occasionally faults on a frame; reset and skip.
tof.reset()
continue
# Draw the camera frame into the left half of the framebuffer,
# scaled to 60% so it leaves room for the depth heat-map on
# the right.
b.draw_image(img, x=0, y=64+8, x_scale=0.6, hint=image.BILINEAR)
# Up-sample the 8x8 depth array 30x with bicubic smoothing and
# blend it into the right half using the depth palette.
# scale=(0, 400) maps 0-400 mm to the full palette range.
tof.draw_depth(b, depth, x=320+64+16, y=64+8, alpha=255,
hint=image.BICUBIC, x_scale=30, y_scale=30,
scale=(0, 400), color_palette=image.PALETTE_DEPTH)
# Copy the composed framebuffer back into the live preview so
# OpenMV IDE shows both panels.
img.set(b)
Wi‑Fi¶
Čip CYW43439 na desce je přístupný přes network — konfigurace sítě jako rozhraní stanice. Po připojení vrátí ipconfig("addr4") dvojici (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])
Bluetooth¶
Stejný čip CYW43439 také poskytuje Bluetooth 5.1. Použijte aioble — Asynchronní BLE pro BLE přátelské k asyncio — například inzerujte jako periferie a čekejte na připojení centrálního zařízení:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="OpenMV-AE3")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
Přehled sběrnic¶
GPIO¶
Použijte machine.Pin ke čtení nebo ovládání kteréhokoli z pinů popsaných na potisku. Výstupy jsou 3,3 V CMOS a mohou zatékat/dodávat až 25 mA na pin.
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())
Kterýkoli vstupní pin může také vyvolat přerušení při změnách hrany:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Sběrnice |
TX |
RX |
RTS |
CTS |
|---|---|---|---|---|
UART1 |
P4 |
P5 |
— |
— |
UART3 |
P9 |
P8 |
P7 |
P6 |
UART4 |
P0 |
P1 |
— |
— |
UART5 |
P2 |
P3 |
— |
— |
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
UART3 je jediná sběrnice s hardwarovým řízením toku. Protože P6–P9 leží na B2B konektoru a jsou vztažené k 1,8 V, UART3 funguje pouze přes převodník úrovní nebo B2B nosnou desku — nepřipojujte k němu přímo logiku 3,3 V.
I²C¶
Sběrnice |
SCL |
SDA |
|---|---|---|
I2C1 |
P4 |
P5 |
I2C2 |
P0 |
P1 |
LPI2C |
P3 |
P2 |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Konektor Qwiic na desce vyvádí I2C2 na úrovni 3,3 V.
I2C1 a I2C2 lze také použít v cílovém (slave) režimu přes machine.I2CTarget pro zpřístupnění paměťové oblasti jinému I²C řadiči:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
Poznámka
Periferie LPI2C není ve firmwaru přístupná. Pokud by byla vyvedena, podporovala by pouze cílový (slave) režim a I2C1 a I2C2 již pokrývají jak provoz řadiče, tak cíle.
SPI¶
Sběrnice |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI0 |
P0 |
P1 |
P2 |
P3 |
from machine import SPI
from machine import Pin
spi = SPI(0, 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)
ADC¶
Alif Ensemble E3 vyvádí dva 12bitové ADC kanály na P8 a P9 (pouze B2B konektor). Oba vstupy jsou vztažené k 1,8 V — read_u16 vrací 0–65535 v rozsahu 0–1,8 V na pinu:
from machine import ADC
import time
adc = ADC("P8")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
Varování
Vstupy ADC AE3 jsou vztažené k 1,8 V, nikoli 3,3 V. Přivedení surového 3,3V signálu nasytí převodník a může poškodit pin — vyšší napětí externě vydělte děličem.
PWM¶
Pin |
Časovač / kanál |
|---|---|
P0 |
TIM0 T1 |
P1 |
TIM0 T0 |
P2 |
TIM1 T1 |
P3 |
TIM1 T0 |
P4 |
TIM2 T1 |
P5 |
TIM2 T0 |
P6 |
TIM9 T0 (pouze B2B) |
P7 |
TIM9 T1 (pouze B2B) |
P8 |
TIM5 T0 (pouze B2B) |
P9 |
TIM5 T1 (pouze B2B) |
Ovládejte kterýkoli z nich přes machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P0"), freq=1_000, duty_u16=32768)
Softwarově bit‑bangované sběrnice¶
machine.SoftI2C a machine.SoftSPI fungují na kterémkoli GPIO, pokud potřebujete další sběrnici.
Teplotní senzor (mimo desku)¶
Firmware obsahuje ovladač fir — ovladač termálního senzoru (fir == far infrared, vzdálené infračervené záření) pro externě zapojený 8 × 8 termální zobrazovač AMG8833. Připojte modul k I²C sběrnici uvedené níže a poté čtěte snímky pomocí 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())
Ovladač fir komunikuje se senzorem pouze přes I²C 1 — zapojte modul na P4 (SCL) a P5 (SDA).
Časování¶
time¶
Modul time pokrývá blokující prodlevy, monotónní tiky a měření uplynulého času:
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)
Virtuální časovače¶
machine.Timer plánuje periodické nebo jednorázové callbacky bez obsazení hardwarového časovačového slotu. Předejte -1 jako id pro použití virtuálního (softwarového) časovače:
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"))
Hodnoty periody jsou v milisekundách. Zavoláním deinit() časovač zastavíte a uvolníte slot.
Hodiny reálného času¶
machine.RTC udržuje aktuální čas přes resety, podporováno 4 KB integrované zálohovací RAM, která přežije hluboký spánek:
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 běží i během hlubokého spánku, takže jej můžete použít jako zdroj probuzení pro machine.deepsleep().
Informace o spuštění a běhu¶
Okno USB bootloaderu¶
Při každém zapnutí spustí kamera krátký bootloader (několik sekund), který umožní OpenMV IDE aktualizovat firmware, aniž by uživatel musel vstupovat do režimu DFU. Po vypršení okna bootloader předá řízení boot.py a poté main.py.
Běžící skript může na vyžádání znovu vstoupit do bootloaderu zavoláním machine.bootloader()
import machine
machine.bootloader()
Souborový systém a pořadí spouštění¶
Firmware AE3 připojuje při spuštění až dva souborové systémy:
Interní flash — vždy připojen na
/flash. Ve výchozím nastavení obsahujemain.pyaREADME.txt; vytvoří se při úplně prvním spuštění.ROMFS — souborový systém pouze pro čtení s mapováním do paměti na
/rom, který slouží k dodávání velkých datových aktiv (např. AI modelů), jež těží z přístupu bez kopírování. MicroPython jej připojuje automaticky při startu, ještě před spuštěním jakéhokoli uživatelského Pythonu.
Po připojení je pracovní adresář nastaven na /flash. Interpret poté spouští skripty z tohoto adresáře:
boot.pyse spustí při každém softwarovém resetu (studený start,Ctrl‑Dz REPL nebo kdykoli běžící skript skončí).main.pyse spustí pouze při studeném startu, ihned poboot.py. Následné softwarové resety znovu spustíboot.py, ale přejdou rovnou do REPL — pro opětovné spuštěnímain.pymusíte desku plně resetovat.
Výchozí main.py dodávaný na čerstvě naflashované desce pouze bliká modrým kanálem uživatelské RGB LED jako tep (dva krátké pulzy, krátká pauza), takže poznáte, že firmware nabootoval čistě i bez připojeného hostitele.
sys.path je rozšířen tak, aby zahrnoval oba souborové systémy a jejich podadresáře lib/, takže importovatelné moduly mohou být umístěny v /flash/lib nebo /rom/lib.
Při připojení přes USB se /flash na hostiteli rovněž zaregistruje jako USB úložiště (mass‑storage), což vám umožní upravovat boot.py, main.py a jakékoli další soubory přímo. Před resetem kamery disk vysuňte (eject), aby hostitel vyprázdnil své zápisy z mezipaměti.
Poznámka
Protože OS zachází s diskem jako s pasivním blokovým zařízením, soubory vytvořené nebo upravené kódem běžícím na OpenMV Cam se neobjeví, dokud hostitel disk znovu nepřipojí. Pokud OS i OpenMV Cam zapisují na stejný souborový systém současně, OS zvítězí a přepíše změny provedené kamerou.
Poznámka
Červený kanál uživatelské RGB LED se může krátce rozsvítit, když hostitel čte z USB úložiště nebo na něj zapisuje — jedná se o indikátor aktivity řízený firmwarem, nikoli o chybu.
Velikosti úložiště¶
AE3 se dodává s:
/flash— souborový systém FAT o velikosti 8 MB, pro čtení i zápis./romna HP jádru — 24 MB ROMFS pouze pro čtení s mapováním do paměti pro skripty a data, která HP jádro načítá při startu./romna HE jádru — 1 MB ROMFS pouze pro čtení vlastněný HE jádrem. Moduly a ML modely, které chcete mít k dispozici pro úlohy@openamp.async_remote, musí být zapečeny do tohoto obrazu, ne do toho na HP.
Indikátor závažné chyby (hard‑fault)¶
Pokud uživatelská RGB LED rychle cyklicky přechází přes všechny barvy — natolik rychle, že to spíše vypadá jako třpytivá bílá LED než jednotlivé odstíny — firmware narazil na neobnovitelnou závažnou chybu (hard fault). K obnově přeflashujte firmware; pokud přeflashování nepomůže, deska může být fyzicky poškozena.
Softwarové knihovny¶
Kompletní seznam modulů — včetně toho, které jsou jedinečné pro sestavení AE3 — najdete v indexu knihoven.