المؤقتات والعدّادات: التحكم بالزمن والتكرار في خط الإنتاج
المؤقت TON: تأخير عند التشغيل
المؤقت TON (Timer ON Delay) هو الأكثر استخداماً في الأتمتة الصناعية. يُؤخّر تفعيل المخرج بعد تحقق شرط الدخل.
الإعلان والاستخدام
VAR
fbTonDelay : TON; // نسخة من المؤقت
bSensorDetect : BOOL; // حسّاس كشف القطعة
bActivatePress : BOOL; // تشغيل المكبس
END_VAR
fbTonDelay(
IN := bSensorDetect, // شرط البدء
PT := T#2s // المدة المطلوبة
);
bActivatePress := fbTonDelay.Q; // المخرج المؤجّل
مخطط التوقيت
IN: ____████████████████████____
|-- PT --|
Q: ________________█████████____
ET: ____/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾____
IN: شرط التشغيلQ: المخرج - يُفعّل بعد مرور PTET: الزمن المنقضي (Elapsed Time)- إذا انقطع IN قبل انتهاء PT، يُعاد ET إلى صفر
تطبيق: منع الإنذارات الكاذبة
في مصنع تعبئة، حسّاس المستوى قد يتذبذب بسبب أمواج السائل. نستخدم TON لتأكيد أن المستوى فعلاً منخفض لمدة 3 ثوانٍ قبل إطلاق إنذار:
fbLowLevelDelay(IN := bLevelLow, PT := T#3s);
bLowLevelAlarm := fbLowLevelDelay.Q;
المؤقت TOF: تأخير عند الإيقاف
المؤقت TOF (Timer OFF Delay) يُبقي المخرج مُفعّلاً لمدة محددة بعد زوال شرط الدخل.
الإعلان والاستخدام
VAR
fbTofExtend : TOF;
bMotionDetected : BOOL;
bLightOn : BOOL;
END_VAR
fbTofExtend(
IN := bMotionDetected,
PT := T#30s
);
bLightOn := fbTofExtend.Q;
مخطط التوقيت
IN: ____████████____________________
|---- PT ----|
Q: ____████████████████████████____
ET: /‾‾‾‾‾‾‾‾‾‾‾‾‾‾____
Qيُفعّل فوراً مع INQيبقى مُفعّلاً لمدة PT بعد انقطاع IN- إذا عاد IN قبل انتهاء PT، يُعاد ET إلى صفر
تطبيق: تشغيل مضخة تزييت بعد توقف المحرك
// مضخة التزييت تعمل مع المحرك وتستمر 60 ثانية بعد توقفه
fbLubeExtend(IN := bMainMotor, PT := T#60s);
bLubePump := fbLubeExtend.Q;
المؤقت TP: نبضة بمدة محددة
المؤقت TP (Timer Pulse) يُولّد نبضة بمدة ثابتة عند كل حافة صاعدة لإشارة الدخل.
الإعلان والاستخدام
VAR
fbPulse : TP;
bTrigger : BOOL;
bBuzzer : BOOL;
END_VAR
fbPulse(
IN := bTrigger,
PT := T#500ms
);
bBuzzer := fbPulse.Q;
مخطط التوقيت
IN: ____█___█████___█___
|PT| |PT|
Q: ____███_____████___
- عند كل حافة صاعدة لـ IN، تبدأ نبضة بمدة PT
- لا يمكن قطع النبضة حتى لو انقطع IN
- نبضة جديدة لا تبدأ إلا بعد انتهاء السابقة وحافة صاعدة جديدة
تطبيق: صافرة تنبيه عند كل إنذار
// صفّارة تصدر صوتاً لمدة ثانيتين عند كل إنذار جديد
fbAlarmBuzzer(IN := bNewAlarm, PT := T#2s);
bBuzzerOutput := fbAlarmBuzzer.Q;
العدّاد التصاعدي CTU
العدّاد CTU (Counter UP) يزيد بمقدار واحد عند كل حافة صاعدة لإشارة العدّ.
الإعلان والاستخدام
VAR
fbCountUp : CTU;
bPartDetected : BOOL; // حسّاس كشف القطعة
bResetCounter : BOOL; // إعادة ضبط
bBoxFull : BOOL; // الصندوق ممتلئ
iCurrentCount : INT; // العدد الحالي
END_VAR
fbCountUp(
CU := bPartDetected, // نبضة العدّ
RESET := bResetCounter, // إعادة ضبط
PV := 24 // القيمة المستهدفة
);
bBoxFull := fbCountUp.Q; // وصل للهدف
iCurrentCount := fbCountUp.CV; // القيمة الحالية
تطبيق: عدّ زجاجات في صندوق
// 24 زجاجة = صندوق كامل -> دفع الصندوق وبدء صندوق جديد
IF fbCountUp.Q THEN
bPushCylinder := TRUE; // ادفع الصندوق
fbCountUp(RESET := TRUE); // أعد العدّاد
fbCountUp(RESET := FALSE);
diTotalBoxes := diTotalBoxes + 1;
END_IF;
العدّاد التنازلي CTD
العدّاد CTD (Counter DOWN) يبدأ من قيمة محددة وينقص بمقدار واحد عند كل نبضة.
الإعلان والاستخدام
VAR
fbCountDown : CTD;
bDispensePulse : BOOL;
bLoadNewBatch : BOOL;
bBatchEmpty : BOOL;
iRemaining : INT;
END_VAR
fbCountDown(
CD := bDispensePulse, // نبضة الإنقاص
LOAD := bLoadNewBatch, // تحميل قيمة جديدة
PV := 100 // العدد الابتدائي
);
bBatchEmpty := fbCountDown.Q; // وصل للصفر
iRemaining := fbCountDown.CV; // المتبقي
تطبيق: متابعة مخزون صناديق التغليف
// بدء دفعة جديدة: 500 صندوق
// كل مرة يُستهلك صندوق، ينقص العدّاد
// عندما يصل للصفر: إنذار "أعد تعبئة المخزون"
fbBoxInventory(
CD := bBoxUsed,
LOAD := bRefillDone,
PV := 500
);
IF fbBoxInventory.CV <= 50 THEN
bLowStockWarning := TRUE; // تحذير: المخزون منخفض
END_IF;
IF fbBoxInventory.Q THEN
bOutOfStock := TRUE; // نفد المخزون!
bStopLine := TRUE; // أوقف الخط
END_IF;
مثال عملي: عدّ القطع المنتجة مع تأخير بين الدفعات
وصف النظام
خط تغليف ينتج دفعات من 12 قطعة. بعد اكتمال كل دفعة:
- يتوقف السير لمدة 5 ثوانٍ لتبديل الصندوق
- يُعاد العدّاد ويستمر الإنتاج
- تُعرض الإحصائيات على شاشة HMI
PROGRAM BatchProduction
VAR
// المداخل
bPartSensor : BOOL; // حسّاس كشف القطعة
// كتل وظيفية
fbPartCounter : CTU; // عدّاد القطع
fbPauseTimer : TON; // مؤقت التوقف
fbShiftTimer : TON; // مؤقت الوردية
// متغيرات داخلية
iBatchSize : INT := 12; // حجم الدفعة
bBatchComplete : BOOL; // دفعة مكتملة
bPauseActive : BOOL; // توقف نشط
// إحصائيات
diBatchCount : DINT := 0; // عدد الدفعات
diTotalParts : DINT := 0; // إجمالي القطع
rPartsPerMin : REAL; // معدل الإنتاج
END_VAR
// عدّ القطع
fbPartCounter(
CU := bPartSensor AND NOT bPauseActive,
RESET := FALSE,
PV := iBatchSize
);
// التحقق من اكتمال الدفعة
bBatchComplete := fbPartCounter.Q;
IF bBatchComplete AND NOT bPauseActive THEN
bPauseActive := TRUE;
diBatchCount := diBatchCount + 1;
diTotalParts := diTotalParts + iBatchSize;
END_IF;
// مؤقت التوقف بين الدفعات
fbPauseTimer(IN := bPauseActive, PT := T#5s);
IF fbPauseTimer.Q THEN
bPauseActive := FALSE;
fbPartCounter(RESET := TRUE);
fbPartCounter(RESET := FALSE);
END_IF;
// التحكم بالسير
bConveyorRun := NOT bPauseActive;
// حساب معدل الإنتاج (قطعة/دقيقة)
fbShiftTimer(IN := TRUE, PT := T#8h);
IF TIME_TO_REAL(fbShiftTimer.ET) > 0.0 THEN
rPartsPerMin := DINT_TO_REAL(diTotalParts) /
(TIME_TO_REAL(fbShiftTimer.ET) / 60000.0);
END_IF;
الخلاصة
المؤقتات الثلاثة (TON, TOF, TP) والعدّادات (CTU, CTD) هي الأدوات الأكثر استخداماً في برامج PLC. كل مؤقت له سلوك مميز يُناسب تطبيقاً محدداً: TON لتأكيد الإشارات وتأخير التشغيل، TOF لتمديد التشغيل بعد زوال الشرط، وTP لتوليد نبضات ثابتة. الجمع بين المؤقتات والعدّادات يُمكّنك من بناء أنظمة عدّ وتوقيت متطورة. في الدرس القادم سنتعلم كيفية بناء كتل وظيفية قابلة لإعادة الاستخدام.