OpenMV AE3¶
Az OpenMV AE3 az Alif Ensemble E3 köré épül — ez egy kétmagos ARM Cortex‑M55 SoC (400 MHz‑es HP mag + 160 MHz‑es HE mag), amely két beépített NPU‑t tartalmaz (400 MHz / 204 GOPS HP NPU + 160 MHz / 46 GOPS HE NPU). A panel az NPU‑kat a PAG7936 1 MP‑es global‑shutter érzékelővel, nagy sebességű USB‑C‑vel, Wi‑Fi‑vel, Bluetooth 5.1‑gyel, egy LSM6DSM IMU‑val, egy mikrofonnal és egy 8×8‑as VL53L8CX time‑of‑flight távolságmérővel párosítja, mindezt egy 30 × 30 mm‑es panelon.
A teljes adatlapért, fényképekért és méretekért lásd az OpenMV AE3 termékoldalt.
Kiemelt jellemzők¶
Alif Ensemble E3 — kétmagos ARM Cortex‑M55 Helium 128 bites SIMD‑del, 400 MHz‑es HP mag + 160 MHz‑es HE mag (~640 / ~256 DMIPS, CoreMark 1748 / 752).
Két NPU: 400 MHz / 204 GOPS HP NPU + 160 MHz / 46 GOPS HE NPU az AI/ML‑hez — más feladatokkal párhuzamosan YOLO objektumészlelést futtat.
Hardveres 2D GPU a méretezéshez.
13,5 MB belső SRAM plusz 5,5 MB beépített MRAM és 32 MB külső octal flash memória (100 MHz 8 bites DDR, 200 MB/s olvasás).
4 KB tartalék RAM a beépített RTC‑vel.
PAG7936 1 MP‑es színes global‑shutter érzékelő.
Beépített IMU (LSM6DSM gyorsulásmérő + giroszkóp), mikrofon és VL53L8CX 8×8 time‑of‑flight érzékelő (akár 4 m‑ig).
Nagy sebességű USB‑C (480 Mb/s) EMI‑szűréssel és TVS‑védelemmel, Wi‑Fi a/b/g/n + Bluetooth 5.1 (chipantenna vagy U.FL opció).
10 felhasználói I/O láb — P0–P3 az oldalsó tűsorokon, P4–P5 a Qwiic csatlakozón, P6–P9 pedig a hátoldali B2B tűsoron. További hibakeresési és helyreállítási vonalak szintén a B2B tűsorra vannak kivezetve.
Minden láb 3,3 V kimenet / 3,3 V tűrésű, 25 mA lábanként, megszakításra képes. Az ADC bemenetek 1,8 V referenciájúak.
Felhasználói RGB LED, felhasználói gomb, helyreállítási kapcsoló, Qwiic csatlakozó.
80 µA mély alvás 3,3 V mellett (24 mA tétlen, 50–60 mA aktív).
Figyelem
Az AE3 I/O lábai nem 5 V tűrésűek. Ne csatlakoztasd az eszközt közvetlenül egy 5 V‑os MCU‑hoz, mint az Arduino Mega — használj szintillesztőt minden 5 V‑os jelhez.
Lábkiosztás¶
Lábkiosztási referencia¶
Az AE3 10 felhasználói lábat (P0–P9) tesz elérhetővé az oldalsó tűsorokon. További jelek — köztük a JTAG és a helyreállítási vonal — a panel hátoldalán lévő B2B (board‑to‑board) tűsorra vannak kivezetve a shieldek és hordozópanelek számára.
Láb neve |
Referencia |
Funkció |
|---|---|---|
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 (csak B2B) |
P7 |
1,8 V |
I2C1 SCL / UART3 RTS / TIM9 T1 (csak B2B) |
P8 |
1,8 V |
I3C SDA / UART3 RX / TIM5 T0 / ADC ch S10 (csak B2B) |
P9 |
1,8 V |
I3C SCL / UART3 TX / TIM5 T1 / ADC ch S11 (csak B2B) |
P10 |
1,8 V |
GPIO / JTAG TCK (csak B2B) |
P11 |
1,8 V |
GPIO / JTAG TDO (csak B2B) |
P13 |
1,8 V |
GPIO / JTAG TMS (csak B2B) |
P14 |
1,8 V |
GPIO / JTAG TDI (csak B2B) |
RESET |
3,3 V |
húzd GND‑re a panel újraindításához |
SW |
3,3 V |
felhasználói gomb (aktív alacsony) |
LED_RED |
3,3 V |
RGB LED vörös csatorna (aktív alacsony) |
LED_GREEN |
3,3 V |
RGB LED zöld csatorna (aktív alacsony) |
LED_BLUE |
3,3 V |
RGB LED kék csatorna (aktív alacsony) |
Megjegyzés
A P0–P5 lábak az oldalsó tűsorokon vannak (3,3 V referenciájúak); a P6–P9 lábak csak a panel hátoldalán lévő B2B tűsoron érhetők el, és 1,8 V referenciájúak. Ha 3,3 V‑ot hajtasz egy 1,8 V referenciájú lábra, az megrongálja a SoC‑ot — győződj meg róla, hogy a B2B tűsorra kötött minden jel 1,8 V‑on van.
Tápláb¶
3.3V — az AE3 fő táprendszere. Ugyanaz a 3,3 V‑os sín a GPIO tűsor forrasztófelületein, a Qwiic csatlakozón és a panel hátoldalán lévő B2B tűsoron is elérhető.
1.8V — a B2B tűsoron csak kimenetként elérhető. Használd 1,8 V‑os logikájú perifériák táplálására egy B2B hordozópanelen; ne hajtsd kívülről a panelra.
GND — közös föld.
Az AE3‑nak nincs VIN lába és nincs LiPo töltője. Három útvonal valamelyikén keresztül táplálható:
USB‑C — a beépített feszültségszabályozó az USB 5 V‑ját 3,3 V‑ra csökkenti, és ezt juttatja a 3,3 V‑os sínre.
Qwiic csatlakozó — hajts egy szabályozott 3,3 V‑os tápot a Qwiic tűsorra a panel Qwiic modulról való táplálásához.
GPIO tűsor / B2B 3,3 V felületek — hajts egy szabályozott 3,3 V‑os tápot az I/O tűsor vagy a B2B csatlakozó bármelyik 3,3 V‑os felületére.
Az USB feszültségszabályozó egy ideális diódán keresztül táplálja a sínt, így a Qwiic / GPIO / B2B oldali külső 3,3 V‑os tápok akkor is táplálhatják a panelt, amikor az USB még csatlakoztatva van, anélkül hogy visszahajtanák az USB feszültségszabályozót.
Javaslat
Használd az akkumulátor‑élettartam becslőt annak modellezésére, hogy egy adott aktív / mély alvás kitöltési tényező mellett mennyi ideig fut az AE3 egy akkumulátorról.
Helyreállítási és hibakeresési lábak¶
RESET — húzd GND‑re a panel újraindításához. Elengedve a SoC normálisan elindul.
A panel elülső (kamera felőli) oldalán, a bal alsó sarokban található egy helyreállítási kapcsoló. Bekapcsolva az AE3 SE UART‑ját az USB‑re kényszeríti, így az OpenMV IDE újraírhatja a beépített rendszerbetöltőt. Ugyanez a helyreállítási mód távolról is kiváltható a B2B csatlakozó RECOVERY lábának alacsonyra húzásával.
Az AE3 mind SWD, mind teljes JTAG hibakeresést támogat:
A panel oldalán lévő 1,8 V‑os SWD tűsor egy Tag-Connect ECV3-06-CTX kábelhez való, és a négy SWD jelet (TCK / TMS / TDO / RSTN) plusz a GND‑t vezeti ki.
A panel hátoldalán lévő B2B tűsor ugyanazokat a hibakeresési lábakat teszi elérhetővé (P10 = TCK, P11 = TDO, P13 = TMS, P14 = TDI), plusz a rendszer RSTN vonalát és egy külön JTAG RSTN vonalat. Ezek a lábak SWD‑hez (TCK + TMS) vagy teljes JTAG‑hoz is használhatók; a JTAG RSTN vonalra csak teljes JTAG módban van szükség.
Minden hibakeresési jel 1,8 V referenciájú — csatlakoztatás előtt győződj meg róla, hogy a hibakereső adaptered 1,8 V‑os logikára van konfigurálva.
Beépített perifériák¶
LED‑ek¶
Az AE3‑nak egyetlen felhasználói RGB LED‑je van, amely szoftveresen vezérelhető a machine.LED segítségével:
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
Kameraérzékelő¶
A PAG7936 a csi — kameraérzékelők modulon keresztül vezérelhető:
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()
A PAG7936 támogatja a triggerelt módot — a képpont‑integráció pontosan minden egyes csi.CSI.snapshot híváshoz igazodik, nem a szabadon futó képkocka‑órajelhez, ami hasznos a felvétel egy külső eseményhez vagy egy másik érzékelőhöz való szinkronizálásához. Engedélyezd a csi.CSI.ioctl segítségével a csi.IOCTL_SET_TRIGGERED_MODE paranccsal. A képkockasebesség nagyjából a szabadon futó mód felére esik, mivel a kiolvasás már nem fűzhető össze a következő képkocka integrációjával:
cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)
NPU¶
Az AE3 két beépített NPU‑ja (400 MHz / 204 GOPS HP NPU + 160 MHz / 46 GOPS HE NPU) a ml — Gépi tanulás modulon keresztül érhető el. A csak olvasható /rom fájlrendszeren tárolt modellek közvetlenül a flash memóriából töltődnek be RAM‑ba másolás nélkül, így még a nagy detektorok is kényelmesen elférnek az élő képkocka‑puffer mellett. Futtass egy YOLOv8 detektort minden képkockán, és rajzold a predikciókat az élő kép tetejére:
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 mag¶
Az AE3 két Cortex‑M55 magot csomagol egyetlen MCU‑ba: a nagy teljesítményű (HP) magot, amely a fő MicroPython példányt, a kamerát, a HP NPU‑t, az USB‑t és így tovább futtatja; valamint a nagy hatékonyságú (HE) magot, amely sokkal alacsonyabb fogyasztáson üzemel, és egy saját, kicsi MicroPython példányba indul. Mindkét mag egy Open-AMP / RPMsg üzenetbuszon osztozik, így a HP mag Python‑függvényeket küldhet a HE magnak, visszakaphatja az eredményeket, és a két felet függetlenül tarthatja.
A legegyszerűbb belépési pont a @openamp.async_remote dekorátor. Becsomagol egy Python‑függvényt, elküldi a HE magnak, és a HE mag asyncio feladatként futtatja. A feladatok regisztrálása után hozz létre egy openamp.RemoteProc példányt a HE firmware flash‑címével, és hívd meg a rproc.start()‑ot a második mag elindításához. Visszahívás nélkül a dekorált függvény print() kimenete az alapértelmezett végponton keresztül a HP mag stdout‑jára továbbítódik — ami praktikus egy „hello world” esetén:
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)
Kétirányú üzenetküldéshez adj át egy visszahívást a dekorátornak. A visszahívás a HP magon fut, valahányszor a HE feladat meghívja az ept.send()‑et:
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)
A HE magnak saját HE NPU‑ja van (160 MHz, 46 GOPS), így egy második ML modellt futtathat párhuzamosan azzal, amivel a HP mag HP NPU‑ja éppen el van foglalva. Egy hasznos felosztás az, ha egy kicsi, mindig bekapcsolt trigger / osztályozó modellt teszel a HE oldalra, és a HP magot csak akkor reagáltatod, ha valami érdekeset jelez — a beépített mikrofonból történő kulcsszófelismerés jó választás, mert folyamatos, kis sávszélességű, és a HE mag sokkal alacsonyabb fogyasztáson marad, mint a HP. A befagyasztott ml.apps.MicroSpeech segéd a dobozból kivéve felismeri az „Yes” és „No” szavakat — mondd ki a szavakat hangosan és tisztán a beépített mikrofonba az észlelés kiváltásához:
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)
Egy gazdagabb felosztásért futtass BlazeFace‑t a HP NPU‑n, miközben a HE mag a háttérben a kulcsszófelismerést végzi — a HP ciklus a legutóbb hallott kulcsszót a kamera képkockájára vetíti:
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")
A HE mag jól alkalmas mindig bekapcsolt vagy alacsony frekvenciájú feladatokra, amelyeket nem akarsz versenyeztetni a HP oldali kamera/NPU folyamattal — kicsi ML következtetés, könnyűsúlyú DSP a mikrofon‑ vagy IMU‑adatokon, és hasonló háttérfeladatok.
Néhány figyelembe veendő megkötés:
Maradj a mikrofonnál és az IMU‑nál, amikor perifériákat hajtasz a HE magról — ezek azok, amelyekre a HE oldalt tervezték. Minden perifériát egyszerre csak egy mag birtokolhat, ezért válassz hozzá HP‑t vagy HE‑t, és maradj annál a szkript teljes élettartama alatt.
Minden
@openamp.async_remotefeladattörzsnek 500 bájtnál kevesebb mpy bájtkódra kell becsomagolódnia — tartsd kicsiben a függvényt, és szervezd ki a nehezebb logikát külön könyvtármodulokba, amelyek a firmware‑be fagyasztódnak.A kiküldött függvényen belüli importok csak azokat a modulokat látják, amelyek a HE mag fájlrendszerén léteznek. A HE magnak saját
/romROMFS‑e van — a HP mag/rom‑jától elkülönülve —, így azokat a modulokat és ML modelleket, amelyeket a HE oldalon elérhetővé akarsz tenni, a HE oldali ROMFS image‑be kell beépíteni, nem a HP‑ba.
Mikrofon¶
A beépített mikrofon a audio — Audio modul modulon keresztül rögzíthető. Minden puffer előjeles 16 bites PCM bytearray‑ként érkezik, ami triviálissá teszi a ulab/numpy modulba való betáplálását gyors DSP céljából. Egy egyszerű hangerő‑detektor — írj ki valamit, valahányszor az RMS hangerő átlép egy küszöbértéket:
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¶
A beépített LSM6DSM gyorsulásmérő + giroszkóp a imu — imu érzékelő modulon keresztül érhető el:
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 érzékelő¶
Az AE3 egy VL53L8CX 8×8‑as többzónás time‑of‑flight érzékelőt hordoz, amely képkockánként akár 64 távolságmérést ad vissza, ~4 m‑es maximális hatótávval. A tof — time-of-flight érzékelő meghajtó modulon keresztül érhető el — hívd meg a tof.init() függvényt az érzékelő indításához, és a tof.read_depth() függvényt egy mélységi képkocka megszerzéséhez milliméteres mérések lapos listájaként (zónánként egy):
import tof
tof.init()
while True:
depth, depth_min, depth_max = tof.read_depth()
print("min:", depth_min, "mm max:", depth_max, "mm")
A mélységi tömb a fő érzékelő színes képkockájára is rajzolható — a tof.draw_depth() egy meglévő image.Image‑re festi, míg a tof.snapshot() egy frissen renderelt mélységi képet ad vissza:
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¶
A beépített CYW43439 a network — hálózati konfiguráció modulon keresztül érhető el állomás (station) interfészként. A csatlakozás után az ipconfig("addr4") az (ip, netmask) párt adja vissza:
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¶
Ugyanaz a CYW43439 Bluetooth 5.1‑et is elérhetővé tesz. Használd a aioble — Aszinkron BLE modult az asyncio‑barát BLE‑hez — például hirdesd magad perifériaként, és várj egy központi eszköz csatlakozására:
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())
Buszreferencia¶
GPIO¶
Használd a machine.Pin osztályt bármely szitanyomott láb olvasásához vagy hajtásához. A kimenetek 3,3 V‑os CMOS‑ak, és lábanként akár 25 mA‑t tudnak nyelni/forrásolni.
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ármely bemeneti láb megszakítást is kiválthat éláttéréskor:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Busz |
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)
A UART3 az egyetlen busz hardveres folyamatvezérléssel. Mivel a P6–P9 lábak a B2B tűsoron vannak és 1,8 V referenciájúak, a UART3 csak szintillesztőn vagy egy B2B hordozópanelen keresztül működik — ne köss rá közvetlenül 3,3 V‑os logikát.
I²C¶
Busz |
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")
A beépített Qwiic csatlakozó az I2C2‑t vezeti ki 3,3 V‑on.
Az I2C1 és az I2C2 cél (slave) módban is használható a machine.I2CTarget segítségével, hogy egy memóriaterületet tegyen elérhetővé egy másik I²C vezérlő számára:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
Megjegyzés
Az LPI2C periféria nincs elérhetővé téve a firmware‑ben. Ha elérhető lenne, csak cél (slave) módot támogatna, és az I2C1 valamint az I2C2 már lefedi mind a vezérlő, mind a cél működést.
SPI¶
Busz |
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¶
Az Alif Ensemble E3 két 12 bites ADC csatornát tesz elérhetővé a P8 és P9 lábon (csak B2B tűsor). Mindkét bemenet 1,8 V referenciájú — a read_u16 0–65535‑öt ad vissza a lábon mért 0–1,8 V tartományban:
from machine import ADC
import time
adc = ADC("P8")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
Figyelem
Az AE3 ADC bemenetei 1,8 V referenciájúak, nem 3,3 V. Ha egy nyers 3,3 V‑os jelet hajtasz be, az telíti az átalakítót, és megrongálhatja a lábat — oszd le a nagyobb feszültségeket külsőleg.
PWM¶
Láb |
Időzítő / csatorna |
|---|---|
P0 |
TIM0 T1 |
P1 |
TIM0 T0 |
P2 |
TIM1 T1 |
P3 |
TIM1 T0 |
P4 |
TIM2 T1 |
P5 |
TIM2 T0 |
P6 |
TIM9 T0 (csak B2B) |
P7 |
TIM9 T1 (csak B2B) |
P8 |
TIM5 T0 (csak B2B) |
P9 |
TIM5 T1 (csak B2B) |
Hajtsd bármelyiket a machine.PWM segítségével:
from machine import Pin, PWM
pwm = PWM(Pin("P0"), freq=1_000, duty_u16=32768)
Szoftveresen bitbillegtetett buszok¶
A machine.SoftI2C és a machine.SoftSPI bármely GPIO‑n működik, ha egy extra buszra van szükséged.
Hőérzékelő (panelen kívüli)¶
A firmware tartalmazza a fir — hőérzékelő-meghajtó (fir == far infrared, távoli infravörös) illesztőprogramot egy külsőleg bekötött AMG8833 8 × 8‑as hőkamerához. Csatlakoztasd a modult az alább felsorolt I²C buszra, majd olvass be képkockákat a fir.init() + fir.snapshot() segítségével:
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())
A fir illesztőprogram csak az I²C 1‑en keresztül beszél az érzékelővel — kösd a modult a P4 (SCL) és P5 (SDA) lábakra.
Időzítés¶
time¶
A time modul lefedi a blokkoló késleltetéseket, a monoton ütemjeleket és az eltelt idő mérését:
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ális időzítők¶
A machine.Timer periodikus vagy egyszeri visszahívásokat ütemez anélkül, hogy elhasználna egy hardveres időzítő‑helyet. Adj át -1‑et azonosítóként egy virtuális (szoftveres) időzítő használatához:
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"))
A periódusértékek ezredmásodpercben vannak. Hívd meg a deinit() metódust a leállításhoz és a hely felszabadításához.
Valós idejű óra¶
A machine.RTC újraindításokon át fenntartja a falióra szerinti időt, amit 4 KB beépített tartalék RAM támogat, amely túléli a mély alvást:
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())
Az RTC a mély alvás alatt is fut, így ébresztési forrásként használhatod a machine.deepsleep() számára.
Indítási és futásidejű információk¶
USB rendszerbetöltő‑ablak¶
Minden bekapcsoláskor a kamera egy rövid rendszerbetöltőt futtat (néhány másodperc), amely lehetővé teszi az OpenMV IDE számára a firmware frissítését anélkül, hogy a felhasználónak DFU módba kellene lépnie. Az ablak lejárta után a rendszerbetöltő átadja a vezérlést a boot.py‑nak, majd a main.py‑nak.
Egy futó szkript igény szerint újra beléphet a rendszerbetöltőbe a machine.bootloader() meghívásával:
import machine
machine.bootloader()
Fájlrendszer és indítási sorrend¶
Az AE3 firmware indításkor legfeljebb két fájlrendszert csatol:
Belső flash — mindig a
/flashpontra csatolva. Alapértelmezetten amain.pyés aREADME.txtfájlokat tartalmazza; a legelső indításkor jön létre.ROMFS — csak olvasható, memóriába leképezett fájlrendszer a
/rompontnál, amelyet nagy adat‑erőforrások (pl. AI modellek) szállítására használnak, amelyek profitálnak a zero‑copy hozzáférésből. A MicroPython automatikusan csatolja indításkor, minden felhasználói Python futása előtt.
A csatolás után a munkakönyvtár a /flash lesz. Az értelmező ezután ebből a könyvtárból futtatja a szkripteket:
A
boot.pyminden szoftveres újraindításkor lefut (hidegindítás,Ctrl‑Da REPL‑ből, vagy valahányszor a futó szkript visszatér).A
main.pycsak hidegindításkor fut le, közvetlenül aboot.pyután. A későbbi szoftveres újraindítások újrafuttatják aboot.py‑t, de egyenesen a REPL‑re ugranak — amain.pyújrafuttatásához teljesen újra kell indítanod a panelt.
A frissen flashelt panelra szállított alapértelmezett main.py csak a felhasználói RGB LED kék csatornáját villogtatja szívverésként (két rövid impulzus, rövid szünet), így gazdagép csatlakoztatása nélkül is megállapíthatod, hogy a firmware tisztán elindult.
A sys.path ki van bővítve, hogy mindkét fájlrendszert és azok lib/ alkönyvtárait tartalmazza, így az importálható modulok a /flash/lib vagy a /rom/lib helyen élhetnek.
USB‑n keresztül csatlakoztatva a /flash egy USB háttértár‑meghajtóként is felsorolódik a gazdagépen, lehetővé téve a boot.py, a main.py és bármely más fájl közvetlen szerkesztését. Add ki a meghajtót a kamera újraindítása előtt, hogy a gazdagép kiürítse a gyorsítótárazott írásokat.
Megjegyzés
Mivel az operációs rendszer passzív blokkeszközként kezeli a meghajtót, az OpenMV Cam‑en futó kód által létrehozott vagy módosított fájlok nem jelennek meg, amíg a gazdagép újra nem csatolja a meghajtót. Ha az operációs rendszer és az OpenMV Cam egyszerre írja ugyanazt a fájlrendszert, az operációs rendszer győz, és felülírja a kamera által végzett változtatásokat.
Megjegyzés
A felhasználói RGB LED vörös csatornája röviden felvillanhat, miközben a gazdagép az USB háttértár‑meghajtóról olvas vagy arra ír — ez egy firmware‑vezérelt aktivitásjelző, nem hiba.
Tárolóméretek¶
Az AE3 a következőkkel kerül szállításra:
/flash— 8 MB FAT fájlrendszer, írható/olvasható./roma HP magon — 24 MB csak olvasható, memóriába leképezett ROMFS azokhoz a szkriptekhez és adatokhoz, amelyeket a HP mag indításkor betölt./roma HE magon — 1 MB csak olvasható ROMFS, amely a HE mag tulajdonában van. Azokat a modulokat és ML modelleket, amelyeket a@openamp.async_remotefeladatok számára elérhetővé akarsz tenni, ebbe az image‑be kell beépíteni, nem a HP‑ba.
Hard‑fault jelző¶
Ha a felhasználói RGB LED gyorsan végigpörög az összes színen — elég gyorsan ahhoz, hogy inkább egy csillogó fehér LED‑nek tűnjön, mint különálló árnyalatoknak —, akkor a firmware egy helyrehozhatatlan hard fault‑ba ütközött. A helyreállításhoz flasheld újra a firmware‑t; ha az újraflashelés nem segít, a panel fizikailag sérülhetett.
Szoftverkönyvtárak¶
A modulok teljes listájáért lásd a könyvtárindexet — beleértve azt is, hogy melyek egyediek az AE3 buildhez.