الرئيسية قاعدة المعرفة الأتمتة والتحكم مشروع تطبيقي: برمجة نظام تعبئة وتغليف آلي كامل
الأتمتة والتحكم

مشروع تطبيقي: برمجة نظام تعبئة وتغليف آلي كامل

نظرة عامة على المشروع: نظام تعبئة آلي

في هذا الدرس الأخير، نُطبّق كل ما تعلمناه في مشروع واقعي: نظام تعبئة سوائل آلي يملأ زجاجات بكمية محددة، يُغلق الغطاء، ويعدّ الإنتاج.

مكونات النظام

┌──────────────────────────────────────────────────────┐
│                    نظام التعبئة الآلي                   │
│                                                       │
│  ┌─────┐   ┌──────┐   ┌──────┐   ┌──────┐   ┌─────┐ │
│  │دخول │→→→│تعبئة │→→→│إغلاق │→→→│ عدّ  │→→→│خروج│ │
│  │الزجاجة│   │السائل│   │الغطاء│   │ وفرز │   │     │ │
│  └─────┘   └──────┘   └──────┘   └──────┘   └─────┘ │
│     ▲          ▲          ▲          ▲                 │
│  حسّاس 1   صمام+حسّاس  أسطوانة   حسّاس 4             │
│  (قُرب)    (مستوى)     (هواء)    (عدّاد)             │
└──────────────────────────────────────────────────────┘

مراحل العمل

  1. الانتظار: السير يعمل حتى يكشف الحسّاس زجاجة
  2. التموضع: إيقاف السير وتثبيت الزجاجة
  3. التعبئة: فتح صمام السائل حتى يصل للمستوى المطلوب
  4. الإغلاق: تمديد أسطوانة إغلاق الغطاء
  5. الإخراج: تشغيل السير لإخراج الزجاجة وعدّها

تحليل المتطلبات: المداخل والمخارج

المداخل الرقمية (DI)

الرقم العنوان الوصف نوع المستشعر
1 I0.0 زر بدء التشغيل زر لحظي NO
2 I0.1 زر الإيقاف زر لحظي NC
3 I0.2 إيقاف طوارئ فطر أحمر NC
4 I0.3 حسّاس دخول الزجاجة قُرب حثّي PNP
5 I0.4 حسّاس موضع التعبئة قُرب حثّي PNP
6 I0.5 حسّاس مستوى السائل سعوي PNP
7 I0.6 حسّاس الأسطوانة ممتدة مغناطيسي
8 I0.7 حسّاس الأسطوانة مرتدة مغناطيسي
9 I1.0 حسّاس عدّ الخروج ضوئي PNP
10 I1.1 حماية حرارية للسير NC

المخارج الرقمية (DO)

الرقم العنوان الوصف الحِمل
1 Q0.0 محرك السير الناقل كونتاكتور 2A
2 Q0.1 صمام التعبئة صمام 24VDC
3 Q0.2 أسطوانة إغلاق الغطاء صمام هواء 5/2
4 Q0.3 لمبة التشغيل (خضراء) LED 24VDC
5 Q0.4 لمبة العطل (حمراء) LED 24VDC
6 Q0.5 صافرة إنذار 24VDC

المداخل التناظرية (AI)

الرقم العنوان الوصف الإشارة
1 IW64 وزن الزجاجة (خلية وزن) 4-20mA

تصميم البرنامج: المراحل والتسلسل

آلة الحالة الرئيسية

TYPE E_FillState :
(
    ST_IDLE       := 0,    // خامل - انتظار أمر التشغيل
    ST_READY      := 10,   // جاهز - السير يعمل
    ST_BOTTLE_IN  := 20,   // زجاجة في موضع التعبئة
    ST_FILLING    := 30,   // جاري التعبئة
    ST_FILL_DONE  := 40,   // التعبئة اكتملت
    ST_CAPPING    := 50,   // جاري إغلاق الغطاء
    ST_CAP_DONE   := 60,   // الإغلاق اكتمل
    ST_EJECT      := 70,   // إخراج الزجاجة
    ST_FAULT      := 99    // عطل
);
END_TYPE

مخطط التسلسل

