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.

OpenMV AE3

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

Pinout OpenMV AE3 PAG7936

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()

Uživatelské tlačítko

AE3 má jedno uživatelské tlačítko (SW):

from machine import Pin

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

Chcete-li desku uvést do hlubokého spánku a probudit ji tlačítkem SW, stačí zavolat machine.deepsleep() — není potřeba žádná konfigurace probuzení, tlačítko je zapojeno přímo na vstup probuzení:

import machine

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

Tlačítko SW můžete také zapojit jako softwarový vypínač. Spouštějte na náběžné hraně — linka se po uvolnění tlačítka uživatelem ustálí na vysoké úrovni, takže další stisk je jednoznačně událostí probuzení:

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.

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_remote se 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 /rom HP 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 Vread_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í obsahuje main.py a README.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.py se spustí při každém softwarovém resetu (studený start, Ctrl‑D z REPL nebo kdykoli běžící skript skončí).

  • main.py se spustí pouze při studeném startu, ihned po boot.py. Následné softwarové resety znovu spustí boot.py, ale přejdou rovnou do REPL — pro opětovné spuštění main.py musí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.

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

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