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.

OpenMV AE3

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

OpenMV AE3 PAG7936 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()

Felhasználói gomb

Az AE3‑nak egyetlen felhasználói gombja van (SW):

from machine import Pin

sw = Pin("SW", Pin.IN)
print(sw.value())

Ha a panelt mély alvásba akarod helyezni, és a SW gombbal akarod felébreszteni, csak hívd meg a machine.deepsleep() függvényt — nincs szükség ébresztési konfigurációra, a gomb közvetlenül egy ébresztő bemenethez van kötve:

import machine

machine.deepsleep()   # press SW to wake the board

A SW gombot szoftveres bekapcsoló kapcsolóként is bekötheted. A felfutó élre indíts — a vonal magasra áll be, miután a felhasználó elengedi a gombot, így a következő nyomás egyértelműen egy ébresztési esemény:

import machine
from machine import Pin

def power_off(_):
    machine.deepsleep()

Pin("SW", Pin.IN).irq(power_off, Pin.IRQ_RISING)

# ...rest of the application runs here. Press SW once to sleep,
# press it again to wake.

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_remote feladattö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 /rom ROMFS‑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 /flash pontra csatolva. Alapértelmezetten a main.py és a README.txt fájlokat tartalmazza; a legelső indításkor jön létre.

  • ROMFS — csak olvasható, memóriába leképezett fájlrendszer a /rom pontná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.py minden szoftveres újraindításkor lefut (hidegindítás, Ctrl‑D a REPL‑ből, vagy valahányszor a futó szkript visszatér).

  • A main.py csak hidegindításkor fut le, közvetlenül a boot.py után. A későbbi szoftveres újraindítások újrafuttatják a boot.py‑t, de egyenesen a REPL‑re ugranak — a main.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:

  • /flash8 MB FAT fájlrendszer, írható/olvasható.

  • /rom a 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.

  • /rom a HE magon — 1 MB csak olvasható ROMFS, amely a HE mag tulajdonában van. Azokat a modulokat és ML modelleket, amelyeket a @openamp.async_remote feladatok 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.