כיצד להשיק במהירות תכני חישת זמן-מעוף אופטית 3D

מאת ‎Stephen Evanczuk

באדיבות ‎DigiKey's North American Editors

מדידת מרחק זמן-מעוף (ToF) אופטי משחקת תפקיד יסודי ביישומים מגוונים החל מחישה תעשייתית עד ממשקי משתמש מבוססי מחוות. עם הזמינות של חיישני ToF מרובי-פיקסלים מהירות-גבוהה, מדויקים, מפתחים יכולים לממש אלגוריתמים של חישת תלת-ממד (3D‏) מתוחכמים יותר הדרושים ביישומים אלה. עם זה, זמן הפיתוח מואט בשל המורכבות של תת-המערכת חישה אופטית מרובת-פיקסלים.

מאמר זה דן בעקרונות הבסיסיים של זמן-מעוף (ToF). אחר כך, המאמר מציג‏ ערכת הערכה ToF אופטית מבית Broadcom המאפשרת למפתחים לבנות במהירות אב-טיפוס ליישומי מדידת מרחק 1D ו-3D‏ מדויקים, כמו גם מימוש מהיר של פתרונות מותאמים-במיוחד לחישת ToF אופטית.

יסודות של טכנולוגיית ToF אופטית

משמשת להשיג מרחק מדויק הדרוש ביישומים מרובים, טכנולוגיית ToF אופטית מאפשרת מדידות המבוססות על הזמן הדרוש לאור לעבור באוויר. החישובים הספציפיים המשמשים לביצוע מדידות אלו מסתמכים באופן כללי על שתי גישות שונות, ToF ישיר ובלתי-ישיר. בגישת ToF ישיר, הידועה גם כ-‏pulse ranging, התקן מודד את הזמן בין שידור וקליטה של פולס אור מסוים על ידי חיישן ToF תוך שימוש במשוואה 1:

משוואה 1משוואה 1

כאשר:

c0 = מהירות האור בריק

T∆ = הזמן שעבר בין שידור וקליטה

למרות שפשוטה עקרונית, היכולת לבצע מדידות מדויקות בגישה זו נתקלת במספר אתגרים,‏ כולל הצורך במשדרים ומקלטים חזקים מספיק, הגדלת אות-לרעש וגילוי מדויק של שפת פולס.

לעומת זאת, שיטות ToF בלתי-ישירות משתמשות‏ בגל רציף מאופנן ומודדות את הפרש הפאזה בין אותות משודרים ונקלטים בהתאם למשוואה 2‏:

d = c0 / 2fmod x ∆φ/2πמשוואה 2

כאשר:

c0 = מהירות האור בריק

fmod = תדר אפנון ליזר

φ∆ = הפרש פאזה נקבע

בנוסף להקטנת דרישות הספק משדר ומקלט, גישת ToF בלתי-ישיר מקטינה דרישות עיצוב פולס, ובכך מפשטת מורכבות תכנון לביצוע תיחום 3D‏ וגילוי תנועה.

שתי השיטות, הישירה והבלתי-ישירה, דורשות תכנון זהיר של הקצה-הקדמי האופטי ובקרה מדויקת של אותות משדר ומקלט. לאורך שנים, מפתחים יכלו להפיק תועלת מחיישני ToF אופטיים משולבים המשלבים התקני שידור וחיישני קליטה במארז אחד. אף על פי כן, דורות קודמים של התקנים אלה בדרך כלל דרשו ממפתחים להתפשר על שילובים מסוימים של ביצועים או מאפייני פעולה כגון צריכת הספק, טווח, דיוק ומהירות. פשרות כאלו התגלו כ‏מגבלות מרכזיות לקבוצה הולכת וגדלה של יישומי חישה תעשייתית הנדרשים לפעול במרחקים בינוניים בטווח של עד ‏10 מטרים (m).

מודולי חיישן ToF בלתי-ישיר מתקדמים יותר כמו ה-AFBR-S50MV85G של Broadcom מתוכננים במיוחד לענות על הצרכים ההולכים וגדלים לתוצאות מדויקות, מהירות גבוהה, בטווחי מרחק בינוניים, תוך כדי שמירה על גודל מארז וצריכת הספק מינימליים. ערכת הערכה AFBR-S50MV85G-EK של Broadcom המבוססת על חיישן זה, וערכת פיתוח תוכנה (SDK) נלווית, מספקות פלטפורמת פיתוח חיישן‏ ToF מרובת-פיקסלים המאפשרת למתכננים לממש במהירות יישומי חישה 3D ToF.

