Arduino Nicla Vision¶
ה‑Arduino Nicla Vision הוא לוח ראייה ממוחשבת בגודל 22.86 × 22.86 מ“מ הבנוי סביב ה‑STMicroelectronics STM32H747AII6 — SoC דו‑ליבתי המשלב Cortex‑M7 ב‑400 MHz עם Cortex‑M4 ב‑200 MHz. קושחת OpenMV רצה כולה על ליבת ה‑M7. הלוח משלב את ה‑MCU עם חיישן CMOS צבעוני GC2145 של 2 MP, IMU בעל 6 צירים LSM6DSOX, מיקרופון MEMS מסוג MP34DT06, מד טווח מסוג time‑of‑flight VL53L1CB, Wi‑Fi + Bluetooth LE 5.1, ומטען סוללה / מד דלק.
ל‑datasheet המלא, תמונות, ומידות ראו את דף המוצר של Arduino Nicla Vision.
עיקרי המאפיינים¶
STMicroelectronics STM32H747AII6 דו‑ליבתי Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). קושחת OpenMV רצה על ליבת ה‑M7 בלבד.
2 MB זיכרון פלאש (flash) פנימי בתוספת 16 MB זיכרון פלאש (flash) חיצוני מסוג QSPI (משמש לאפליקציה + ROMFS).
1 MB SRAM פנימי.
מקודד/מפענח JPEG חומרתי.
חיישן CMOS צבעוני GC2145 של 2 MP.
IMU מובנה (מד תאוצה + ג’ירוסקופ LSM6DSOX), מיקרופון MEMS (MP34DT06JTR), ומד טווח VL53L1CB מסוג time‑of‑flight (עד ~4 מ«).
Wi‑Fi b/g/n (2.4 GHz) + Bluetooth LE 5.1 באמצעות מודול Murata 1DX (CYW4343W) — מתחבר לאנטנה המצורפת דרך מחבר U.FL שעל הלוח.
USB מהיר (480 Mb/s) דרך Micro USB באמצעות ULPI PHY חיצוני (USB3320C).
13 פיני I/O למשתמש על מחברי הקצה של Arduino — ארבעה LPIO דיגיטליים (
D0–D3), שלושה כניסות אנלוגיות של 1.8 V (A0–A2), הזוגSCL/SDAשל I²C, ורביעיית ה‑SPISCLK/CIPO/COPI/CS.תמיכה בסוללה — מחבר Li‑Po בגב, מטען בסגנון BQ, ומד דלק MAX17262 על אפיק ה‑PMIC הפנימי.
מחבר ESLOV בעל 5 פינים בגב להרחבת I²C ללא הלחמה.
אזהרה
הפינים הדיגיטליים של המשתמש הם 3.3 V כברירת מחדל אך מנותבים דרך ממירי מתח הניתנים לתכנות בתוכנה (VDDIO_EXT) שניתן להגדיר מחדש ל‑1.8 V. הפינים האנלוגיים (A0–A2) הם 1.8 V בלבד — הם עוקפים את ממירי המתח ומתחברים ישירות אל ה‑MCU. הזרמת 3.3 V אל A0–A2 תפגע ב‑SoC.
מפת פינים¶
מדריך פינים¶
שלושה‑עשר פיני משתמש חשופים על מחברי הקצה של Arduino (J1 ו‑J2). אותות נוספים של debug, שחזור, ו‑PMIC מנותבים אל test pads בגב הלוח.
שם פין |
מדריך |
פונקציה |
|---|---|---|
D0 |
3.3 V |
GPIO / LPIO0 (J1‑1) |
D1 |
3.3 V |
LPUART1 TX / TIM1 CH2 / LPIO1 (J2‑3) |
D2 |
3.3 V |
LPUART1 RX / TIM1 CH3 / LPIO2 (J2‑4) |
D3 |
3.3 V |
GPIO / LPIO3 (J2‑5) |
A0 |
1.8 V |
ADC1 channel 4 (J1‑8) |
A1 |
1.8 V |
ADC2 channel 2 (J1‑7) |
A2 |
1.8 V |
ADC3 channel 5 (J1‑2) |
SCL |
3.3 V |
I2C1 SCL / UART4 RX / TIM4 CH3 (J2‑2) |
SDA |
3.3 V |
I2C1 SDA / UART4 TX / TIM4 CH4 (J2‑1) |
SCLK |
3.3 V |
SPI4 SCK / TIM1 CH3N (J1‑6) |
CIPO |
3.3 V |
SPI4 MISO / TIM1 CH3 (J1‑5) |
COPI |
3.3 V |
SPI4 MOSI / TIM1 CH4 (J1‑4) |
CS |
3.3 V |
SPI4 NSS / TIM1 CH2 (J1‑3) |
RESET |
3.3 V |
משכו ל‑GND (או לחצו על המתג שעל הלוח) כדי לאתחל את הלוח |
LED_RED |
3.3 V |
ערוץ אדום של RGB LED (פעיל בנמוך) |
LED_GREEN |
3.3 V |
ערוץ ירוק של RGB LED (פעיל בנמוך) |
LED_BLUE |
3.3 V |
ערוץ כחול של RGB LED (פעיל בנמוך) |
הערה
D0–D3 ו‑SCLK/CIPO/COPI/CS יושבים מאחורי ממיר המתח הדו‑כיווני TXB0108 — רכיב זה תומך רק בהנעת GPIO מסוג push‑pull, כך שתעבורת אפיק מסוג open‑drain (למשל 1‑Wire או I²C מבוססי bit‑bang על אותם פינים) לא תעבוד.
SCL/SDA יושבים מאחורי ממיר נפרד NTS0304 התומך בהנעה מסוג push‑pull וגם open‑drain, ולכן I²C 1 עובד שם.
שני הממירים מיוחסים אל VDDIO_EXT (3.3 V כברירת מחדל מה‑PMIC שעל הלוח), וחוזק ההנעה שלהם מוגבל בהשוואה ל‑GPIO ישיר — הם תוכננו לעומסי אות ולא לעומסי הספק.
פיני הספק¶
פיני מחבר הקצה:
VIN (J2‑9) — מסילת המערכת הראשית 3.6 – 5 V. ה‑PMIC מקבל כאן את הכניסה שלו.
VDDIO_EXT (J2‑7) — יציאה של מסילת ממיר המתח, 1.8 V או 3.3 V (3.3 V כברירת מחדל). השתמשו בה כדי להזין התקנים היקפיים חיצוניים של 1.8 V או 3.3 V המחוברים לפיני LPIO/SPI/I²C כך שידברו באותה רמת לוגיקה כמו המחברים.
VBAT (J3‑2) — כניסת סוללת Li‑Po. ה‑PMIC שעל הלוח טוען את התא מ‑VIN ומדווח על מצב הטעינה דרך מד הדלק.
NTC (J3‑1) — כניסת תרמיסטור Li‑Po אופציונלית.
GND (J2‑6) — הארקה משותפת.
NC (J2‑8) — ללא חיבור.
Test pads בגב הלוח:
+3V3 — מסילת 3.3 V ראשית.
D_P / D_N — זוג נתוני USB מהיר (אחרי ה‑PHY).
ה‑USB ומחבר ה‑ESLOV מזינים שניהם את VIN דרך זוג דיודות אידיאליות LM66100 (אחת לכל מקור), כך שכל מקור הספק יכול להפעיל את הלוח בעצמו ושניהם לעולם אינם מניעים זה את זה לאחור. אם אתם מניעים את VIN חיצונית ב‑J2‑9, היא מקבלת עדיפות — הדיודות פשוט מפסיקות להוליך מ‑USB / ESLOV ברגע שהמסילה החיצונית עולה גבוה יותר.
ניתן אפוא להפעיל את הלוח דרך כל אחד מהמסלולים הבאים:
Micro USB — 5 V אל VIN דרך הדיודה האידיאלית שבצד ה‑USB.
מחבר ESLOV — עד 5 V על פין ה‑
VESLOVשל J5, מנותב אל VIN דרך הדיודה האידיאלית שבצד ה‑ESLOV (ראו מחבר ESLOV).פין VIN (J2‑9) — הניעו ספק מיוצב של 3.6 – 5 V ישירות.
סוללת Li‑Po — חברו למחבר הסוללה J4 בגב או לרפידות VBAT/GND/NTC על J3 / J2‑6. אל תחברו שתי סוללות בו‑זמנית.
מחבר ESLOV¶
J5 בגב הלוח הוא מחבר ESLOV של Molex בעל 5 פינים ללא הלחמה:
פין |
שם |
פונקציה |
|---|---|---|
J5‑1 |
VESLOV |
כניסת הספק (≤ 5 V) — מצורף עם OR אל |
J5‑2 |
INT |
כניסת פסיקה חיצונית על |
J5‑3 |
SCL_EXT |
משותף עם רפידת ה‑ |
J5‑4 |
SDA_EXT |
משותף עם רפידת ה‑ |
J5‑5 |
GND |
הארקה משותפת |
ה‑SCL_EXT/SDA_EXT של ESLOV וה‑SCL/SDA של J2 הם אותם פינים — אפיק I²C 1 אחד החשוף על שני מחברים.
טיפ
השתמשו במעריך חיי הסוללה כדי לדגמן כמה זמן ה‑Nicla Vision יפעל על סוללה עבור מחזור עבודה נתון של פעילות / שינה עמוקה.
פיני שחזור ו‑debug¶
RESET — גם מתג רגעי בחלק העליון של הלוח וגם רפידה (J3‑4 / test pad P5) הקשורה לקו ה‑NRST של ה‑SoC. משכו ל‑GND כדי לאתחל.
ה‑Nicla Vision משתמש ב‑double‑tap reset הסטנדרטי של Arduino כדי להיכנס ל‑bootloader של Arduino — לחצו במהירות פעמיים על כפתור ה‑reset והלוח יזוהה כהתקן DFU. OpenMV IDE משתמש במצב זה כדי לרענן את הקושחה.
אותות ה‑SWD של ה‑STM32 חשופים בגב הלוח דרך שורה של test pads בין שני מחברי ה‑J2. הלחימו מחבר 2.54 מ“מ (100‑mil) אליהם כדי לחבר מתאם ST‑LINK או J‑Link:
P1 / P2 — אפיק I²C של ה‑PMIC הפנימי על PF0 (SDA) ו‑PF1 (SCL). זהו
machine.I2C(2)ב‑Nicla Vision ונושא את תעבורת ה‑PMIC, מד הדלק, וה‑ToF.P3 — TMS / SWDIO (PA13)
P4 — TCK / SWCLK (PA14)
P5 — NRST
P6 — TDO / SWO (PB3)
P7 — מסילת +1V8 (מקור ה‑I/O של ה‑SoC — וגם הייחוס הנכון עבור מתאם ה‑debug).
P8 —
VOTP_PMIC— תכנות במפעל בלבד. חייב להישאר לא מחובר.
כל אותות ה‑debug מיוחסים ל‑1.8 V — טבעת ה‑I/O של ה‑STM32H747 בלוח זה פועלת ממסילת ה‑+1V8. הגדירו את מתאם ה‑debug שלכם ללוגיקת 1.8 V לפני החיבור.
התקנים היקפיים מובנים¶
LEDs¶
ל‑Nicla Vision יש RGB LED יחיד למשתמש, הניתן לשליטה בתוכנה דרך machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
נורית DL2 CHARGE נפרדת בצד הלוח מחווטת ישירות אל יציאת ה‑CHGB של ה‑PMIC — היא נדלקת בעוד סוללת Li‑Po נטענת מ‑USB / ESLOV / VIN ואינה ניתנת לשליטה על ידי המשתמש.
חיישן המצלמה¶
ה‑GC2145 מונע דרך מודול csi — חיישני מצלמה
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
כשאתם מבקשים framesize קטן, מנהל ההתקן של ה‑GC2145 חותך חלון קריאה קטן באופן יחסי מהחיישן — כברירת מחדל יחס ההקטנה מהקריאה אל הפלט מוגבל ל‑3x כדי לשמור על קצב פריימים גבוה. csi.IOCTL_SET_FOV_WIDE מעלה את התקרה הזו ל‑5x, מה שאומר שמנהל ההתקן מושך מאזור רחב יותר של החיישן כשמזרימים רזולוציות קטנות. התוצאה היא שדה ראייה רחב יותר באופן ניכר ברזולוציות קטנות, במחיר מסוים של תפוקה:
cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE) # returns the current setting
ליבת M4¶
ליבת ה‑Cortex‑M4 חשופה דרך openamp לתקשורת בין‑מעבדים. קושחת OpenMV רצה על ה‑M7 בלבד; ל‑M4 אין סביבת ריצה משלו של MicroPython, כך ששימוש בו משמעו בניית קושחת C נפרדת וטעינתה ממערכת הקבצים באמצעות openamp.RemoteProc. קושחת דוגמה בנויה מראש המממשת נקודת קצה של UART וירטואלי זמינה במאגר openamp_vuart — עקבו אחר ה‑README שלו כדי לבנות את vuart.elf
import openamp
import time
def ept_recv_callback(src_addr, data):
print("Received:", data.decode())
ept = openamp.Endpoint("vuart-channel", callback=ept_recv_callback)
rproc = openamp.RemoteProc("vuart.elf")
rproc.start()
count = 0
while True:
if ept.is_ready():
ept.send("Hello World %d!" % count, timeout=1000)
count += 1
time.sleep_ms(1000)
בפועל מוטב להתייחס לתמיכה זו כהדגמה של ממשק ה‑openamp ולא כפלטפורמה דו‑ליבתית עובדת — לא ניתן לאתחל את ה‑M4 בנפרד מה‑M7, כך שעצירת ה‑M4 מאלצת אתחול מלא של המערכת.
מיקרופון¶
המיקרופון PDM מסוג MP34DT06JTR שעל הלוח נקלט דרך audio — מודול אודיו על גבי התקן ה‑DFSDM של ה‑STM32. כל חוצץ (buffer) מגיע כ‑PCM bytearray בעל סימן של 16 ביט, מוכן להזנה אל ulab/numpy לעיבוד אותות — לדוגמה, גלאי עוצמת קול פשוט:
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¶
מד התאוצה + הג’ירוסקופ LSM6DSOX שעל הלוח חשופים דרך imu — חיישן imu
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)
ה‑IMU מחווט לאפיק SPI פנימי ייעודי (SPI5) כך שאינו מתחרה עם ה‑SPI4 של המשתמש המוצא אל המחברים.
מד טווח time‑of‑flight¶
מד הטווח VL53L1CB מסוג time‑of‑flight של ST שעל הלוח יושב על אפיק ה‑I²C של ה‑PMIC הפנימי (I²C 2). השתמשו במנהל ההתקן הקפוא vl53l1x — מנהל התקן לחיישן מרחק VL53L1X ToF כדי לקבל קריאות מרחק עד ~4 מ«:
import time
from machine import I2C
import vl53l1x
bus = I2C(2) # internal bus (PMIC / fuel gauge / ToF)
tof = vl53l1x.VL53L1X(bus)
while True:
print("Distance:", tof.read(), "mm")
time.sleep_ms(100)
מד דלק לסוללה¶
מד הדלק ModelGauge m5 MAX17262 של Maxim עוקב אחר המתח, הזרם, הטמפרטורה, ומצב הטעינה של סוללת ה‑Li‑Po. הוא יושב על I²C 2 בכתובת 0x36.
ל‑MAX17262 יש חיישת זרם פנימית, כך שאוגר הזרם נקרא ישירות במיקרו‑אמפר ללא גורם Rsense חיצוני ליישום. קריאת מד הדלק בלתי מזיקה — אין מנהל התקן מסופק, אך את האוגרים המתועדים ב‑datasheet של MAX17262 ניתן לקרוא ישירות:
import time
import struct
from machine import I2C
FUEL_GAUGE = 0x36 # MAX17262
def read_reg(bus, addr, reg):
return struct.unpack("<H", bus.readfrom_mem(addr, reg, 2))[0]
def read_signed(bus, addr, reg):
v = read_reg(bus, addr, reg)
return v - 0x10000 if v & 0x8000 else v
bus = I2C(2)
while True:
# 0x05 RepCap — remaining capacity, raw × 0.5 mAh
rep_cap = read_reg(bus, FUEL_GAUGE, 0x05) * 0.5
# 0x06 RepSOC — state of charge, raw / 256 %
soc = read_reg(bus, FUEL_GAUGE, 0x06) / 256
# 0x08 Temp — die temperature, signed, raw / 256 °C
temp = read_signed(bus, FUEL_GAUGE, 0x08) / 256
# 0x09 VCell — battery voltage, raw × 78.125 µV
vcell = read_reg(bus, FUEL_GAUGE, 0x09) * 78.125 / 1_000_000
# 0x0A Current — signed, raw × 156.25 µA
current = read_signed(bus, FUEL_GAUGE, 0x0A) * 156.25 / 1000
# 0x0B AvgCurrent — averaged current
avg_curr = read_signed(bus, FUEL_GAUGE, 0x0B) * 156.25 / 1000
# 0x10 FullCapRep — learned full capacity, raw × 0.5 mAh
full_cap = read_reg(bus, FUEL_GAUGE, 0x10) * 0.5
# 0x11 TTE — time-to-empty (valid while discharging), raw × 5.625 s
tte_s = read_reg(bus, FUEL_GAUGE, 0x11) * 5.625
# 0x20 TTF — time-to-full (valid while charging), raw × 5.625 s
ttf_s = read_reg(bus, FUEL_GAUGE, 0x20) * 5.625
# 0x17 Cycles — charge-cycle counter, 1% per LSB
cycles = read_reg(bus, FUEL_GAUGE, 0x17) / 100
print("V: %.3f V" % vcell)
print("Capacity: %.1f / %.1f mAh (%.1f %%)" % (rep_cap, full_cap, soc))
print("Temp: %.1f C" % temp)
print("Current: %.1f mA (avg %.1f mA)" % (current, avg_curr))
print("TTE: %.0f s TTF: %.0f s" % (tte_s, ttf_s))
print("Cycles: %.2f" % cycles)
print()
time.sleep_ms(1000)
Current הוא בעל סימן בשיטת two’s-complement: חיובי בעת טעינה, שלילי בעת פריקה. TTE משמעותי רק כשהזרם שלילי; TTF רק כשהזרם חיובי.
רכיב ניהול הספק (PMIC)¶
ה‑PMIC MC34PF1550A0EP של NXP מטפל בכל מייצב ב‑Nicla Vision — מסילת ה‑+3V3 הראשית, מסילת ליבת / I/O של ה‑SoC +1V8, VDDIO_EXT אל ממירי המתח, ומטען ה‑Li‑Po. הוא יושב על I²C 2 בכתובת 0x08.
אזהרה
קריאת אוגרי PMIC היא בסדר; כתיבה אליהם מסוכנת. הגדרה שגויה של מייצב buck או הגדרת מטען עלולה לפגוע באופן קבוע בלוח, בסוללה, או בשניהם. התייחסו אל ה‑PMIC כאל קריאה בלבד אלא אם אתם יודעים בדיוק מה אתם עושים.
הדבר השימושי ביותר שה‑PMIC מספר לכם ושמד הדלק אינו יכול הוא מכונת המצבים של המטען — האם הלוח פועל כעת מ‑USB / ESLOV / VIN, באיזה שלב של מחזור הטעינה נמצאת ה‑Li‑Po, והאם המטען נמצא בתקלה תרמית או בתקלת watchdog. אוגרי המטען נמצאים בהיסט של 0x80 במרחב כתובות ה‑I²C הראשי של ה‑PF1550 (ראו §22.2 של datasheet של PF1550), כך שלדוגמה CHG_INT_OK בכתובת מטען 0x04 נקרא מאוגר PMIC 0x84
import time
from machine import I2C
PMIC = 0x08
# Charger state machine (low nibble of CHG_SNS, register 0x87)
CHG_STATES = {
0x0: "precharge",
0x1: "fast charge (constant current)",
0x2: "fast charge (constant voltage)",
0x3: "end of charge",
0x4: "done",
0x6: "timer fault",
0x7: "thermistor suspend",
0x8: "off — input invalid or charger disabled",
0x9: "battery overvoltage",
0xA: "thermal shutdown",
0xC: "linear mode (not charging)",
}
bus = I2C(2)
while True:
# 0x84 CHG_INT_OK — single-bit indicators
ok = bus.readfrom_mem(PMIC, 0x84, 1)[0]
vbus_ok = bool(ok & (1 << 5)) # bit 5 — VBUS valid (USB/ESLOV/VIN)
bat_ok = bool(ok & (1 << 2)) # bit 2 — battery OK
chg_ok = bool(ok & (1 << 3)) # bit 3 — charger actively charging
thm_ok = bool(ok & (1 << 7)) # bit 7 — thermistor in normal range
# 0x87 CHG_SNS — charger state + thermal regulation flag
chg_sns = bus.readfrom_mem(PMIC, 0x87, 1)[0]
state = CHG_STATES.get(chg_sns & 0x0F, "reserved")
treg = bool(chg_sns & (1 << 7)) # thermal regulation active
print("VBUS valid: ", vbus_ok)
print("battery OK: ", bat_ok)
print("charger active: ", chg_ok)
print("thermistor normal: ", thm_ok)
print("thermal reg active: ", treg)
print("state: ", state)
print()
time.sleep_ms(1000)
אוגרי קריאה‑בלבד נוספים ששווה לעיין בהם ב‑datasheet (כולם בהיסט מטען 0x80): 0x80 CHG_INT (פסיקות מטען נעולות — דגלי תקלה), 0x86 VBUS_SNS (מצב ה‑VBUS הרב‑סיביתי כולל OVLO / UVLO / DPM), ו‑0x88 BATT_SNS (נוכחות סוללה ומצב זרם יתר).
Wi‑Fi¶
ה‑Murata 1DX (CYW4343W) שעל הלוח חשוף דרך network — הגדרת רשת כממשק תחנה. חברו את האנטנה המצורפת אל מחבר ה‑U.FL שעל הלוח לפני הפעלת הרדיו:
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¶
אותו Murata 1DX חושף גם Bluetooth LE 5.1. השתמשו בaioble — BLE אסינכרוני ל‑BLE ידידותי ל‑asyncio — לדוגמה, פרסום כהתקן היקפי והמתנה ל‑central שיתחבר:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="Nicla-Vision")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
מדריך אפיקים¶
GPIO¶
השתמשו בmachine.Pin כדי לקרוא או להניע כל אחד מהפינים המסומנים בסילקסקרין. היציאות הן 3.3 V CMOS (ברירת מחדל VDDIO_EXT) וממירי המתח מגבילים את חוזק ההנעה לכל פין למספר מיליאמפר — הם תוכננו לעומסי אות ולא לעומסי הספק.
from machine import Pin
out = Pin("D0", Pin.OUT)
out.on()
out.off()
out.value(1)
inp = Pin("D1", Pin.IN, Pin.PULL_UP)
print(inp.value())
כל פין כניסה יכול גם להפעיל פסיקה במעברי קצה:
def handler(pin):
print("triggered:", pin)
Pin("D1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
אפיק |
TX |
RX |
|---|---|---|
UART4 |
SDA |
SCL |
from machine import UART
uart = UART(4, baudrate=115200)
uart.write("hello")
uart.read(5)
הערה
ה‑UART4 חולק את פיניו עם I²C 1 — אותן רפידות SDA/SCL נושאות את שני האפיקים. בחרו UART או I²C, לא את שניהם, על אותם פינים.
הסילקסקרין D1/D2 מציין גם UART_TX/UART_RX, אך בקושחה זו פינים אלו מנותבים אל LPUART1, ולא אל machine.UART. machine.UART(1) עצמו שמור לבקר ה‑Bluetooth שעל השבב ואינו נגיש על המחברים.
I²C¶
אפיק |
SCL |
SDA |
|---|---|---|
I2C1 |
SCL |
SDA |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
רפידות ה‑SCL/SDA על J2 ופיני ה‑SCL_EXT/SDA_EXT של מחבר ה‑ESLOV נוחתים על אותו אפיק I²C 1 — ראו מחבר ESLOV למעלה למפת הפינים של ה‑ESLOV.
ניתן להשתמש באותה חומרה גם במצב target (slave) דרך machine.I2CTarget כדי לחשוף אזור זיכרון לבקר I²C אחר:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
SPI¶
אפיק |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI4 |
COPI |
CIPO |
SCLK |
CS |
from machine import SPI
from machine import Pin
spi = SPI(4, baudrate=10_000_000)
cs = Pin("CS", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
ADC¶
ה‑Nicla Vision חושף שלושה ערוצי ADC של 12 ביט על A0, A1, ו‑A2. כל השלושה מיוחסים ל‑1.8 V — read_u16 מחזיר 0–65535 על פני 0–1.8 V בפין:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
אזהרה
כניסות ה‑ADC של ה‑Nicla Vision מיוחסות ל‑1.8 V (ואין להן ממיר מתח לפני ה‑SoC). הזרמת אות של 3.3 V תרווה את הממיר ועלולה לפגוע בפין — חלקו מתחים גבוהים יותר חיצונית.
PWM¶
פין |
טיימר / ערוץ |
|---|---|
D1 |
TIM1 CH2 |
D2 |
TIM1 CH3 |
SCL |
TIM4 CH3, TIM16 CH1 |
SDA |
TIM4 CH4, TIM17 CH1 |
SCLK |
TIM1 CH3N |
CIPO |
TIM1 CH3 |
COPI |
TIM1 CH4 |
CS |
TIM1 CH2 |
הניעו כל אחד מהם דרך machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D1"), freq=1_000, duty_u16=32768)
הערה
מספר פינים חולקים ערוצי TIM1:
TIM1 CH2 נמצא על
D1וגםCS.TIM1 CH3 נמצא על
D2וגםCIPO;SCLKמוציא את המשלים ההפוך (TIM1 CH3N) של אותו ערוץ.TIM1 CH4 נמצא על
COPIבלבד.
בחרו צרכן אחד לכל ערוץ טיימר. פיני רביעיית ה‑SPI (SCLK/CIPO/COPI/CS) גם אינם יכולים להיות מונעים ב‑PWM בעוד machine.SPI(4) משתמש בהם.
אפיקים מבוססי bit‑bang בתוכנה¶
machine.SoftI2C ו‑machine.SoftSPI עובדים על כל GPIO אם אתם זקוקים לאפיק נוסף.
חיישן תרמי (חיצוני ללוח)¶
הקושחה כוללת את מנהל ההתקן fir — מנהל התקן לחיישן תרמי (fir == far infrared) עבור מצלמות הדמיה תרמיות מחווטות חיצונית:
MLX90621 — מערך IR של 16 × 4
MLX90640 — מערך IR של 32 × 24
MLX90641 — מערך IR של 16 × 12
AMG8833 — מערך IR של 8 × 8
חווטו את המודול אל אפיק ה‑I²C של הלוח וקראו פריימים עם 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())
מנהל ההתקן fir מדבר עם החיישן רק על גבי I²C 1 — חווטו את המודול אל רפידות ה‑SCL / SDA המסומנות בסילקסקרין.
תזמון¶
time¶
המודול time מכסה השהיות חוסמות, טיקים מונוטוניים, ומדידת זמן שחלף:
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)
טיימרים וירטואליים¶
machine.Timer מתזמן פונקציות callback מחזוריות או חד‑פעמיות מבלי לצרוך משבצת טיימר חומרתי. העבירו -1 כ‑id כדי להשתמש בטיימר וירטואלי (תוכנה):
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"))
ערכי המחזור הם במילישניות. קראו לdeinit() כדי לעצור ולשחרר את המשבצת.
שעון זמן‑אמת¶
machine.RTC שומר על זמן שעון‑קיר לאורך אתחולים:
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())
Watchdog¶
machine.WDT מאתחל את הלוח אם האפליקציה נתקעת. לאחר ההפעלה לא ניתן לעצור אותו או להגדירו מחדש — האכילו אותו מעת לעת בתוך הלולאה הראשית שלכם:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
מידע על אתחול וזמן ריצה¶
עדכון קושחה (DFU)¶
ה‑Nicla Vision משתמש ב‑double‑tap reset הסטנדרטי של Arduino כדי להיכנס ל‑bootloader של Arduino. לחצו במהירות פעמיים על כפתור ה‑reset — הלוח מזוהה מחדש על גבי USB כהתקן DFU ו‑OpenMV IDE יכול לצרוב קושחה חדשה.
סקריפט פעיל יכול להיכנס מחדש ל‑bootloader לפי דרישה על ידי קריאה לmachine.bootloader()
import machine
machine.bootloader()
מערכת קבצים וסדר אתחול¶
קושחת ה‑Nicla Vision מעלה עד שתי מערכות קבצים באתחול:
זיכרון פלאש (flash) פנימי — תמיד מועלה ב‑
/flash. מכילmain.pyו‑README.txtכברירת מחדל; נוצר באתחול הראשון ממש.ROMFS — מערכת קבצים לקריאה בלבד, ממופת זיכרון ב‑
/romהמועלית אוטומטית על ידי MicroPython בעת ההפעלה.
לאחר ההעלאה, ספריית העבודה מוגדרת ל‑/flash. המפרש מריץ אז סקריפטים מספרייה זו:
boot.pyמורץ בכל אתחול רך (cold boot,Ctrl‑Dמה‑REPL, או בכל פעם שהסקריפט הרץ חוזר).main.pyמורץ רק ב‑cold boot, מיד לאחרboot.py. אתחולים רכים עוקבים מריצים מחדש אתboot.pyאך צונחים ישירות אל ה‑REPL — כדי להריץ מחדש אתmain.pyעליכם לאתחל את הלוח לחלוטין.
ברירת המחדל של main.py המסופקת על לוח שזה עתה נצרב פשוט מהבהבת את הערוץ הכחול של ה‑RGB LED של המשתמש כפעימת לב (שני פעימות קצרות, רווח קצר), כך שתוכלו לדעת שהקושחה אותחלה בנקיון ללא host מחובר.
sys.path מורחב כדי לכלול את שתי מערכות הקבצים ואת תת‑הספריות lib/ שלהן, כך שמודולים הניתנים לייבוא יכולים לשבת ב‑/flash/lib או ב‑/rom/lib.
כשמחובר על גבי USB, /flash מזוהה גם ככונן אחסון המוני USB ב‑host, ומאפשר לכם לערוך את boot.py, main.py, וכל קובץ אחר ישירות. הוציאו את הכונן לפני אתחול המצלמה כדי שה‑host ירוקן את הכתיבות שבמטמון שלו.
הערה
מכיוון שמערכת ההפעלה מתייחסת אל הכונן כאל התקן בלוקים פסיבי, קבצים שנוצרו או שונו על ידי קוד הרץ על המצלמה לא יופיעו עד שה‑host יעלה מחדש את הכונן. אם גם מערכת ההפעלה וגם המצלמה כותבות לאותה מערכת קבצים בו‑זמנית, מערכת ההפעלה תנצח ותדרוס שינויים שביצעה המצלמה. השתמשו בכרטיס ה‑SD עבור כל נתון שהסקריפט כותב חזרה, והעלו מחדש לפני קריאת קבצים אלו מה‑host.
הערה
הערוץ האדום של ה‑RGB LED של המשתמש עשוי להידלק לרגע קצר בעוד ה‑host קורא או כותב אל כונן האחסון ההמוני USB — זהו מחוון פעילות מבוסס קושחה, ולא תקלה.
גדלי אחסון¶
ה‑Nicla Vision מגיע עם:
/flash— מערכת קבצים FAT של 11 MB, קריאה/כתיבה./rom— ROMFS ממופת זיכרון לקריאה בלבד של 4 MB, משמש לשליחת סקריפטים ומודלי ML שמרוויחים מגישת mmap ללא העתקה.
מחוון hard‑fault¶
אם ה‑RGB LED של המשתמש עובר במהירות בין כל הצבעים — מהר מספיק שזה נוטה להיראות כמו נורית לבנה מנצנצת ולא כגוונים נפרדים — הקושחה נתקלה ב‑hard fault שאי אפשר להתאושש ממנו. צרבו מחדש את הקושחה כדי להתאושש; אם הצריבה מחדש אינה עוזרת, ייתכן שהלוח ניזוק פיזית.
ספריות תוכנה¶
ראו את אינדקס הספרייה לרשימה המלאה של המודולים — כולל אלו הייחודיים לבניית ה‑Nicla Vision.