8- שעון חול דיגיטלי

בפרויקט הזה, נבנה שעון חול דיגיטלי למשך שעה אחת, כשהוא יתן לנו אינדיקציה (ע”י הדלקת נורת led) כל 10 דק’.

עד כה, כשרצינו שמשהו יקרה כל פרק זמן ספציפי השתמשנו בפונקציה ()delay על מנת לבצע עיכוב של כמה שניות לפני חזרה על ה loop. זה שימושי, אבל מגביל. מכיוון שכאשר ה Arduino קורא לפונ’ ()delay הוא מקפיא את מצבו הנוכחי לזמן שהכנסנו כפרמטר בפונק ()delay, וזה אומר שהוא לא יכול לקלוט ערכים, לבצע חישובים או ולהוציא פלט בזמן הזה. בנוסף, אם אנו רוצים שמשהו יקרה כל מס’ שניות קבוע, לדוג’ 10 שניות, לקרוא ל ()delay של 10 שניות יהיה מסובך, כי כיצד אנו יודעים כמה זמן לוקח לארדואינו לבצע את הפעולות האטומיות (התוכנית עצמה) שכתבנו? כיצד נכניס את זה בחישוב? לאורך זמן (שעה, יום, שבוע) התוכנית תצא מסנכרון.

על כן, ישנה פונ’ מובנת אחרת שעוזרת לנו לפתור את הבעיה הזאת, כבר השתמשנו בה בפרויקט 6. וזאת הפונ’ ()millis (ניתן לקרוא עליה בהרחבה כאן), שעוקבת אחרי הזמן שה Arduino פועל באלפיות השניה.

עד כה, הצהרנו על משתנים כ int (מספרים שלמים). אך לא הסברנו כיצד זה בא לידי ביטוי בזיכרון. int זהו משתנה לשמירת מספר שלם (Integer) ב16 סיביות (ביטים), בגלל הגבלת כמות הסיביות הוא יכול לשמור ערכים הנעים בין 32,767 ל 32,768-. אלה כמובן מספרים גדולים, אך אם ה Arduino יספור עם ()millis נצא מטווח הערכים כבר לאחר דקה (1,000*60). לכן נשתמש במשתנה מסוג חדש, הנקרא long ומחזיק מספרים באורך של 32 סיביות (ביטים). המשתנה החדש הזה יכול להחזיק מספרים בין 2,147,483,647 ל 2,147,483,648-. ומכיוון שאנו לא יכולים להריץ את הזמן לאחור כדי לקבל מספרים שליליים נשתמש ב unsigned long. כשמשתנה כלשהו נקרא unsigned הוא מקבל אך ורק ערכים חיוביים, לכן ה unsigned long יתחיל לספור מ0 (ולא מ2,147,483,648-) ונקבל ערכים עד 4,294,967,295 (ניתן לקרוא עליו בהרחבה כאן). תוכלו לחשב ולבדוק שהמספר הזה מספיק כדי לאחסן כמעט 50 ימים.

אז איך בעצם נוכל לחשב כמה זמן עבר? ע”י לקיחת דיגמה עם ()millis בתחילת הפעולה של התוכנית וע”י לקיחת דגימה נוספת והשוואתה לדגימה הראשונה, אם נחסיר את הדגימה הנוכחית מהדגימה הראשונה ונגלה שהמספר שווה או גדול מ10 שניות, נידע שעברו 10 שניות.

התכנון הוא להשתמש במתג מרקורי (מתג הטיה), כל פעם שנשנה את מצבו נתחיל מחזור (ספירה) חדש של הדלקת נורות ה LED. מתג ההטיה עובד בדיוק כמו מתג רגיל בכך שהוא חיישן on/off, בדרך כלל יש להם חלל קטן בתוכם וכדור מתכת, כאשר נטה אותו בדרך הנכונה הכדור יתגלגל לצד אחד של החלל ומחבר את שתי הפינות בלוח המטריצה שלנו, מה שסוגר את המתג (כך הוא מזהה את הכיוון בו הוא נמצא). בפרויקט שלנו נשתמש בו כקלט דיגיטלי.

 

חיבור הרכיבים

חברו ללוח המטריצה חוטים מגשרים מעמודות ה+ וה-, אל ה 5V וה GND (בהתאמה, כפי שעשינו עד כה). מקמו 6 נורות LED על גבי לוח המטריצה כשאל האנודה של כל אחת מהן (הרגל הארוכה) חברו חוט מגשר אל הפינים הדיגיטליים 2-7 (כולל), ומהרגל הקצרה חברו נגד 220Ω אל עמודת ה- (מינוס) של לוח המטריצה).

מקמו את מתג ההטיה על גבי לוח המטריצה כשהחץ שעל ראש המתג צריך להיות למעלה-במעלי לוח המטריצה. להלן סכמה ואיור להמחשה:

Arduino Project number 8

 

הקוד