כיצד מודול משולב מפשט מדידת מרחק ToF

פותח עבור יישומי חישה תעשייתיים, מודול ה-AFBR-S50MV85G מספק פתרון‏ שלם של חישת ToF אופטית במארז יחיד. הרכיבים המשולבים שלו כוללים לייזר נפלט-משטח חלל-אנכי ‏(VCSEL‏) 850 ננומטר (nm) עבור הארה אינפרה-אדומה (IR), מטריצת‏ חיישן 32-פיקסלים משושה, עדשות משולבות עבור VCSEL‏ ואופטיקת חיישן, ‏ומעגל משולב ייחודי-ליישום (ASIC).

המשדר, הממוקם באורינטציה קבועה ביחס למטריצת החישה, מאיר אובייקט יעד וגורם למספר פיקסלים במטריצת החישה לגלות את אות ה-IR המוחזר. בעבודה בסיסית, זה מאפשר למודול לתמוך במדידה מדויקת של מרחק ממשטחים לבנים, שחורים, צבעוניים, מתכתיים או רטרורפלקטיביים (retroreflective), אפילו באור שמש ישיר, הודות ליכולות המובנות שלו להחליש אור סביבה.

עם קיטון המרחק אל אובייקט, פיצוי אוטומטי עבור שגיאות פרלקסה (parallax errors) מאפשר למעשה מדידות ללא מגבלה נמוכה של מרחק.‏ בו-זמנית, השילוב של הארת IR ומטריצת חישה מאפשר זמינות של מידע נוסף אודות האובייקט, כולל תנועה, מהירות, זווית נטיה או יישור צידי. כתוצאה מכך, המודול יכול לספק נתונים דרושים כדי לקבוע כיוון ומהירות של אובייקט מטרה חולף או מתקרב (איור 1‏).

תרשים של נתונים שנאספו ממטריצת החישה 8 x‏ 4 פיקסלים של מודול Broadcom AFBR-S50MV85G (הקלק להגדלה)איור 1‏: תוך שימוש בנתונים שנאספו ממטריצת החישה 8 x‏ 4 פיקסלים של מודול AFBR-S50MV85G, מפתחים יכולים לממש יישומי 3D המסוגלים למדוד מאפייני תנועה של אובייקט. (מקור תמונה: Broadcom)

כדי לארגן עבודה מדויקת של ה-VCSEL‏ ומטריצת החישה שלו, המעגל המשולב הייחודי-ליישום (ASIC) של המודול מספק את כל המעגלים הדרושים עבור דחיפת ה-VCSEL, לכידת אות אנלוגי ממטריצת החישה ואכשור אות דיגיטלי (איור 2‏).

תרשים של מעגל משולב ייחודי-ליישום (ASIC) משולב במודול Broadcom AFBR-S50MV85Gאיור 2‏: מעגל משולב ייחודי-ליישום (ASIC) משולב במודול ה-AFBR-S50MV85G כולל את כל המעגלים הדרושים כדי לדחוף את מקור האור VCSEL‏ של המודול, לקבל אותות נקלטים ממטריצת החישה ולהפיק נתונים דיגיטליים להעברה דרך אפיק SPI. (מקור תמונה: Broadcom)

מעגלי האספקה המשולבים של ה-ASIC מאפשרים למודול לעבוד מאספקה יחידה של‏ ‏5 וולט, בעוד מתנד נגד-קבל (RC) מקוזז-טמפרטורה ומכויל-מפעל וחוג נעול פאזה (PLL‏) דיגיטלי משולבים מספקים את כל אותות השעון הדרושים. הודות לשילוב זה, מפתחים יכולים לכלול בקלות את המודול בתכנים שלהם תוך שימוש ביחידת מיקרו-בקר (MCU) ‏ומספר רכיבים חיצוניים נוספים. הממשק עם יחידת המיקרו-בקר דורש רק פין כניסה/יציאה למטרה-כללית (GPIO‏) עבור אות נתונים-מוכנים‏ מהמודול, יחד עם חיבור באמצעות הממשק ההיקפי הטורי הדיגיטלי (SPI) של המודול (איור 3‏).

