OpenMV AE3

OpenMV AE3, Alif Ensemble E3 üzerine kuruludur — iki çip üstü NPU’ya (400 MHz / 204 GOPS HP NPU + 160 MHz / 46 GOPS HE NPU) sahip, çift ARM Cortex‑M55 SoC’tur (400 MHz HP çekirdeği + 160 MHz HE çekirdeği). Kart, NPU’ları PAG7936 1 MP global‑shutter sensörü, USB‑C high‑speed, Wi‑Fi, Bluetooth 5.1, bir LSM6DSM IMU, bir mikrofon ve 8×8 VL53L8CX time‑of‑flight mesafe ölçer ile birlikte 30 × 30 mm’lik tek bir kartta bir araya getirir.

OpenMV AE3

Eksiksiz veri sayfası, fotoğraflar ve boyutlar için OpenMV AE3 ürün sayfasına bakın.

Öne Çıkanlar

  • Alif Ensemble E3 — Helium 128‑bit SIMD’li çift ARM Cortex‑M55, 400 MHz HP çekirdeği + 160 MHz HE çekirdeği (~640 / ~256 DMIPS, CoreMark 1748 / 752).

  • Çift NPU: AI/ML için 400 MHz / 204 GOPS HP NPU + 160 MHz / 46 GOPS HE NPU — diğer iş yükleriyle birlikte YOLO nesne tespiti çalıştırır.

  • Ölçeklendirme için donanımsal 2D GPU.

  • 13,5 MB dahili SRAM ile birlikte 5,5 MB çip üstü MRAM ve 32 MB harici octal flash bellek (100 MHz 8‑bit DDR, 200 MB/s okuma).

  • Çip üstü RTC ile birlikte 4 KB yedek RAM.

  • PAG7936 1 MP renkli global‑shutter sensör.

  • Kart üstü IMU (LSM6DSM ivmeölçer + jiroskop), mikrofon ve VL53L8CX 8×8 time‑of‑flight sensör (4 m’ye kadar).

  • EMI filtrelemesi ve TVS korumalı high‑speed USB‑C (480 Mb/s), Wi‑Fi a/b/g/n + Bluetooth 5.1 (çip anten veya U.FL seçeneği).

  • 10 kullanıcı I/O pini — yan başlıklardaki P0–P3, Qwiic konnektöründeki P4–P5 ve arkadaki B2B başlığındaki P6–P9. Ek hata ayıklama ve kurtarma hatları da B2B başlığına yönlendirilmiştir.

  • Tüm pinler 3,3 V çıkış / 3,3 V toleranslı, pin başına 25 mA, kesme yeteneğine sahiptir. ADC girişleri 1,8 V referanslıdır.

  • Kullanıcı RGB LED’i, kullanıcı düğmesi, kurtarma anahtarı, Qwiic konnektörü.

  • 3,3 V’ta 80 µA derin uyku (24 mA boşta, 50–60 mA aktif).

Uyarı

AE3’ün I/O pinleri 5 V toleranslı değildir. Cihazı Arduino Mega gibi bir 5 V MCU’ya doğrudan bağlamayın — herhangi bir 5 V sinyali için bir seviye dönüştürücü kullanın.

Pin Çıkış Şeması

OpenMV AE3 PAG7936 Pin Çıkış Şeması

Pin referansı

AE3, yan başlıklarda 10 kullanıcı pini (P0–P9) sunar. JTAG ve kurtarma hattı da dahil olmak üzere ek sinyaller, shield’lar ve taşıyıcı kartlar için kartın arkasındaki bir B2B (kart‑kart) başlığına yönlendirilir.

Pin adı

Referans

İşlev

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 (yalnızca B2B)

P7

1,8 V

I2C1 SCL / UART3 RTS / TIM9 T1 (yalnızca B2B)

P8

1,8 V

I3C SDA / UART3 RX / TIM5 T0 / ADC ch S10 (yalnızca B2B)

P9

1,8 V

I3C SCL / UART3 TX / TIM5 T1 / ADC ch S11 (yalnızca B2B)

P10

1,8 V

GPIO / JTAG TCK (yalnızca B2B)

P11

1,8 V

GPIO / JTAG TDO (yalnızca B2B)

P13

1,8 V

GPIO / JTAG TMS (yalnızca B2B)

P14

1,8 V

GPIO / JTAG TDI (yalnızca B2B)

RESET

3,3 V

kartı sıfırlamak için GND’ye çekin

SW

3,3 V

