איך הארדואינו מבחינת ביצועים והאם מתאים למערכות זמן-אמת?

 

כל מפתח שהתנסה בעבודה עם ארדואינו, יודע שהפיתוח הוא קל ומהיר, יחסית לאפשרויות פיתוח אחרות, כגון בניית לוח אלקטרוני באופן עצמי, כתיבת דרייברים ללוח וכתיבת קוד היישום עצמו. קלות הפיתוח הזו, נובעת משתי סיבות עיקריות: עקרון "החומרה הפתוחה" (Open Hardware) וסביבת-הפיתוח המוכללת (IDE) של הארדואינו. אך האם תהיתם פעם, עד כמה מהירים ביצועי הארדואינו? אולי אף שאלתם את עצמכם, "האם ארדואינו מתאים ליישומי 'זמן אמת' (Real time)?" המאמר שלפניכם, מסביר את הנושא וגם מביא מידע חשוב, לכל מי שמעוניין להתעמק בעולם הארדואינו.

איך הארדואינו מבחינת ביצועים?

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

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

Arduino Pro Micro

ארדואינו פרו מיני - מהיר או איטי?

 

מה גורם לביצועים הפחותים?

על הלוח של כל ארדואינו, קיים מיקרובקר. לרוב זהו בקר ממשפחת MEGA של חברת AVR, ובחלק מהלוחות, ניתן למצוא בקרים של ARM. באופן עקרוני הבקר הינו בעל ביצועים טובים יחסית לבקרים מסוגו. חרף זאת, בשילוב עם חומרת הארדואינו וסביבת-הפיתוח (IDE) שלו, מתקבלים יישומים בעלי ביצועים שאינם אופטימליים. הסיבה העיקרית לפגיעה בביצועים היא פשוטה ומובנת: הקוד של סביבת-הפיתוח ממומש כך שיהיה ידידותי ככל האפשר ויחסוך מהמפתח את הצורך להבין , מה קורה "מתחת למכסה מנוע". יעילות ומהירות מעולם לא היוו מטרה מרכזית בסביבת-הפיתוח לארדואינו. זה אולי נשמע כחסרון, אך למעשה מבחינת רוב משתמשי הארדואינו, זהו יתרון מובהק. רוב המשתמשים אינם זקוקים לביצועים מדהימים ולא מפתחים מערכות זמן-אמת. לפיכך מילי-שניה יותר או פחות, לא תשנה דבר במערכת שהם רוצים ליצור. לעומת זאת, קלות ומהירות הפיתוח היא הדבר הכי מושך עבורם וזו תכונה בולטת בארדואינו.

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

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

מה זה בדיוק "ביצועים לא אופטימליים"?

בסופו של דבר, רוב המשתמשים בארדואינו, מפתחים מערכת כלשהי המבוססת על הלוח הפופולרי והיא עובדת כמצופה. אז למה מתכוונים כשאומרים שארדואינו אינו מתאים לשמש במערכות "זמן אמת"?