תרשים מודול AFBR-S50MV85G של Broadcom (הקלק להגדלה)איור 3‏: מודול AFBR-S50MV85G של Broadcom דורש רק יחידת מיקרו-בקר (MCU) ומספר רכיבים נוספים עבור מימוש מערכת חישת ToF שלמה. (מקור תמונה: Broadcom)

כדי להשלים תכן חומרה פשוט זה, פונקציונליות התוכנה הנלווית הדרושה כדי לממש מדידת מרחק מסופקת כולה בתוכנת דרייבר ToF של Broadcom. בעוד המודול מטפל באיסוף נתונים אופטיים עבור יישומי מדידת מרחק, תוכת הדרייבר Broadcom ToF הכלולה ב-AFBR-S50 SDK מבצעת את כל צעדי הקונפיגורציה של החומרה, כיול ומדידות. במהלך המדידות, תוכנת הדרייבר מחלצת את ערכי המרחק כמו גם המשרעת של הפיקסלים.

כיצד לפתח במהירות יישום מדידת מרחק

בשילוב עם ה-AFBR-S50 SDK, ערכת ההערכה AFBR-S50MV85G-EK של Broadcom מספקת ‏ פלטפורמה מקיפה עבור בניית אב-טיפוס מהירה ופיתוח מהיר של יישומי מדידת מרחק. הערכה מגיעה עם‏ לוח מתאם הכולל את מודול ה-AFBR-S50MV85G, לוח הערכה FRDM-KL46Z של NXP מבוסס על Arm Cortex-M0+ MCU וכבל‏ mini-USB עבור חיבור מכלול לוח ההערכה למחשב נייד או מערכת משובצת אחרת (איור 4‏).

תמונה של ערכת הערכה AFBR-S50MV85G-EK של Broadcomאיור 4‏: ערכת ההערכה AFBR-S50MV85G-EK של Broadcom ותוכנה נלווית מספקות פלטפורמה שלמה עבור הערכה ובניית אב-הטיפוס ליישומי מדידת מרחק ToF. (מקור תמונה: Broadcom)

ביצוע מדידת מרחק ToF עם ערכת ההערכה דורש‏ מספר צעדים בלבד כדי להתחיל. לאחר הורדת ה-AFBR-S50 SDK,‏ אשף התקנה (setup wizard) מנחה את המפתח לאורך תהליך התקנה מהיר. אחרי שהמפתח מתחיל את אפליקציית התוכנה AFBR-S50 Explorer של Broadcom הכלולה בחבילת ה-SDK, התוכנה מתחברת ללוח ההערכה AFBR-S50 דרך ממשק ה-USB‏, מקבלת את נתוני המדידות באמצעות תוכנת הדרייבר הרצה על ה-MCU של לוח ה-NXP, ומאפשרת למשתמש להציג את התוצאות בתרשים‏ 1D או 3D‏ (איור 5‏).

תמונה של תוכנת Broadcom AFBR-S50 Explorer (הקלק להגדלה)איור 5‏: תוכנת ה-AFBR-S50 Explorer מפשטת הערכה של מדידות ToF באמצעות תרשימי 3D‏ המראים משרעת הארה שהתקבלה עבור כל פיקסל במטריצת החיישן ToF. (מקור תמונה: Broadcom)

כמתואר באיור 5‏, מראה תרשים ה-3D‏ מציג קריאות מכל פיקסל, אך התוכנה מספקת מראה חלופי המאפשר למפתחים לראות רק את הפיקסלים הנחשבים תקפים עבור מדידה. במראה חלופי זה, פיקסלים שאינם עומדים בקריטריונים מוגדרים מוסרים מהתרשים (איור 6‏).

תמונה של תוכנת AFBR-S50 Explorer של Broadcom (הקלק להגדלה)איור 6‏: באמצעות תוכנת AFBR-S50 Explorer של Broadcom, מפתחים יכולים לצפות בתרשימי 3D‏ של מדידות מפושטות המשמיטות פיקסלים שלא עומדים בקריטריונים מוגדרים מראש. (מקור תמונה: Broadcom)