kullanıcı düğmesi (aktif düşük)

LED_RED

3,3 V

RGB LED kırmızı kanalı (aktif düşük)

LED_GREEN

3,3 V

RGB LED yeşil kanalı (aktif düşük)

LED_BLUE

3,3 V

RGB LED mavi kanalı (aktif düşük)

Not

P0–P5 yan başlıklardadır (3,3 V referanslı); P6–P9 yalnızca kartın arkasındaki B2B başlığında sunulur ve 1,8 V referanslıdır. 1,8 V referanslı bir pine 3,3 V uygulamak SoC’a zarar verir — B2B başlığına bağlanan herhangi bir sinyalin 1,8 V’ta olduğundan emin olun.

Güç pinleri

  • 3.3V — AE3’ün ana güç rayı. Aynı 3,3 V rayı GPIO başlığının lehim pedlerinde, Qwiic konnektöründe ve kartın arkasındaki B2B başlığında sunulur.

  • 1.8VB2B başlığında yalnızca çıkış olarak sunulur. Bunu bir B2B taşıyıcısındaki 1,8 V mantık çevre birimlerini beslemek için kullanın; kartın dışından sürmeyin.

  • GND — ortak toprak.

AE3’ün VIN pini ve LiPo şarj cihazı yoktur. Üç yoldan biriyle beslenebilir:

  • USB‑C — kart üstü regülatör, USB’den gelen 5 V’u 3,3 V’a düşürür ve bunu 3,3 V rayına aktarır.

  • Qwiic konnektörü — kartı bir Qwiic modülünden beslemek için Qwiic başlığına regüle edilmiş bir 3,3 V besleme uygulayın.

  • GPIO başlığı / B2B 3,3 V pedleri — I/O başlığındaki veya B2B konnektöründeki herhangi bir 3,3 V pedine regüle edilmiş bir 3,3 V besleme uygulayın.

USB regülatörü rayı bir ideal diyot üzerinden besler, böylece Qwiic / GPIO / B2B tarafındaki harici 3,3 V beslemeler, USB hâlâ takılıyken bile USB regülatörünü geri sürmeden kartı besleyebilir.

Tüyo

AE3’ün belirli bir aktif / derin uyku görev döngüsünde bir pil ile ne kadar çalışacağını modellemek için pil ömrü tahmin aracını kullanın.

Kurtarma ve hata ayıklama pinleri

  • RESET — kartı sıfırlamak için GND’ye çekin. Serbest bırakmak SoC’un normal şekilde başlamasını sağlar.

Kartın ön (kamera tarafı) yüzünde, sol alt köşede bir kurtarma anahtarı vardır. Etkinleştirildiğinde, AE3’ün SE UART’ını USB üzerinden zorlar, böylece OpenMV IDE kart üstü önyükleyiciyi (bootloader) yeniden flashlayabilir. Aynı kurtarma modu, B2B konnektöründeki RECOVERY pinini düşüğe çekerek uzaktan da tetiklenebilir.

AE3 hem SWD hem de tam JTAG hata ayıklamayı destekler:

  • Kartın yanındaki 1,8 V SWD başlığı bir Tag-Connect ECV3-06-CTX kablosu içindir ve dört SWD sinyalini (TCK / TMS / TDO / RSTN) ve GND’yi dışa çıkarır.

  • Kartın arkasındaki B2B başlığı aynı hata ayıklama pinlerini (P10 = TCK, P11 = TDO, P13 = TMS, P14 = TDI) ve ayrıca sistem RSTN ile ayrı bir JTAG RSTN‘yi sunar. Bu pinler SWD (TCK + TMS) veya tam JTAG için kullanılabilir; JTAG RSTN hattı yalnızca tam JTAG modunda gereklidir.

Tüm hata ayıklama sinyalleri 1,8 V referanslıdır — bağlamadan önce hata ayıklama adaptörünüzün 1,8 V mantık için yapılandırıldığından emin olun.

Kart üstü çevre birimleri

LED’ler

AE3’ün machine.LED aracılığıyla yazılımdan kontrol edilebilen tek bir kullanıcı RGB LED’i vardır:

from machine import LED

LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()

Kullanıcı düğmesi

AE3’ün tek bir kullanıcı düğmesi (SW) vardır:

from machine import Pin

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

Kartı derin uykuya geçirmek ve SW ile tekrar uyandırmak için yalnızca machine.deepsleep() çağırın — herhangi bir uyandırma yapılandırması gerekmez, düğme doğrudan bir uyandırma girişine bağlıdır:

import machine

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

SW‘yi bir yumuşak güç anahtarı olarak da bağlayabilirsiniz. Yükselen kenarda tetikleyin — kullanıcı düğmeyi bıraktıktan sonra hat yükseğe oturur, böylece bir sonraki basış kesin olarak bir uyandırma olayıdır:

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 sensörü

PAG7936, csi — kamera sensörleri modülü aracılığıyla sürülür:

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 tetiklemeli modu destekler — piksel entegrasyonu, serbest çalışan çerçeve saati yerine her bir csi.CSI.snapshot çağrısıyla tam olarak hizalanır; bu, yakalamayı harici bir olaya veya başka bir sensöre senkronize etmek için kullanışlıdır. Bunu csi.CSI.ioctl aracılığıyla csi.IOCTL_SET_TRIGGERED_MODE ile etkinleştirin. Okuma artık bir sonraki çerçevenin entegrasyonuyla ardışık çalışmadığı için çerçeve hızı serbest çalışan modun yaklaşık yarısına düşer:

cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)

NPU

AE3’ün iki çip üstü NPU’su (400 MHz / 204 GOPS HP NPU + 160 MHz / 46 GOPS HE NPU) ml — Makine Öğrenmesi modülü aracılığıyla sunulur. Salt okunur /rom dosya sisteminde depolanan modeller, RAM’e kopyalanmadan doğrudan flash bellekten yüklenir, böylece büyük tespit ediciler bile canlı çerçeve arabelleğinin (frame buffer) yanına rahatça sığar. Her çerçevede bir YOLOv8 tespit edici çalıştırın ve tahminleri canlı görüntünün üzerine çizin:

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 çekirdeği

AE3, tek bir MCU içinde iki Cortex‑M55 çekirdeği paketler: ana MicroPython örneğini, kamerayı, HP NPU’yu, USB’yi vb. çalıştıran yüksek performanslı (HP) çekirdek; ve çok daha düşük güçte duran ve kendi küçük MicroPython örneğine önyükleme yapan yüksek verimli (HE) çekirdek. Her iki çekirdek de bir Open-AMP / RPMsg mesaj veri yolunu paylaşır, böylece HP çekirdeği Python işlevlerini HE çekirdeğine gönderebilir, sonuçları geri alabilir ve iki yarımı birbirinden ayrı tutabilir.

En basit giriş noktası @openamp.async_remote dekoratörüdür. Bir Python işlevini paketler, HE çekirdeğine gönderir ve HE çekirdeği bunu bir asyncio görevi olarak çalıştırır. Görevleri kaydettikten sonra, openamp.RemoteProc‘u HE aygıt yazılımının (firmware) flash adresiyle örnekleyin ve ikinci çekirdeği önyüklemek için rproc.start() çağırın. Geri çağırma (callback) olmadan, dekore edilen işlevin print() çıktısı varsayılan uç nokta üzerinden HP çekirdeğinin stdout’una iletilir — bir “hello world” için kullanışlıdır:

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)

Çift yönlü mesajlaşma için dekoratöre bir geri çağırma (callback) iletin. Geri çağırma, HE görevi ept.send() çağırdığında HP çekirdeğinde çalışır:

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 çekirdeğinin kendi HE NPU‘su (160 MHz, 46 GOPS) vardır, böylece HP çekirdeğinin HP NPU’su ne ile meşgulse onunla paralel olarak ikinci bir ML modeli çalıştırabilir. Kullanışlı bir bölüşüm, HE tarafına küçük, her zaman açık bir tetikleyici / sınıflandırıcı model koymak ve HP çekirdeğinin yalnızca ilginç bir şey işaretlendiğinde tepki vermesini sağlamaktır — kart üstü mikrofondan anahtar kelime algılama buna iyi uyar çünkü süreklidir, düşük bant genişliklidir ve HE çekirdeği HP’den çok daha düşük güçte kalır. Dondurulmuş ml.apps.MicroSpeech yardımcısı kutudan çıktığı gibi “Yes” ve “No” kelimelerini tanır — tespiti tetiklemek için kelimeleri kart üstü mikrofona yüksek ve net bir şekilde söyleyin:

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)

