אחרי שהגדרנו מה בדיוק המערכת אמורה לעשות, נצלול אל הצד הטכני של הפלטפורמה והתוכנה, נראה למה אי אפשר לסמוך על המדריכים באינטרנט, ונגלה איך באמת כותבים קוד מתאים שירוץ ללא מגע יד אדם.
שלב 4: ההכנות
הפלטפורמה, כפי שציינתי בפוסט הקודם, היא Raspberry Pi Zero 1.3 הקטן והזול (שבמקרה גם היה לי בהישג יד). מערכת ההפעלה שבחרתי להתקין עליו היא Raspbian Stretch Lite: הפצת לינוקס סטנדרטית לרספברי פיי, אך ללא שולחן העבודה הגרפי ("Desktop"). אפשר היה להתקין גם את ה-Raspbian המלאה, אבל ממילא אין לי צורך בגרפיקה, וגרסת ה-Lite קטנה יותר ונטענת מהר יותר.
את הקובץ הרלוונטי להתקנה מורידים מהדף הזה וצורבים בעזרת המחשב האישי והתוכנה Etcher על כרטיס Micro SD, לפי המדריך הזה. בסיום התהליך, שהוא באמת פשוט מאוד, מעבירים את הכרטיס לפיי, מחברים אליו מקלדת ומסך ומחברים לחשמל. הפיי מבקש שם משתמש וסיסמה, אז נשתמש בברירת המחדל pi ו-raspberry, בהתאמה. כעת, לפני שניגש לפרויקט, נכתוב את הפקודה
sudo raspi-config
זה יפתח לנו מסך צבעוני עם תפריט, ובו נרצה לעשות שלושה דברים חשובים:
- לשנות את סיסמת ברירת המחדל, ליתר ביטחון. נכון, הפיי לא מחובר לשום רשת, אבל בעתיד הכול יכול לקרות ובאופן כללי כדאי להתרגל לעשות דברים כאלה.
- בתפריט Boot Options, באופציה Desktop/CLI, לבחור ב-Console Autologin כדי שבהפעלות הבאות לא נצטרך להזין שם משתמש וסיסמה. זה יהיה חשוב במיוחד כשהמערכת תפעל בשטח בלי מסך!
- בתפריט Localization Options, באופציה Change keyboard layout, לבחור במקלדת אמריקנית (US) ולא בבריטית (UK) שמוגדרת כברירת מחדל. את כל שאר הפרמטרים שיופיעו אפשר וכדאי להשאיר כמות שהם. עכשיו, כשנקיש למשל Shift+3, נקבל את התו הצפוי "#" ולא את סימן הליש"ט "£"…
לא לשכוח לאתחל את הפיי אחרי כל השינויים האלה. כדי לאתחל אותו משורת הפקודה אפשר לכתוב:
sudo shutdown -r now
שלב 5: הקוד
בגדול, התוכנה צריכה לרוץ בלולאה אינסופית: לקרוא מחרוזת מהמקלדת, לבדוק אם היא זהה לסיסמה הסודית (ואם כן, להפעיל את הממסר לעשר שניות), וחוזר חלילה. לא מסובך בטירוף, ומערכת ההפעלה נותנת לנו כמה אופציות מוכנות מראש לשפת תכנות. מתוך אלה בחרתי ב-Python בגלל הנושא של הפעלת הממסר: מהחיפושים שעשיתי ברשת, נראה היה שהגישה לפיני הקלט/פלט של הפיי (GPIO) הכי קלה ונוחה בפייתון, בעזרת הספריה gpiozero. מה שלא ידעתי זה שהספרייה הזו לא מותקנת כברירת מחדל בגרסת Lite של מערכת ההפעלה, וזה הכריח אותי להתחבר לרשת. למזלי היה לי מתאם WiFi עם חיבור USB. בעקבות המדריך הזה, פתחתי קובץ הגדרות מסוים לעריכה:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
והוספתי לו את הקוד הבא, כמובן עם שם הרשת והסיסמה הנכונים:
network={ ssid="YOUR_NETWORK_SSID" psk="WIFI_PASSWORD" }
בעורך הטקסט nano לוחצים Ctrl+O ואחרי זה Enter כדי לשמור את השינויים, ו-Ctrl+X כדי לצאת. אחרי אתחול של הפיי, מתאם ה-WiFi החיצוני נכנס לפעולה ויכולתי להתקין את הספריה בעזרת הפקודה הבאה, שמצאתי באתר שמוקדש לה:
apt install python3-gpiozero
מטעמי ביטחון שדה, אחרי שווידאתי שהספריה עובדת (בעזרת קוד לניסוי), מחקתי את פרטי ההתחברות ל-WiFi. מי יודע לאן המידע הזה יתגלגל בעתיד? למטרות בדיקת הקוד בחרתי לחבר לפיי שני לדים. אחד אדום שיסמן שהתוכנה פועלת (שוב, זו תהיה אינדיקציה חשובה למפעיל כשהמערכת תהיה בשטח ללא מסך), ואחד צהוב שידמה בינתיים את הממסר. מצאתי מיפוי ברור של הפינים של הפיי וחיברתי את האנודה ("פלוס") של הלד האדום לפין GPIO 17, את האנודה של הלד הצהוב לפין GPIO 27 הצמוד אליו, ואת הקתודות של שניהם דרך נגד 510 אוהם (למה לא?) ל-GND.
כיוון שהגדרתי מראש שהנושא של החלפת עברית/אנגלית לא מעניין אותי, ומערכת ההפעלה מכירה בינתיים רק אנגלית, הקלדתי את אותיות הסיסמה הסודית "עוץ לי גוץ לי" וקיבלתי את מחרוזת המטרה "gu. kh du. kh". כדי לאפשר יציאה נוחה מהתוכנית גם לי וגם למפעיל בשטח הגדרתי סיסמה נוספת לסיום ההרצה, והנה לפניכם צילום מסך (מילולית!) של התוכנה במלוא תפארתה:
כדי להריץ את התוכנה הזו, ששמרתי בשם sisma.py, צריך לכתוב את הפקודה הזו:
python3 sisma.py
שימו לב שהשימוש בספריה gpiozero גורם לעיכוב בלתי-נמנע של מספר שניות מרגע הקריאה לתוכנית ועד שהלד האדום נדלק.
שלב 6: המלכודת
כזכור, המטרה היא שהתוכנה תפעל אוטומטית ברגע שהמערכת תחובר לחשמל. לשם כך, לפחות על פי רוב המדריכים שתמצאו בגוגל, עלינו להכניס את פקודת ההפעלה לקובץ מסוים בתיקיה etc שנקרא rc.local . ניכנס אליו לעריכה עם הפקודה
sudo nano /etc/rc.local
ולפני הפקודה "exit 0" שמופיעה שם בסוף, נוסיף את הפקודה שמריצה את התוכנית שלנו, בתוספת רווח והתו &. התוספת הזו אומרת למערכת להריץ את התוכנה במקביל לתהליכים אחרים, במקום לתקוע אותם עד שהתוכנה תגמור לעבוד:
python3 /home/pi/sisma.py &
שימו לב שהפקודה הזו כוללת את הנתיב למיקום של התוכנה, כי כשהקובץ rc.local מורץ, המערכת לא נמצאת בהכרח בתיקיה ה"נכונה". וכמובן, אם שמרתם את הקוד שלכם בתיקיה אחרת, רשמו את המיקום הנכון בפקודה. נאתחל את הפיי שוב, ואם עשינו הכל נכון… ניתקל בשגיאה! אחרי כחצי דקה של טעינת מערכת ההפעלה, מופיעה הודעה מסתורית שאומרת EOFError: EOF when reading a line. מה קרה פה?
ובכן, מסתבר שאמנם אפשר להריץ תוכנות מ-rc.local, אבל זה מתבצע בסביבה וירטואלית נפרדת מזו של הממשק "הרגיל", ולכן הן לא מסוגלות להתחבר ל-stdin, כלומר לקלט הסטנדרטי שמגיע מהמקלדת. חיפושים נוספים שביצעתי ברשת הובילו למבוי סתום, אז פניתי לאנשים הטובים בפייסבוק, וקיבלתי טיפ (תודה עידו!) שמה שדרוש הוא הפעלה של התוכנה אחרי שמתבצע ה-login האוטומטי. חיפשתי שוב עם המידע החדש וגיליתי שאת זה לא עושים ב-rc.local אלא בקובץ נסתר אחר, בתיקיית הבית home/pi, שנקרא .bashrc . נמחק את הפקודה הבעייתית מ-rc.local ונוסיף אותה – הפעם בלי הנתיב ובלי ה-"&" – לסוף של .bashrc .
ועכשיו זה עובד. אחרי שמערכת ההפעלה עולה, התוכנה מתחילה לרוץ מעצמה, מוציאה פלט נכון ללדים ולמסך וקולטת את הסיסמאות מהמקלדת. מעולה!
שלב 6.5: מה אם…?
בזמן שחיפשתי, בתסכול הולך וגובר, פתרון לבעיית ההרצה מ-rc.local, ניסיתי לחשוב גם מה הייתי עושה אם היה מדובר בפרויקט של לקוח והייתי מגלה שאין שום פתרון בלינוקס לבעיה הזו. מה עושים בכזה מצב? אומרים ללקוח "אופס, סליחה, מסתבר שאני לא מבין כלום בלינוקס ושאי אפשר לסמוך על המדריכים באינטרנט?"
ובכן, עם קצת חשיבה עקומה, ייתכן שאפשר לעקוף את הבעיה באמצעות מיקרו-בקר חיצוני שמדמה מקלדת, כמו בלוח ה-Digispark. הרעיון הוא להריץ ב-rc.local תוכנה קטנה שרק "תרים" פין פלט כלשהו ב-Raspberry Pi (את זה אני כבר יודע שאפשר לבצע בלי תקלות). המיקרו-בקר החיצוני יזהה את הסיגנל, ימתין כמה שניות ואז "יקליד" את פקודת ההרצה לשורת הפקודה, ממש כמו משתמש אנושי. עם קצת מזל הפיי לא יידע להבדיל בין המקלדת הרגילה לבין המקלדת המדומה ויריץ את התוכנה.
בפוסט הבא בסדרה נסגור את הקצוות הפתוחים, נשלים את החומרה ונגן על המערכת שלנו מפני ונדליסטים שלוחצים על מקשים לא רצויים.
תודה על כל הפוסטים המעניינים.
לדעתי אתה צריך קצת יותר לסמוך על לינוקס שתעשה לך את מה שאתה רוצה.
פרויקט מהסוג הזה תפור לדעתי על לינוקס.
הפרויקט הזה רץ על לינוקס…