PLC论坛-全力打造可编程控制器专业技术论坛

 找回密码
 注册哦

QQ登录

只需一步,快速开始

微信扫码登录

查看: 41267|回复: 0

[三菱] 国产大模型Chat对PLC的ST语言的逻辑编写能力对比.

[复制链接]
发表于 2024-8-8 09:27:51 | 显示全部楼层 |阅读模式
话不多说,准备好提问的问题,我们直接看结果;这次准备对比文心一言,星火大模型,通义前问这三个国产模式。以下是提问主题:

问题一:你会PLC的ST编程吗?

问题二:路口有三盏灯,分别是红灯,绿灯,黄灯,请用ST语言写一段这样的逻辑程序,红灯亮10秒,黄灯亮2秒,然后绿灯亮8秒,依次循环。

    首先看通义千问的结果:



代码如下:
VAR
2    timer_red : TON;   // 定时器用于红灯
3    timer_yellow : TON; // 定时器用于黄灯
4    timer_green : TON;  // 定时器用于绿灯
5    state : INT;       // 当前状态变量:1 - 红灯,2 - 黄灯,3 - 绿灯
6    cycle_start : BOOL; // 循环开始标志
7
8PROGRAM MAIN
9BEGIN
10    (* 初始化 *)
11    state := 1; // 初始状态为红灯
12    timer_red.IN := TRUE;  // 启动红灯定时器
13    timer_yellow.IN := FALSE;
14    timer_green.IN := FALSE;
15    cycle_start := TRUE;
16
17    (* 主循环 *)
18    WHILE TRUE DO
19        CASE state OF
20            1: // 红灯阶段
21                IF timer_red.Q THEN  // 红灯定时时间到
22                    timer_red.IN := FALSE;  // 停止红灯定时器
23                    timer_yellow.IN := TRUE; // 启动黄灯定时器
24                    state := 2;
25                END_IF;
26
27            2: // 黄灯阶段
28                IF timer_yellow.Q THEN  // 黄灯定时时间到
29                    timer_yellow.IN := FALSE; // 停止黄灯定时器
30                    timer_green.IN := TRUE;   // 启动绿灯定时器
31                    state := 3;
32                END_IF;
33
34            3: // 绿灯阶段
35                IF timer_green.Q THEN  // 绿灯定时时间到
36                    timer_green.IN := FALSE; // 停止绿灯定时器
37                    cycle_start := TRUE;     // 准备重新开始下一个周期
38                    state := 1;             // 回到红灯阶段
39                END_IF;
40        END_CASE;
41
42        (* 当一个完整周期结束时重新启动计时器 *)
43        IF (timer_red.Q AND timer_yellow.Q AND timer_green.Q) AND cycle_start THEN
44            timer_red.IN := TRUE;
45            timer_yellow.PT := T#10S; // 设置红灯持续时间
46            timer_yellow.IN := FALSE;
47            timer_green.PT := T#2S;  // 设置黄灯持续时间
48            timer_green.IN := FALSE;
49            cycle_start := FALSE;
50        END_IF;
51    END_WHILE;

52END_PROGRAM

从上述代码来看,不需要死循环且TON没有实例化;

第2次对通义提问:



代码如下:
VAR
2    timer_red : TON;   // 定时器用于红灯
3    timer_yellow : TON; // 定时器用于黄灯
4    timer_green : TON;  // 定时器用于绿灯
5    state : INT;       // 当前状态变量:1 - 红灯,2 - 黄灯,3 - 绿灯
6
7PROGRAM MAIN
8BEGIN
9    (* 初始化 *)
10    state := 1;
11
12    (* 状态机循环 *)
13    WHILE TRUE DO
14        CASE state OF
15            1: // 红灯阶段
16                timer_red.PT := T#10S; // 设置红灯时间为10秒
17                timer_red.IN := TRUE;
18                IF timer_red.Q THEN  // 红灯定时时间到
19                    timer_red.IN := FALSE;
20                    state := 2;
21                END_IF;
22
23            2: // 黄灯阶段
24                timer_yellow.PT := T#2S; // 设置黄灯时间为2秒
25                timer_yellow.IN := TRUE;
26                IF timer_yellow.Q THEN  // 黄灯定时时间到
27                    timer_yellow.IN := FALSE;
28                    state := 3;
29                END_IF;
30
31            3: // 绿灯阶段
32                timer_green.PT := T#8S;  // 设置绿灯时间为8秒
33                timer_green.IN := TRUE;
34                IF timer_green.Q THEN  // 绿灯定时时间到
35                    timer_green.IN := FALSE;
36                    state := 1;         // 回到红灯阶段
37                END_IF;
38        END_CASE;
39    END_WHILE;