Daha zengin bir bölüşüm için, HE çekirdeği arka planda anahtar kelime algılamayı işlerken HP NPU’da BlazeFace çalıştırın — HP döngüsü en son duyulan anahtar kelimeyi kamera çerçevesi üzerine bindirir:

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 çekirdeği, HP tarafındaki kamera/NPU işlem hattıyla yarışmasını istemediğiniz her zaman açık veya düşük hızlı iş yükleri için çok uygundur — küçük ML çıkarımı, mikrofon veya IMU verileri üzerinde hafif DSP ve benzeri arka plan işleri.

Akılda tutulması gereken birkaç kısıtlama:

  • HE çekirdeğinden çevre birimlerini sürerken mikrofon ve IMU’ya bağlı kalın — HE tarafı bunlar için tasarlanmıştır. Her çevre birimi aynı anda yalnızca bir çekirdeğe ait olabilir, bu nedenle bunun için HP veya HE seçin ve betiğin ömrü boyunca buna bağlı kalın.

  • Her @openamp.async_remote görev gövdesi 500 bayttan az mpy bytecode’a paketlenmelidir — işlevi küçük tutun ve daha ağır mantığı aygıt yazılımına (firmware) dondurulan ayrı kütüphane modüllerine ayırın.

  • Gönderilen işlev içindeki içe aktarmalar yalnızca HE çekirdeğinin dosya sisteminde var olan modülleri görür. HE çekirdeğinin kendi /rom ROMFS’i vardır — HP çekirdeğinin /rom‘undan ayrıdır — bu nedenle HE’de kullanılabilir olmasını istediğiniz modüller ve ML modelleri HP olanına değil, HE tarafındaki ROMFS imajına gömülmelidir.

Mikrofon

Kart üstü mikrofon audio — Audio Modülü aracılığıyla yakalanır. Her arabellek işaretli‑16‑bit PCM bytearray olarak gelir, bu da hızlı DSP için ulab/numpy‘a beslemeyi son derece kolaylaştırır. Basit bir ses yüksekliği algılayıcısı — RMS ses seviyesi bir eşiği aştığında yazdırır:

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

Kart üstü LSM6DSM ivmeölçer + jiroskop, imu — imu sensörü aracılığıyla sunulur:

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 sensörü

AE3, çerçeve başına 64 mesafe okuması döndüren, ~4 m maksimum menzile sahip bir VL53L8CX 8×8 çok bölgeli time‑of‑flight sensörü taşır. Bu, tof — uçuş süresi sensörü sürücüsü modülü aracılığıyla sunulur — sensörü başlatmak için tof.init(), derinlik çerçevesini milimetre okumalarından oluşan düz bir liste (bölge başına bir tane) olarak almak için tof.read_depth() çağırın:

import tof

tof.init()
while True:
    depth, depth_min, depth_max = tof.read_depth()
    print("min:", depth_min, "mm  max:", depth_max, "mm")

Derinlik dizisi, ana sensörden gelen bir renkli çerçevenin üzerine de çizilebilir — tof.draw_depth() onu mevcut bir image.Image üzerine boyar, tof.snapshot() ise yeni oluşturulmuş bir derinlik görüntüsü döndürür:

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

Kart üstü CYW43439, network — ağ yapılandırması aracılığıyla bir istasyon arabirimi olarak sunulur. Bağlandıktan sonra ipconfig("addr4") (ip, netmask) çiftini döndürür:

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

Aynı CYW43439 ayrıca Bluetooth 5.1 sunar. asyncio dostu BLE için aioble — Asenkron BLE kullanın — örneğin, bir çevre birimi olarak yayın yapın ve bir merkezin bağlanmasını bekleyin:

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

Veri yolu referansı

GPIO

Serigrafi baskılı pinlerden herhangi birini okumak veya sürmek için machine.Pin kullanın. Çıkışlar 3,3 V CMOS’tur ve pin başına 25 mA’e kadar çekebilir/sağlayabilir.

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

Herhangi bir giriş pini, kenar geçişlerinde bir kesme de tetikleyebilir:

def handler(pin):
    print("triggered:", pin)

Pin("P1", Pin.IN, Pin.PULL_UP).irq(
    handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)

UART

Veri yolu

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, donanımsal akış kontrolüne sahip tek veri yoludur. P6–P9 B2B başlığında bulunduğu ve 1,8 V referanslı olduğu için, UART3 yalnızca bir seviye dönüştürücü veya bir B2B taşıyıcısı aracılığıyla çalışır — ona doğrudan 3,3 V mantık bağlamayın.

I²C

Veri yolu

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

Kart üstü Qwiic konnektörü I2C2‘yi 3,3 V‘ta dışa çıkarır.