IDLE ──(بدء)──→ READY ──(زجاجة)──→ BOTTLE_IN
                  ▲                      │
                  │                (تثبيت 500ms)
                  │                      ▼
             EJECT ←──(1s)── CAP_DONE ← CAPPING ← FILL_DONE ← FILLING
               │                                                  │
               │                                          (حسّاس المستوى)
          (حسّاس خروج)
               │
               ▼
             READY (دورة جديدة)

كتابة الكود: Structured Text للمراحل الرئيسية

PROGRAM FillingSystem
VAR
    // حالة النظام
    eState         : E_FillState := ST_IDLE;
    ePrevState     : E_FillState;

    // مداخل
    bStartBtn      : BOOL;     // I0.0
    bStopBtn       : BOOL;     // I0.1
    bEStop         : BOOL;     // I0.2
    bBottleEntry   : BOOL;     // I0.3
    bBottleInPos   : BOOL;     // I0.4
    bLevelFull     : BOOL;     // I0.5
    bCylExtended   : BOOL;     // I0.6
    bCylRetracted  : BOOL;     // I0.7
    bExitSensor    : BOOL;     // I1.0
    bThermalOK     : BOOL;     // I1.1

    // مخارج
    bConveyor      : BOOL;     // Q0.0
    bFillValve     : BOOL;     // Q0.1
    bCapCylinder   : BOOL;     // Q0.2
    bGreenLamp     : BOOL;     // Q0.3
    bRedLamp       : BOOL;     // Q0.4
    bBuzzer        : BOOL;     // Q0.5

    // تناظري
    iRawWeight     : INT;      // IW64
    rBottleWeight  : REAL;

    // مؤقتات
    fbSettleTimer  : TON;      // استقرار الزجاجة
    fbFillTimeout  : TON;      // مهلة التعبئة
    fbCapTimeout   : TON;      // مهلة الإغلاق
    fbEjectTimer   : TON;      // زمن الإخراج
    fbBuzzerPulse  : TP;       // نبضة الصافرة

    // عدّادات
    fbBottleCount  : CTU;      // عدّاد الزجاجات
    diTotalBottles : DINT;     // إجمالي الإنتاج
    diBatchCount   : DINT;     // عدد الدفعات

    // إعدادات (قابلة للتعديل من HMI)
    tSettleTime    : TIME := T#500ms;
    tFillTimeout   : TIME := T#15s;
    tCapTimeout    : TIME := T#5s;
    tEjectTime     : TIME := T#1s;
    iBatchSize     : INT := 24;
    rTargetWeight  : REAL := 500.0;  // غرام
END_VAR

// ═══════════════════════════════════════════
// حماية الطوارئ (تُنفّذ دائماً بغض النظر عن الحالة)
// ═══════════════════════════════════════════
IF bEStop OR NOT bThermalOK THEN
    eState := ST_FAULT;
END_IF;

// ═══════════════════════════════════════════
// قراءة الوزن التناظري
// ═══════════════════════════════════════════
rBottleWeight := FC_ScaleAnalog(
    iRawValue := iRawWeight,
    rEngMin := 0.0,
    rEngMax := 1000.0
);

