SCL编程
用SCL写一个配料的程序:1、物料共8种,根据物料的重量配方配料;2、共有一个原料称;3、配料过程按快速,慢速,点补执行;4、当前配料重量到达偏差允许后进入下一物料的配;4、配料完成记录每种物料最终配料的实际重量;5、要求可以设置8个配方。以下是一个简单的SCL程序示例,用于配料过程的控制:
FUNCTION_MATERIAL_MIXING : FUNCTION_BLOCK
VAR_INPUT
Fast_Speed_Time : TIME; // 快速模式下每个物料称重所需的时间
Slow_Speed_Time : TIME; // 慢速模式下每个物料称重所需的时间
Point_Comp_Time : TIME; // 点补模式下每个物料称重所需的时间
Recipe_Count : INT; // 配方数量
Material_Count : INT; // 物料种类数量
Material_Weight : ARRAY OF REAL; // 每个物料的重量
Recipe : ARRAY OF REAL; // 每个配方中每个物料的重量
Allowable_Error : REAL; // 允许的偏差值
END_VAR
VAR_OUTPUT
Material_Weight_Result : ARRAY OF REAL; // 实际称重得到的每个物料的重量
END_VAR
VAR
Current_Recipe_Index : INT := 1; // 当前使用的配方编号
Current_Material_Index : INT := 1; // 当前使用的物料编号
Mixing_Speed : INT := 0; // 当前混合速度(0:停止,1:快速,2:慢速,3:点补)
Mixing_Timer : TON; // 称重计时器
Mixing_Error : REAL; // 当前秤重的误差值
Material_Weight_Temp : REAL; // 当前物料的重量暂存值
Recipe_Target_Weight : REAL; // 当前配方所需的总重量
Recipe_Material_Weight : ARRAY OF REAL; // 当前配方中每个物料需要的重量
END_VAR
Mixing_Timer(IN:=TRUE, PT:=Mixing_Speed_Time);
CASE Mixing_Speed OF
0:// 暂停状态
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 1;
END_IF
1:// 快速模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 2;
END_IF
2:// 慢速模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 3;
END_IF
3:// 点补模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 0;
Material_Weight_Temp := Scale_Read(); // 读取当次称出的物料重量
Mixing_Error := ABS(Material_Weight_Temp - Recipe_Material_Weight); // 计算偏差值
IF Mixing_Error <= Allowable_Error THEN // 偏差值在允许范围内,记录当前物料的称重结果
Material_Weight_Result := Material_Weight_Temp;
ELSE // 偏差值超出允许范围,重复此次物料的配制
Mixing_Speed := 3;
END_IF
IF Current_Material_Index = Material_Count THEN // 当前配制完成,进入下一个配方或结束程序
Recipe_Target_Weight := 0;
FOR i:=1 TO Material_Count DO
Recipe_Target_Weight := Recipe_Target_Weight + Recipe_Material_Weight;
END_FOR
IF ABS(Recipe_Target_Weight - Total_Material_Weight) <= Allowable_Error THEN // 配方总重量在允许范围内,记录当前配方的结果,进入下一个配方(如有)
FOR i:=1 TO Material_Count DO
Material_Weight := Material_Weight_Result;
END_FOR
IF Current_Recipe_Index < Recipe_Count THEN // 还有其他配方需要配制
Current_Recipe_Index := Current_Recipe_Index + 1;
Material_Weight_Result := 0; // 清空记录本次配制的实际物料重量
Mixing_Speed := 1;
ELSE // 所有配方均已配制完成
// 完成配方过程后的处理
END_IF
ELSE // 配方总重量不在允许范围内,重复此次配方的配制
Mixing_Speed := 1;
END_IF
Current_Material_Index := 1;
ELSE // 当前配制未完成,继续下个物料的配制
Current_Material_Index := Current_Material_Index + 1;
Mixing_Speed := 1; // 回到快速模式
END_IF
END_IF
END_CASE
Recipe_Material_Weight := Recipe;
Mixing_Timer(IN:=TRUE, PT:=Fast_Speed_Time); // 初始化计时器,开始快速称重
Mixing_Speed := 1; // 进入快速模式
END_FUNCTION_BLOCK
需要注意的是,此程序仅为示例,其中的具体细节和实现方式可能会因不同的硬件设备和环境而有所区别。建议参照具体设备的文档和说明,进行相应的修改和调整。 称的实际重量不会清零采用累加的形式完成 liudeng 发表于 2023-04-12 14:02
称的实际重量不会清零采用累加的形式完成 ...
如果称的实际重量不会在每次称重后自动清零,那么可以通过进行累加的方式,计算出每个物料的实际重量。下面是一个修改后的SCL程序示例:
FUNCTION_MATERIAL_MIXING : FUNCTION_BLOCK
VAR_INPUT
Fast_Speed_Time : TIME; // 快速模式下每个物料称重所需的时间
Slow_Speed_Time : TIME; // 慢速模式下每个物料称重所需的时间
Point_Comp_Time : TIME; // 点补模式下每个物料称重所需的时间
Recipe_Count : INT; // 配方数量
Material_Count : INT; // 物料种类数量
Recipe : ARRAY OF REAL; // 8个配方中每个物料的重量
Allowable_Error : REAL; // 允许的偏差值
END_VAR
VAR_OUTPUT
Material_Weight_Result : ARRAY OF REAL; // 实际称重得到的每个物料的重量
END_VAR
VAR
Current_Recipe_Index : INT := 1; // 当前使用的配方编号
Current_Material_Index : INT := 1; // 当前使用的物料编号
Mixing_Speed : INT := 0; // 当前混合速度(0:停止,1:快速,2:慢速,3:点补)
Mixing_Timer : TON; // 称重计时器
Mixing_Error : REAL := 0.0; // 当前秤重的误差值
Material_Weight_Temp : REAL := 0.0; // 当前物料的重量暂存值
Recipe_Target_Weight : REAL := 0.0; // 当前配方所需的总重量
Recipe_Material_Weight : ARRAY OF REAL; // 当前配方中每个物料需要的重量
Total_Material_Weight : REAL := 0.0; // 每次称重后实际重量的累加值
END_VAR
Mixing_Timer(IN:=TRUE, PT:=Fast_Speed_Time);
CASE Mixing_Speed OF
0:// 暂停状态
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 1;
END_IF
1:// 快速模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 2;
END_IF
2:// 慢速模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 3;
END_IF
3:// 点补模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 0;
Material_Weight_Temp := Material_Weight_Temp + Scale_Read(); // 将本次称重得到的重量累加到暂存值上
Mixing_Error := ABS(Material_Weight_Temp - Recipe_Material_Weight); // 计算偏差值
IF Mixing_Error &lt;= Allowable_Error THEN // 偏差值在允许范围内,记录当前物料的称重结果
Total_Material_Weight := Total_Material_Weight + Material_Weight_Temp; // 累加实际重量
Material_Weight_Result := Total_Material_Weight;// 记录当前物料的实际重量
ELSE // 偏差值超出允许范围,重复此次物料的配制
Mixing_Speed := 3;
END_IF
IF Current_Material_Index = Material_Count THEN // 当前配制完成,进入下一个配方或结束程序
Recipe_Target_Weight := 0;
FOR i:=1 TO Material_Count DO
Recipe_Target_Weight := Recipe_Target_Weight + Recipe_Material_Weight;
END_FOR
IF ABS(Recipe_Target_Weight - Total_Material_Weight) &lt;= Allowable_Error THEN // 配方总重量在允许范围内,记录当前配方的结果,进入下一个配方(如有)
FOR i:=1 TO Material_Count DO
Recipe := Material_Weight_Result; liudeng 发表于 2023-04-12 14:02
称的实际重量不会清零采用累加的形式完成 ...
好的,以下是一个修改后的SCL程序示例,用于配料过程的控制:
FUNCTION_MATERIAL_MIXING : FUNCTION_BLOCK
VAR_INPUT
Fast_Speed_Time : TIME; // 快速模式下每个物料称重所需的时间
Slow_Speed_Time : TIME; // 慢速模式下每个物料称重所需的时间
Point_Comp_Time : TIME; // 点补模式下每个物料称重所需的时间
Recipe_Count : INT; // 配方数量
Material_Count : INT; // 物料种类数量
Recipe : ARRAY OF ARRAY OF REAL; // 8个配方中每个物料的重量
Allowable_Error : REAL; // 允许的偏差值
END_VAR
VAR_OUTPUT
Material_Weight_Result : ARRAY OF REAL; // 实际称重得到的8种物料的重量
END_VAR
VAR
Current_Recipe_Index : INT := 1; // 当前使用的配方编号
Current_Material_Index : INT := 1; // 当前使用的物料编号
Mixing_Speed : INT := 0; // 当前混合速度(0:停止,1:快速,2:慢速,3:点补)
Mixing_Timer : TON; // 称重计时器
Mixing_Error : REAL; // 当前秤重的误差值
Material_Weight_Temp : REAL; // 当前物料的重量暂存值
Recipe_Target_Weight : REAL; // 当前配方所需的总重量
Recipe_Material_Weight : ARRAY OF REAL; // 当前配方中每个物料需要的重量
END_VAR
Mixing_Timer(IN:=TRUE, PT:=Fast_Speed_Time); // 初始化计时器,开始快速称重
Mixing_Speed := 1; // 进入快速模式
WHILE Current_Recipe_Index <= Recipe_Count DO // 遍历所有配方
Recipe_Material_Weight := Recipe; // 载入当前配方占比
Recipe_Target_Weight := 0; // 初始化当前配方所需总重量
FOR j:=1 TO Material_Count DO // 计算当前配方所需总重量
Recipe_Target_Weight := Recipe_Target_Weight + Recipe_Material_Weight;
END_FOR
WHILE ABS(Recipe_Target_Weight - Material_Weight_Result) > Allowable_Error DO// 等待目标重量的达成
CASE Mixing_Speed OF
0:// 暂停状态
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 1;
END_IF
1:// 快速模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 2;
END_IF
2:// 慢速模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 3;
END_IF
3:// 点补模式
IF Mixing_Timer.Q THEN
Mixing_Timer(IN:=FALSE);
Mixing_Speed := 0;
Material_Weight_Temp := Scale_Read(); // 读取当次称出的物料重量
Mixing_Error := ABS(Material_Weight_Temp - Recipe_Material_Weight); // 计算偏差值
IF Mixing_Error <= Allowable_Error THEN // 偏差值在允许范围内,记录当前物料的称重结果
Material_Weight_Result := Material_Weight_Result + Material_Weight_Temp;
Current_Material_Index := Current_Material_Index + 1; // 当前物料编号加一
IF Current_Material_Index > Material_Count THEN // 当前配制完成,记录实际称重得到的每个物料的重量
FOR i:=1 TO Material_Count DO
Material_Weight_Result := Material_Weight_Result + Material_Weight_Result;
END_FOR
Current_Material_Index := 1;
Mixing_Speed := 1; // 进入快速模式
ELSE
Mixing_Speed := 3; // 继续点补模式,处理 负偏差时继续当前物料的配置,出现正偏差且超过允许范围则停止配置,显示偏差值,提示是否继续 liudeng 发表于 2023-04-12 14:15
负偏差时继续当前物料的配置,出现正偏差且超过允许范 ...
好的,以下是一个修改后的SCL程序示例,用于配料过程的控制:
FUNCTION_MATERIAL_MIXING : FUNCTION_BLOCK
VAR_INPUT
Fast_Speed_Time : TIME; // 快速模式下每个物料称重所需的时间
Slow_Speed_Time : TIME; // 慢速模式下每个物料称重所需的时间
Point_Speed_Time: TIME; // 点补模式下每个物料称重所需的时间
Target_Weight : ARRAY OF REAL; // 各物料的目标重量
Allow_Deviation : REAL; // 允许的偏差范围
END_VAR
VAR_OUTPUT
Actual_Weight : ARRAY OF REAL; // 各物料的实际重量
END_VAR
VAR
Current_Material: USINT; // 当前物料编号
Current_Mode : USINT; // 当前配料模式
Current_Weight : REAL; // 当前物料称重值
Target_Weight_Pos : USINT; // 目标重量数组中的位置
Allow_Negative_Deviation : BOOL; // 是否允许负偏差
Allow_Positive_Deviation : BOOL; // 是否允许正偏差
Deviation : REAL; // 当前偏差值
Continue : BOOL; // 是否继续配料
Stop : BOOL; // 是否停止配料
END_VAR
Target_Weight_Pos := 1;
Allow_Negative_Deviation := TRUE;
Allow_Positive_Deviation := TRUE;
Continue := TRUE;
Stop := FALSE;
WHILE (NOT Stop) DO
CASE Current_Mode OF
0: // 快速模式
WAIT FOR Fast_Speed_Time;
1: // 慢速模式
WAIT FOR Slow_Speed_Time;
2: // 点补模式
WAIT FOR Point_Speed_Time;
END_CASE
Current_Weight := Read_Current_Weight(); // 读取当前重量
IF (Current_Weight >= Target_Weight - Allow_Deviation AND
Current_Weight <= Target_Weight + Allow_Deviation) THEN
// 当前偏差在允许范围内
Actual_Weight := Actual_Weight + Current_Weight;
Target_Weight_Pos := Target_Weight_Pos + 1;
Current_Mode := 0;
IF (Target_Weight_Pos > 8) THEN
// 配料完成
Stop := TRUE;
END_IF
ELSE
// 当前偏差超出允许范围
Deviation := Target_Weight - Current_Weight;
IF (Deviation > Allow_Deviation AND Allow_Positive_Deviation) THEN
// 正偏差超出允许范围,继续配料?
Continue := Show_Message("Positive deviation is too large, do you want to continue?", YES_NO);
IF (NOT Continue) THEN
// 停止配料
Stop := TRUE;
END_IF
ELSIF (Deviation < -Allow_Deviation AND Allow_Negative_Deviation) THEN
// 负偏差超出允许范围,继续当前物料的配料
Actual_Weight := Actual_Weight + Current_Weight;
ELSE
// 停止配料
Stop := TRUE;
END_IF
END_IF
END_WHILE
END_FUNCTION_BLOCK
注意:需要根据实际情况进行修改和调整。 配料开始为快速模式,距离当前物料目标重量差值A时转慢速模式,距离目标重量差值B时转为点补模式 liudeng 发表于 2023-04-12 14:31
配料开始为快速模式,距离当前物料目标重量差值A时转 ...
好的,以下是一个修改后的SCL程序示例,用于配料过程的控制:
FUNCTION_MATERIAL_MIXING : FUNCTION_BLOCK
VAR_INPUT
Fast_Speed_Time : TIME; // 快速模式下每个物料称重所需的时间
Slow_Speed_Time : TIME; // 慢速模式下每个物料称重所需的时间
PointAdd_Time : TIME; // 点补模式下每个物料称重所需的时间
Allow_Deviation : REAL; // 允许的偏差范围
Switch_Slow_Diff: REAL; // 切换到慢速模式的差值
Switch_Point_Diff : REAL; // 切换到点补模式的差值
END_VAR
VAR_OUTPUT
Material_Weights : ARRAY OF REAL; // 每种物料的实际重量
Mixing_Ok : BOOL; // 配料是否完成
END_VAR
VAR
Current_Material : INT := 1; // 当前正在配置的物料编号
Current_Weight : REAL := 0.0; // 当前物料的累加重量
Target_Weight : REAL := 0.0; // 当前物料的目标重量
Speed_Mode : INT := 1; // 配料速度模式(1:快速,2:慢速,3:点补)
Is_Switching_Speed : BOOL := FALSE; // 是否正在切换速度模式
Is_Switching_Material : BOOL := FALSE; // 是否正在切换物料
Is_Mixing : BOOL := FALSE; // 是否在配料过程中
END_VAR
// 配料开始
IF NOT Is_Mixing THEN
// 初始化配料参数
Current_Material := 1;
Current_Weight := 0.0;
Target_Weight := Formula;
Speed_Mode := 1;
Is_Switching_Speed := FALSE;
Is_Switching_Material := FALSE;
Is_Mixing := TRUE;
END_IF
// 判断当前是否在“切换速度模式”或“切换物料”的过程中
IF Is_Switching_Speed OR Is_Switching_Material THEN
RETURN;
END_IF
// 获取当前物料的实时重量
Current_Weight := Get_Current_Weight();
// 判断当前物料是否达到目标重量
IF ABS(Current_Weight - Target_Weight) <= Allow_Deviation THEN
// 记录当前物料的实际重量
Material_Weights := Current_Weight;
// 判断是否为最后一个物料,如果是则完成配料
IF Current_Material = 8 THEN
Mixing_Ok := TRUE;
Is_Mixing := FALSE;
ELSE
// 切换到下一个物料
Current_Material := Current_Material + 1;
Target_Weight := Formula;
// 重置速度模式为快速模式
Speed_Mode := 1;
Is_Switching_Speed := FALSE;
END_IF
ELSE
// 根据当前速度模式,计算下一个称重所需的时间
VAR Next_Time : TIME := 0;
CASE Speed_Mode OF
1: Next_Time := Fast_Speed_Time;
2: Next_Time := Slow_Speed_Time;
3: Next_Time := PointAdd_Time;
END_CASE
// 判断是否需要切换速度模式
IF NOT Is_Switching_Speed THEN
VAR Diff : REAL := Current_Weight - Target_Weight;
IF ABS(Diff) <= Switch_Slow_Diff AND Speed_Mode < 2 THEN
Speed_Mode := 2;
Is_Switching_Speed := TRUE;
Is_Switching_Material := FALSE;
// 计算切换速度模式时需要等待的时间
Next_Time := ABS(Diff) / (Formula - Current_Weight) * Fast_Speed_Time;
ELSEIF ABS(Diff) <= Switch_Point_Diff AND Speed_Mode < 3 THEN
Speed_Mode := 3;
Is_Switching_Speed := TRUE;
Is_Switching_Material := FALSE;
// 计算切换速度模式时需要等待的时间
Next_Time := ABS(Diff) / (Formula - Current_Weight) * Fast_Speed_Time;
END_IF
END_IF
// 判断是否需要切换物料
IF NOT Is_Switching_Material AND Speed_Mode = 1 AND Current_Weight >= Target_Weight THEN
Is_Switching_Material := TRUE;
// 计算切换物料时需要等待的时间
Next_Time := 5.0; // 假设需要等待5秒钟
END_IF
// 执行下一个称重
IF NOT Is_Switching_Speed AND NOT Is_Switching_Material THEN
Start_Weighting(Next_Time);
END_IF
END_IF
在以上示例中,配料开始时默认为快速模式。当当前物料的实际重量与目标重量之间的差值小于等于切换到慢速模式时的差值(Switch_Slow_Diff)时,程序将自动切换到慢速模式;当该差值小于等于切换到点补模式时的差值(Switch_Point_Diff)时,程序将自动切换到点补模式。在切换速度模式时,程序会根据当前速度模式的进度,计算出需要等待的时间。在执行完一个物料的配料过程后,程序将记录该物料的实际重量,并判断是否需要继续配置下一个物料。如果任意物料的实际重量超过允许的偏差范围,则程序将停止配料并显示偏差值,提示是否继续。
页:
[1]