如何在 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) 我如何知道函数块内部 EN
是 HIGh
或者我如何访问该变量?
2) 我无法将线圈连接到我的 Q
输出。它只连接到 ENO
。我如何控制 ENO
的状态?
但这还不是全部。我添加了时间和日期库
但我发现唯一可以处理时间的是 RTCLK.GetDateAndTime
功能块。而且我不知道如何使用它。
我的简单任务是仅获取当前时间和星期几,如果启用了本周并且当前时间在输入范围内 T1
- make Q
= HIGH
否则 LOW
.
有什么提示吗?
编写一个函数块如下,循环调用(例如每 60 秒):
- 在开始时重置您的控制位(如果
当前日期和时间在您指定的时间间隔内)
- 读取系统时钟的当前日期和当前时间
CPU(控制器)
- 提取实际时间和实际日期。检查实际时间是否为
在您指定的时间间隔内(例如 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 *)
我正在尝试完成非常简单的任务,但看起来我不知道该怎么做。
我的任务是日程安排。从 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) 我如何知道函数块内部 EN
是 HIGh
或者我如何访问该变量?
2) 我无法将线圈连接到我的 Q
输出。它只连接到 ENO
。我如何控制 ENO
的状态?
但这还不是全部。我添加了时间和日期库
但我发现唯一可以处理时间的是 RTCLK.GetDateAndTime
功能块。而且我不知道如何使用它。
我的简单任务是仅获取当前时间和星期几,如果启用了本周并且当前时间在输入范围内 T1
- make Q
= HIGH
否则 LOW
.
有什么提示吗?
编写一个函数块如下,循环调用(例如每 60 秒):
- 在开始时重置您的控制位(如果 当前日期和时间在您指定的时间间隔内)
- 读取系统时钟的当前日期和当前时间 CPU(控制器)
- 提取实际时间和实际日期。检查实际时间是否为 在您指定的时间间隔内(例如 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 *)