40END_PROGRAM

从上述代码来看,不需要死循环且TON没有实例化,几乎没有什么变化。

第3次提问:



代码如下:
VAR
2    timer_red : TON;   // 定时器用于红灯
3    timer_yellow : TON; // 定时器用于黄灯
4    timer_green : TON;  // 定时器用于绿灯
5    state : INT;       // 当前状态变量:1 - 红灯,2 - 黄灯,3 - 绿灯
6
7(* 初始化部分 *)
8initialization
9BEGIN
10    state := 1;
11    timer_red.PT := T#10S;  // 设置红灯初始时间为10秒
12    timer_yellow.PT := T#2S; // 设置黄灯初始时间为2秒
13    timer_green.PT := T#8S;  // 设置绿灯初始时间为8秒
14END_INITIALIZATION;
15
16(* 主程序部分 *)
17program main
18BEGIN
19    (* 在每次扫描时检查当前状态并更新定时器设置 *)
20    CASE state OF
21        1: // 红灯阶段
22            timer_red.IN := TRUE;
23            IF timer_red.Q THEN  // 红灯定时时间到
24                timer_red.IN := FALSE;
25                state := 2;
26                timer_yellow.IN := TRUE;
27            END_IF;
28
29        2: // 黄灯阶段
30            IF timer_yellow.Q THEN  // 黄灯定时时间到
31                timer_yellow.IN := FALSE;
32                state := 3;
33                timer_green.IN := TRUE;
34            END_IF;
35
36        3: // 绿灯阶段
37            IF timer_green.Q THEN  // 绿灯定时时间到
38                timer_green.IN := FALSE;
39                state := 1;         // 回到红灯阶段
40                timer_red.IN := TRUE;
41            END_IF;
42    END_CASE;

43END_PROGRAM

第三次提示后,还是和之前差不多,也许判断的语法相差比较大,逻辑基本上还是看的下去,只是不能直接运行,肯定也不符合IEC61131的规范;

通义千问实测失败。进行下一项。

    接下来我们看星火大模型的表现:

首次提问:



代码如下:

PROGRAM TrafficLightControl

VAR

    RedLight: BOOL; // 红灯

    YellowLight: BOOL; // 黄灯

    GreenLight: BOOL; // 绿灯

    Timer: TON; // 定时器

END_VAR

