الرئيسية قاعدة المعرفة الأتمتة والتحكم الكتل الوظيفية: بناء مكونات قابلة لإعادة الاستخدام
الأتمتة والتحكم

الكتل الوظيفية: بناء مكونات قابلة لإعادة الاستخدام

الدالة FUNCTION: حساب بدون ذاكرة

الدالة (FUNCTION) هي وحدة برمجية تستقبل مدخلات وتُرجع نتيجة واحدة. ليس لها ذاكرة: نفس المدخلات تُنتج دائماً نفس المخرج.

مثال: تحويل درجة الحرارة

FUNCTION FC_CelsiusToFahrenheit : REAL
VAR_INPUT
    rCelsius : REAL;
END_VAR

FC_CelsiusToFahrenheit := (rCelsius * 9.0 / 5.0) + 32.0;
END_FUNCTION

مثال: التحويل الخطي (Scaling)

دالة مستخدمة في كل مشروع تقريباً لتحويل القراءة الخام إلى قيمة هندسية:

FUNCTION FC_Scale : REAL
VAR_INPUT
    rRawValue : REAL;    // القيمة الخام (مثلاً 0-27648)
    rRawMin   : REAL;    // الحد الأدنى للخام
    rRawMax   : REAL;    // الحد الأعلى للخام
    rEngMin   : REAL;    // الحد الأدنى الهندسي (مثلاً 0.0)
    rEngMax   : REAL;    // الحد الأعلى الهندسي (مثلاً 100.0)
END_VAR

IF (rRawMax - rRawMin) <> 0.0 THEN
    FC_Scale := ((rRawValue - rRawMin) / (rRawMax - rRawMin))
                * (rEngMax - rEngMin) + rEngMin;
ELSE
    FC_Scale := 0.0;  // حماية من القسمة على صفر
END_IF;
END_FUNCTION

استدعاء الدالة

// تحويل قراءة مستشعر ضغط: 0-27648 -> 0-10 بار
rPressure := FC_Scale(
    rRawValue := INT_TO_REAL(iRawPressure),
    rRawMin := 0.0,
    rRawMax := 27648.0,
    rEngMin := 0.0,
    rEngMax := 10.0
);

كتلة الدالة FUNCTION_BLOCK: حساب مع ذاكرة

كتلة الدالة (FUNCTION_BLOCK) تختلف عن الدالة العادية في أنها تحتفظ بحالتها بين دورات المسح. هذا يجعلها مثالية للمؤقتات والعدّادات والتحكم PID.

مثال: كاشف الحافة الصاعدة

FUNCTION_BLOCK FB_RisingEdge
VAR_INPUT
    bSignal : BOOL;
END_VAR
VAR_OUTPUT
    bPulse : BOOL;
END_VAR
VAR
    bPrevious : BOOL := FALSE;  // ذاكرة الحالة السابقة
END_VAR

bPulse := bSignal AND NOT bPrevious;
bPrevious := bSignal;
END_FUNCTION_BLOCK

الفرق الجوهري

// الدالة: لا ذاكرة، يمكن استدعاؤها مباشرة
rResult := FC_Scale(rRawValue := 1000.0, ...);

// كتلة الدالة: لها ذاكرة، تحتاج إنشاء نسخة
VAR
    fbMyEdge : FB_RisingEdge;  // نسخة (Instance)
END_VAR
fbMyEdge(bSignal := bSensor);  // استدعاء
IF fbMyEdge.bPulse THEN ...    // قراءة المخرج

كل نسخة من كتلة الدالة لها ذاكرتها المستقلة. يمكنك إنشاء عدة نسخ لنفس الكتلة:

VAR
    fbEdge1 : FB_RisingEdge;  // لحسّاس 1
    fbEdge2 : FB_RisingEdge;  // لحسّاس 2
END_VAR

البرنامج PROGRAM: المستوى الأعلى

البرنامج (PROGRAM) هو المستوى الأعلى الذي يُنفّذه PLC مباشرة. يحتوي على المنطق الرئيسي ويستدعي الدوال والكتل الوظيفية.

PROGRAM PLC_PRG
VAR
    // نسخ الكتل الوظيفية
    fbMotor1   : FB_MotorControl;
    fbMotor2   : FB_MotorControl;
    fbFillCtrl : FB_FillControl;

    // متغيرات البرنامج
    eSystemState : E_SystemState := IDLE;
END_VAR

// استدعاء كتل التحكم بالمحركات
fbMotor1(
    bStart := bStartBtn AND (eSystemState = RUNNING),
    bStop := bStopBtn OR (eSystemState = FAULTED),
    bEStop := bEmergencyStop
);

fbMotor2(
    bStart := fbMotor1.bRunning,  // المحرك 2 يعمل بعد 1
    bStop := bStopBtn,
    bEStop := bEmergencyStop
);

التسلسل الهرمي

PROGRAM (برنامج رئيسي)
  ├── FUNCTION_BLOCK (كتل وظيفية - لها ذاكرة)
  │     ├── FUNCTION_BLOCK (كتل متداخلة)
  │     └── FUNCTION (دوال مساعدة)
  └── FUNCTION (حسابات بسيطة)

بناء كتلة وظيفية للتحكم بمحرك

تصميم الكتلة

FUNCTION_BLOCK FB_MotorControl
VAR_INPUT
    bStart      : BOOL;       // أمر التشغيل
    bStop       : BOOL;       // أمر الإيقاف
    bEStop      : BOOL;       // إيقاف طوارئ
    bReset      : BOOL;       // إعادة ضبط العطل
    tStartDelay : TIME := T#0s; // تأخير بدء التشغيل
