מה נלמד כאן
- איך שולטים במהירות של מנוע ולא רק בהדלקה וכיבוי
- מה זה משתנה בבלוקים ולמה הוא נראה כמו קפסולה כתומה
- איך מזהים לחיצה אחת נקייה על כפתור, בלי שהיא תיספר עשר פעמים
- מה עושים הבלוקים wait until ו-write analog pin
- למה התוכנית שומרת גם את המהירות הקודמת במשתנה lastSpeed
ההילוכים שבכיס
בטח החזקתם פעם מאוורר קטן ביד ביום חם. לוחצים על הכפתור פעם אחת — נשיבה עדינה. לוחצים שוב — סערה. לוחצים שוב — כיבוי. הכפתור הזה לא רק מדליק ומכבה; הוא מחליף הילוך.
למה בכלל צריך הילוכים? כי לא תמיד רוצים את המקסימום. מהירות נמוכה שקטה יותר, ומחזיקה את הסוללה הרבה יותר זמן. בדיוק כמו אופניים — לא רוכבים כל הדרך בהילוך הכי כבד.

בשיעור הזה נבנה בדיוק את זה, רק עם שלושה כפתורים נפרדים במקום אחד: אדום = עצור, כחול = איטי, ירוק = מהיר. כל אחד מהם קופץ ישר להילוך שלו.
הרכיבים
את שני הרכיבים המרכזיים אתם כבר מכירים, אז לא נתחיל מאפס.
המנוע והמנהל שלו
המנוע ומודול ההנעה L9119S נלמדו בשיעור 10. תזכורת בשורה אחת: הלוח חלש מדי כדי להזיז מנוע בעצמו, ולכן הוא שולח פקודות למודול ההנעה, והמודול הוא זה שמזרים למנוע את הכוח מהמתח הראשי.
למודול יש שני פיני שליטה למנוע אחד: A-1A ו-A-1B. הם עובדים כזוג:
- A-1A גבוה ו-A-1B אפס ← המנוע מסתובב לכיוון אחד
- A-1A אפס ו-A-1B גבוה ← המנוע מסתובב לכיוון ההפוך
- שניהם אפס ← המנוע עוצר
בפרויקט הזה אנחנו רוצים כיוון אחד בלבד, אז A-1B יישאר תמיד על 0 ואת כל השליטה נעשה דרך A-1A.
שלושת הכפתורים
כפתורים למדנו בשיעור 4. הדבר היחיד שחשוב להיזכר בו כאן הוא כיוון הקריאה, כי הוא מבלבל בפעם הראשונה.
לכל כפתור יש נגד 10KΩ שמחבר אותו ל-5V. כל עוד לא לוחצים, הנגד מושך את הפין למעלה והלוח קורא 1. ברגע שלוחצים, הכפתור פותח דרך ישירה ל-GND, וה-GND מנצח — הפין צונח ל-0.
אז בתוכנית שלנו: לחוץ = 0. לא לחוץ = 1. קצת הפוך מהאינטואיציה, אבל ככה זה בנוי.
החיבור

הסכמה מתחלקת לשני חלקים.
למעלה — המנוע. המנוע מתחבר לשני הברגים OA1 ו-OA2 של המודול. מהמודול יוצאים ארבעה חוטים אל הלוח:
| חיבור במודול | לאן |
|---|---|
| A-1A | פין 5 |
| A-1B | פין 16 |
| VCC | 5V |
| GND | GND |
למטה — הכפתורים. שלושה מעגלים זהים, אחד מתחת לשני. בכל אחד: 5V ← נגד 10KΩ ← נקודת הקריאה ← כפתור ← GND. הפין של הלוח מתחבר בדיוק בנקודת הקריאה, באמצע בין הנגד לכפתור.
| כפתור | פין | תפקיד |
|---|---|---|
| אדום | 17 | עצירה |
| כחול | 18 | מהירות נמוכה |
| ירוק | 19 | מהירות מלאה |

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