נתחיל בהגדרת המשתנים הגלובלים: תחילה ניצור משתנה int, קבוע, בשם switchPin כדי לשמור את מס’ הפין של מתג ההטיה. לאחר מכן ניצור משתנה unsigned מסוג long בשם previousTime, על מנת לשמור את הזמן האחרון בו בוצע שינוי (בו נדלק led). ניצור עוד שתי משתנים מסוג int, הראשון בשם switchState שישמור את המצב הנוכחי של מתג ההטיה, והשני בשם prevSwitchState שישמור את המצב הקודם של מתג ההטיה. את שתיהם, כרגע, נאתחל ל 0. ניצור משתנה מסוג int בשם led שישמור איזה לד (ע”י המספר שלו) הוא הבא בתור שיש להדליקו (נכניס לתוכו 2 כי הלד הראשון שמחובר לפין הדיגיטלי הוא פין מס’ 2). ולבסוף, המשתנה האחרון יהיה מסוג long ונקרא לו interval. המשתנה ישמור את הזמן (באלפיות השניה) שאנו רוצים להמתין בין הדלקת כל נורה (אם נכפיל אותו ב6 נקבל את זמן שעון החול כולו).

בפוקנציית ה ()setup: דבר ראשון אנו נכריז על הפינים הדיגיטלים 2-7 אליהם מחוברים נורות הלד כפיני output, בעזרת הפונ’ ()pinMode. נבצע זאת בלולאה מ2 עד 8 (לא כולל) כדי שנוכל לגשת להיעזר במשתנה x (שסופר את הלולאה) כמספר הפין שיש לאתחל. ונכריז על פין מס’ 8 ששמור במשתנה בשם switchPin כ input כדי לקלוט את הערך ממתג ההטיה.

בפונקציית ה ()loop:

הדבר הראשון שנעשה כשה Arduino מתחיל את התוכנית (לאחר כל ההכרזות וההגדרות) הוא לקחת את הזמן הנוכחי ולהכניס אותו למשתנה חדש בשם currentTime (גם הוא יהיה unsigned long).

כעת, נבדוק בעזרת if האם עבר מספיק זמן: בתנאי ה if נחסיר מהזמן שלקחנו כעת (currentTime) את הזמן שלקחנו בהתחלה (previousTime) ונבדוק האם זה גדול מה interval (המשתנה השומר בתוכו את פרק הזמן הספציפי בו יש להדליק את הנורה באלפיות השניה). אם currentTime פחות הזמן ההתחלתי (previousTime ששוה ל0, כי הזמן שבו ה Arduino התחיל לפעול הוא 0 אלפיות השניה) גדול מ 600,000 אלפיות השניה, ז”א שעברו 10 דק’. לכן נכניס את הערך שב currentTime לתוך previousTime (על מנת להתחיל מחזור חדש של 600,000 אלפיות השניה), נדליק את ה led הבא בתור שיש להדליקו (מספרו נמצא במשתנה led) עם הפונ’ ()digitalWrite, ולבסוף נעלה את led באחד (במקום לכתוב led=led+1, ישנו קיצור מקובל ע”י כתיבת ++led), ולבסוף נכניס לתוך ה if הזה עוד if בו נדבוק האם הגענו ללד מס’ 7 (אני לא כתבתי כלום בתוכו, החלטתי שלא לבצע דבר, אך אתם יכולים לכתוב מה שעולה על רוחכם, כמו לולאה שתכבה את כל הלדים ולהתחיל את המשתנה led מחדש להיות 2) ולבסוף נסגור את ה if.

כעת אחרי בדיקת הזמן, נרצה לבדוק האם הפכו לנו את שעון החול, במקרה שלנו יותר נכון הטו. אם הטו אותו נתחיל את הספירה מחדש, במידה ולא נמשיך כרגיל. דבר ראשון נקרא את הערך ממתג ההטיה המחובר לפין מס’ 8 ששמור במשתנה switchPin, נבצע זאת עם הפונ’ ()digitalRead, ונשמור את הערך במשתנה switchState.

ונבצע בדיקה, בעזרת משפט if, כדי לבדוק האם מתג ההטיה במצב אחר ממה שהיה (המצב הקודם שמור במשתנה בשם prevSwitchState). במידה והם שונים נאתחל את שעון החול, ז”א נעבור עם לולאה על כל הפינים ונאתחל בעזרת הפונ’ digitalWrtie את הפינים להיות כבויים (LOW), לאחר מכן נאתחל את הפין ההתחלתי (השמור במשתנה בשם led) להיות 2, ולבסוף נאתחל את הזמן (ע”י הצבת הערך שב cureentTime במשתנה previousTime). ונסגור את ה if.

בסוף פונ’ ה loop, נבצע הצבה של הערך ממתג ההטיה (שמרנו אותו במשתנה switchState) בתוך prevSwitchState, על מנת שנוכל גם בלולאה הבאה להשוות את הערך ממתג ההטיה לערך החדש שיהיה שם (אם נשנה אותו) או לאותו אחד (אם לא נזיז את מתג ההטיה).

 

לסיכום

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

במידה ואתם רוצים לשנות את הזמן הקבוע בו נורה נדלקת יש לשנות את המשתנה interval (עכשיו הוא נמצא על 600,000 מילי שניות = 10 דק’, כדי לבצע בדיקה, כשבניתי את הפרויקט, החלפתי אותו ל 1,000 = 1 שניה).