I2C1 ve I2C2, bir bellek bölgesini başka bir I²C denetleyicisine sunmak için machine.I2CTarget aracılığıyla hedef (slave) modunda da kullanılabilir:

from machine import I2CTarget

buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)

Not

LPI2C çevre birimi aygıt yazılımında sunulmaz. Sunulsaydı yalnızca hedef (slave) modunu desteklerdi ve I2C1 ile I2C2 zaten hem denetleyici hem de hedef çalışmasını kapsar.

SPI

Veri yolu

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, P8 ve P9 üzerinde (yalnızca B2B başlığı) iki 12‑bit ADC kanalı sunar. Her iki giriş de 1,8 V referanslıdır — read_u16, pindeki 0–1,8 V aralığında 0–65535 döndürür:

from machine import ADC
import time

adc = ADC("P8")
while True:
    voltage = adc.read_u16() * 1.8 / 65535
    print(voltage)
    time.sleep_ms(100)

Uyarı

AE3’ün ADC girişleri 3,3 V değil, 1,8 V referanslıdır. Ham bir 3,3 V sinyali sürmek dönüştürücüyü doyurur ve pine zarar verebilir — daha yüksek gerilimleri harici olarak bölün.

PWM

Pin

Zamanlayıcı / kanal

P0

TIM0 T1

P1

TIM0 T0

P2

TIM1 T1

P3

TIM1 T0

P4

TIM2 T1

P5

TIM2 T0

P6

TIM9 T0 (yalnızca B2B)

P7

TIM9 T1 (yalnızca B2B)

P8

TIM5 T0 (yalnızca B2B)

P9

TIM5 T1 (yalnızca B2B)

Bunlardan herhangi birini machine.PWM aracılığıyla sürün:

from machine import Pin, PWM

pwm = PWM(Pin("P0"), freq=1_000, duty_u16=32768)

Yazılım bit‑banged veri yolları

Ekstra bir veri yoluna ihtiyacınız varsa machine.SoftI2C ve machine.SoftSPI herhangi bir GPIO’da çalışır.

Termal sensör (kart dışı)

Aygıt yazılımı, harici olarak bağlanmış bir AMG8833 8 × 8 termal görüntüleyici için fir — termal sensör sürücüsü (fir == far infrared) sürücüsünü içerir. Modülü aşağıda listelenen I²C veri yoluna bağlayın, ardından fir.init() + fir.snapshot() ile çerçeveleri okuyun:

import time
import image
import fir

fir.init()                          # auto‑detects the sensor
clock = time.clock()

while True:
    clock.tick()
    try:
        img = fir.snapshot(x_scale=5, y_scale=5,
                           color_palette=image.PALETTE_IRONBOW,
                           hint=image.BICUBIC,
                           copy_to_fb=True)
    except OSError:
        continue
    print(clock.fps())

fir sürücüsü sensörle yalnızca I²C 1 üzerinden konuşur — modülü P4 (SCL) ve P5 (SDA)’ya bağlayın.

Zamanlama

time

time modülü, bloklayan gecikmeleri, monoton tikleri ve geçen süre ölçümünü kapsar:

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)

Sanal zamanlayıcılar

machine.Timer, bir donanım zamanlayıcı yuvası tüketmeden periyodik veya tek seferlik geri çağırmaları (callback) zamanlar. Sanal (yazılım) bir zamanlayıcı kullanmak için id olarak -1 iletin:

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

Periyot değerleri milisaniye cinsindendir. Yuvayı durdurmak ve serbest bırakmak için deinit() çağırın.

Gerçek zamanlı saat

machine.RTC, derin uykuyu atlatan 4 KB çip üstü yedek RAM ile desteklenerek sıfırlamalar boyunca duvar saati zamanını korur:

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 ayrıca derin uyku boyunca çalışır, böylece bunu machine.deepsleep() için bir uyandırma kaynağı olarak kullanabilirsiniz.

Önyükleme ve çalışma zamanı bilgisi

USB önyükleyici penceresi

Her açılışta kamera, kullanıcının DFU moduna girmesine gerek kalmadan OpenMV IDE’nin aygıt yazılımını güncellemesine olanak tanıyan kısa bir önyükleyici (birkaç saniye) çalıştırır. Pencere sona erdikten sonra önyükleyici boot.py‘a ve ardından main.py‘a kontrolü devreder.

Çalışan bir betik, machine.bootloader() çağırarak istek üzerine önyükleyiciye yeniden girebilir:

import machine

machine.bootloader()

Dosya sistemi ve önyükleme sırası

AE3 aygıt yazılımı, önyüklemede en fazla iki dosya sistemi bağlar:

  • Dahili flash bellek — her zaman /flash‘ta bağlıdır. Varsayılan olarak main.py ve README.txt dosyalarını barındırır; ilk önyüklemede oluşturulur.

  • ROMFS — sıfır kopya erişimden yararlanan büyük veri varlıklarını (örn. AI modelleri) göndermek için kullanılan, /rom‘da salt okunur, belleğe eşlenmiş dosya sistemi. Herhangi bir kullanıcı Python’u çalışmadan önce, başlangıçta MicroPython tarafından otomatik olarak bağlanır.

Bağlandıktan sonra çalışma dizini /flash olarak ayarlanır. Yorumlayıcı ardından betikleri o dizinden çalıştırır:

  • boot.py, her yumuşak sıfırlamada (soğuk önyükleme, REPL’den Ctrl‑D veya çalışan betik döndüğünde) çalıştırılır.

  • main.py, boot.py‘dan hemen sonra yalnızca soğuk önyüklemede çalıştırılır. Sonraki yumuşak sıfırlamalar boot.py‘ı yeniden çalıştırır ancak doğrudan REPL’e düşer — main.py‘ı yeniden çalıştırmak için kartı tamamen sıfırlamanız gerekir.

Yeni flashlanmış bir kartta gönderilen varsayılan main.py, yalnızca bir kalp atışı olarak kullanıcı RGB LED’inin mavi kanalını yakıp söndürür (iki kısa darbe, kısa boşluk), böylece herhangi bir ana bilgisayar bağlı olmadan aygıt yazılımının temiz bir şekilde önyüklendiğini anlayabilirsiniz.

sys.path, her iki dosya sistemini ve onların lib/ alt dizinlerini içerecek şekilde genişletilir, böylece içe aktarılabilir modüller /flash/lib veya /rom/lib‘de bulunabilir.

USB üzerinden bağlandığında, /flash ayrıca ana bilgisayarda bir USB yığın depolama sürücüsü olarak görünür ve boot.py, main.py ile diğer dosyaları doğrudan düzenlemenize olanak tanır. Ana bilgisayarın önbelleğe alınmış yazmalarını boşaltması için kamerayı sıfırlamadan önce sürücüyü çıkarın.

Not

İşletim sistemi sürücüyü pasif bir blok aygıtı olarak ele aldığından, OpenMV Cam üzerinde çalışan kod tarafından oluşturulan veya değiştirilen dosyalar, ana bilgisayar sürücüyü yeniden bağlayana kadar görünmez. Hem işletim sistemi hem de OpenMV Cam aynı dosya sistemine aynı anda yazarsa, işletim sistemi kazanır ve kamera tarafından yapılan değişikliklerin üzerine yazar.

Not

Ana bilgisayar USB yığın depolama sürücüsünden okurken veya ona yazarken kullanıcı RGB LED’inin kırmızı kanalı kısa süreliğine yanabilir — bu bir arıza değil, aygıt yazılımı tarafından sürülen bir etkinlik göstergesidir.

Depolama boyutları

AE3 şunlarla birlikte gelir:

  • /flash8 MB FAT dosya sistemi, okuma/yazma.

  • HP çekirdeğindeki /rom — HP çekirdeğinin başlangıçta yüklediği betikler ve veriler için 24 MB salt okunur, belleğe eşlenmiş ROMFS.

  • HE çekirdeğindeki /rom — HE çekirdeğine ait 1 MB salt okunur ROMFS. @openamp.async_remote görevlerine sunulmasını istediğiniz modüller ve ML modelleri, HP olanına değil, bu imaja gömülmelidir.

Donanımsal hata (hard‑fault) göstergesi

Kullanıcı RGB LED’i tüm renkler arasında hızla geçiş yapıyorsa — belirgin tonlardan ziyade parıldayan beyaz bir LED gibi görünecek kadar hızlı — aygıt yazılımı kurtarılamaz bir donanımsal hatayla (hard fault) karşılaşmıştır. Kurtarmak için aygıt yazılımını yeniden flashlayın; yeniden flashlamak yardımcı olmazsa, kart fiziksel olarak hasar görmüş olabilir.

Yazılım kütüphaneleri

Modüllerin tam listesi için — AE3 yapısına özgü olanlar da dahil — kütüphane dizinine bakın.