כדי לחקור דיוק מדידות וביצועים בתרחישי יישום שונים כמו תאורה, החזרה וסוג משטח, מפתחים יכולים לצפות בהשפעה של תצורות חישה שונות כמו שימוש ביותר פיקסלים עבור יישומי 3D מוגברים, או פחות פיקסלים עבור יישומי 1D הדורשים מדידות מדויקות יותר. אחרי הערכת שיטות מדידה באבי-הטיפוס שלהם, מפתחים יכולים לסמוך על תוכנת הדוגמה הכלולה ב-AFBR-S50 SDK של Broadcom למימוש מהיר של יישומי חישת ToF מותאמים-במיוחד.

בנייה של יישומי תוכנה חישת ToF מותאמים-במיוחד

Broadcom בונה תמיכה ביישומי חישת ToF סביב ‏ארכיטקטורה יעילה מבוססת על ספריית הליבה AFBR-S50, שכוללת קוד ייחודי לחומרת חיישן, ממשק תכנות יישום (API) ושכבות hardware abstraction‏ (HAL‏) (איור 7‏).

תרשים של סביבת עבודה ToF של Broadcomאיור 7‏: בסביבת עבודה ToF של Broadcom, ממשק תכנות יישום (API) דרייבר של ה-ToF מספק קוד יישום משתמש עם גישה לכיול, מדידה ופונקציות הערכה בספריית הליבה של דרייבר ToF מהודר-מראש. (מקור תמונה: Broadcom)

כחלק מחבילת ה-AFBR-S50 SDK, ‏Broadcom מספקת את ספריית הליבה כקובץ ספריה ANSI-C מהודר-מראש המשבץ את כל הנתונים והאלגוריתמים הנחוצים להרצת חומרת ה-AFBR-S50MV85G. ספריית הליבה, הרצה על ה-MCU של מערכת מדידת המרחק, מספקת פונקציונליות שכוללת כיול, מדידה והערכה לביצוע מדידת מרחק עם עומס עיבוד וצריכת הספק מינימליים. מאחר ופונקציות ספריית הליבה מטפלות בכל הפרטים הבסיסיים, מחזור המדידה הבסיסי הנראה על ידי המפתח הוא פשוט (איור 8‏).

תמונה של תוכנת Broadcom AFBR-S50 SDK ToF (הקלק להגדלה)איור 8‏: תוכנת ה-Broadcom AFBR-S50 SDK ToF מקטינה למינימום את עומס העבודה של המעבד תוך שימוש בפסקים (Interrupts‏) והתקשרויות בחזרה (Callbacks). (מקור תמונה: Broadcom)

בתחילת כל מחזור מדידה (יזום על ידי פסק (Interrupt‏) קוצב-זמן מחזורי, או IRQ‏), ה-MCU יוזם את המדידה ומיד חוזר למצב לא-פעיל (או ממשיך לעבד קוד יישום מסוים). לאחר השלמת המדידה, מודול ה-AFBR-S50MV85G משתמש בקו ה-GPIO‏ המחובר כדי לאותת על פסק (Interrupt), מעורר את ה-MCU ליזום קריאת נתונים על אפיק ה-SPI לפני חזרה למצבו הקודם. לאחר השלמת קריאת הנתונים (איתות על ידי SPI done IRQ‏), ה-MCU מבצע קוד להערכת נתוני חיישן ToF שנתקבלו.

כדי למנוע אבדן נתוני מדידה, ספריית הליבה מונעת את ההתחלה של מחזור מדידה חדש על ידי חסימת חוצץ הנתונים עד לקריאה לרוטינת הערכה.‏ לכן, מפתחים כוללים בדרך כלל חוצץ‏ כפול עבור נתונים גולמיים כדי לאפשר ביצוע מדידות ומשימות הערכה מופרדות.

עבור מפתחי תוכנת יישום, רוטינות ספריית הליבה מגנות‏ על פרטי הכיול, המדידה וההערכה. למעשה, מפתחים יכולים להשתמש בערכת ההערכה וביישום AFBR-S50 Explorer כפלטפורמת אב-טיפוס שלמה למסירת נתוני מדידה לקוד יישום תוכנה רמה-גבוהה.

