פרויקט מסכם: מערכת בקרה שלמה
בפרקים הקודמים למדנו כל חלק בנפרד: חיישן ספרתי, מפסק גבול, גשר H, צג וזמזם. בפרק הזה נחבר אותם למערכת אמיתית אחת: מחסום חניון שסופר את המכוניות הנכנסות והיוצאות, מציג את מספר המקומות הפנויים, מתריע כשהחניון מלא, ומרים ומוריד את הזרוע בעזרת מנוע דו-כיווני עם שני מפסקי גבול. השומר יכול להפעיל אותו ידנית בכל רגע. נעבור יחד את כל שלבי העבודה ההנדסית: מן הדרישות במילים, דרך דיאגרמת המלבנים, טבלת ההדקים, תרשים המצבים ותרשים החיווט, ועד התוכנית המלאה ולבסוף תוכנית הבדיקות. אלה בדיוק השלבים שנעבור בפרויקט הגמר.
- נכתוב את דרישות המערכת במשפטים שאפשר לבדוק, ונקשר כל דרישה לבדיקה.
- נשרטט דיאגרמת מלבנים וטבלת מבואות ומוצאות, ונבחר הדקים ורכיבים בעזרת חישוב.
- נתכנן מכונת מצבים למחסום עם תנאי בטיחות: היפוך כיוון כשיש מכשול, ופסק זמן שמוביל למצב תקלה.
- נכתוב תוכנית שאינה עוצרת (millis()) עם מצבי enum, סינון קפיצות ומונה.
- נבדוק את המערכת לפי תוכנית בדיקות ונשווה את הצג הטורי להתנהגות הצפויה.
- נכיר דרכים להרחיב את הפרויקט (ESP32, בקר שני, PLC) ואת אופן הערכתו.
הגדרת דרישות המערכת (Requirements)
כל פרויקט מתחיל בשאלה: מה המערכת צריכה לעשות? לפני החיווט והתוכנית נכתוב את מה שבעל החניון רוצה, במשפטים קצרים שאפשר לבדוק: אחרי הבדיקה נוכל לומר "התקיים" או "לא התקיים".
| סימון | הדרישה |
|---|---|
| R1 | מכונית לפני הזרוע והחניון אינו מלא: הזרוע עולה אוטומטית. |
| R2 | כל מכונית שעוברת מתחת לזרוע נספרת פעם אחת; הולך רגל אינו נספר. |
| R3 | כל מכונית שיוצאת בנתיב היציאה מופחתת מן הספירה. |
| R4 | הצג מציג את מספר המקומות הפנויים ואת מצב המחסום. |
| R5 | החניון מלא: האדומה דולקת, הירוקה כבויה, הזרוע אינה עולה אוטומטית, וצפצוף קצר למכונית חדשה. |
| R6 | הזרוע נעצרת במפסקי הגבול, ויורדת מעצמה 5 s אחרי שהמכונית עברה. |
| R7 | בטיחות: עצם מתחת לזרוע בזמן הירידה הופך מיד את התנועה לעלייה. |
| R8 | בטיחות: הזרוע לא הגיעה למפסק הגבול בתוך 6 s: המנוע נעצר, ומצב תקלה עם התרעה. |
| R9 | השומר מרים ומוריד את הזרוע בשני לחצנים בכל זמן, במקביל להפעלה האוטומטית, ובעזרתם מוציא את המערכת מתקלה. |
נבנה דגם מוקטן ובו 3 מקומות בלבד, כדי למלא אותו מהר בבדיקה; בחניון אמיתי נשנה קבוע אחד בתוכנית. המכונית חוצה קודם את קרן הכניסה, אחר כך עוברת מתחת לזרוע וחוצה את קרן הבטיחות, ורק כשהיא יוצאת ממנה נספור אותה.
דיאגרמת מלבנים ובחירת חיישנים (Block Diagram)
מן הדרישות נגזור מה המערכת צריכה "לחוש" ומה היא צריכה "לעשות", ונשרטט זאת בדיאגרמת מלבנים: החיישנים משמאל, הבקר באמצע, והמפעילים והחיווי מימין.
אפשר היה להשתמש גם בחיישן על-קולי (מודד מרחק, אבל דורש תוכנית מדידה) או בלולאה השראתית ברצפה (מגלה רק מתכת, אבל דורשת חפירה ומעגל מיוחד). נבחר במחסום אור כי הוא נותן מוצא ספרתי פשוט. נקודת התורפה שלו היא שגם אדם קוטע אותו, ואותה נפתור בלוגיקה: נספור רק עצם שעבר קודם בחיישן הכניסה (R2).
טבלת מבואות ומוצאות ובחירת רכיבים (I/O Table)
לפני כל חיווט נכתוב טבלת I/O (טבלת מבואות ומוצאות). הטבלה הזאת היא החוזה בין תרשים החיווט לבין התוכנית: כל הדק מופיע בשניהם באותו מספר. ההדקים D0 ו-D1 נשמרים לצג הטורי, ו-A4 ו-A5 לפס I2C.
| ההדק (מבואות) | השם בתוכנית | מחובר אל | פעיל כאשר |
|---|---|---|---|
| D2 | ENTRY_PIN | מקלט מחסום האור בכניסה | LOW = מכונית לפני הזרוע |
| D3 | EXIT_PIN | מקלט מחסום האור ביציאה | LOW = מכונית יוצאת |
| D4 | BEAM_PIN | מקלט קרן הבטיחות | LOW = עצם מתחת לזרוע |
| D5 | LS_OPEN_PIN | מפסק גבול עליון, NC | HIGH = הזרוע למעלה |
| D6 | LS_CLOSED_PIN | מפסק גבול תחתון, NC | HIGH = הזרוע למטה |
| D7 | BTN_OPEN_PIN | לחצן OPEN ידני | LOW = לחוץ |
| D8 | BTN_CLOSE_PIN | לחצן CLOSE ידני | LOW = לחוץ |
| ההדק (מוצאות) | השם בתוכנית | מחובר אל | פעיל כאשר |
|---|---|---|---|
| D9 | IN1_PIN | מבוא IN1 של L298N | HIGH = הרמת הזרוע |
| D10 | IN2_PIN | מבוא IN2 של L298N | HIGH = הורדת הזרוע |
| D11 | GREEN_PIN | נורית ירוקה + 330 Ω | HIGH = יש מקום |
| D12 | RED_PIN | נורית אדומה + 330 Ω | HIGH = מלא, או תקלה (מהבהבת) |
| A0 | BUZZER_PIN | זמזם דרך BC547 | HIGH = התרעה |
| A4 A5 | lcd | צג LCD 16×2, כתובת 0x27 | SDA · SCL |
כל המבואות מוגדרים עם INPUT_PULLUP, כלומר עם נגד משיכה למעלה פנימי: הלחצן או החיישן מחברים את ההדק לאדמה, ולכן הרמה הפעילה היא LOW. את מפסקי הגבול נחבר דרך המגע הסגור במנוחה (NC): כשהזרוע לוחצת עליהם המגע נפתח וההדק נעשה HIGH.
הזרם קטן מן 20 mA המומלצים להדק של Uno. את הזמזם נפעיל דרך טרנזיסטור BC547 עם נגד בסיס 1 kΩ (פרק 10), ולכן ההדק מספק לו רק זרם קטן; זרם הקולט של BC547 מותר עד 100 mA (ערך אופייני לפי גיליון הנתונים), וזה מספיק לזמזם קטן.
מנוע דו-כיווני: גשר H:
מנוע הזרוע הוא מנוע זרם ישר של 12 V. נהפוך את כיוון סיבובו בהיפוך קוטביות המתח עליו בעזרת גשר H ברכיב L298 שעל יחידת L298N. הבקר נותן שני אותות לוגיים, והגשר מעביר את זרם המנוע ממקור 12 V נפרד. לפי גיליון הנתונים L298 עומד בזרם של עד 2 A לכל גשר, ושני מבואות שווים עוצרים את המנוע במהירות (בלימה).
| IN1 (D9) | IN2 (D10) | המנוע | המצב בתוכנית |
|---|---|---|---|
| HIGH | LOW | מרים את הזרוע | OPENING |
| LOW | HIGH | מוריד את הזרוע | CLOSING |
| LOW | LOW | עצור (בלימה) | CLOSED · OPEN · FAULT |
במקום גשר H אפשר להשתמש בשני ממסרים עם מגע מחליף: המנוע בין שתי נקודות COM, שני מגעי NO אל +12 V ושני מגעי NC אל האדמה. לעולם לא נפעיל את שניהם יחד: זו נעילה הדדית. כשמשתמשים בשני מגענים למנוע תלת-מופעי, הפעלתם יחד היא קצר בין שני מופעים, ולכן שם הנעילה חובה במעגל עצמו בעזרת מגע NC, ולא רק בתוכנית.
תרשים מצבים של המחסום (State Diagram)
- פסק זמן: זמן הרמת הזרוע בדגם הוא 4 s (מדדנו אותו), ונאפשר פי 1.5 ממנו, 6 s. אחרי זמן זה ברור שהזרוע תקועה, שהמנוע מקולקל או שמפסק הגבול שבור (R8).
- מצב תקלה: המנוע עצור, האדומה מהבהבת, הזמזם פועל. לא יוצאים ממנו אוטומטית: אדם בודק את המחסום ואז לוחץ OPEN או CLOSE (R9).
- היפוך כיוון: ב-CLOSING קרן קטועה מעבירה אותנו מיד ל-OPENING (R7), וב-OPEN לא נוריד את הזרוע כל עוד הקרן קטועה.
סינון הקפיצות מעכב את היפוך הכיוון ב-50 ms בלבד, והזרוע זזה בזמן הזה מרחק קטן מאוד. ובכל זאת הזרוע אינה נעצרת מיד בגלל ההתמדה, ולכן מרכיבים על זרוע אמיתית גם שפה גומית ומגבילים את הכוח שלה.
תרשים חיווט והפעלה ראשונה (Wiring and Bring-up)
נחלק את החיווט לשני תרשימים: המוצאות והמבואות. מספרי ההדקים בשניהם לקוחים מאותה טבלת מבואות ומוצאות שממנה נבנים קבועי התוכנית.
הפעלה ראשונה: לא נטען את התוכנית המלאה מיד, אלא נבדוק כל חלק בנפרד, כדי שהתקלות לא יתערבבו זו בזו:
- תוכנית קצרה שמדפיסה digitalRead() לכל מבוא: נקטע כל קרן ביד ונלחץ על כל לחצן ומפסק.
- נרים את הזרוע ביד ונראה שכל מפסק גבול משתנה במקום הנכון.
- נסובב את המנוע רגע קצר לכל כיוון ונוודא ש-IN1 מרים את הזרוע.
- תוכנית הדוגמה של הספרייה כותבת על הצג: אם לא מופיע דבר, נבדוק את כתובת I2C ואת הניגודיות.
- רק אחרי כל זה נטען את התוכנית המלאה.
התוכנית המלאה (The Complete Sketch)
התוכנית היא מכונת מצבים שאינה עוצרת: אין בה delay() בשום מקום. כל מחזור של loop() נמשך פחות ממילישנייה, ויש בו שלושה צעדים קבועים: הספירה, אחריה מכונת המצבים (switch (state)), ואחריה החיווי.
- enum State הוא טיפוס שערכיו הם שמות המצבים. state שומר את המצב הנוכחי, ו-tState את רגע הכניסה אליו, וממנו נחשב את פסקי הזמן.
- סינון קפיצות לכל מבוא: נקבל רמה חדשה רק אם היא נשארה יציבה 50 ms, ונחשב את שני הקצוות:rose (נעשה פעיל) ו-fell (חדל להיות פעיל). הלחצן פועל על הקצה, ולכן לחיצה ארוכה אינה נספרת פעמיים.
- הפונקציה go() היא המקום היחיד שמשנה את המצב: היא קובעת את המנוע (כיוון אחד לכל היותר), שומרת את הזמן ומדפיסה שורה.
- armed נעשה אמת כשחיישן הכניסה פעיל; נספור מכונית רק כשעצם יוצא מקרן הבטיחות ו-armed אמת (R2).
- הצג נכתב רק כשמשהו משתנה (lcdDirty), כי כתיבה דרך I2C נמשכת כמה מילישניות.
// Parking gate controller - final project (chapter 14)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const byte ENTRY_PIN = 2; // IR beam before the arm, LOW = car
const byte EXIT_PIN = 3; // IR beam in the exit lane, LOW = car
const byte BEAM_PIN = 4; // safety beam under the arm, LOW = blocked
const byte LS_OPEN_PIN = 5; // NC limit switch, HIGH = arm is up
const byte LS_CLOSED_PIN = 6; // NC limit switch, HIGH = arm is down
const byte BTN_OPEN_PIN = 7; // manual buttons, LOW = pressed
const byte BTN_CLOSE_PIN = 8;
const byte IN1_PIN = 9, IN2_PIN = 10; // L298N: IN1 = up, IN2 = down
const byte GREEN_PIN = 11, RED_PIN = 12, BUZZER_PIN = A0;
const int CAPACITY = 3; // places in the model lot
const unsigned long DEBOUNCE_MS = 50;
const unsigned long MOVE_MAX_MS = 6000; // limit switch must be reached
const unsigned long HOLD_MS = 5000; // stay open after the car passed
const unsigned long BEEP_MS = 500;
enum State { CLOSED, OPENING, OPEN, CLOSING, FAULT };
const char *NAMES[] = { "CLOSED", "OPENING", "OPEN", "CLOSING", "FAULT" };
enum { ENTRY, EXITS, BEAM, LS_OPEN, LS_CLOSED, B_OPEN, B_CLOSE, N_IN };
struct Input {
byte pin;
bool activeHigh;
bool on, raw, rose, fell; // debounced level, raw level, edges
unsigned long t; // time of the last raw change
};
Input in[N_IN] = {
{ ENTRY_PIN, false }, { EXIT_PIN, false }, { BEAM_PIN, false },
{ LS_OPEN_PIN, true }, { LS_CLOSED_PIN, true },
{ BTN_OPEN_PIN, false }, { BTN_CLOSE_PIN, false }
};
LiquidCrystal_I2C lcd(0x27, 16, 2);
State state = CLOSED;
unsigned long tState = 0, tBeep = 0;
int cars = 0;
bool armed = false, beep = false, lcdDirty = true;
bool active(const Input &k) {
return digitalRead(k.pin) == (k.activeHigh ? HIGH : LOW);
}
void readInputs(unsigned long now) {
for (byte i = 0; i < N_IN; i++) {
Input &k = in[i];
bool r = active(k);
k.rose = k.fell = false;
if (r != k.raw) { k.raw = r; k.t = now; } // raw change: restart
else if (r != k.on && now - k.t >= DEBOUNCE_MS) {
k.on = r; k.rose = r; k.fell = !r; // stable: accept it
}
}
}
void stamp(unsigned long now) {
Serial.print("t="); Serial.print(now / 1000);
Serial.print('.'); Serial.print((now / 100) % 10);
Serial.print(" ");
}
void go(State s, unsigned long now) { // the only place that moves
state = s; tState = now; lcdDirty = true;
digitalWrite(IN1_PIN, s == OPENING); // one direction at most
digitalWrite(IN2_PIN, s == CLOSING);
if (s == CLOSED) armed = false;
stamp(now); Serial.print("state: "); Serial.println(NAMES[s]);
}
void count(int d, unsigned long now) {
cars += d; lcdDirty = true;
stamp(now);
Serial.print(d > 0 ? "car in free = " : "car out free = ");
Serial.println(CAPACITY - cars);
}
void showLcd() {
lcd.setCursor(0, 0);
if (cars >= CAPACITY) lcd.print("PARKING FULL ");
else {
lcd.print("Free places: "); lcd.print(CAPACITY - cars);
lcd.print(" ");
}
lcd.setCursor(0, 1);
lcd.print("Gate: "); lcd.print(NAMES[state]); lcd.print(" ");
lcdDirty = false;
}
void setup() {
Serial.begin(9600);
for (byte i = 0; i < N_IN; i++) {
pinMode(in[i].pin, INPUT_PULLUP);
in[i].raw = in[i].on = active(in[i]);
}
pinMode(IN1_PIN, OUTPUT); pinMode(IN2_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT); pinMode(RED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// position unknown after power-up: close first
go(in[LS_CLOSED].on ? CLOSED : CLOSING, millis());
lcd.init();
lcd.backlight();
}
void loop() {
unsigned long now = millis();
readInputs(now);
bool full = cars >= CAPACITY;
// 1. counting
if (in[ENTRY].on) armed = true; // came through the entry lane
if (in[BEAM].fell && armed) { armed = false; count(+1, now); }
if (in[EXITS].fell && cars > 0) count(-1, now);
if (in[ENTRY].rose && full) {
beep = true; tBeep = now;
stamp(now); Serial.println("lot FULL, entry refused");
}
full = cars >= CAPACITY;
// 2. state machine
if (in[LS_OPEN].on && in[LS_CLOSED].on && state != FAULT)
go(FAULT, now); // both limits: broken wire
switch (state) {
case CLOSED:
if (in[B_OPEN].rose || (in[ENTRY].on && !full)) go(OPENING, now);
break;
case OPENING:
if (in[LS_OPEN].on) go(OPEN, now);
else if (in[B_CLOSE].rose) go(CLOSING, now);
else if (now - tState > MOVE_MAX_MS) go(FAULT, now);
break;
case OPEN:
if (in[BEAM].on || (in[ENTRY].on && !full)) tState = now;
if (in[B_CLOSE].rose && !in[BEAM].on) go(CLOSING, now);
else if (now - tState >= HOLD_MS) go(CLOSING, now);
break;
case CLOSING: // obstacle: reverse at once
if (in[BEAM].on || in[B_OPEN].rose) go(OPENING, now);
else if (in[LS_CLOSED].on) go(CLOSED, now);
else if (now - tState > MOVE_MAX_MS) go(FAULT, now);
break;
case FAULT: // motor off: wait for a person
if (in[B_OPEN].rose) go(OPENING, now);
else if (in[B_CLOSE].rose) go(CLOSING, now);
break;
}
// 3. indication
if (beep && now - tBeep >= BEEP_MS) beep = false;
bool blink = (now / 500) % 2;
digitalWrite(GREEN_PIN, !full && state != FAULT);
digitalWrite(RED_PIN, state == FAULT ? blink : full);
digitalWrite(BUZZER_PIN, state == FAULT || beep);
if (lcdDirty) showLcd();
}תוכנית בדיקות (Test Plan)
תוכנית בדיקות היא טבלה שנכתוב לפני הבדיקה: לכל אירוע, המצב והמוצאות הצפויים; אחר כך נבצע ונרשום את התוצאה. כל דרישה מופיעה לפחות בשורה אחת.
| # | הדרישה | האירוע | הצפוי | התוצאה |
|---|---|---|---|---|
| 1 | R4 | הפעלה כשהזרוע למטה | CLOSED, ירוקה, "Free places: 3" | ☐ |
| 2 | R1 R6 | מכונית בכניסה, יש מקום | OPENING ואחר כך OPEN ב-LS_OPEN | ☐ |
| 3 | R2 R6 | המכונית חוצה את הקרן | הספירה +1; אחרי 5 s CLOSING ואחר כך CLOSED | ☐ |
| 4 | R2 | שתי מכוניות ברצף | הזרוע נשארת למעלה, הספירה +2 | ☐ |
| 5 | R5 | המקום האחרון התמלא | אדומה, הירוקה כבויה, "PARKING FULL" | ☐ |
| 6 | R7 R2 | הולך רגל בקרן בזמן הירידה | OPENING מיד; הספירה אינה משתנה | ☐ |
| 7 | R5 | מכונית בכניסה, החניון מלא | נשאר CLOSED, צפצוף 0.5 s | ☐ |
| 8 | R3 R1 | מכונית יוצאת ואחרת ממתינה | הספירה −1 ואחר כך OPENING אוטומטית | ☐ |
| 9 | R8 | הזרוע תקועה בזמן הירידה | FAULT אחרי 6 s: מנוע עצור, אדומה מהבהבת, זמזם | ☐ |
| 10 | R9 | לחצן CLOSE בזמן תקלה | CLOSING ואחר כך CLOSED | ☐ |
| 11 | R9 | לחצן OPEN בלי מכונית | OPENING, OPEN, ואחרי 5 s הזרוע יורדת | ☐ |
| 12 | R8 | חוט LS_OPEN קרוע | FAULT מיד: שני המפסקים "פעילים" יחד | ☐ |
נבצע את שורות 1–10 כניסוי אחד. זמני האירועים בשניות: מכונית בכניסה ב-2 ומתחת לזרוע בין 7 ל-9; שתי מכוניות בין 20 ל-31; הולך רגל ב-38; מכונית רביעית ממתינה מ-52; מכונית יוצאת ב-56; הזרוע תקועה בין 69 ל-79; השומר לוחץ CLOSE ב-80. הזנו את הרצף הזה למודל של התוכנית בשפת פייתון, שמבצע את אותם תנאים בכל מילישנייה, וקיבלנו:
t=0.0 state: CLOSED t=2.0 state: OPENING t=6.1 state: OPEN t=9.0 car in free = 2 t=14.0 state: CLOSING t=18.0 state: CLOSED t=20.0 state: OPENING t=24.1 state: OPEN t=27.0 car in free = 1 t=31.0 car in free = 0 t=36.0 state: CLOSING t=38.0 state: OPENING t=40.1 state: OPEN t=45.1 state: CLOSING t=49.1 state: CLOSED t=52.0 lot FULL, entry refused t=57.0 car out free = 1 t=57.0 state: OPENING t=61.1 state: OPEN t=64.0 car in free = 0 t=69.0 state: CLOSING t=75.0 state: FAULT t=80.0 state: CLOSING t=84.1 state: CLOSED
נשווה את היומן לטבלה: בשנייה 38 הכיוון התהפך והולך הרגל לא נספר; ב-52 המכונית נדחתה; ב-57 יצאה מכונית והזרוע עלתה למכונית הממתינה; ב-75.0 נכנסנו למצב תקלה, 6 s אחרי תחילת הירידה. כל זמן מאוחר ב-50 ms מן האירוע בגלל סינון הקפיצות.
הרחבות לפרויקט (Extensions)
דיווח אלחוטי עם ESP32: לוח ESP32 שולח בכל דקה את מספר המקומות הפנויים לדף באינטרנט, וכך הנהג יודע עוד לפני שהוא מגיע. עדיף להשאיר את Uno לבקרה ולהוסיף ESP32 לתקשורת בלבד: תקלה ברשת אינה עוצרת את המחסום.
בקר שני: צג גדול ליד הרחוב מופעל על ידי בקר שני, והבקר הראשון שולח אליו את הספירה בכל שינוי. זו תקשורת בממשק מכונה-מכונה: שורת טקסט על קו טורי (TX אל RX עם אדמה משותפת).
אותו מחסום עם PLC: במפעל בונים מחסום כזה לרוב עם בקר מתוכנת (PLC), ואת התוכנית שלו כותבים בדיאגרמת סולם, כמו בפרק 2 של מקצוע 33.102:
נשווה: ב-Arduino המצב הוא המשתנה state, וב-PLC הוא סליל K1 או K2 עם מגע החזקה עצמית. היפוך הכיוון הוא שני מגעים של BEAM: המגע הסגור במנוחה בשלב ההורדה עוצר את ההורדה, והמגע הפתוח במנוחה המקביל בשלב ההרמה מפעיל את ההרמה. פסק הזמן הוא קוצב זמן TON, והספירה היא מונה CTU/CTD עם השוואה שנותנת NOT_FULL. והנעילה ההדדית היא מגע K2 סגור במנוחה בשלב של K1 ולהפך, במקום הפונקציה go().
הערכת הפרויקט (Assessment Checklist)
| התחום | נקודות | מה נבדק | ✓ |
|---|---|---|---|
| תיעוד | 25 | דרישות, דיאגרמת מלבנים, טבלת הדקים, תרשים מצבים, חיווט שתואם לתוכנית | ☐ |
| סדר בחיווט | 20 | חוטים קצרים ומקובעים, צבעים קבועים, תוויות, מקור נפרד ואדמה משותפת | ☐ |
| בטיחות | 25 | היפוך מול מכשול, פסק זמן ותקלה, מפסקי NC, נתיך, דיודות, בלי מתח רשת | ☐ |
| בדיקות | 30 | תוכנית לפני הביצוע, כל דרישה נבדקה, יומן מצורף, הדגמת תקלה מול המורה | ☐ |
סיכום נוסחאות הפרק:
| החוק | הנוסחה |
|---|---|
| מקומות פנויים | free = CAPACITY − cars |
| נגד לנורית חיווי | R = VCC − VFIF |
| זרם בלחצן עם נגד משיכה למעלה | I = VCCRPU |
| פסק הזמן לתנועה | tmax = 1.5·tmove |
| זמן קטיעת הקרן על ידי מכונית | t = Lcarv |
מילון מונחים:
| עברית | English | العربية |
|---|---|---|
| דרישות המערכת | System requirements | متطلبات النظام |
| מחסום חניון | Parking barrier | بوابة الموقف (الذراع) |
| דיאגרמת מלבנים | Block diagram | مخطّط الكتل |
| מחסום אור (שולח-מקלט) | Through-beam sensor | الحاجز الضوئي |
| טבלת מבואות ומוצאות | I/O table | جدول المداخل والمخارج |
| מפסק גבול | Limit switch | مفتاح نهاية المشوار |
| תכנון בטוח-כשל | Fail-safe design | التصميم الآمن عند العطل |
| נעילה הדדית | Interlock | الإقفال المتبادل |
| מכונת מצבים | State machine | آلة الحالات |
| תרשים מצבים | State diagram | مخطّط الحالات |
| פסק זמן | Timeout | المهلة الزمنية |
| מצב תקלה | Fault state | حالة العطل |
| סינון קפיצות | Debouncing | إزالة الارتداد |
| תוכנית בדיקות | Test plan | خطّة الاختبار |
| דיאגרמת סולם | Ladder diagram | المخطّط السلّمي |
| בקר מתוכנת (PLC) | Programmable logic controller | المتحكّم المنطقي القابل للبرمجة |
שאלות לתרגול:
א. איזו שורה משנים?
ב. כמה תווים כותבת התוכנית בשורה הראשונה של הצג כאשר החניון ריק? האם השורה מספיקה?
א. חשבו את מהירות קצה הזרוע.
ב. כמה זז הקצה בתוך 50 ms?
א. חשבו את ההתנגדות.
ב. בחרו 220 Ω וחשבו את הזרם בפועל.
א. אילו הדקים פנויים ב-Uno (בלי D0 ו-D1)?
ב. המחסום השני צריך: IN3, IN4, LS_OPEN2, LS_CLOSED2, BEAM2. האם ההדקים מספיקים?
ג. הציעו שני פתרונות.
א. איזה חיישן או יחידה מוסיפים כדי לדעת את השעה?
ב. איזה תנאי בתוכנית משנים?