Arduino Portenta H7¶
ה‑Arduino Portenta H7 הוא לוח פיתוח תעשייתי בגודל 66 × 25 מ“מ הבנוי סביב STMicroelectronics STM32H747XI — שבב SoC דו‑ליבתי המשלב ליבת Cortex‑M7 ב‑400 MHz עם ליבת Cortex‑M4 ב‑200 MHz. קושחת OpenMV רצה כולה על ליבת ה‑M7 ותוכננה לשימוש עם ה‑Portenta Vision Shield (מהדורת Ethernet או LoRa), המוסיף מצלמת Himax HM01B0 / HM0360, זוג מיקרופוני PDM וחריץ microSD ללוח ה‑Portenta H7 הבסיסי.
ל‑datasheet מלא, תמונות ומידות ראו את דף המוצר של Arduino Portenta H7.
עיקרי הדברים¶
STMicroelectronics STM32H747XI דו‑ליבתי Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). קושחת OpenMV רצה על ליבת ה‑M7 בלבד; ליבת ה‑M4 נחשפת דרך openamp עבור תקשורת בין‑מעבדים.
8 MB של SDRAM חיצוני בתוספת 2 MB של flash פנימי ו‑16 MB של QSPI flash חיצוני.
מקודד/מפענח JPEG חומרתי.
Wi‑Fi b/g/n (2.4 GHz) + Bluetooth LE 5.1 דרך מודול Murata 1DX (CYW4343W) — מתחבר לאנטנה המצורפת דרך מחבר U.FL מובנה.
USB‑C במהירות גבוהה (480 Mb/s).
22 פיני קלט/פלט למשתמש בכותרות העליונות בסגנון Arduino MKR — D0–D14 (דיגיטליים) בתוספת A0–A6 (אנלוגיים).
שני מחברים בצפיפות גבוהה של 80 פינים בתחתית חושפים את כל מארג ה‑STM32H747 — DCMI, DSI, Ethernet RMII, FDCAN, SDIO, SAI/I²S, ערוצי UART, SPI/I²C/טיימרים נוספים וכן הלאה. מגנים כמו ה‑Vision Shield מתחברים למחברים אלה.
JTAG / SWD מוצאים אל מחברי ה‑HD בתחתית עבור ניפוי שגיאות מתקדם.
תמיכה בסוללה — מחבר JST ל‑Li‑Po של 3.7 V בתוספת מטען ומנטר סוללה מובנים.
מפת פינים¶
סימוכין לפינים¶
22 פיני משתמש נחשפים בכותרות הקצה העליונות בסגנון Arduino MKR — 15 דיגיטליים (D0-D14) בתוספת 7 אנלוגיים (A0-A6). פינים רבים נוספים של ה‑SoC זמינים דרך מחברי ה‑80 פינים בצפיפות גבוהה בתחתית עבור עבודה עם מגנים; ראו את ה‑PDF של מפת הפינים המלאה של Arduino עבור מיפוי זה.
שם פין |
סימוכין |
פונקציה |
|---|---|---|
D0 |
3.3 V |
TIM8 CH3N |
D1 |
3.3 V |
TIM1 CH1 / SPI5 NSS |
D2 |
3.3 V |
TIM1 CH2 / SPI5 MISO |
D3 |
3.3 V |
GPIO |
D4 |
3.3 V |
TIM3 CH2 / TIM8 CH2 / USART6 RX |
D5 |
3.3 V |
TIM3 CH1 / TIM8 CH1 / USART6 TX |
D6 |
3.3 V |
TIM1 CH1 / I2C3 SCL |
D7 |
3.3 V |
TIM5 CH4 / SPI2 NSS |
D8 |
3.3 V |
SPI2 MOSI (משותף עם A3 / A5) |
D9 |
3.3 V |
SPI2 SCK |
D10 |
3.3 V |
SPI2 MISO (משותף עם A2 / A4) |
D11 |
3.3 V |
I2C3 SDA |
D12 |
3.3 V |
I2C3 SCL |
D13 |
3.3 V |
USART1 RX / TIM1 CH3 |
D14 |
3.3 V |
USART1 TX / TIM1 CH2 |
A0 |
3.3 V |
ADC12 IN0 (אנלוגי בלבד) |
A1 |
3.3 V |
ADC12 IN1 (אנלוגי בלבד) |
A2 |
3.3 V |
ADC123 IN12 (אנלוגי בלבד; משותף עם D10) |
A3 |
3.3 V |
ADC12 IN13 (אנלוגי בלבד; משותף עם D8) |
A4 |
3.3 V |
ADC123 IN12 (משותף עם D10) |
A5 |
3.3 V |
ADC12 IN13 (משותף עם D8) |
A6 |
3.3 V |
DAC1 OUT1 / ADC12 IN18 |
A7 |
3.3 V |
TIM3 CH1 / ADC12 IN3 (לא חשוף בכותרות) |
D20 |
3.3 V |
כינוי של |
D21 |
3.3 V |
כינוי של |
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 (פעיל בנמוך) |
הערה
A0-A3 הם רפידות אנלוגיות בלבד ב‑STM32H747 ללא פונקציית GPIO — התייחסו אליהן כאל כניסות ADC בלבד. A2/A4 ו‑A3/A5 חולקים את הפינים הפיזיים שלהם עם D10 ו‑D8 בהתאמה, כך שאינכם יכולים להניע PWM או SPI עליהם בזמן קריאתם כאנלוגיים. A7 נמצא על מחברי ה‑HD בתחתית.
פיני הספקה¶
פיני כותרת MKR:
VIN — מסילת המערכת הראשית אל ה‑PMIC המובנה. ניזונה דרך דיודה ממסילת ה‑
+5V, מפין ה‑VINשל MKR, או ממחברי ה‑80 פינים HD בתחתית.+5V — מסילת 5 V הניזונה מ‑USB, ממחבר ה‑ESLOV, או מפין ה‑
+5Vשל MKR עצמו.+3V3 — מסילת 3.3 V הראשית (פלט וסת מיתוג של ה‑PMIC).
AREF — מקור מתח ייחוס אנלוגי עבור פיני ה‑ADC. ברירת מחדל 3.3 V; הניעו חיצונית כדי להשתמש בייחוס אחר.
GND — הארקה משותפת.
כניסת סוללה:
JST ל‑Li‑Po בחזית הלוח מקבל תא Li‑Po של 3.7 V. ה‑PMIC טוען אותו בכל פעם ש‑
+5VאוVINנוכחים.
ניתן להזין את ה‑Portenta H7 דרך כל אחת מהדרכים האלה:
USB‑C — מספק 5 V ל‑PMIC המובנה.
מחבר ESLOV — עד 5 V על
VESLOV(ראו מחבר ESLOV).פין VIN — הניעו ישירות אספקת 5 V מיוצבת.
סוללת Li‑Po — חברו ל‑JST שבחזית.
מחבר ESLOV¶
בצד הלוח נמצא מחבר ESLOV בן 5 פינים ללא הלחמה:
פין |
שם |
פונקציה |
|---|---|---|
1 |
VESLOV |
פלט הספק 5 V (אותה מסילה כמו ה‑ |
2 |
INT |
כניסת פסיקה חיצונית על |
3 |
SCL_EXT |
משותף עם רפידת ה‑ |
4 |
SDA_EXT |
משותף עם רפידת ה‑ |
5 |
GND |
הארקה משותפת |
ה‑SCL_EXT/SDA_EXT של ESLOV וה‑D12/D11 של כותרת MKR הם אותם פינים — אפיק I²C 3 יחיד החשוף בשני מחברים.
טיפ
השתמשו ב‑מעריך חיי הסוללה כדי לדמות כמה זמן ה‑Portenta H7 יפעל על סוללה עבור מחזור עבודה נתון של פעילות / שינה עמוקה.
פיני שחזור וניפוי שגיאות¶
RESET — גם פין חשוף בכותרת העליונה וגם מתג רגעי בצד הלוח, מחוברים לקו ה‑NRST של ה‑SoC. משכו ל‑GND או לחצו על הכפתור כדי לאפס.
ה‑Portenta H7 משתמש ב‑איפוס לחיצה כפולה הסטנדרטי של Arduino כדי להיכנס ל‑bootloader של Arduino. לחצו במהירות על כפתור האיפוס פעמיים — הלוח נספר מחדש דרך USB כהתקן DFU ו‑OpenMV IDE יכול לצרוב תמונת firmware חדשה.
אותות ה‑SWD של ה‑STM32 חשופים על מחבר ה‑HD J1 בתחתית:
J1‑73— NRSTJ1‑75— SWDIO (PA13)J1‑77— SWCLK (PA14)J1‑79— SWO (PB3)
חברו אותם דרך Portenta Breakout, מתאם ניפוי השגיאות הרשמי של Arduino, או נושאת מותאמת אישית עם כותרת בצעד 1.27 מ“מ. כל אותות ניפוי השגיאות הם בייחוס 3.3 V.
הערה
כאשר ה‑Portenta Vision Shield מחובר, אותם אותות SWD/JTAG מנותבים מעלה אל כותרת ה‑JTAG הסטנדרטית בת 20 הפינים של ARM Cortex Debug שעל המגן (צעד 1.27 מ“מ / 0.05″).
התקנים היקפיים מובנים¶
נוריות LED¶
ל‑Portenta H7 יש נורית RGB LED יחידה למשתמש, הניתנת לשליטה תוכנתית דרך machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
נורית טעינה כתומה נפרדת ליד ה‑JST של הסוללה נדלקת כאשר המטען המובנה מזרים זרם לתוך תא Li‑Po מחובר; היא אינה ניתנת לשליטה על ידי המשתמש.
חיישן מצלמה (Vision Shield)¶
כאשר ה‑Portenta Vision Shield (מהדורת Ethernet או LoRa) מחובר, חיישן ה‑Himax מונע דרך מודול ה‑csi — חיישני מצלמה
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.GRAYSCALE)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
נתמכות שתי גרסאות של Vision Shield:
HM01B0 — מונוכרום 320 × 320.
HM0360 — מונוכרום 640 × 480.
אזהרה
בזמן שמצלמת ה‑Vision Shield מאותחלת, פיני כותרת ה‑MKR הבאים נתפסים על ידי הקושחה ו‑אינם ניתנים לשימוש:
פין MKR |
סיבה |
|---|---|
|
TIM1 CH1 — שעון אב של המצלמה |
|
TIM1 CH1 (חלופי) — שעון אב של המצלמה |
|
I²C 3 SDA — משותף עם המצלמה; האפיק שמיש אך הימנעו מכתובת ה‑I²C של החיישן ( |
|
I²C 3 SCL — משותף עם המצלמה; האפיק שמיש אך הימנעו מכתובת ה‑I²C של החיישן ( |
|
DCMI HSYNC — גם משבית את ה‑DAC |
|
DCMI PXCLK |
למידת מכונה¶
ml — למידת מכונה מריץ מודלים מכומתים של TFLite על ליבת ה‑Cortex‑M7 עם גרעיני CMSIS‑NN — מהיר מספיק עבור גלאים קומפקטיים בכמה פריימים לשנייה. מודלים על מערכת הקבצים /rom לקריאה בלבד נטענים ישירות מ‑flash ללא העתקה ל‑RAM. הנה גלאי BlazeFace בגודל 128×128 המכסה בשכבת על את הפנים שזוהו ואת ששת נקודות הציון שלהן בכל פריים ממצלמת ה‑Vision Shield:
import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace
# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.QVGA)
csi0.window((240, 240))
# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# faces is a list of ((x, y, w, h), score, keypoints) tuples
for r, score, keypoints in model.predict([img]):
ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)
# keypoints is a ndarray of shape (6, 2)
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
print(clock.fps(), "fps")
ליבת M4¶
ליבת ה‑Cortex‑M4 נחשפת דרך openamp עבור תקשורת בין‑מעבדים. קושחת OpenMV רצה על ליבת ה‑M7 בלבד; ל‑M4 אין סביבת ריצה משלו של MicroPython, כך ששימוש בו פירושו בניית תמונת firmware נפרדת ב‑C וטעינתה ממערכת הקבצים דרך openamp.RemoteProc. firmware לדוגמה בנוי מראש המממש נקודת קצה של 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 כופה אתחול מלא של המערכת.
מיקרופון (Vision Shield)¶
ה‑Vision Shield נושא זוג מיקרופוני PDM הנקלטים דרך audio — מודול אודיו מעל ההתקן ההיקפי SAI4 של ה‑STM32. כל חוצץ מגיע כ‑PCM של 16 ביט עם סימן בתוך bytearray, מוכן להזנה אל ulab/numpy עבור DSP — למשל, גלאי עוצמת קול פשוט:
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
העבירו channels=2 ל‑audio.init כדי לקבל דגימות משולבות משני המיקרופונים.
מד דלק של סוללה¶
מד הדלק Maxim MAX17262 ModelGauge m5 עוקב אחר המתח, הזרם, הטמפרטורה ומצב הטעינה של סוללת ה‑Li‑Po. הוא יושב על I²C 1 בכתובת 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(1)
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 הוא משלים‑לשניים עם סימן: חיובי בזמן טעינה, שלילי בזמן פריקה. TTE משמעותי רק כאשר הזרם שלילי; TTF רק כאשר הזרם חיובי.
שבב ניהול הספק¶
ה‑PMIC מסוג NXP PF1550 מטפל בכל וסת ב‑Portenta H7 — מסילת ה‑+3V3 הראשית, מסילת ה‑+1V8 של ליבת/קלט‑פלט ה‑SoC, ומטען ה‑Li‑Po. הוא יושב על I²C 1 בכתובת 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(1)
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/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 — למשל, פרסמו כהתקן היקפי והמתינו שמרכז יתחבר:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="Portenta-H7")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
LoRa (Vision Shield)¶
ה‑מהדורת LoRa של ה‑Vision Shield מוסיפה מודול LoRaWAN מסוג Murata CMWX1ZZABZ המחווט ל‑Portenta H7 מעל UART. מודול ה‑lora עוטף את קושחת פקודות ה‑AT ותומך בהצטרפות OTAA או ABP, uplink ו‑downlink:
from lora import Lora
from lora import BAND_EU868
from lora import LoraErrorTimeout
lora = Lora(band=BAND_EU868, poll_ms=60000)
print("Device EUI:", lora.get_device_eui())
appEui = "1234567890123456"
appKey = "12345678901234567890123456789012"
try:
lora.join_OTAA(appEui, appKey)
except LoraErrorTimeout as e:
print("Join timed out — try moving near a window:", e)
lora.set_port(3)
lora.send_data("HeLoRA world!", True)
while True:
if lora.available():
data = lora.receive_data()
if data:
print("Port:", data["port"], "Data:", data["data"])
lora.poll()
השתמשו ב‑BAND_US915 / BAND_AS923 / BAND_AU915 וכו« עבור אזורים שאינם באירופה, ועברו ל‑lora.Lora.join_ABP() אם שרת הרשת שלכם משתמש בהפעלת ABP.
אזהרה
בזמן שמודול ה‑LoRa בשימוש, מנהל ההתקן תופס את פיני כותרת ה‑MKR הבאים כקווי בקרה עבור ה‑Murata CMWX1ZZABZ — הם אינם ניתנים לשימוש:
פין MKR |
סיבה |
|---|---|
|
פין BOOT של מודול LoRa |
|
פין RST של מודול LoRa |
Ethernet (Vision Shield)¶
ה‑מהדורת Ethernet של ה‑Vision Shield מוסיפה שקע RJ45 עם מגנטיקה המחווט אל ה‑MAC של Ethernet 10/100 של ה‑STM32H747 מעל RMII. חברו כבל Ethernet וה‑PHY מופיע כממשק LAN; DHCP רץ אוטומטית ברגע שהקישור עולה:
import network
import time
lan = network.LAN()
lan.active(True)
while not lan.isconnected():
time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])
כרטיס microSD (Vision Shield)¶
כאשר מוכנס כרטיס הוא ממוטמן אוטומטית ב‑/sdcard וניתן לשימוש דרך מערכת הקבצים הרגילה:
import os
for entry in os.listdir("/sdcard"):
print(entry)
סימוכין לאפיקים¶
GPIO¶
השתמשו ב‑machine.Pin כדי לקרוא או להניע כל אחד מהפינים המסומנים בהדפס המשי. הפלטים הם CMOS של 3.3 V ויכולים לשקוע/לספק עד 20 mA לפין (140 mA סך הכל על פני כל הכותרת).
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 |
|---|---|---|
UART1 |
D14 |
D13 |
UART6 |
D5 |
D4 |
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
אפיק |
SCL |
SDA |
|---|---|---|
I2C3 |
D12 |
D11 |
from machine import I2C
i2c = I2C(3, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
רפידות ה‑D11/D12 שעל כותרת MKR ופיני ה‑SDA_EXT/SCL_EXT של מחבר ה‑ESLOV נוחתים על אותו אפיק I²C 3 — ראו מחבר ESLOV למעלה עבור מפת הפינים של ESLOV.
ניתן להשתמש באותה חומרה גם במצב יעד (slave) דרך machine.I2CTarget כדי לחשוף אזור זיכרון לבקר I²C אחר:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(3, addr=0x42, mem=buf)
SPI¶
אפיק |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI2 |
D8 |
D10 |
D9 |
D7 |
from machine import SPI
from machine import Pin
spi = SPI(2, baudrate=10_000_000)
cs = Pin("D7", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
ADC¶
ה‑Portenta H7 חושף שמונה ערוצי ADC של 12 ביט על A0–A7. כולם בייחוס 3.3 V — read_u16 מחזיר 0–65535 על פני 0–3.3 V בפין:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 3.3 / 65535
print(voltage)
time.sleep_ms(100)
DAC¶
ערוץ DAC יחיד של 12 ביט נחשף על DAC1 (A6 / D21) דרך pyb.DAC
from pyb import DAC
dac = DAC("DAC1")
dac.write(int(0.5 * 255)) # 8‑bit output, ~1.65 V
PWM¶
פין |
טיימר / ערוץ |
|---|---|
D0 |
TIM8 CH3N |
D1 |
TIM1 CH1, TIM8 CH3N |
D2 |
TIM1 CH2, TIM8 CH2N |
D4 |
TIM3 CH2, TIM8 CH2 |
D5 |
TIM3 CH1, TIM8 CH1 |
D6 |
TIM1 CH1 |
D7 |
TIM5 CH4 |
D13 |
TIM1 CH3 |
D14 |
TIM1 CH2 |
A7 |
TIM3 CH1 |
הניעו כל אחד מהם דרך machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D4"), freq=1_000, duty_u16=32768)
הערה
כמה פינים חולקים ערוצי טיימר:
TIM1 CH1 נמצא על
D1וגםD6.TIM1 CH2 נמצא על
D2וגםD14.TIM8 CH3N נמצא על
D0וגםD1.
בחרו צרכן אחד לכל ערוץ טיימר.
אזהרה
TIM1 שמור עבור שעון האב של המצלמה כאשר ה‑Vision Shield מאותחל דרך csi — חיישני מצלמה — D1, D2, D6, D13 ו‑D14 אינם ניתנים להנעה ב‑PWM בזמן שהמצלמה פעילה.
אפיקים תוכנתיים בשיטת 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 3 — חברו את המודול ל‑D12 (SCL) ול‑D11 (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 כמזהה כדי להשתמש בטיימר וירטואלי (תוכנתי):
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 שומר על זמן שעון קיר על פני איפוסים. מחבר ה‑HD חושף גם רפידת COINCELL שיכולה לגבות את ה‑RTC מסוללת CR2032 על פני אובדן הספק:
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()
מידע על אתחול וזמן ריצה¶
עדכון firmware (DFU)¶
ה‑Portenta H7 משתמש ב‑איפוס לחיצה כפולה הסטנדרטי של Arduino כדי להיכנס ל‑bootloader של Arduino. לחצו במהירות על כפתור האיפוס פעמיים — הלוח נספר מחדש דרך USB כהתקן DFU ו‑OpenMV IDE יכול לצרוב תמונת firmware חדשה.
סקריפט רץ יכול להיכנס מחדש ל‑bootloader לפי דרישה על ידי קריאה ל‑machine.bootloader()
import machine
machine.bootloader()
מערכת קבצים וסדר אתחול¶
קושחת ה‑Portenta H7 ממטמנת עד שלוש מערכות קבצים באתחול:
flash פנימי — תמיד ממוטמן ב‑
/flash. מכילmain.pyו‑README.txtכברירת מחדל; נוצר באתחול הראשון בלבד.כרטיס microSD — אם Vision Shield מחובר וכרטיס מוכנס, הוא ממוטמן ב‑
/sdcard.ROMFS — מערכת קבצים לקריאה בלבד, ממופת לזיכרון ב‑
/romהממוטמנת אוטומטית על ידי MicroPython באתחול.
לאחר ההטמעה, ספריית העבודה מוגדרת ל‑/sdcard כאשר הכרטיס נוכח, אחרת ל‑/flash. המפרש מריץ אז סקריפטים מאותה ספרייה:
boot.pyמורץ ב‑כל איפוס רך (אתחול קר,Ctrl‑Dמה‑REPL, או בכל פעם שהסקריפט הרץ מסתיים).main.pyמורץ רק באתחול קר, מיד לאחרboot.py. איפוסים רכים עוקבים מריצים מחדש אתboot.pyאך נופלים ישירות ל‑REPL — כדי להריץ מחדש אתmain.pyעליכם לאפס את הלוח לחלוטין.
הנחת boot.py או main.py על כרטיס ה‑SD עוקפת את העותק שב‑flash מבלי לגעת בו — שני הקבצים מחופשים בספריית האתחול (/sdcard כאשר הכרטיס ממוטמן, אחרת /flash).
ברירת המחדל של main.py הנשלחת על לוח שזה עתה נצרב פשוט מהבהבת את הערוץ ה‑כחול של נורית ה‑RGB LED למשתמש כדופק לב (שני פולסים קצרים, מרווח קצר), כך שתוכלו לדעת שהקושחה אותחלה בנקיון ללא מארח כלשהו מחובר.
sys.path מורחב כך שיכלול את כל שלוש מערכות הקבצים ואת תת‑הספריות lib/ שלהן, כך שמודולים הניתנים לייבוא יכולים לשכון ב‑/flash/lib, /sdcard/lib, או /rom/lib.
כדי לאלץ את המערכת להתעלם מכרטיס SD מוכנס (למשל כדי להריץ את main.py שב‑flash גם כאשר כרטיס נוכח), צרו קובץ ריק בשם SKIPSD בשורש של /flash.
כאשר מחובר דרך USB, מערכת קבצי האתחול (/sdcard אם כרטיס נוכח, אחרת /flash) נספרת גם כן ככונן אחסון המוני USB במארח, ומאפשרת לכם לערוך את boot.py, main.py וכל קובץ אחר ישירות. הוציאו את הכונן לפני איפוס הלוח כדי שהמארח ישטוף את הכתיבות השמורות במטמון שלו.
הערה
מכיוון שמערכת ההפעלה מתייחסת לכונן כאל התקן בלוקים פסיבי, קבצים שנוצרו או שונו על ידי קוד הרץ על המצלמה לא יופיעו עד שהמארח יטמין מחדש את הכונן. אם גם מערכת ההפעלה וגם המצלמה כותבות לאותה מערכת קבצים באותו זמן, מערכת ההפעלה תנצח ותדרוס שינויים שנעשו על ידי המצלמה. השתמשו בכרטיס ה‑SD עבור כל נתון שהסקריפט כותב בחזרה, והטמינו מחדש לפני קריאת קבצים אלה מהמארח.
הערה
הערוץ ה‑אדום של נורית ה‑RGB LED למשתמש עשוי להידלק לרגע בזמן שהמארח קורא או כותב לכונן אחסון ההמוני של USB — זהו מחוון פעילות מונע‑קושחה, ולא תקלה.
גדלי אחסון¶
ה‑Portenta H7 נשלח עם:
/flash— מערכת קבצים FAT בגודל 11 MB, קריאה/כתיבה./rom— ROMFS בגודל 4 MB לקריאה בלבד הממופה לזיכרון, משמש לשליחת סקריפטים ומודלי ML שמרוויחים מגישת mmap ללא העתקה./sdcard— הגודל המלא של כל כרטיס microSD המוכנס ב‑Vision Shield (כאשר נוכח), קריאה/כתיבה.
מחוון תקלה קשה¶
אם נורית ה‑RGB LED למשתמש מתחלפת במהירות בין כל הצבעים — מהיר מספיק כך שהיא נוטה להיראות כ‑נורית LED לבנה מנצנצת ולא כגוונים נפרדים — הקושחה נתקלה בתקלה קשה בלתי ניתנת לשחזור. צרבו מחדש את הקושחה כדי להתאושש; אם צריבה מחדש אינה עוזרת, ייתכן שהלוח ניזוק פיזית.
ספריות תוכנה¶
ראו את אינדקס הספרייה עבור הרשימה המלאה של המודולים — כולל אילו מהם ייחודיים לבניית ה‑Portenta H7.