עבור מפתחים שצריכים לממש תוכנת יישום מותאמת-במיוחד, חבילת ה-AFBR-S50 SDK משלבת את מודולי ספריית הליבה המהודרים-מראש עם מספר דוגמאות תוכנה. כתוצאה מכך, מפתחים יכולים ליצור במהירות יישומי חישת ToF משלהם על ידי בנייה על יישומי הדוגמה המסופקים ב-SDK. מפתחים יכולים לגשת לחומרת AFBR-S50MV85G ופונקציונליות ספריית ליבה AFBR-S50 בקוד תוכנה הייחודי-ליישום שלהם על ידי קריאה לפונקציות ב-AFBR-S50 SDK API וציון הפונקציות שלהם עבור הקריאות-החוזרות השונות הנתמכות על ידי ספריית הליבה (ראה שוב איור 7‏).

חברת Broadcom מספקת תעוד נרחב על ה-API ותוכנות הדוגמה, דבר המאפשר למפתחים לנוע במהירות באימוץ דוגמאות התוכנה לצרכים שלהם או להתחיל מהתחלה. למעשה, המדידה הבסיסית ומחזור ההערכה הם פשוטים, פשוט התאמת פונקציות מותאמות-במיוחד וקריאות API למחזור המדידה (ראה שוב איור 8‏). לדוגמה, ‏מחזור מדידה, כפי שנדון לעיל, כולל שלושה שלבים: אינטגרציה של התקן ToF, קריאת נתונים והערכה. קריאות API ספריית ליבה שאמורות ליזום את שלושת השלבים האלה כוללות:

  • ()Argus_TriggerMeasurement, שמעורר מסגרת מדידה יחידה באופן אסינכרוני‏
  • ()Argus_GetStatus, שמחזיר STATUS_OK עם השלמה מוצלחת של המדידה
  • ()Argus_EvaluateData, שמעריך מידע שימושי מנתוני המדידה הגולמיים

Broadcom מדגימה חוג מדידה בסיסי זה ביישום דוגמה הכלול בתפוצת ה-SDK המוצגת ברשימה 1.

עותק
int main(void)
{
   status_t status = STATUS_OK;
   
   /* Initialize the platform hardware including the required peripherals
   * for the API. */
   hardware_init();
   
   /* The API module handle that contains all data definitions that is
   * required within the API module for the corresponding hardware device.
   * Every call to an API function requires the passing of a pointer to this
   * data structure. */
   argus_hnd_t * hnd = Argus_CreateHandle();
   handle_error(hnd ? STATUS_OK : ERROR_FAIL, "Argus_CreateHandle failed!");
   
   /* Initialize the API with default values.
   * This implicitly calls the initialization functions
   * of the underlying API modules.
   *
   * The second parameter is stored and passed to all function calls
   * to the S2PI module. This piece of information can be utilized in
   * order to determine the addressed SPI slave and enabled the usage
   * of multiple devices on a single SPI peripheral. */
   
   status = Argus_Init(hnd, SPI_SLAVE);
   handle_error(status, "Argus_Init failed!");
   
   /* Print some information about current API and connected device. */
   uint32_t value = Argus_GetAPIVersion();
   uint8_t a = (value >> 24) & 0xFFU;
   uint8_t b = (value >> 16) & 0xFFU;
   uint8_t c = value & 0xFFFFU;
   uint32_t id = Argus_GetChipID(hnd);
   argus_module_version_t mv = Argus_GetModuleVersion(hnd);
   print("\n##### AFBR-S50 API - Simple Example ##############\n"
   " API Version: v%d.%d.%d\n"
   " Chip ID: %d\n"
   " Module: %s\n"
   "##################################################\n",
   a, b, c, id,
   mv == AFBR_S50MV85G_V1 ? "AFBR-S50MV85G (v1)" :
   mv == AFBR_S50MV85G_V2 ? "AFBR-S50MV85G (v2)" :
   mv == AFBR_S50MV85G_V3 ? "AFBR-S50MV85G (v3)" :
   mv == AFBR_S50LV85D_V1 ? "AFBR-S50LV85D (v1)" :
   mv == AFBR_S50MV68B_V1 ? "AFBR-S50MV68B (v1)" :
   mv == AFBR_S50MV85I_V1 ? "AFBR-S50MV85I (v1)" :
   mv == AFBR_S50SV85K_V1 ? "AFBR-S50SV85K (v1)" :
   "unknown");
      
/* Adjust some configuration parameters by invoking the dedicated API methods. */
   status = Argus_SetConfigurationFrameTime( hnd, 100000 ); // 0.1 second = 10 Hz
   handle_error(status, "Argus_SetConfigurationFrameTime failed!");
   
   /* The program loop ... */
   for (;;)
   {
      myData = 0;
      /* Triggers a single measurement.
      * Note that due to the laser safety algorithms, the method might refuse
      * to restart a measurement when the appropriate time has not been elapsed
      * right now. The function returns with status #STATUS_ARGUS_POWERLIMIT and
      * the function must be called again later. Use the frame time configuration
      * in order to adjust the timing between two measurement frames. */
      Argus_TriggerMeasurement(hnd, measurement_ready_callback);
      handle_error(status, "Argus_StartMeasurementTimer failed!");
      STATUS_ARGUS_POWERLIMIT)
      {
         /* Not ready (due to laser safety) to restart the measurement yet.
         * Come back later. */
         continue;
      }
      else
      {
         /* Wait until measurement data is ready. */
      do
         {
            status = Argus_GetStatus(hnd);
         }
         while (status == STATUS_BUSY);
         handle_error(status, "Waiting for measurement data ready (Argus_GetStatus) failed!");
         /* The measurement data structure. */
         argus_results_t res;
         
         /* Evaluate the raw measurement results. */
         status = Argus_EvaluateData(hnd, &res, (void*) myData);
         handle_error(status, "Argus_EvaluateData failed!");
         
         /* Use the obtain results, e.g. print via UART. */
         print_results(&res);
         }
      }
}

