הפרויקט השני שאני מתכבד לארח כאן בבלוג הוא לוח התוצאות האלקטרוני של עומר פוקס, אדם שחושב בגדול. כמה גדול? פשוט תסתכלו על התמונה הבאה: כל השחור הזה הוא לא משטח העבודה, אלא הצד האחורי של הפרויקט!
הפרויקט, כפי שבוודאי כבר ניחשתם, הוא לוח תוצאות גדול למשחקי ספורט. הוא כולל שתי ספרות מסוג 7-Segment לתוצאה של הקבוצה המארחת (HOME), שתי ספרות לתוצאה של הקבוצה האורחת (AWAY) ועוד כמה תוספות שנראה מיד. בהתאם לגודל הפלטפורמה, עומר לא הסתפק ברכיבי 7-Segment מהמדף (אפשר בכלל להשיג בגדלים כאלה?) אלא יצר את הסגמנטים של הספרות בעצמו מנוריות LED: שלוש נוריות LED אדומות 5 מ"מ בעלות בהירות גבוהה לכל סגמנט, כלומר 21 נוריות לספרה ו-84 ללוח כולו!
איך שולטים בשמונים וארבע נוריות LED? ראשית, כל נוריות ה-LED של ספרה מסוימת חולקות את אותו חיבור Ground: זה מה שמאפשר שליטה בכל ספרה בנפרד, באמצעות חיבורה או ניתוקה מה-Ground. שנית, כל שלשה שמגדירה Segment מסוים מחוברת לאותו מקור מתח (כל שלוש נוריות ה-LED במקביל). שלישית, מקור המתח של כל סגמנט משותף לסגמנטים המקבילים בשאר הספרות. במילים אחרות, צריך רק אחד-עשר חיבורים: שבעה לשליטה בסגמנטים וארבעה לבחירת ספרה. אם מבודדים ומציגים את הספרות בזו אחר זו ובקצב מהיר מספיק, לא תהיה "התנגשות" בין הסגמנטים המקבילים, וזה עדיין ייראה כאילו כל הספרות השונות מוארות יחדיו.
לוח ארדואינו רגיל יכול לשלוט בלי בעיה באחד-עשר חיבורים כאלה, אבל הוא לא יעמוד בדרישות הזרם: כדי להאיר היטב, נורית LED יחידה כזו זקוקה למשהו כמו 25 מיליאמפר, כלומר 75 לסגמנט, אך פין פלט של ארדואינו יכול לספק רק 40 מיליאמפר. הפתרון: MAX7219. ג'וק זה מיועד ספציפית לשליטה בעד שמונה ספרות 7-Segment (טוב, למעשה 8-Segment, כולל הנקודה העשרונית שלא נעשה בה שימוש בפרויקט זה). ה-MAX7219 מטפל בעצמו בכל מה שדרוש מבחינת תזמון, רענון התצוגה וכדומה. הארדואינו צריך רק לומר לו, דרך ממשק SPI בסיסי, איזה סגמנט באיזו ספרה צריך להיות מואר. כדי לפשט את העניינים עוד יותר, עומר לא טרח להתעסק עם הפקודות הישירות לרכיב אלא נעזר בתיווך של הספריה LEDControl. בזכות ה-MAX7219 והספריה, ההפעלה של הספרות אינה דורשת דבר מלבד חיווט נכון – לא שזה טריוויאלי, בהתחשב במספר נוריות ה-LED!
אבל לוח תוצאות דורש יותר מסתם הפעלה סטטית של ספרות, וכאן נכנס לתמונה הקוד. בצד האחורי של הלוח, ליד הארדואינו Duemilanove וה-MAX7219, מולחמים גם שלושה לחצנים. הקוד בודק בכל פעם אם אחד מהם לחוץ, ואם כן – ממתין בלולאה עד שהלחיצה מסתיימת או שחולפות שלוש שניות, המוקדם מביניהם. עיכוב של 10 אלפיות השניה בין קריאה לקריאה מבטיח שלא תהיה השפעה של Bouncing. לחצן אחד מעלה או מוריד (בהתאם למשך הלחיצה) את הניקוד של קבוצת HOME, הלחצן השני עושה אותו הדבר לקבוצת AWAY, והשלישי מאפס את הניקוד ואת הזמן (בלחיצה ארוכה) או מחליף בין תצוגת הניקוד לבין תצוגת הזמן שעבר מתחילת ה"משחק". הטיפול בנושא הזמן, הפרדה לשעות, דקות וכו', בוצע בעזרת הספריה Time.
ההלחמות של הלחצנים וה-MAX7219
הספריה LEDControl מטפלת בספרות בודדות, אך הניקוד במשחק, ששמור במשתנה מסוג int, עשוי להיות דו-ספרתי. איך מתרגמים מספר לשתי ספרות נפרדות? למשל, אם הניקוד של אחת הקבוצות הוא 43, איך נדע לשלוח לספרה הימנית 3 ולשמאלית 4? הטריק שעומר בחר הוא, כמו שאומרים, הישן ביותר בספר – ועם זאת בהחלט יעיל ושווה אזכור לטובת המתכנתים המתחילים שבקהל.
פעולת החילוק ("/") בשפת C אינה בדיוק החילוק שאנחנו מכירים מבית הספר: היא רגישה לטיפוס המשתנה שאיתו עובדים. אם נחלק, למשל, 21 ב-2, וכל המשתנים המעורבים יהיו מטיפוס int, התשובה שנקבל לא תהיה 10.5 (כי משתני int אינם כוללים נקודה עשרונית) אלא פשוט 10, בלי שארית ובלי הודעת שגיאה. זאת אומרת שאם ניקח משתנה מטיפוס int עם ערך דו-ספרתי ונחלק אותו ב-10, נקבל את ספרת העשרות שלו בלבד! כדי לבודד את ספרת האחדות, לעומת זאת, נשתמש בפעולה המשלימה לחילוק: שארית ("%"). אופרטור זה מחזיר לנו את השארית מחלוקה של מספר שלם אחד באחר. אם נכתוב 21 % 2 התשובה תהיה 1, ואם 43 % 10 התשובה תהיה 3.
אם תסתכלו בקוד של עומר (ראו בהמשך), תראו שהוא לא לקח בחשבון את האפשרות של ניקוד גבוה מ-99. מה יקרה אם מישהו יהיה אובססיבי מספיק כדי ללחוץ על הלחצן מאה פעמים? הקוד שולח את הניקוד-חלקי-עשר כמו שהוא אל הספרה המתאימה בלוח דרך הספריה LEDControl, ומסתבר שכאשר ספריה זו מקבלת מספר גדול מ-9 היא עוברת לבסיס הקסדצימלי (בסיס 16), שנהוג לייצג את הספרות ה"עודפות" בו באמצעות התווים A-F. הלוח יראה לנו את הניקוד "A0"!
באמצע הלוח, בין זוגות הספרות, יש נקודתיים בדמות שתי נוריות LED ירוקות שמאירות תמיד, ומעל כל ניקוד שלט עם שם הקבוצה, מואר מבפנים בנוריות LED חזקות במיוחד של 12 וולט. החשמל לכל הרכיבים מגיע מסוללת 12V גדולה, ולוח התוצאות נתמך מאחור ב"משולש אזהרה" של רכב – רעיון מקורי בהחלט.
אורכו של קוד ה-C של לוח התוצאות הוא 524 שורות ברוטו. חלק מזה מוקדש לרווחים ולקטעים ישנים שסומנו כהערות ואינם משתתפים בתוצר הסופי. עדיין, חלק הארי של התוכנה – יותר מחצי, בהערכה גסה – אינו קשור לפונקציונליות שדיברנו עליה עד כה, אלא ל"ביצת ההפתעה" של הפרויקט: הפונקציה המפלצתית crazyseven שמופעלת כאשר לוחצים לחיצה ממושכת על שלושת הלחצנים בבת אחת. זהו למעשה תסריט ארוך של אפקטים שונים ומשונים על הסגמנטים של הספרות, אותם תוכלו לראות בסרטון הזה.
לסיום, הנה לכם הקוד המלא של לוח התוצאות, עם אזהרה בצדו: זהו קוד "מלוכלך" שנכתב כך שיעשה את המוטל עליו – ושום דבר מעבר לזה. כל מי שינסה ללמוד ממנו לתכנת את הארדואינו בצורה אופטימלית עושה זאת על אחריותו בלבד…
תודה לעומר על המידע והתמונות, ואנחנו מחכים לפרויקטים שלכם!
היי עידו ..
בעקרון אני יודע לקרוא טמפ' מחיישן – אמנם בנתיים זה עבד רק על תרמיסטור ולא על חיישן יותר מדוייק.. כרגע הבעיה שלי היא שאני לא יודע להפנות את הפלט לתצוגה :-/
אני מתכנן בסופו של דבר לקנות 2 ספרות גדולות ( 6 אינץ' גובה – כל אחת ) מהאתר של Sparkfun ולתכנת ארדואינו נאנו – לארוז את הכל יפה 🙂 ולתלות באולם.
אגב.. איך מתחברים לארדואינו נאנו ? לא ראיתי שיש לו כניסת USB או משהו בדומה ?
לנאנו יש חיבור מיני-USB קטן בקצה. לא לבלבל עם ה"ארדואינו מיני", ששם באמת אין חיבור USB!
יש מצב ,
אם כי הפרויקט שאני מתכנן לעשות הוא די פשוט.
אני רוצה לעשות מד חום – עם תצוגה דיגיטלית גדולה .
זה הכל.
אני צריך לדעת לקרוא נתונים מחיישן טמפ' ולתרגם אותם לתצוגה דיגיטלית של 2 או 3 ספרות. ואז לארוז את זה יפה ולתלות באולם.
נשמע אחלה פרויקט למתחילים.
קודם כל, יש לי פוסט ישן על קריאת טמפרטורה מחיישן – https://www.idogendel.com/whitebyte/archives/121
לתצוגה, אתה בהחלט יכול להיעזר במה שעומר עשה כאן בפוסט – רק קח בחשבון בעיה שהוא הבחין בה, שנוריות ה-LED הפשוטות לא מאירות חזק כמו בתצוגות "מסחריות" ולא ייראו כל כך טוב בחדר מואר היטב. תצטרך למצוא לזה פתרון.
מאוד יפה,
if (reset_state == 2 and home_state==2 and away_state==2)
הAND כאן זה כמו || ?
יפה ששמת לב! העניין הזה עבר מתחת לרדאר שלי – זה מה שקורה כשמתכנתים בעיקר בפסקל… מסתבר שה-C הלא-סטנדרטי של ארדואינו מסוגל להבין גם את האופרטורים and, or, xor ואפילו not!
אה, מגניב! מאוד מאוד שימושי,
התבלבלתי עם הAND בדקתי עכשיו, AND זה כמו הסימן &&
אני חושב שלא צריך לכתוב כשערים לוגים כי יש סימנים במקומם כמו || && !
מעניין מה חשב מי שהוסיף את האופרטורים האלה לשפה. אולי הרציונל היה להפוך את התכנות לקצת יותר ידידותי ואינטואיטיבי, אבל מה שקורה בפועל זה בלבול מוח וחוסר תאימות עם סטנדרטים. אני ממליץ בחום לכל מי שקורא את זה להמשיך להשתמש באופרטורים התקניים של C!
יופי של פרוייקט.
תודה על השיתוף!
עידו !
אני חייב לומר לך שהדלקת אותי לגמרי עם הארדואינו הזה .
כל מה שעניין אותי בארדואינו זה לקרוא תוצאות מחיישנים ועכשיו אני מבין שאפשר לעשות הרבה יותר.
אז.. למרות שאני בתקופת בחינות.. קניתי את הקיט למתקדמים של הארדואינו..
וקיבלתי arduino Uno SMD R2 .. ותהיתי מה זה ה- SMD הזה ?
בכל אופן.. ברגע שיהיה לי מעט זמן אני אכנס לזה .
שימי.
🙂
ב-SMD הכוונה לתצורה של המיקרו-בקר שעל הלוח, ה"ג'וק" הראשי. ברוב דגמי ה-Uno הג'וק הוא בתצורת DIP, שנראית כמו מלבן ארוך עם רגליים ארוכות. אצלך (ובארדואינו לאונרדו החדשים) הוא בצורת מרובע קטן ושטוח עם רגליים קצרות – Surface Mount Device.
מבחינת תכנות ועבודה עם הארדואינו זה אותו דבר בדיוק. שיהיה בכיף, ואולי יום אחד יופיע כאן גם פרויקט שלך 😉
יפה מאוד!
ומה אחרי FF?
התכוונת אחרי F0… הלוח לא באמת סופר בהקסדצימלי, כי החישובים נעשים בחלוקה ושארית מ-10 ולא מ-16. אולי, אם תחפור עמוק בקוד של הספריה, תמצא את התשובה המדויקת לשאלה – אני אסתפק בינתיים ב"לא מוגדר" 🙂
כלומר, F9 🙂
ממש אין לי כוח לנבור בקוד…
אולי עומר יבדוק בשבילי?
צודק לגמרי! F9. גם אני כבר התבלבלתי מהבלגן הזה 🙂
אפשר לחוס על האצבעות של עומר – הסתכלתי שוב בדף של הספריה LEDControl וכתוב שם במפורש שהיא פשוט מתעלמת מערכים מעל 15 (F), ובמקרים כאלה לא תציג כלום. זאת אומרת, אחרי F9 אמור להופיע 0 (ולא 00).
פרויקט חמוד ביותר. לאיזה משחק זה מיועד?
אולטימייט פריזבי
תענוג!
עומר איזה מלךךךך!!