מרחק, נוכחות ותנועה
מערכת בקרה צריכה לעתים קרובות תשובות לשאלות פשוטות: כמה רחוק מאיתנו הגוף? האם מישהו נכנס לחדר? בפרק זה נכיר שני חיישנים שעונים על השאלות האלה: החיישן העל-קולי וחיישן התנועה. לכל חיישן נסרטט את החיבור, נכתוב סקיצה שלמה שעברה הידור, ונחשב מה נקרא בצג הטורי. בסוף הפרק נעיף מבט קצר בחיישני מרחק ותנועה נוספים.
- נבין כיצד החיישן העל-קולי מודד מרחק מזמן ההד, ונחשב אותו לפי d = v·t2 ולפי הקיצור d ≈ t58.
- נחבר את המודול HC-SR04 לבקר ונמדוד את רוחב הפולס בפקודה pulseIn() עם זמן המתנה מרבי.
- נבנה מערכת עזר לחניה: זמזם שמצפצף מהר יותר ככל שהגוף מתקרב.
- נחבר את חיישן התנועה HC-SR501 ונדליק נורית למשך זמן קבוע אחרי התנועה האחרונה בעזרת millis().
- נשווה בין חיישני מרחק ותנועה: מה כל אחד מודד, מה תחום המדידה שלו, והאם המוצא שלו תקבילי או ספרתי.
חיישן מרחק על-קולי (Ultrasonic Distance Sensor)
הקול הולך אל הגוף וחוזר ממנו, כך שהדרך שהוא עובר היא 2·d ; לכן בחוק הבא נחלק ב-2. מהירות הקול באוויר היא כ-343 m/s בטמפרטורה 20 °C. היא משתנה מעט עם טמפרטורת האוויר, אבל בפרויקטים שלנו השינוי קטן, ולכן נתייחס אליה כקבועה.
| סימן | משמעות | יחידת מידה |
|---|---|---|
| d | המרחק בין החיישן לגוף | [m] |
| t | זמן ההלוך ושוב, שהוא רוחב הפולס בהדק ECHO | [s] |
| v | מהירות הקול באוויר, כ-343 m/s | [m/s] |
מאיפה מגיע המספר 58? החיישן נותן לנו את הזמן במיקרו-שניות, ואנחנו רוצים את המרחק בסנטימטרים. נכתוב את המהירות ביחידות האלה, 343 m/s = 0.0343 cm/µs , ונציב בחוק:
כלומר הקול צריך 58 µs בערך כדי לעבור סנטימטר אחד ולחזור.
ההפרש בין שתי הדרכים הוא 0.2 cm בלבד, כי 58 קרוב מאוד למספר 58.31.
המודול HC-SR04: הדקים ואופן הפעולה:
| תכונה | ערך |
|---|---|
| הזנה | מתח 5 V וזרם 15 mA |
| תדר הגל | 40 kHz |
| תחום מדידה | מ-2 cm עד 4 m |
| זווית המדידה | 15° בערך |
| פולס הדק | t ≥ 10 µs |
| בין שתי מדידות | t ≥ 60 ms |
החיישן ספרתי: יש לו רק מבוא ומוצא ספרתיים. הבקר מעלה את TRIG למשך 10 µs, וזהו פולס ההדק (טריגר). אז המודול שולח צרור של 8 מחזורים בתדר 40 kHz ומעלה את ECHO, ומוריד אותו כשההד מגיע. רוחב הפולס בהדק ECHO הוא הזמן t. כל ערך בטבלה הוא "ערך טיפוסי לפי גיליון הנתונים", והערכים עשויים להשתנות מעט בין יצרנים.
כדי למדוד את רוחב הפולס נשתמש בפקודה pulseIn(): היא ממתינה עד שההדק עולה, ואז מחזירה את משך הזמן שבו נשאר גבוה, במיקרו-שניות. הארגומנט השלישי 30000UL הוא זמן ההמתנה המרבי: אם לא מגיע פולס תוך 30 ms , הפקודה מחזירה 0. זמן ההמתנה הזה מספיק למרחק של עד 514 cm , כלומר יותר מתחום המדידה של החיישן.
const int TRIG = 9;
const int ECHO = 10;
const float V = 0.0343; // speed of sound: 343 m/s = 0.0343 cm/us
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
void loop() {
digitalWrite(TRIG, HIGH); // 10 us trigger pulse
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
unsigned long t = pulseIn(ECHO, HIGH, 30000UL); // 0 = timeout
Serial.print("t = "); Serial.print(t);
if (t == 0) {
Serial.println(" us no echo");
} else {
Serial.print(" us d = "); Serial.print(V * t / 2, 1);
Serial.println(" cm");
}
delay(100);
}t = 583 us d = 10.0 cm t = 2915 us d = 50.0 cm t = 5831 us d = 100.0 cm t = 11662 us d = 200.0 cm t = 0 us no echo
הקריאה הטיפוסית לגופים במרחקים 10, 50, 100, 200 סנטימטר; בשורה האחרונה אין גוף: לא חזר הד, ולכן pulseIn החזירה את הערך 0.
א. חשבו את המרחק לפי החוק.
ב. חשבו אותו לפי הקיצור.
מערכת עזר לחניה (Parking Assist)
החיישן העל-קולי מודד את המרחק אל הקיר, והזמזם מצפצף מהר יותר ככל שהמכונית מתקרבת. נחלק את המרחק לארבעה אזורים, ונוסיף זמזם סביל בין D8 לבין האדמה. הפקודה tone(BUZZ, 2000, 60) מוציאה גל ריבועי בתדר 2000 Hz למשך 60 ms ואז נעצרת מעצמה. במקום delay ארוך בין הצפצופים נשווה את millis() לזמן הצפצוף הקודם, וכך המדידה נשארת מהירה.
| אזור | מרחק | זמזם |
|---|---|---|
| 0 | יותר מ-100 cm | שקט |
| 1 | מ-50 עד 100 cm | כל 500 ms |
| 2 | מ-25 עד 50 cm | כל 200 ms |
| 3 | 25 cm או פחות | רציף: עצור! |
const int TRIG = 9, ECHO = 10, BUZZ = 8; // BUZZ: passive buzzer
const unsigned int GAP[] = {0, 500, 200, 0}; // ms between beeps
unsigned long lastBeep = 0;
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
void loop() {
digitalWrite(TRIG, HIGH); delayMicroseconds(10); digitalWrite(TRIG, LOW);
unsigned long t = pulseIn(ECHO, HIGH, 30000UL);
float d = (t == 0) ? 999.0 : t / 58.0; // no echo = far away
int z = (d > 100) ? 0 : (d > 50) ? 1 : (d > 25) ? 2 : 3;
if (z == 0) noTone(BUZZ);
else if (z == 3) tone(BUZZ, 2000); // stop: continuous tone
else if (millis() - lastBeep >= GAP[z]) {
tone(BUZZ, 2000, 60); // short beep
lastBeep = millis();
}
Serial.print("d = "); Serial.print(d, 1);
Serial.print(" cm zone "); Serial.println(z);
delay(60);
}d = 999.0 cm zone 0 d = 150.8 cm zone 0 d = 90.5 cm zone 1 d = 40.2 cm zone 2 d = 12.1 cm zone 3
מכונית מתקרבת לקיר, ובשורה הראשונה אין הד. המרחק המוצג גדול מעט מהמרחק האמיתי: 150.8 cm לגוף במרחק 150 cm , כי הסקיצה מחלקת ב-58 ולא במספר 58.31. גבולות האזורים בזמן ההד: t = 58·d , כלומר 5800 , 2900 ו-1450 µs.
חיישן תנועה PIR (PIR Motion Sensor)
בתוכו יש רכיב פירואלקטרי בעל שני חצאים, ומעליו כיפה לבנה שהיא עדשת פרנל, המחלקת את שדה הראייה לגזרות. כשאדם עובר מגזרה לגזרה, מגיעה לשני החצאים קרינה שונה והמוצא עולה. לכן אדם שיושב בלי לזוז "נעלם" אחרי זמן קצר: החיישן מגלה שינוי ולא נוכחות.
| תכונה | הערך ב-HC-SR501 ("ערך טיפוסי לפי גיליון הנתונים") |
|---|---|
| מתח הזנה | מ-4.5 V עד 20 V |
| מוצא | ספרתי: 3.3 V כשיש תנועה, 0 V כשאין |
| טווח גילוי | עד 7 m בערך, מכוונן בפוטנציומטר Sx |
| זווית גילוי | חרוט של פחות מ-120° |
| זמן השהיה Tx | מכוונן בפוטנציומטר Tx: מכמה שניות ועד כמה דקות |
| זמן חימום אחרי ההפעלה | עד דקה בערך |
על המודול יש גם מגשר קטן לבחירת מצב הפעלה חוזרת. במצב H כל תנועה חדשה מתחילה את זמן ההשהיה מחדש, כך שהמוצא נשאר גבוה כל עוד התנועה נמשכת. במצב L המוצא יורד אחרי Tx גם אם התנועה נמשכת. הערכים משתנים מעט בין גרסאות של המודול.
מוצא החיישן 3.3 V, והבקר מוזן במתח 5 V. לפי גיליון הנתונים של ATmega328P ההדק נקרא HIGH החל מ-3 V בערך, והמתח 3.3 V גדול מזה, ולכן נחבר את המוצא ישירות להדק D2 (וזה בטוח גם עבור ESP32). נורית החיווי שעל D7 מחוברת בטור לנגד 330 Ω, ולכן עובר בה זרם של כ-9 mA.
נרצה שהנורית תידלק כשיש תנועה ותישאר דולקת 30 s אחרי התנועה האחרונה. נכוון את המודול למצב H ולזמן Tx הקצר ביותר, ונשאיר את מדידת הזמן לסקיצה: נשמור ב-lastMotion את זמן הקריאה האחרונה של HIGH , ונכבה כשעברו 30 s מאז.
const int PIR = 2, LAMP = 7;
const unsigned long HOLD = 30000UL; // ms after the last motion
unsigned long lastMotion = 0;
bool lampOn = false;
void report(const char *msg) {
Serial.print("t = "); Serial.print(millis() / 1000.0, 1);
Serial.print(" s "); Serial.println(msg);
}
void setup() {
Serial.begin(9600);
pinMode(PIR, INPUT); pinMode(LAMP, OUTPUT);
delay(60000UL); // PIR warm-up
Serial.println("ready");
}
void loop() {
unsigned long now = millis();
if (digitalRead(PIR) == HIGH) {
lastMotion = now; // motion: restart the timer
if (!lampOn) {
lampOn = true; digitalWrite(LAMP, HIGH); report("lamp ON");
}
}
if (lampOn && now - lastMotion >= HOLD) {
lampOn = false; digitalWrite(LAMP, LOW); report("lamp OFF");
}
}ready t = 65.2 s lamp ON t = 114.7 s lamp OFF t = 152.3 s lamp ON t = 185.1 s lamp OFF
הקריאה האחרונה של HIGH בתנועה הראשונה הייתה בזמן 68.4 s , והתנועה השנייה התחילה בזמן 81 s:
לכן הנורית נשארה דולקת, והתנועה השנייה התחילה את הספירה מחדש. הקריאה האחרונה של HIGH בתנועה זו הייתה בזמן 84.7 s:
חיישני מרחק ותנועה נוספים (Other Distance and Motion Sensors)
מלבד החיישן העל-קולי וחיישן התנועה נפגוש בפרויקטים חיישני מרחק ותנועה נוספים. לא נרחיב עליהם בספר זה, אבל כדאי לדעת מה כל אחד מהם מודד, מה התחום שלו, מה סוג המוצא שלו והיכן משתמשים בו. הטבלה משווה ביניהם לבין שני החיישנים שלמדנו:
| החיישן | מה הוא מודד? | תחום טיפוסי | המוצא | שימוש טיפוסי |
|---|---|---|---|---|
| על-קולי HC-SR04 | מרחק לפי זמן ההד | מ-2 cm עד 4 m | פולס ספרתי בהדק ECHO | עזר לחניה, מפלס נוזל |
| חיישן התנועה HC-SR501 | שינוי בקרינה התרמית: תנועה של אדם | עד 7 m בערך | ספרתי: כן / לא | תאורת מדרגות, אזעקה |
| חיישן מרחק אינפרא-אדום (Sharp GP2Y0A21) | מרחק לפי מיקום האור המוחזר מהגוף | מ-10 cm עד 80 cm | מתח תקבילי, והקשר אינו לינארי | רובוט שמתחמק ממכשולים |
| מקודד סיבובי (KY-040) | זווית הסיבוב של הציר וכיוונו | סיבוב ללא הגבלה, 20 פולסים לסיבוב | פולסים ספרתיים בשני ערוצים, A ו-B | כפתור תפריט או עוצמה, מיקום ציר של מנוע |
| מד תאוצה (MPU6050) | תאוצה והטיית המכשיר ביחס לאופק | מ-±2 g עד ±16 g | ספרתי, דרך אפיק הנתונים I2C | זיהוי הטיה, רובוט מאזן, ספירת צעדים |
סיכום נוסחאות הפרק:
| החוק | הנוסחה |
|---|---|
| מרחק בשיטת ההד | d = v·t2 |
| הקיצור (v = 343 m/s) | d[cm] ≈ t[µs]58 |
| זמן ההד למרחק נתון | t[µs] ≈ 58·d[cm] |
מילון מונחים:
| עברית | English | العربية |
|---|---|---|
| חיישן על-קולי | Ultrasonic sensor | الحسّاس فوق الصوتي |
| הד | Echo | الصدى |
| מהירות הקול | Speed of sound | سرعة الصوت |
| פולס הדק (טריגר) | Trigger pulse | نبضة القدح |
| רוחב הפולס | Pulse width | عرض النبضة |
| זמן המתנה מרבי | Timeout | مهلة الانتظار |
| זמזם | Buzzer | الطنّان (البازر) |
| חיישן תנועה (PIR) | Passive infrared sensor | حسّاس الحركة بالأشعة تحت الحمراء |
| חיישן סביל (פסיבי) | Passive sensor | حسّاس سلبي |
| גביש פירואלקטרי | Pyroelectric element | العنصر الكهروحراري |
| עדשת פרנל | Fresnel lens | عدسة فرينل |
| זמן השהיה | Hold (delay) time | زمن الإمساك |
| מצב הפעלה חוזרת | Retrigger mode | وضع إعادة القدح |
| חיישן מרחק אינפרא-אדום | IR distance sensor | حسّاس المسافة بالأشعة تحت الحمراء |
| מקודד סיבובי | Rotary encoder | المرمِّز الدوّار |
| מד תאוצה | Accelerometer | مقياس التسارع |
שאלות לתרגול:
א. חשבו את המרחק לפי החוק.
ב. חשבו אותו לפי הקיצור.
ב. סקיצה משתמשת בזמן המתנה מרבי של 10000 µs: מהו המרחק הגדול ביותר שהיא מודדת?
א. מדידת מפלס המים במכל מלמעלה.
ב. הדלקת אור במדרגות כשאדם עולה.
ג. כפתור שמסובבים לשני הכיוונים כדי לבחור פריט בתפריט.
ד. זיהוי הטיה של משטח ביחס לאופק.
א. HC-SR04.
ב. HC-SR501.
ג. חיישן המרחק Sharp.