שני משתנים
בראש התוכנית, עוד לפני הלולאה, יושבים שני בלוקים כתומים:
set [fanSpeed] to [0] set [lastSpeed] to [0]
משתנה הוא קופסה עם שם שאפשר לשים בה מספר ולהחליף אותו מתי שרוצים. בארגז הבלוקים יוצרים אותו בקטגוריה Variables בלחיצה על ״Make a Variable״, ואז השם שנתתם מופיע כקפסולה כתומה קטנה שאפשר לגרור לתוך חורים של בלוקים אחרים.
- fanSpeed — המהירות שאנחנו רוצים עכשיו.
- lastSpeed — המהירות שכבר שלחנו למנוע.
למה שניים? נגיע לזה עוד רגע, וזה החלק החכם בתוכנית.
שני הבלוקים האלה רצים פעם אחת בלבד, כשהלוח נדלק. הם קובעים שהמאוורר מתחיל כבוי.
הלולאה
כל השאר יושב בתוך forever, הבלוק הכתום שעוטף את מה שבתוכו. בפנים ראשונה יושבת שורת serial print [115200] (fanSpeed) — היא שולחת את המהירות הנוכחית לקונסול במחשב. זה לא משנה כלום בהתנהגות, אבל זה מאפשר לכם לראות בעיניים מה קורה בתוך התוכנית.
שלוש חתיכות זהות
עכשיו שלוש חתיכות באותו מבנה בדיוק. הנה הראשונה, של כפתור העצירה:
if < read digital pin [17] = [0] > then wait [200] milliseconds wait until < read digital pin [17] = [1] > set [fanSpeed] to [0]
נקרא אותה שורה-שורה.
if < read digital pin [17] = [0] > — ״אם פין 17 קורא 0״, כלומר: אם לוחצים על הכפתור האדום. שימו לב שהתנאי יושב בחור המשושה של ה-if, ובתוכו בלוק ההשוואה = עם קריאת הפין משמאל והמספר 0 מימין.
wait [200] milliseconds — המתנה של חמישית שנייה. זה נראה מיותר, אבל הוא פותר בעיה אמיתית: כפתור מכני קופץ. ברגע הלחיצה המגעים נוגעים ונפרדים כמה פעמים ביעף, והלוח — שקורא אלפי פעמים בשנייה — רואה מזה ערבוביה של 0 ו-1. ההמתנה הקצרה נותנת לקפיצות להירגע. קוראים לזה דיבאונס.
wait until < read digital pin [17] = [1] > — ״חכה עד שפין 17 יחזור ל-1״, כלומר עד שהאצבע עוזבת. הבלוק הזה עוצר את התוכנית במקום עד שהתנאי מתקיים. בלעדיו, לחיצה ארוכה של שנייה הייתה נספרת כמאות לחיצות.
set [fanSpeed] to [0] — רק עכשיו, אחרי שהלחיצה הסתיימה, נרשמת המהירות החדשה.
שתי החתיכות הבאות זהות לגמרי, רק עם פין אחר וערך אחר:
| כפתור | פין | fanSpeed נהיה |
|---|---|---|
| אדום | 17 | 0 |
| כחול | 18 | 179 |
| ירוק | 19 | 255 |
למה 179 ולמה 255
הבלוק write analog pin מקבל מספר בין 0 ל-255. זה לא מתח ולא סיבובים לדקה — זה אחוז הזמן שהפין דלוק.
תדמיינו שהלוח מדליק ומכבה את הפין מהר מאוד, מאות פעמים בשנייה. אם הוא דלוק כל הזמן, זה 255. אם הוא דלוק בדיוק חצי מהזמן, זה בערך 128. המנוע כבד מכדי להספיק לעצור בין ההבהובים, ולכן הוא פשוט מרגיש את הממוצע ומסתובב בחצי כוח. השיטה הזאת נקראת PWM.
אז 255 זה ״דלוק כל הזמן״ — מהירות מלאה. ו-179 זה בערך 70% — מהירות נמוכה נעימה. למה לא 50? כי מנוע קטן פשוט לא מתחיל להסתובב מתחת לערך מסוים; אין לו מספיק כוח להתגבר על החיכוך שלו עצמו. 179 הוא ערך שנבדק ועובד.
ההשוואה החכמה בסוף
if < fanSpeed != lastSpeed > then write analog pin [5] to (fanSpeed) write analog pin [16] to [0] set [lastSpeed] to (fanSpeed)
הסימן != אומר ״לא שווה״. אז התנאי קורא: ״אם המהירות שאנחנו רוצים שונה מזו שכבר שלחנו למנוע — אז...״
זה החלק שמפריד בין תוכנית מגושמת לתוכנית נקייה. הלולאה רצה עשר פעמים בשנייה. בלי התנאי הזה, הלוח היה שולח למנוע את אותה פקודה בדיוק עשר פעמים בשנייה, לנצח, גם כשאף אחד לא נגע בכלום. עם התנאי, הפקודה נשלחת רק ברגע שמשהו באמת השתנה.
שלושת הבלוקים בפנים: הראשון שולח את המהירות לפין 5 (A-1A), השני מוודא שפין 16 (A-1B) על אפס כדי שהמנוע יסתובב לכיוון אחד, והשלישי מעדכן את lastSpeed — כלומר רושם ״שלחנו, זכרנו״. בלי השורה השלישית התנאי היה מתקיים לנצח וכל הרעיון היה מתפרק.
wait [100] milliseconds בסוף הלולאה נותן ללוח נשימה קטנה בין סבב לסבב.
מריצים
⬇ להורדת הקובץ Adjustable_Speed_Fan.sb3 — גוררים אותו לתוך ACECode ולוחצים Upload.
ההסבר המלא על צריבה נמצא בשיעור ההתקנה.
אחרי הצריבה: לחצו על הכחול — המאוורר מתחיל לנשוב בעדינות. לחצו על הירוק — הוא קופץ למהירות מלאה. לחצו על האדום — הוא נעצר.

