משואת ה-IR, שהיא חלק מפרויקט גדול יותר, נועדה לעשות דבר אחד פשוט – לשדר בתת-אדום (IR) מספר אחד קטן פעם בשניה. מה שהופך אותה למעניינת הם אילוצי הסוללה. בפוסט זה אסביר את האילוצים ואיך בחרתי להתמודד איתם כדי להפוך את המשואה לחסכונית במיוחד.
בנוסף על האופטימיזציות ה"רגילות" בעולם המחשוב, שמנסות לצמצם את זמן הריצה של עיבוד מסוים או את כמות הזיכרון הנדרש עבורו, יש אופטימיזציה נוספת וחשובה במיקרו-בקרים: צמצום צריכת החשמל. במקרה הספציפי של משואת ה-IR, אופטימיזציה זו חשובה במיוחד, מכיוון שהסוללה שנבחרה עבורה היא סוללת ה"מטבע" החלשה CR2032.
לפני הכל: מהירות שעון
לסוללה זו, כשהיא מלאה לגמרי, מתח נקוב של 3V בלבד, מה שמציב אוטומטית גבול עליון למהירות השעון של המיקרו-בקר. כמובן, אפשר להוסיף למערכת ממיר מתח שיקבל 3V ויוציא 5V, או כמה שצריך, אבל ההמרה כרוכה בהפסדים מסוימים וחבל על החשמל. הנה גרף מהירות השעון המרבית (המובטחת) כפונקציה של המתח, מתוך ה-datasheet של המיקרו-בקר ATtiny13A:
הצירים של הגרף לא מפורטים מדי, אבל אם עושים את החשבון רואים, למשל, שתדר השעון 9.6MHz של המתנד הפנימי של ה-ATtiny13A ייצא מהטווח הבטוח ברגע שהסוללה תיחלש ותאבד כעשרה אחוזים מהמתח שלה. האופציה השניה של המתנד הפנימי, 4.8MHz, מתאימה לטווח מתחים גדול יותר ולכן תוכל להחזיק מעמד יותר זמן.
תדר שעון נמוך יותר צורך פחות חשמל, אך כדי לשלוח אות ב-IR "סטנדרטי" צריך להפיק גל נושא בתדר 38KHz ולהספיק גם לנהל את הבייטים שמשודרים עליו, אז יש גבול לכמה נמוך אפשר לרדת.
חומרה: שינה
שליחת קוד המשואה אמורה להימשך בסביבות עשר אלפיות השניה. מה עושים בשאר 990 אלפיות השניה של כל מחזור? לולאת המתנה (כמו מה שמתחבא מאחורי הפונקציה delay בארדואינו) היא הבזבזנית ביותר: על פי טבלאות המאפיינים החשמליים, ה-ATtiny13A בפעילות מלאה שכזו צורך – בתדר של 4MHz ובמתח של 3V – עד 1.8 מיליאמפר.
זה אמנם לא הרבה, ואפילו CR2032 תוכל להחזיק מעמד יותר ממאה שעות של פעולה רצופה – אבל זה עדיין רק ימים ספורים. אם נעביר את המיקרו-בקר בזמן ההמתנה למצב שנקרא "Power down", נוכל לרדת לצריכה מרבית של 10 מיקרואמפר ולהכפיל את זמן הפעולה הכולל פי עשרה ויותר.
למעשה, בטבלה שב-datasheet מופיע מצב "Power down" נוסף עם צריכה של 2 מיקרואמפר בלבד, אך במצב זה, הדבר היחיד שיכול להעיר את המיקרו-בקר משנתו הוא סיגנל חיצוני. כדי לשדר פעם בשניה (פלוס מינוס), אנחנו חייבים איזשהו טיימר פנימי שימשיך לפעול, וזה יהיה טיימר ה-Watchdog שצורך את שמונת המיקרואמפר הנוספים. לשמחתנו, אחת מהגדרות ה-Watchdog מאפשרת כניסה שלו לפעולה תוך שניה אחת – אז בתום השידור פשוט נפעיל את ה-Watchdog, נעביר את המיקרו-בקר למצב "Power down" ונחכה.
חומרה: התעוררות
ל-Watchdog יש, ברוב המיקרו-בקרים המודרניים, שני מצבי פעולה: Reset ו-Interrupt. במצב הראשון, ברגע שנגמרת הספירה-לאחור, המיקרו-בקר עובר אתחול מלא (שגם מוציא אותו כמובן ממצב השינה). הדרך הזו היא הכי קלה וקצרה מבחינת קוד התוכנה, אבל לא בהכרח הכי חסכונית בחשמל. הסיבה לכך היא שהאתחול המלא, וכל פקודות ההכנה שרצות ממנו ועד תחילת שידור הקוד ב-IR, לוקחים בעצמם קצת זמן וחשמל. אם נעבור למצב Interrupt (שבו ה-Watchdog מעיר את המיקרו-בקר, וזה מריץ פונקציית פסיקה וממשיך לרוץ מאותו מקום בו הלך קודם לישון) אולי נוכל לצמצם עוד יותר את הצריכה.
זה, כמובן, דבר שצריך לבדוק ולא להניח באופן עיוור – הרי גם פונקציית הפסיקה כרוכה בעיבוד מסוים, ואם רצף האתחול קצר במיוחד, היא עשויה להיות למעשה יקרה יותר ממנו. כאומדן ראשוני, בדקתי בפלט האסמבלי של הקוד שלי כמה פקודות רצות מהאתחול ועד לשידור (24), וכמה רצות בפסיקה (10). ההפרש הזה זניח לגמרי ביישום הספציפי של המשואה, אך ביישומים בהם מצבי השינה קצרים וצפופים מאד, החיסכון של 14 פקודות אסמבלי לכל התעוררות יצטבר למשהו משמעותי.
מה עוד?
הסיפור לא נגמר כאן. עדיין בתחום החומרה, ניתן לכבות את החשמל למודולים מסוימים במיקרו-בקר אם הם אינם נחוצים. למשל, במקרה של המשואה, שאין לה שום קלט ובוודאי שלא קלט אנלוגי, לא צריך לתת חשמל למודול ה-ADC. שינוי של ביט יחיד ברגיסטר PRR (ראשי תיבות של Power Reduction Register) מספיק כדי לחסוך לנו בסביבות 260 מיקרואמפר בזמן שהמיקרו-בקר פעיל! כיבוי של מודול המשווה האנלוגי (Analog Comparator) חוסך עוד כ-60 מיקרואמפר.
כלל חשוב באופטימיזציה הוא לזהות את המקומות הבזבזניים באמת ולהשקיע את מירב המאמצים שם, במקום להיטפל לקטנות. לכן, אחרי שהגדרתי את מצב השינה לזמן ההמתנה, היעד "הנכון" הבא בתור חייב להיות דווקא שלב השידור, שבו הלד התת-אדום "מושך" עשרה או עשרים מיליאמפר במשך כמה אלפיות שניה. בהנחה שכבר צמצמתי את הזרם הזה למינימום האפשרי במסגרת טווח השידור הרצוי, חיסכון משמעותי נוסף בצריכה לא יכול להגיע מהחומרה אלא רק מהתוכנה – בחירה נכונה של פרמטרים ושל פרוטוקול שידור, שימזערו את זמן ה-ON של הלד.
פוסט נהדר בעיני.
אם מותר להתעניין, איזה מין מידע אמורה המשואה לשדר?
בשלב זה, לפחות, המשואה משדרת רק מספר זיהוי פשוט (16 ביט). החלק השני והגדול יותר של הפרויקט מחפש את מספר הזיהוי כדי לדעת אם הוא נמצא בסביבת משואה רלוונטית, ואז עושה דברים מעניינים יותר שאסור לי לספר עליהם 🙂