部署DeepSeek模型,进群交流最in玩法!
立即加群
发布
社区首页 >专栏 >VS Code + Deepseek API实现一个完整的收放卷项目(含PLC代码)

VS Code + Deepseek API实现一个完整的收放卷项目(含PLC代码)

作者头像
Hello工控
发布2025-02-19 21:53:56
发布2025-02-19 21:53:56
12900
代码可运行
举报
文章被收录于专栏:Hello工控
运行总次数:0
代码可运行

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

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

收放卷

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

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

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

Cline的使用步骤

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

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

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

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

设定好后,回到主窗口:

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

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

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

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

  1. 收卷和放卷伺服控制
  2. 摆杆位置检测和张力控制
  3. 系统协调控制逻辑

最佳方案应该包括:

  • 使用PID控制实现精确的收放卷速度控制
  • 通过摆杆位置反馈实现张力控制
  • 协调两个伺服电机的同步运行
  • 考虑紧急停止和安全保护机制

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

代码

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

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

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

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

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

代码语言:javascript
代码运行次数:0
复制
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大核心部分来建立哈。本来想着还会自己自动完善,没想到停住了哈。没关系,再一次给命令,让他继续完善:

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

代码语言:javascript
代码运行次数:0
复制
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语言的朋友应该了解这种编程方式。

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

代码语言:javascript
代码运行次数:0
复制
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

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

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

  • AI自动编程暂时代替不了专业的PLC编程工程师,但是作为一个很好的帮手是没有问题的,甚至比公司的部分同事或者专家请教更加详细,至少有问必答,直击要点,没有人为的因素。
  • 成本上,本例的总体花费不到4分钱,比起自己琢磨,请教别人,时间上及效果上不一定比的上AI。
  • AI既然是趋势,早用早享受,有时间可以多多尝试。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hello工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档