END_VAR
VAR_OUTPUT
    bRunning    : BOOL;       // المحرك يعمل
    bFaulted    : BOOL;       // حالة عطل
    bReady      : BOOL;       // جاهز للتشغيل
    tRunTime    : TIME;       // زمن التشغيل التراكمي
END_VAR
VAR
    bLatch      : BOOL;       // قفل ذاتي داخلي
    fbDelayOn   : TON;        // مؤقت تأخير التشغيل
    fbRunTimer  : TON;        // مؤقت زمن التشغيل
    bThermalTrip: BOOL;       // حماية حرارية
END_VAR

// كشف العطل
IF bEStop OR bThermalTrip THEN
    bFaulted := TRUE;
    bLatch := FALSE;
END_IF;

// إعادة ضبط العطل
IF bReset AND NOT bEStop AND NOT bThermalTrip THEN
    bFaulted := FALSE;
END_IF;

// حالة الجاهزية
bReady := NOT bFaulted AND NOT bEStop;

// منطق التشغيل
IF bStart AND bReady THEN
    bLatch := TRUE;
ELSIF bStop OR bFaulted THEN
    bLatch := FALSE;
END_IF;

// تأخير التشغيل
fbDelayOn(IN := bLatch, PT := tStartDelay);
IF tStartDelay > T#0s THEN
    bRunning := fbDelayOn.Q;
ELSE
    bRunning := bLatch;
END_IF;

// حساب زمن التشغيل
fbRunTimer(IN := bRunning, PT := T#24h);
tRunTime := fbRunTimer.ET;
END_FUNCTION_BLOCK

المكتبات: إعادة استخدام الكتل بين المشاريع

المكتبة (Library) هي مجموعة من الدوال والكتل الوظيفية المُختبرة التي تُضاف لأي مشروع جديد.

تنظيم المكتبة

MyFactoryLib/
├── Motors/
│   ├── FB_MotorControl        // تحكم محرك أساسي
│   ├── FB_MotorVFD            // تحكم عبر محول تردد
│   └── FB_StarDelta           // تشغيل نجمة-مثلث
├── Sensors/
│   ├── FC_Scale               // تحويل خطي
│   ├── FB_AnalogInput         // معالجة مدخل تناظري
│   └── FB_SensorDiag          // تشخيص أعطال المستشعر
├── Valves/
│   ├── FB_OnOffValve          // صمام تشغيل/إيقاف
│   └── FB_ProportionalValve   // صمام تناسبي
└── Utilities/
    ├── FB_AlarmHandler        // إدارة الإنذارات
    ├── FC_Clamp               // تحديد القيمة ضمن نطاق
    └── FB_DataLogger          // تسجيل البيانات

فوائد المكتبات

  • توحيد: نفس الكود في كل مشروع
  • جودة: كود مُختبر ومُثبت في الميدان
  • سرعة: مشروع جديد يبدأ بأساس متين
  • صيانة: تحديث المكتبة يُفيد كل المشاريع

مثال عملي: مكتبة تحكم خاصة بمصنعك

دالة تحديد النطاق (Clamp)

FUNCTION FC_Clamp : REAL
VAR_INPUT
    rValue : REAL;
    rMin   : REAL;
    rMax   : REAL;
END_VAR

IF rValue < rMin THEN
    FC_Clamp := rMin;
ELSIF rValue > rMax THEN
    FC_Clamp := rMax;
ELSE
    FC_Clamp := rValue;
END_IF;
END_FUNCTION

كتلة مراقبة عتبات المستشعر

FUNCTION_BLOCK FB_ThresholdMonitor
VAR_INPUT
    rValue     : REAL;
    rHighHigh  : REAL := 100.0;
    rHigh      : REAL := 80.0;
    rLow       : REAL := 20.0;
    rLowLow    : REAL := 0.0;
    tDelay     : TIME := T#2s;
END_VAR
VAR_OUTPUT
    bAlarmHH   : BOOL;    // إنذار مرتفع جداً
    bAlarmH    : BOOL;    // إنذار مرتفع
    bAlarmL    : BOOL;    // إنذار منخفض
    bAlarmLL   : BOOL;    // إنذار منخفض جداً
    iAlarmCount: INT;     // عدد الإنذارات النشطة
END_VAR
VAR
    fbDelayHH  : TON;
    fbDelayH   : TON;
    fbDelayL   : TON;
    fbDelayLL  : TON;
END_VAR

fbDelayHH(IN := rValue >= rHighHigh, PT := tDelay);
fbDelayH(IN := rValue >= rHigh, PT := tDelay);
fbDelayL(IN := rValue <= rLow, PT := tDelay);
fbDelayLL(IN := rValue <= rLowLow, PT := tDelay);

bAlarmHH := fbDelayHH.Q;
bAlarmH := fbDelayH.Q;
bAlarmL := fbDelayL.Q;
bAlarmLL := fbDelayLL.Q;

iAlarmCount := BOOL_TO_INT(bAlarmHH) + BOOL_TO_INT(bAlarmH)
             + BOOL_TO_INT(bAlarmL) + BOOL_TO_INT(bAlarmLL);
END_FUNCTION_BLOCK

الخلاصة

الدوال (FUNCTION) للحسابات بدون ذاكرة، والكتل الوظيفية (FUNCTION_BLOCK) للتحكم مع ذاكرة. بناء مكتبة كتل وظيفية مُختبرة يُسرّع تطوير المشاريع الجديدة ويرفع جودة الكود. في الدرس القادم سنستخدم هذه المفاهيم لمعالجة الإشارات التناظرية وبناء كتلة متكاملة لقراءة المستشعرات.

function-block FB FC encapsulation library reuse الكتلة الوظيفية الدالة التغليف المكتبة إعادة الاستخدام التنظيم