רשימה 1: קוד דוגמה בתפוצת ה-Broadcom AFBR-S50 SDK מדגים את תבנית התכנון הבסיסי עבור איסוף והערכה של נתוני ToF ממודול ה-AFBR-S50MV85G. (קוד מקור: Broadcom)

כמתואר ברשימה, שלוש קריאות הפונקציה API המוזכרות לעיל יוצרות את עמוד השדרה של ביצוע מחזור מדידות. על ידי עיון בתעוד ה-API ויישומי דוגמה אחרים ב-SDK, מפתחים יכולים לממש במהירות יישומי 3D מורכבים תוך שימוש ביכולת של המודול לספק את הנתונים הנחוצים כדי לקבוע מאפיינים מתקדמים כגון מהירות, כיוון וזווית נטיה של אובייקט מטרה.

מסקנה

התקני חישת ToF אופטית אפשרו יישומים בסגמנטים מגוונים הדורשים מדידת מרחק מדויק, אך מגבלות בטווחי מדידה, דיוק, או אמינות בלמו התרחבות ליישומים כמו מערכות חישה תעשייתיות הדורשות מהתקנים בהספק נמוך להיות מסוגלים לספק תוצאות מדויקות בטווחים ארוכים יותר. ‏תת-מערכת ToF אופטית משולבת מבית Broadcom עומדת בדרישות עולות אלו עבור יישומי חישה של הדור-הבא. תוך שימוש בערכת הערכה המבוססת על התקן זה, מפתחים יכולים לממש במהירות מערכות עבור מדידות מדויקות ביישומים חד-מימדיים (1D), ולמעקב אחר תנועה מורכבת של אובייקט ביישומים תלת-מימדיים (3D).

DigiKey logo

מיאון אחריות: דעות, אמונות ונקודות מבט המובעות על ידי מחברים שונים ו/או משתתפי פורום באתר אינטרנט זה לא בהכרח משקפות את הדעות, האמונות ונקודות המבט של חברת DigiKey או את המדיניות הרשמית של חברת DigiKey.

אודות כותב זה

Image of Stephen Evanczuk

Stephen Evanczuk

ל- Stephen Evanczuk יש ניסיון של יותר מ- 20 שנה בכתיבה עבור תעשיית האלקטרוניקה על מגוון רחב של נושאים, כולל חומרה, תוכנה, מערכות ויישומים, כולל IoT. הוא קיבל את הדוקטורט שלובמדעי המוח ברשתות נוירונים ועבד בתעשייה התעופה-וחלל על מערכות מאובטחות מבוזרות בסדר-גודל עצום ועל שיטות להאצת אלגוריתמים. כיום, כשהוא לא כותב מאמרים על טכנולוגיה והנדסה, הוא עובד על יישומים של למידה עמוקה למערכות זיהוי והמלצה.

אודות מוציא לאור זה

DigiKey's North American Editors