مشروع ختامي: نظام تحكّم متكامل
في الفصول السابقة تعلّمنا كل جزء وحده: حسّاسا رقميا، مفتاح نهاية المشوار، جسر 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 | LED أخضر + 330 Ω | HIGH = يوجد مكان |
| D12 | RED_PIN | LED أحمر + 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 – מנוע דו-כיווני: גשר H:
محرّك الذراع محرّك تيار مستمر 12 V. نعكس اتجاهه بعكس قطبية الجهد عليه بواسطة جسر H (גשר 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. هل تكفي الأطراف؟
ج. نقترح حلّين.
أ. أيّ حسّاس أو وحدة نضيف لمعرفة الساعة؟
ب. أيّ شرط في البرنامج نغيّر؟