抖音粉丝群1
『7x24小时有问必答』

AI浪潮下的计算机行业——从业者现状与未来展望


我们在新能源行业设备开发中,收放卷是很经典常用的设备模块,不管是电芯电池卷绕机、叠片机、制片机等,都需要这个模块。那我们刚好利用上期介绍的让AI自动编写plc程序的两种方法中其一,即:VS code +cline + deepseek API 的方式来做本期的分享。


具体的方法在上一篇查看:DeepSeek大显神威,PLC编程也能如此高效有趣?



1.png

收放卷


我们这里以锂电池,特别是圆柱电池电芯为例,内部基本组成:正极片+负极片+双层隔膜。其他的组成部分还包含外壳、盖帽、电解液、PTC元件、垫圈以及安全阀等关键组件。


2.png

那生成这种电池的设备,这里以其中的卷绕工艺为核心的设备:

3.png

其中,正负极片和隔膜卷的收放是最典型的一个部分。上图红色圈内,就是正极片、负极片、上隔膜及下隔膜伺服放卷的位置。

4.png




5.png

Cline的使用步骤



当然,上述的收放卷是一个典型的结构,四个收放卷本质上是同一套代码,可以用面向对象的思维来架构,新建一个FB,再实例化四个功能块即可。


我们这里用AI来辅助实现收放卷,打开VS code,找到cline对话窗口:


6.png

提问之前,可以设置好API key,在右上角的设置栏,点击打开:

7.png

当然,AI的模型选择可以按照需求而定,这里我们以Deepseek为例进行演示:

8.png

设定好后,回到主窗口:

9.png

在最下方的Type a message输入您的需求,本例:两个伺服系统,一个收卷一个放卷,中间有摆杆控制,请给出最佳的解决方案。


需求输入完毕后,点击发送即可等待AI自动推理的过程,如果中文提问,一般也是中文回答,如果依然回答的英文,请在需求加上,以中文回答这个提示词即可。


根据任务描述,需要设计一个收卷和放卷系统,中间有摆杆控制。从环境信息中可以看到一些相关的ST(结构化文本)文件,包括dancer_control.st、pid_winder.st等,这些可能包含了现有的控制逻辑。

首先需要分析现有文件内容,了解当前系统实现。然后设计一个包含以下关键组件的解决方案:

  1. 收卷和放卷伺服控制

  2. 摆杆位置检测和张力控制

  3. 系统协调控制逻辑

最佳方案应该包括:

  • 使用PID控制实现精确的收放卷速度控制

  • 通过摆杆位置反馈实现张力控制

  • 协调两个伺服电机的同步运行

  • 考虑紧急停止和安全保护机制


根据我们的需求,设计思路非常赞,基本包含:伺服的控制、摆杆位置检测和张力控制、系统协调控制。方案也很清晰,除了PID的调节,还考虑到了紧急停止及安全保护机制,这点非常不错。



10.png

代码



接下来,我们重点是让他生成代码,最开始还要询问我编程电脑上现用的dancer.st文件,但实际上没有,所以重新让他生成。


11.png

跟AI交流,就是简单直接,想要什么直接提,不像跟我们同事或者请教领导之类的,还要考虑措辞。


全新的收放卷的控制系统,给出了我们3大核心功能,模块化编程,思路清晰,不亚于我们工程师哈。


12.png


这里,它自动在桌面创建了一个文件,把所有代码放到winder_control.st里面,方便我们全部复制,用记事本的方式打开即可,亲测有效。


