如何在 Codesys 3.5 中的 ST 自定义功能块中实时工作

How to work with real time in custom function block on ST in Codesys 3.5

我正在尝试完成非常简单的任务,但看起来我不知道该怎么做。

我的任务是日程安排。从 1:00 到 2:00 每天输出 Q1 必须是 HIGH。我找不到对我有帮助的功能块。我决定创建自己的。

这是我的定义。

FUNCTION_BLOCK Shedule
VAR_INPUT
    EN: BOOL;

    MO: INT;
    TU: INT;
    WE: INT;
    TH: INT;
    FR: INT;
    SA: INT;
    SU: INT;

    T1: STRING;
END_VAR
VAR_OUTPUT
    Q: BOOL;
END_VAR

思路是这样的。 EN 已输入。输出 Q 也应该是 HIGH 也变成 HIGH

其他是星期几。如果我想在那天安排工作,我可以设置 1 或 0。非常通用的功能块,可以创建任何类型的日程表。

问题 1:当我将工作日变量类型设置为 BOOL 时,当我将块添加到 LD 行时,它会为每个工作日参数创建联系人。

怎样才能让线路只连接EN个联系人?

如果我尝试用EN/ENO添加功能块,那么我不知道

1) 我如何知道函数块内部 ENHIGh 或者我如何访问该变量? 2) 我无法将线圈连接到我的 Q 输出。它只连接到 ENO。我如何控制 ENO 的状态?

但这还不是全部。我添加了时间和日期库

但我发现唯一可以处理时间的是 RTCLK.GetDateAndTime 功能块。而且我不知道如何使用它。

我的简单任务是仅获取当前时间和星期几,如果启用了本周并且当前时间在输入范围内 T1 - make Q = HIGH 否则 LOW.

有什么提示吗?

编写一个函数块如下,循环调用(例如每 60 秒):

  1. 在开始时重置您的控制位(如果 当前日期和时间在您指定的时间间隔内)
  2. 读取系统时钟的当前日期和当前时间 CPU(控制器)
  3. 提取实际时间和实际日期。检查实际时间是否为 在您指定的时间间隔内(例如 1:00 到 2:00)并设置您的控制位 合适

您应该使用库函数来处理日期和时间值。也许您应该查看免费图书馆 OSCAT BASIC。该网站是德文的,但文档和软件是英文的。

本例用于读取plc时间并转换为字符串。此代码是为带有 SCL(结构化控制语言)的西门子 PLC 开发的:

(*************************************************************************************)

FUNCTION  FC11 : STRING

TITLE = 'Convert date and time to string'


(*******************************************************************************

 FUNCTION: Convert date and time to string

*******************************************************************************)

// ------------------------------------------------------------------------------
// parameter
// ------------------------------------------------------------------------------

VAR_TEMP

DTAsString          : STRING[14];

DateTime            : DATE_AND_TIME;
DateTimeAsByteArray AT DateTime
                    : ARRAY[0..7] OF BYTE;

ReturnValue         : INT;

Year                : INT;
Month               : INT;
Day                 : INT;
Hours               : INT;
Minutes             : INT;
Seconds             : INT;

END_VAR

// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------

//Inizialize 
DTAsString  := '';

//Read PLC date and time 
ReturnValue := READ_CLK(CDT := DateTime  // OUT: DATE_AND_TIME
                        );

//Split data and time value    
Year        := BCD_TO_INT(DateTimeAsByteArray[0]);
Month       := BCD_TO_INT(DateTimeAsByteArray[1]);
Day         := BCD_TO_INT(DateTimeAsByteArray[2]);
Hours       := BCD_TO_INT(DateTimeAsByteArray[3]);
Minutes     := BCD_TO_INT(DateTimeAsByteArray[4]);
Seconds     := BCD_TO_INT(DateTimeAsByteArray[5]);

//Build string
//------------

//Year
//----
IF (Year >= 10) THEN
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '20');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= INT_TO_STRING(Year),L:=2));
ELSE
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '200');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= INT_TO_STRING(Year),L:=1));    
END_IF;    

//Month
//-----
IF (Month >= 10) THEN     
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= INT_TO_STRING(Month),L:=2));
ELSE
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '0');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= INT_TO_STRING(Month),L:=1));        
END_IF;

//Day
//---
IF (Day >= 10) THEN
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Day),L:=2));
ELSE
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '0');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Day),L:=1));
END_IF;

//Hours
//-----
IF (Hours >= 10) THEN
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Hours),L:=2));
ELSE
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '0');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Hours),L:=1));
END_IF;

//Minutes
//-------
IF (Minutes >= 10) THEN
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Minutes),L:=2));
ELSE
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '0');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Minutes),L:=1));
END_IF;

//Seconds
//-------
IF (Seconds >= 10) THEN
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Seconds),L:=2));
ELSE
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= '0');
    DTAsString :=  CONCAT (IN1:= DTAsString, IN2:= RIGHT(IN:= I_STRNG(Seconds),L:=1));
END_IF;

//Return Date and Time as String
//------------------------------    
FC11 := DTAsString;

END_FUNCTION

//*******************************************************************************

(* Nothing beyond this *)