נשתמש בדוגמא לשם הבהרת הנושא: נניח שמתקיימת תחרות ריצה חשובה מאד ומעוניינים להשתמש בלוח ארדואינו לבקרת מערכת המצלמה שמוצבת בקצה המסלול ובעזרת חיישן, מצלמת תמונה בדיוק ברגע שבו כל אחד מהרצים חוצה את קו הסיום (מערכות כאלה נקראות בז'רגון המקצועי "פוטו פיניש" - Photo Finish). כמובן שמתכנן המערכת רוצה שהמערכת תהיה מדויקת ככל האפשר, כי לעיתים הפרש הזמנים בין רץ אחד לאחר עומד על פחות ממילי-שניה (אלפית השניה), ורק מערכת הפוטו-פיניש מאפשרת לקבוע מי מהם הגיע במקום הראשון, השני, השלישי וכך הלאה..
כפי שהוסבר, הארדואינו אינו מגיב במהירות הגבוהה ביותר האפשרית ו"האיטיות" הזה, עשויה להתבטא בסדרי גודל של מילי-שניות. בפעולות יום-יומיות זה לא יפריע לנו, אך בדוגמא לעיל, במקרה ששני רצים מגיעים לקו-הסיום בו-זמנית (מבחינת השופט), רק לוח שמסוגל להגיב בסדר-גודל של מיקרו-שניות, יוכל להבדיל מי מהם הגיע שבריר-שניה קודם ומי מהם הגיע רגע מאוחר יותר.

האם ניתן לשפר את ביצועי הארדואינו?

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

אך ידוע שמבחינת החומרה, לוח הארדואינו כולל בקר מהיר. האם יש דרך לשפר את הביצועים ולקבל את המקסימום? התשובה היא כן.
כדי לקבל מלוח הארדואינו את יכולותיו המירביים, יש "לעקוף" את הקוד שמייצרת סביבת-הפיתוח המקורית ולכתוב קוד עצמי, שמשתמש במשאבי הבקר באופן אופטימלי. דוגמא אחת בסיסית וחשובה לשיפור התגובתיות של הארדואינו, היא מימוש עצמי של פונקציונליות המקבילה לפקודה "()digitalWrite". הפקודה digitalWrite משמשת לפנייה לפין קלט/פלט (I/O) וקביעת רמתו (0 או 1). הפקודה ממומשת בסביבת הארדואינו בצורה שאינה אופטימלית  ולכן מתקבלים ביצועים איטיים יחסית כשמשתמשים בפקודה הזו כדי לשלוט בפין כלשהו. ניתן לכתוב קוד תוך שימוש בפקודות "קרובות לחומרה" (Low-level), שמבצע ישירות את השליטה על פין I/O ולהשיג מהירות גבוהה פי 10 ויותר מזו שמספקת סביבת-הפיתוח!

דוגמאות להמחשה

על-מנת להמחיש את ההבדל בין ביצועים של סביבת ארדואינו סטנדרטית לבין קוד אופטימלי, נערכה הבדיקה הבאה: נבחר לוח ארדואינו UNO, מתח עבודה 5V, תדר עבודה 16MHz. נכתב קוד פשוט ש"מנדנד" את פין D12 בין רמה לוגית נמוכה ("0") לבין רמה גבוהה ("1") וחוזר חלילה במהירות המירבית (כלומר ללא שום השהייה מכוונת). הקוד נכתב פעם אחת בעזרת סביבת התוכנה Arduino ובפעם השניה בסביבת הפיתוח שנקראת Atmel Studio שמיועדת לפיתוח באופן מקצועי לבקרים ממשפחת AVR (כמו הבקר הקיים ברוב הדגמים של הארדואינו). בשני המקרים הקוד נטען לבקר בעזרת מתקן-תכנות ייעודי (Programmer) וללא שימוש ב-Bootloader. לאחר טעינת הקוד לבקר חובר סקופ בין פין האדמה (GND) ופין D12 ונמדד תדר האות שמופיע בפין זה, על-מנת להשוות את המהירות המתקבלת בכול אחת מהשיטות.

קוד המקור ששימש בבדיקה:

 

ARDUINO

void setup()
{
  // Set digital pin D12 as an output
  pinMode(12, OUTPUT);
}

 

void loop()
{
  digitalWrite(12, HIGH); // Set pin 12 output to HI
  digitalWrite(12, LOW); // Set pin 12 output to LOW
}

 

STUDIO

int toggleFlag = 1;    // Flag used for toggeling process

int PinPB4_ON = 1<<4;    // Value of 4th bit on

 

DDRB = 0xFF;    // Set all port B pin as outputs
PORTB = (1<<PORTB4);    // Init Arduino's pin D12 to HI

 

while (1)     // Loop forever
{
   if (toggleFlag)
   {
     PORTB = 0;    // Turn off all bits
   }
else
   {
      PORTB = PinPB4_ON;    // Turn on 4th bit of Port B (Arduino's D12 pin)
   }
   toggleFlag = !toggleFlag;
}

 

 

תוצאות הבדיקה:

  • הקוד שמומש בסביבת הארדואינו גרם לפין D12 להתנדנד בתדר 150KHz.
  • הקוד שמומש בסביבת Atmel Studio גרם לפין D12 להתנדנד בתדר 600KHz.
  • הקוד שנכתב בסביבת Atmel Studio רץ פי 4 יותר מהר מהקוד שנכתב ב-Arduino.

 מסקנות:

  • כתיבת קוד בסביבה מקצועית מאפשרת לקבל ביצועים עדיפים על-פני הקוד המתקבל בסביבת ארדואינו, אפילו ללא שימת-דגש על אופטמיזציה. כלומר  "כתיבת סטנדרטית" עבור ארדואינו בסביבת-פיתוח מקצועית, תיצור ברוב המקרים קוד מהיר יותר ביחס לקוד שנוצר על-ידי סביבת-הפיתוח Arduino.
  • בסביבת-פיתוח מקצועית ניתן לבצע אופטימיזציות לביצועים, על-ידי מימוש קוד ש"קרוב לחומרה" (Low level programming) . בסביבת Arduino בה נעשה שימוש בפונקציות מערכת מוכנות, לא ניתן להגיע לאותם ביצועים.

 

לסיכום

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


 

תקועים עם פרויקט בארדואינו וצריכים עזרה? צרו קשר