החומרה הכי נפוצה שלא הכרתם

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

בדיקה של המשוון האנלוגי בלוח ארדואינו, עם המגן-מקרא שלי
בדיקה של המשוון האנלוגי בלוח ארדואינו, עם המגן-מקרא שלי

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

מה זה Analog Comparator

ה-AC, שאפשר להשיג אגב גם כרכיב בפני עצמו, הוא מעגל חשמלי עם שתי כניסות קלט (מסומנות כפלוס ומינוס, או כחיובית ושלילית) ויציאה אחת. הכניסות מקבלות מתחים אנלוגיים אבל היציאה היא "דיגיטלית": אם המתח בכניסה החיובית יותר גבוה מהמתח בכניסה השלילית אז המתח שביציאה יהיה HIGH, כמו מתח ההפעלה של המעגל עצמו. אם לא, אז המתח ביציאה יהיה LOW, האדמה.

AC במיקרו-בקרים

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

דיאגרמת המשוון האנלוגי, מתוך ה-Datasheet של ATmega328P
דיאגרמת המשוון האנלוגי, מתוך ה-Datasheet של ATmega328P (לחצו להגדלה)

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

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

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

ה-AC בארדואינו: שימוש בסיסי

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

במשוון האנלוגי של ATmega328P, המתח לכניסה החיובית יכול להגיע משני מקורות בלבד: פין AIN0 (פין דיגיטלי מס' 6 בארדואינו), או מתח רפרנס פנימי. מה שבוחר ביניהם הוא ACBG – ביט 6 ברגיסטר ACSR. ברירת המחדל שלו ("0") היא הפין החיצוני, וכאן נשתמש בה.

המתח לכניסה השלילית מגיע מ-AIN1 (פין 7 בארדואינו), או – דרך איזשהו מולטיפלקסר פנימי – מאחד מהפינים ה"אנלוגיים" של ה-ADC. גם כאן, נסתמך על ברירת המחדל "0" של ביט ACME (ביט 6 ברגיסטר ADCSRB), שמנטרלת את המולטיפלקסר ומשאירה אותנו עם AIN1 בלבד.

כבר בשלב זה, בלי שום הגדרות נוספות ובעצם בלי לגעת בכלום, ה-AC עובד ואפשר לראות את הפלט שלו בביט ACO (האות O, לא הספרה אפס) שהוא ביט 5 ברגיסטר ACSR. הנה קוד שעובד ישר מהקופסה לארדואינו Uno – נסו ותראו שכאשר המתח על פין 6 גבוה יותר מאשר על פין 7, הלד המובנה נדלק ולהיפך:

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, ACSR & (1 << ACO));
}

אגב, הפינים 6 ו-7 הם עדיין במצב input רגיל ואפשר לקרוא את המתח בהם עם digitalRead. אם אנחנו לא זקוקים לפונקציונליות הכפולה, אפשר לנטרל את ה-Digital input buffer הפנימי שלהם ולחסוך טיפה חשמל. את זה עושים על ידי כתיבת "1" לביטים AIN0D ו-AIN1D (ביטים 0 ו-1 ברגיסטר DIDR1).

שימוש בפסיקת ה-AC

ה-AC יכול להפעיל למעשה שתי פסיקות: אחת ישירה (דרך הווקטור ANALOG_COMP_vect) ואחת בעקיפין, אם מחברים את פלט ה-AC לטיימר/מונה ומפעילים את פסיקת העדכון של המונה (TIMER1_CAPT_vect). כאן, בשביל ההדגמה, נשתמש בפסיקה הישירה בלבד. הביטים ACIS1 ו-ACIS0 (ביטים 1 ו-0 ברגיסטר ACSR) קובעים מה יעורר את הפסיקה: ב-"00" היא תפעל כשהפלט משתנה לכל כיוון שהוא, ב-"10" כשהפלט יורד מ-HIGH ל-LOW, וב-"11" כשהוא עולה מ-LOW ל-HIGH. אנחנו נשתמש בברירת המחדל "00".

כדי לאפשר את הפסיקה עצמה צריך לכתוב "1" לביט ACIE (ביט 3 ב-ACSR), וכמובן לכתוב את פונקציית הפסיקה. קוד העזר הסמוי של ארדואינו כבר נותן לפסיקות לעבוד באופן כללי, אז הקוד שלנו מסתכם ב:

void setup() {
  pinMode(13, OUTPUT);
  ACSR |= (1 << ACIE); // Enable AC interrupt
}

void loop() {
}

ISR(ANALOG_COMP_vect) {
  PINB |= 32; // Toggle LED
}

זה עובד, רק שימו לב שאם אתם בודקים את הקוד עם פוטנציומטר, כפי שעשיתי בתמונה בהתחלה, בהחלט יכולה להיות תופעה של Bounce, כמו בלחצנים.

אז למה הסודיות?

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

אז למה היצרנים ממשיכים לשים Analog Comparator במיקרו-בקרים שלהם? בהנחה שלא פספסתי איזשהו שימוש חשוב ונפוץ (כיתבו לי בתגובות אם כן), אז ייתכן שזה עניין של תאימות לאחור וגם הרגל. התכנון בסיליקון כבר קיים, לכל המתחרים יש כזה, אז למה לא?

להרשמה
הודע לי על
8 תגובות
מהכי חדשה
מהכי ישנה לפי הצבעות
Inline Feedbacks
הראה את כל התגובות

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

פוסט שלם על opamp בלי להגיד פעם אחת opamp…

אבל זה בדיוק הקטע של opamp… לכל שימוש מעשי gain של 100,000 ומעלה הוא אינסופי.

אמנם opamp אידיאלי יכול לשמש כמגבר שרת כאשר הוא מחובר ללא חוג משוב, אבל ההפך אינו בהכרח נכון. יתרה מכך, מגבר שרת הוא רק מימוש אפשרי אחד למשוון, אבל עקרונית משוון ממיר מאות אנלוגי (מתח כלשהו) לאות דיגיטלי (או קטן מהערך הסף או גדול ממנו), כשהאות הדיגיטלי יכול להיות מכל מיני סוגים וללא תלות ישירה במתחי האספקה כמו שיש במשוון ממגבר שרת. קח למשל את LM393 הנפוץ – הוא בכלל בעל יציאת open collector. זו התנהגות שונה ממה שהיית מקבל ממגבר שרת. יתרה מכך, ברכיבים אמיתיים ולא אידיאליים מגבר שרת יכול להכניס כל מיני סיבוכים ולשמש כמשוון די גרוע בהשוואה… לקרוא עוד »

לדעתי המשוון כבר קיים שם בשביל לבצע פעולות ADC אז למה לא לפתוח אותו החוצה ולהגיד תראו גם לי יש
שאלה מעניינת האם יש משוון אחד (מגבר שרת) או יותר
אם יש אחד אז הוא יפסיק את הפעולה שלו כול פעם שנכנס אות אנלוגי

רק תאוריה
וכמו שאמרת
זה כבר מתוכנן וקל להכניס לסיליקון אז למה לא