תשימו לב לדבר אחד יפה: אם תעברו מהירוק לכחול, המאוורר לא נעצר באמצע — הוא פשוט מאט. הוא לא עובר דרך אפס, כי אף אחד לא אמר לו לעבור דרך אפס.
מה קרה כאן
שלושת הכפתורים לא שולטים במנוע ישירות. הם רק כותבים מספר לתוך משתנה. המשתנה הוא הזיכרון של התוכנית.
ואז, במקום אחד ויחיד בסוף הלולאה, התוכנית מסתכלת על המספר הזה ומשווה אותו למה שכבר שלחה. רק אם יש הבדל — היא פועלת.
זו תבנית שחוזרת בכל מכשיר חכם שתפגשו: קלט שומר מצב, ומצב מניע פעולה. הפרדה בין ״מה המשתמש רוצה״ ל״מה המכשיר עושה״ היא מה שמאפשר להוסיף כפתור רביעי מחר בלי לשבור כלום.
תרגילים
הילוך ביניים. שנו את הערך של הכפתור הכחול מ-179 ל-120. האם המנוע עדיין מתחיל להסתובב? נסו 100, 90, 80 — ומצאו את המספר הכי נמוך שבו הוא עוד זז.
הילוך רביעי. הוסיפו כפתור רביעי על פין 21 והעתיקו חתיכת if נוספת, עם set [fanSpeed] to [200]. שימו לב שאתם צריכים להעתיק גם את wait until.
כיוון הפוך. בתוך ה-if האחרון, החליפו בין השניים: write analog pin [5] to [0] ו-write analog pin [16] to (fanSpeed). לאיזה כיוון מסתובב עכשיו המדחף?
תראו את הזיכרון. גררו קפסולה כתומה שנייה לתוך שורת הקונסול כדי להדפיס גם את lastSpeed לצד fanSpeed. לחצו כפתור וצפו בהם: איזה מהם משתנה ראשון, וכמה זמן עובר עד שהשני מדביק אותו?