// ═══════════════════════════════════════════
// آلة الحالة الرئيسية
// ═══════════════════════════════════════════
CASE eState OF

    // ─── خامل: انتظار أمر التشغيل ───
    ST_IDLE:
        bConveyor := FALSE;
        bFillValve := FALSE;
        bCapCylinder := FALSE;

        IF bStartBtn AND NOT bEStop AND bThermalOK THEN
            eState := ST_READY;
        END_IF;

    // ─── جاهز: السير يعمل ───
    ST_READY:
        bConveyor := TRUE;
        bFillValve := FALSE;
        bCapCylinder := FALSE;

        IF bStopBtn THEN
            eState := ST_IDLE;
        END_IF;

        IF bBottleInPos THEN
            eState := ST_BOTTLE_IN;
        END_IF;

    // ─── زجاجة في الموضع: إيقاف وانتظار الاستقرار ───
    ST_BOTTLE_IN:
        bConveyor := FALSE;
        fbSettleTimer(IN := TRUE, PT := tSettleTime);

        IF fbSettleTimer.Q THEN
            fbSettleTimer(IN := FALSE);
            eState := ST_FILLING;
        END_IF;

    // ─── التعبئة: فتح الصمام ───
    ST_FILLING:
        bFillValve := TRUE;
        fbFillTimeout(IN := TRUE, PT := tFillTimeout);

        // اكتملت التعبئة
        IF bLevelFull OR (rBottleWeight >= rTargetWeight) THEN
            bFillValve := FALSE;
            fbFillTimeout(IN := FALSE);
            eState := ST_FILL_DONE;
        END_IF;

        // تجاوز المهلة
        IF fbFillTimeout.Q THEN
            bFillValve := FALSE;
            fbFillTimeout(IN := FALSE);
            eState := ST_FAULT;
        END_IF;

    // ─── التعبئة اكتملت: انتقل للإغلاق ───
    ST_FILL_DONE:
        bFillValve := FALSE;
        eState := ST_CAPPING;

    // ─── إغلاق الغطاء ───
    ST_CAPPING:
        bCapCylinder := TRUE;
        fbCapTimeout(IN := TRUE, PT := tCapTimeout);

        IF bCylExtended THEN
            fbCapTimeout(IN := FALSE);
            eState := ST_CAP_DONE;
        END_IF;

        IF fbCapTimeout.Q THEN
            fbCapTimeout(IN := FALSE);
            eState := ST_FAULT;
        END_IF;

    // ─── الإغلاق اكتمل: ارجع الأسطوانة ───
    ST_CAP_DONE:
        bCapCylinder := FALSE;

        IF bCylRetracted THEN
            eState := ST_EJECT;
        END_IF;

    // ─── إخراج الزجاجة ───
    ST_EJECT:
        bConveyor := TRUE;
        fbEjectTimer(IN := TRUE, PT := tEjectTime);

        IF fbEjectTimer.Q AND NOT bBottleInPos THEN
            fbEjectTimer(IN := FALSE);
            diTotalBottles := diTotalBottles + 1;
            eState := ST_READY;
        END_IF;

    // ─── عطل ───
    ST_FAULT:
        bConveyor := FALSE;
        bFillValve := FALSE;
        bCapCylinder := FALSE;

        // إعادة ضبط بعد زوال سبب العطل
        IF bStartBtn AND NOT bEStop AND bThermalOK THEN
            eState := ST_IDLE;
        END_IF;

END_CASE;