初始的自动plc代码,我们展示在下方(st语言实现的):

    PROGRAM WinderControl
    VAR
        // 伺服控制变量
        unwind_servo : SERVO_DRIVE;
        rewind_servo : SERVO_DRIVE;
        
        // 摆杆控制变量
        dancer_pos : REAL;  // 摆杆位置
        dancer_setpoint : REAL := 0.5; // 摆杆设定位置
        tension_PID : PID_CONTROLLER;
        
        // 系统状态
        system_state : (IDLE, RUNNING, FAULT);
        emergency_stop : BOOL := FALSE;
        
        // 运行参数
        line_speed : REAL := 1.0; // 线速度 m/s
        material_thickness : REAL := 0.001; // 材料厚度 m
        
    END_VAR

    // 初始化
    IF FIRST_SCAN THEN
        // 初始化PID参数
        tension_PID.Kp := 1.0;
        tension_PID.Ki := 0.1;
        tension_PID.Kd := 0.01;
        tension_PID.Ts := 0.01; // 采样时间10ms
        
        system_state := IDLE;
    END_IF

    // 主控制逻辑
    CASE system_state OF
        IDLE:
            // 待机状态处理
            IF start_command THEN
                system_state := RUNNING;
            END_IF
            
        RUNNING:
            // 运行状态处理
            RunControlLogic();
            
            IF emergency_stop THEN
                system_state := FAULT;
            END_IF
            
        FAULT:
            // 故障处理
            EmergencyStop();
            IF reset_command THEN
                system_state := IDLE;
            END_IF
    END_CASE

    按照AI的自动生成逻辑,基本框架也是按照上述的3大核心部分来建立哈。本来想着还会自己自动完善,没想到停住了哈。没关系,再一次给命令,让他继续完善:

    13.png

    14.png

    但是此处出现失败,应该是文件替换这块出错了,但是不影响哈,所以切换了write_to_file功能自动继续完善和生成:

      PROGRAM WinderControl
      VAR
          // 伺服控制变量
          unwind_servo : SERVO_DRIVE;
          rewind_servo : SERVO_DRIVE;
          unwind_speed : REAL := 0.0;
          rewind_speed : REAL := 0.0;
          speed_ratio : REAL := 1.0;
          
          // 摆杆控制变量
          dancer_pos : REAL;  // 摆杆位置
          dancer_setpoint : REAL := 0.5; // 摆杆设定位置
          tension_PID : PID_CONTROLLER;
          tension_error : REAL;
          
          // 系统状态
          system_state : (IDLE, RUNNING, FAULT) := IDLE;
          emergency_stop : BOOL := FALSE;
          start_command : BOOL := FALSE;
          reset_command : BOOL := FALSE;
          
          // 运行参数
          line_speed : REAL := 1.0; // 线速度 m/s
          material_thickness : REAL := 0.001; // 材料厚度 m
          max_acceleration : REAL := 0.1; // 最大加速度 m/s²
          
          // 安全参数
          max_tension : REAL := 100.0; // 最大张力 N
          min_tension : REAL := 10.0; // 最小张力 N
          
      END_VAR

      // 初始化
      IF FIRST_SCAN THEN
          // 初始化PID参数
          tension_PID.Kp := 1.0;
          tension_PID.Ki := 0.1;
          tension_PID.Kd := 0.01;
          tension_PID.Ts := 0.01; // 采样时间10ms
          
          system_state := IDLE;
      END_IF

      // 主控制逻辑
      CASE system_state OF
          IDLE:
              // 待机状态处理
              IF start_command THEN
                  system_state := RUNNING;
              END_IF
              
          RUNNING:
              // 运行状态处理
              RunControlLogic();
              
              // 安全检测
              IF emergency_stop OR tension_error > max_tension OR tension_error < min_tension THEN
                  system_state := FAULT;
              END_IF
              
          FAULT:
              // 故障处理
              EmergencyStop();
              IF reset_command THEN
                  system_state := IDLE;
              END_IF
      END_CASE

      // 伺服控制逻辑
      METHOD RunControlLogic : BOOL
      VAR_INPUT
      END_VAR
      VAR
          speed_cmd : REAL;
          accel_time : REAL;
      END_VAR

      // 计算收放卷速度
      speed_cmd := line_speed / (2 * 3.14159 * unwind_servo.radius);
      unwind_speed := speed_cmd;
      rewind_speed := speed_cmd * speed_ratio;

      // 速度同步控制
      IF ABS(unwind_speed - rewind_speed) > 0.01 THEN
          speed_ratio := unwind_speed / rewind_speed;
      END_IF

      // 摆杆位置控制
      tension_error := dancer_setpoint - dancer_pos;
      tension_PID.PV := dancer_pos;
      tension_PID.SP := dancer_setpoint;
      tension_PID.CYCLE();

      // 应用PID输出调整速度
      unwind_speed := unwind_speed + tension_PID.CV;
      rewind_speed := rewind_speed - tension_PID.CV;

      // 限制速度范围
      unwind_speed := LIMIT(unwind_speed, 0.0, 10.0);
      rewind_speed := LIMIT(rewind_speed, 0.0, 10.0);

      // 应用速度指令
      unwind_servo.SetSpeed(unwind_speed);
      rewind_servo.SetSpeed(rewind_speed);

      RunControlLogic := TRUE;
      END_METHOD

      // 紧急停止处理
      METHOD EmergencyStop : BOOL
      VAR_INPUT
      END_VAR

      // 立即停止伺服
      unwind_servo.Stop();
      rewind_servo.Stop();

      // 复位状态
      emergency_stop := TRUE;
      start_command := FALSE;

      EmergencyStop := TRUE;
      END_METHOD

      相对比而言,较最开始的代码加了两个Method,熟悉st语言的朋友应该了解这种编程方式。


      15.png

      16.png

      17.png

      最终,任务完成后还会自动给出此次需求的总结陈词。先不论代码质量如何,单单就这个思路和框架值得我们参考。最后,把这个自动生成的代码供大家去品鉴:

        PROGRAM WinderControl
        VAR
            // 伺服控制变量
            unwind_servo : SERVO_DRIVE;
            rewind_servo : SERVO_DRIVE;
            unwind_speed : REAL := 0.0;
            rewind_speed : REAL := 0.0;
            speed_ratio : REAL := 1.0;

            // 摆杆控制变量
            dancer_pos : REAL;  // 摆杆位置
            dancer_pos_filtered : REAL := 0.5; // 滤波后摆杆位置
            dancer_setpoint : REAL := 0.5; // 摆杆设定位置
            tension_PID : PID_CONTROLLER;
            tension_error : REAL;
            tension_avg : REAL := 0.0; // 平均张力
            tension_var : REAL := 0.0; // 张力方差

            // 系统状态
            system_state : (IDLE, RUNNING, FAULT) := IDLE;
            emergency_stop : BOOL := FALSE;
            start_command : BOOL := FALSE;
            reset_command : BOOL := FALSE;

            // 运行参数
            line_speed : REAL := 1.0; // 线速度 m/s
            material_thickness : REAL := 0.001; // 材料厚度 m
            max_acceleration : REAL := 0.1; // 最大加速度 m/s²

            // 安全参数
            max_tension : REAL := 100.0; // 最大张力 N
            min_tension : REAL := 10.0; // 最小张力 N
            max_tension_var : REAL := 50.0; // 最大张力方差
            material_break_threshold : REAL := 0.01; // 断料检测阈值

        END_VAR

        // 初始化
        IF FIRST_SCAN THEN
            // 初始化PID参数
            tension_PID.Kp := 1.0;
            tension_PID.Ki := 0.1;
            tension_PID.Kd := 0.01;
            tension_PID.Ts := 0.01; // 采样时间10ms

            system_state := IDLE;
        END_IF

        // 主控制逻辑
        CASE system_state OF
            IDLE:
                // 待机状态处理
                IF start_command THEN
                    system_state := RUNNING;
                END_IF

            RUNNING:
                // 运行状态处理
                RunControlLogic();

                // 安全检测
                IF emergency_stop OR 
                   tension_error > max_tension OR 
                   tension_error < min_tension OR
                   tension_var > max_tension_var OR
                   ABS(dancer_pos_filtered - dancer_setpoint) > material_break_threshold THEN
                    system_state := FAULT;
                END_IF

            FAULT:
                // 故障处理
                EmergencyStop();
                IF reset_command THEN
                    system_state := IDLE;
                END_IF
        END_CASE

        // 伺服控制逻辑
        METHOD RunControlLogic : BOOL
        VAR_INPUT
        END_VAR
        VAR
            speed_cmd : REAL;
            accel_time : REAL;
        END_VAR

        // 计算收放卷速度
        speed_cmd := line_speed / (2 * 3.14159 * unwind_servo.radius);
        unwind_speed := speed_cmd;
        rewind_speed := speed_cmd * speed_ratio;

        // 速度同步控制
        IF ABS(unwind_speed - rewind_speed) > 0.01 THEN
            speed_ratio := unwind_speed / rewind_speed;
        END_IF

        // 摆杆位置滤波
        dancer_pos_filtered := 0.8 * dancer_pos_filtered + 0.2 * dancer_pos;

        // 摆杆位置控制
        tension_error := dancer_setpoint - dancer_pos_filtered;
        tension_PID.PV := dancer_pos_filtered;
        tension_PID.SP := dancer_setpoint;

        // 自适应PID参数
        IF ABS(tension_error) > 0.1 THEN
            tension_PID.Kp := 2.0;
            tension_PID.Ki := 0.2;
        ELSIF ABS(tension_error) > 0.05 THEN
            tension_PID.Kp := 1.0;
            tension_PID.Ki := 0.1;
        ELSE
            tension_PID.Kp := 0.5;
            tension_PID.Ki := 0.05;
        END_IF

        tension_PID.CYCLE();

        // 张力统计
        tension_avg := 0.9 * tension_avg + 0.1 * tension_error;
        tension_var := 0.9 * tension_var + 0.1 * (tension_error - tension_avg) * (tension_error - tension_avg);

        // 应用PID输出调整速度
        unwind_speed := unwind_speed + tension_PID.CV;
        rewind_speed := rewind_speed - tension_PID.CV;

        // 限制速度范围
        unwind_speed := LIMIT(unwind_speed, 0.0, 10.0);
        rewind_speed := LIMIT(rewind_speed, 0.0, 10.0);

        // 应用速度指令
        unwind_servo.SetSpeed(unwind_speed);
        rewind_servo.SetSpeed(rewind_speed);

        RunControlLogic := TRUE;
        END_METHOD

        // 紧急停止处理
        METHOD EmergencyStop : BOOL
        VAR_INPUT
        END_VAR

        // 立即停止伺服
        unwind_servo.Stop();
        rewind_servo.Stop();

        // 复位状态
        emergency_stop := TRUE;
        start_command := FALSE;

        EmergencyStop := TRUE;
        END_METHOD

        当然,这里的安全保护方面的代码,并没有完善,所以还可以继续提需求,直到让您满意为止。例如,断料检测这块,让他继续:

        18.png

        综合上述,我个人的体验感受:

        • AI自动编程暂时代替不了专业的PLC编程工程师,但是作为一个很好的帮手是没有问题的,甚至比公司的部分同事或者专家请教更加详细,至少有问必答,直击要点,没有人为的因素。

        • 成本上,本例的总体花费不到4分钱,比起自己琢磨,请教别人,时间上及效果上不一定比的上AI。

          19.png

        • AI既然是趋势,早用早享受,有时间可以多多尝试。


        免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
        您需要登录后才可以回帖 登录 | 立即注册

        本版积分规则

        上一主题上一主题         下一主题下一主题
        QQ手机版小黑屋粤ICP备17165530号

        关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

        法律保护:PLC技术网,plcjs.com,plcjs.net等字样
        Copyright 2010-2030. All rights reserved. 


        微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码