METHOD ControlTrafficLights

    CASE Timer.Q OF

        0: // 红灯亮10秒

            RedLight := TRUE;

            YellowLight := FALSE;

            GreenLight := FALSE;

            Timer(IN:= NOT Timer.Q, PT:= T#10S);

        1: // 黄灯亮2秒

            RedLight := FALSE;

            YellowLight := TRUE;

            GreenLight := FALSE;

            Timer(IN:= NOT Timer.Q, PT:= T#2S);

        2: // 绿灯亮8秒

            RedLight := FALSE;

            YellowLight := FALSE;

            GreenLight := TRUE;

            Timer(IN:= NOT Timer.Q, PT:= T#8S);

    END_CASE;

END_METHOD

代码分析来看,这个存在TON使用同一个实例的问题,而且也没有看到状态切换;我们需要再次提示;

第二次提问:



第二次的代码如下:

PROGRAM TrafficLightControl

VAR

    RedLight: BOOL; // 红灯

    YellowLight: BOOL; // 黄灯

    GreenLight: BOOL; // 绿灯

    Timer: TON; // 定时器

END_VAR

METHOD ControlTrafficLights

    CASE Timer.Q OF

        0: // 红灯亮10秒

            RedLight := TRUE;

            YellowLight := FALSE;

            GreenLight := FALSE;

            Timer(IN:= NOT Timer.Q, PT:= T#10S);

        1: // 黄灯亮2秒

            RedLight := FALSE;

            YellowLight := TRUE;

            GreenLight := FALSE;

            Timer(IN:= NOT Timer.Q, PT:= T#2S);

        2: // 绿灯亮8秒

            RedLight := FALSE;

            YellowLight := FALSE;

            GreenLight := TRUE;

            Timer(IN:= NOT Timer.Q, PT:= T#8S);

    END_CASE;

END_METHOD

如上所示,代码和上次一模一样,没有任何改善;测试失败,进入一个模型的测试。



  接下来看下文心一言的表现,进行第一次提问:



代码如下:

PROGRAM TrafficLightControl
VAR
    RedLightTimer  : TON; // 红灯计时器
    YellowLightTimer : TON; // 黄灯计时器
    GreenLightTimer  : TON; // 绿灯计时器
    LightState     : INT; // 灯的状态(0=红灯,1=黄灯,2=绿灯)
END_VAR

// 初始化部分
BEGIN
    // 初始化计时器和灯的状态
    RedLightTimer(IN:=FALSE, PT:=T#10s); // 红灯计时器设置为10秒
    YellowLightTimer(IN:=FALSE, PT:=T#2s); // 黄灯计时器设置为2秒
    GreenLightTimer(IN:=FALSE, PT:=T#8s); // 绿灯计时器设置为8秒
    LightState := 0; // 初始状态为红灯
END_BEGIN

// 主逻辑部分
WHILE TRUE DO
    CASE LightState OF
        0: // 红灯状态
            // 红灯亮
            IF RedLightTimer.Q THEN
                // 红灯计时完成,切换到黄灯
                RedLightTimer(IN:=FALSE); // 重置红灯计时器
                YellowLightTimer(IN:=TRUE); // 启动黄灯计时器
                LightState := 1; // 切换到黄灯状态
            END_IF;
        1: // 黄灯状态
            // 黄灯亮
            IF YellowLightTimer.Q THEN
                // 黄灯计时完成,切换到绿灯
                YellowLightTimer(IN:=FALSE); // 重置黄灯计时器
                GreenLightTimer(IN:=TRUE); // 启动绿灯计时器
                LightState := 2; // 切换到绿灯状态
            END_IF;
        2: // 绿灯状态
            // 绿灯亮
            IF GreenLightTimer.Q THEN
                // 绿灯计时完成,切换到红灯
                GreenLightTimer(IN:=FALSE); // 重置绿灯计时器
                RedLightTimer(IN:=TRUE); // 启动红灯计时器
                LightState := 0; // 切换到红灯状态
            END_IF;
    END_CASE;
     
    // 这里可以添加控制灯的输出逻辑
    // 例如:
    // IF LightState = 0 THEN
    //     // 控制红灯输出为ON
    // ELSEIF LightState = 1 THEN
    //     // 控制黄灯输出为ON
    // ELSEIF LightState = 2 THEN
    //     // 控制绿灯输出为ON
    // END_IF;
     
    // 延时或者等待以确保逻辑循环不会过快执行
    // 这通常是通过PLC的扫描周期或者特定的延时指令来实现
    // 在这里我们假设PLC的扫描周期足够慢以支持这个逻辑
END_WHILE;

点评代码:仍然是无法执行的,状态切走后,TON的实例没有扫描,会导致无法继续执行。

第2次提问:



代码如下:

PROGRAM TrafficLightControl
VAR
    // 定时器
    RedLightTimer   : TON; // 红灯定时器
    YellowLightTimer: TON; // 黄灯定时器
    GreenLightTimer : TON; // 绿灯定时器
     
    // 灯光状态
    LightState      : INT; // 1=红灯,2=黄灯,3=绿灯
     
    // 灯光输出(假设连接到PLC的物理输出)
    RedLightOutput  : BOOL; // 红灯输出
    YellowLightOutput: BOOL; // 黄灯输出
    GreenLightOutput: BOOL; // 绿灯输出
     
    // 定时器是否在运行标志
    RedTimerRunning   : BOOL;
    YellowTimerRunning: BOOL;
    GreenTimerRunning : BOOL;
END_VAR

// 初始化
IF NOT RedTimerRunning THEN
    // 只在红灯定时器未运行时设置
    LightState := 1; // 初始状态为红灯
    RedLightTimer(IN:=TRUE, PT:=T#10s); // 红灯定时器设为10秒
    RedTimerRunning := TRUE; // 标记红灯定时器正在运行
    YellowLightTimer(IN:=FALSE); // 黄灯定时器关闭
    GreenLightTimer(IN:=FALSE); // 绿灯定时器关闭
     
    // 设置输出
    RedLightOutput := TRUE;
    YellowLightOutput := FALSE;
    GreenLightOutput := FALSE;
END_IF

// 红灯逻辑
IF LightState = 1 AND RedLightTimer.Q THEN
    // 红灯时间到,切换到黄灯
    LightState := 2;
    RedLightTimer(IN:=FALSE); // 停止红灯定时器
    RedTimerRunning := FALSE; // 标记红灯定时器已停止
    YellowLightTimer(IN:=TRUE, PT:=T#2s); // 启动黄灯定时器
    YellowTimerRunning := TRUE; // 标记黄灯定时器正在运行
    RedLightOutput := FALSE; // 红灯灭
END_IF

// 黄灯逻辑
IF LightState = 2 AND YellowLightTimer.Q THEN
    // 黄灯时间到,切换到绿灯
    LightState := 3;
    YellowLightTimer(IN:=FALSE); // 停止黄灯定时器
    YellowTimerRunning := FALSE; // 标记黄灯定时器已停止
    GreenLightTimer(IN:=TRUE, PT:=T#8s); // 启动绿灯定时器
    GreenTimerRunning := TRUE; // 标记绿灯定时器正在运行
    YellowLightOutput := FALSE; // 黄灯灭
END_IF

// 绿灯逻辑
IF LightState = 3 AND GreenLightTimer.Q THEN
    // 绿灯时间到,切换到红灯
    LightState := 1;
    GreenLightTimer(IN:=FALSE); // 停止绿灯定时器
    GreenTimerRunning := FALSE; // 标记绿灯定时器已停止
    RedLightTimer(IN:=TRUE, PT:=T#10s); // 启动红灯定时器
    RedTimerRunning := TRUE; // 标记红灯定时器正在运行
    GreenLightOutput := FALSE; // 绿灯灭
END_IF

// 设置当前灯光输出
RedLightOutput := (LightState = 1);
YellowLightOutput := (LightState = 2);
GreenLightOutput := (LightState = 3);

// 注意:在实际应用中,您可能还需要考虑其他事件和条件,如交通流量、行人按钮等。
// 此外,如果PLC复位或重启,您可能需要一种机制来重新初始化LightState和定时器状态。
END_PROGRAM

检测结果还是一样,TON的用法有问题;仿真如下:



   

  从上述论述可以看出,国产大模型在逻辑编程的推理方面,目前还不近人意,提示词的理解很多时候理解不了。目前看PLC工程师短期内还是可以继续发展的;后续PLC工程师可以利用AI工具加快代码的编辑。毕竟AI工具生成的注释和变量名还是比较规范的。生成后自行修改一部分逻辑可以得到自己想要的答案。

大家有兴趣研发AI生成代码技术的,欢迎加群一起交流。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册哦

本版积分规则

QQ|小黑屋|手机版|Archiver|PLC技术网-PLC论坛 ( 粤ICP备17165530号 )|网站地图

GMT+8, 2024-9-10 20:30 , Processed in 0.043899 second(s), 26 queries .

快速回复 返回顶部 返回列表