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.
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ı¶
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.8V — B2B 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()
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_remotegö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
/romROMFS’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 olarakmain.pyveREADME.txtdosyaları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’denCtrl‑Dveya ç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ırlamalarboot.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:
/flash— 8 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_remotegö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.