// ═══════════════════════════════════════════
// المخارج العامة
// ═══════════════════════════════════════════
bGreenLamp := (eState <> ST_IDLE) AND (eState <> ST_FAULT);
bRedLamp := (eState = ST_FAULT);
fbBuzzerPulse(IN := (eState = ST_FAULT), PT := T#2s);
bBuzzer := fbBuzzerPulse.Q;

// عدّاد الدفعات
IF diTotalBottles MOD iBatchSize = 0 AND diTotalBottles > 0 THEN
    diBatchCount := diTotalBottles / iBatchSize;
END_IF;

شاشة HMI: واجهة المشغّل

الشاشة الرئيسية

┌────────────────────────────────────────────┐
│         نظام التعبئة الآلي - Dr.Machine     │
├────────────────────────────────────────────┤
│                                            │
│  الحالة: [██ جاري التعبئة ██]              │
│                                            │
│  ┌────────┐  ┌────────┐  ┌────────┐       │
│  │ الوزن  │  │ العدد  │  │الدفعات │       │
│  │ 485 غ  │  │  156   │  │   6    │       │
│  └────────┘  └────────┘  └────────┘       │
│                                            │
│  السير: ██ يعمل    الصمام: □ مغلق         │
│  الأسطوانة: □ مرتدة  الحرارة: ✓ طبيعي     │
│                                            │
│  [  بدء  ] [  إيقاف  ] [ إعدادات ]        │
├────────────────────────────────────────────┤
│  آخر إنذار: لا يوجد              14:32:05  │
└────────────────────────────────────────────┘

متغيرات HMI الأساسية

// للعرض على الشاشة
VAR_GLOBAL
    iHMI_State       : INT;        // رقم الحالة
    sHMI_StateName   : STRING(30); // اسم الحالة بالعربية
    rHMI_Weight      : REAL;       // الوزن الحالي
    diHMI_TotalCount : DINT;       // إجمالي الإنتاج
    diHMI_BatchCount : DINT;       // عدد الدفعات
    rHMI_PartsPerMin : REAL;       // معدل الإنتاج
END_VAR

// أسماء الحالات للعرض
CASE eState OF
    ST_IDLE:      sHMI_StateName := 'خامل';
    ST_READY:     sHMI_StateName := 'جاهز';
    ST_FILLING:   sHMI_StateName := 'جاري التعبئة';
    ST_CAPPING:   sHMI_StateName := 'إغلاق الغطاء';
    ST_EJECT:     sHMI_StateName := 'إخراج';
    ST_FAULT:     sHMI_StateName := 'عطل!';
END_CASE;

الاختبار والتشغيل التجريبي

مراحل الاختبار

اختبار المداخل/المخارج (I/O Test)

قبل تشغيل البرنامج، تحقق من كل مدخل ومخرج يدوياً:

قائمة فحص I/O:
□ I0.0: اضغط زر البدء → LED يضيء في جدول المراقبة
□ I0.1: اضغط زر الإيقاف → LED يضيء
□ I0.2: فعّل الطوارئ → LED يضيء
□ I0.3: ضع جسم أمام حسّاس الدخول → LED يضيء
□ I0.4: ضع جسم أمام حسّاس الموضع → LED يضيء
□ Q0.0: فعّل من جدول المراقبة → السير يعمل
□ Q0.1: فعّل من جدول المراقبة → الصمام يفتح
□ Q0.2: فعّل من جدول المراقبة → الأسطوانة تمتد

اختبار التسلسل خطوة بخطوة

// وضع الاختبار اليدوي: تقدّم خطوة بخطوة
VAR
    bManualMode  : BOOL;      // تفعيل الوضع اليدوي
    bStepForward : BOOL;      // تقدّم للمرحلة التالية
END_VAR

IF bManualMode AND bStepForward THEN
    CASE eState OF
        ST_IDLE:      eState := ST_READY;
        ST_READY:     eState := ST_BOTTLE_IN;
        ST_BOTTLE_IN: eState := ST_FILLING;
        ST_FILLING:   eState := ST_FILL_DONE;
        ST_FILL_DONE: eState := ST_CAPPING;
        ST_CAPPING:   eState := ST_CAP_DONE;
        ST_CAP_DONE:  eState := ST_EJECT;
        ST_EJECT:     eState := ST_READY;
    END_CASE;
END_IF;

قائمة التحقق قبل التشغيل النهائي

□ جميع حسّاسات الطوارئ تعمل وتوقف النظام فوراً
□ الحماية الحرارية للمحرك مضبوطة على التيار الصحيح
□ المهلات الزمنية (Timeouts) مناسبة لسرعة الخط الفعلية
□ ضغط الهواء كافٍ لتشغيل الأسطوانة
□ الصمام يُغلق تماماً (لا تسريب)
□ العدّاد يعدّ بشكل صحيح
□ شاشة HMI تعرض جميع البيانات بشكل صحيح
□ الإنذارات تظهر وتُسجّل
□ وضع الاختبار اليدوي يعمل
□ النسخة الاحتياطية محفوظة

الخلاصة والخطوات القادمة

في هذه السلسلة من 12 درساً، غطّينا أساسيات برمجة PLC من المفاهيم الأولية إلى مشروع تعبئة متكامل:

  • الدروس 1-2: مفهوم PLC ومكوناته المادية
  • الدروس 3-4: لغتا البرمجة الأساسيتان (Ladder Logic و Structured Text)
  • الدروس 5-7: أنواع البيانات والمؤقتات والكتل الوظيفية
  • الدروس 8-9: المعالجة التناظرية والتحكم بالمحركات
  • الدروس 10-11: الاتصالات الصناعية وتشخيص الأعطال
  • الدرس 12: مشروع تطبيقي متكامل

للتعمّق أكثر

  • التحكم PID: ضبط الحرارة والضغط والتدفق بدقة
  • شبكات الأمان: Safety PLC ومعايير SIL/ISO 13849
  • SCADA: أنظمة المراقبة والتحكم عن بعد
  • Industry 4.0: ربط PLC بالسحابة وتحليل البيانات
  • الروبوتات الصناعية: التكامل بين PLC والروبوت

المعرفة النظرية مهمة، لكن الخبرة الحقيقية تأتي من الممارسة العملية. ابدأ بمشاريع صغيرة وتدرّج في التعقيد.

project packaging sequence HMI commissioning automation-project مشروع تطبيقي التعبئة التسلسل شاشة التشغيل التشغيل التجريبي النظام الكامل