『7x24小时有问必答』
根据Deepseek官网的最新消息,V4版本正式发布,具备世界顶级推理性能。
对于我们来说,更加关注的当然是PLC编程的能力。这期我们看看到底如何?

01
性能

按照Deepseek自己宣布的资料看:

其性能和Claude-Opus-4.6、GPT5.4、Gemini3.1不相上下,到底实测如何,我想还是交给使用过Deepseek V4的用户。只有真实的应用场景,才能得出自己的结论。毕竟,所有的模型刚出来,没有亮眼的指标和性能,怎么好意思拿出手。

02
值得说的两点

AI领域实际上,也就是中美两个大国为主。美国以闭源模型为主,而我们国家的主流大模型都基本开源。

而这次,Deepseek V4迟迟没有发布,据说是为了适配我们国产的芯片。毕竟目前的国际环境,不走这一步,长远来看,肯定会受别人限制,在战略层面来说,这次是非常重要的一点。我们国人肯定希望有一个真的能和CC这类大模型旗鼓相当。

对于我目前做的RealPLC产品而言,在国内基本会接入Deepseek的模型:

而另外一点就是超长上下文,其中有句话是这样的:

未来,长的上下文能力也是大模型处理能力的一个指标。毕竟,记忆能力和本身的上下文承载能力是非常相关的。这本身也能在某种程度上降低token的使用成本。

03
实测PLC编程能力

最简单的一个需求,让AI自己去证明自己的PLC编程能力,所以我们这样进行测试:

这里我们直接用的专家模式,按Deepseek的介绍对应的就是V4-pro模型:

具体的代码贴下方了:
FUNCTION_BLOCK FB_Centrifuge(*        离心机控制功能块:      - 多段速自动运行 (低速/高速)      - 安全联锁: 急停、盖关闭、振动保护      - 振动信号低通滤波与去抖确认      - 斜坡发生器避免速度突变      - 故障锁存与外部复位      - 运行时间统计 (RETAIN 掉电保持)*)VAR_INPUT      Start                   : BOOL;           // 启动按钮      Stop                     : BOOL;           // 停止按钮      EmergencyStop       : BOOL;           // 急停 (常闭触点 true=正常)      LidClosed             : BOOL;           // 盖子关闭检测      VibrationSensor    : REAL;           // 振动传感器 0..100%      SpeedFeedback       : REAL;           // 转速反馈 rpm      ResetFault            : BOOL;           // 外部故障复位END_VARVAR_OUTPUT      MotorRun               : BOOL;           // 电机运行      SpeedSetpoint       : REAL;           // 速度给定      WaterValve            : BOOL;           // 清洗水阀      LidLock                : BOOL;           // 盖子电磁锁      Error                   : BOOL;           // 综合故障      ErrorID                : WORD;           // 故障代码      CurrentState         : INT;            // 当前状态 (用于HMI)END_VARVAR       // ----- 状态定义 -----      eState : (IDLE, LOCKING, ACCEL_TO_LOW, LOW_SPEED_HOLD,                     ACCEL_TO_HIGH, HIGH_SPEED_HOLD, DECELERATING,                     WASHING, UNLOCKING, FAULT) := IDLE;       // ----- 边沿检测 -----      rtrStart      : R_TRIG;      rtrStop       : R_TRIG;      rtrEStop      : R_TRIG;      rtrReset      : R_TRIG;       // ----- 定时器 -----      tRamp          : TON;      // 斜坡时间      tLowHold      : TON;      // 低速保持      tHighHold    : TON;      // 高速保持      tWash          : TON;      // 清洗时间      tVibDebounce: TON;      // 振动超限去抖      tRunningMeter: TON;     // 运行计时单位脉冲       // ----- 速度斜坡计算 -----      rRampStartSpeed   : REAL :=  0.0;      rRampTargetSpeed : REAL :=  0.0;      rRampElapsed       : REAL;      rRampDuration      : REAL;       // ----- 振动滤波 (一阶低通) -----      rVibFiltered       : REAL :=  0.0;      rFilterAlpha       : REAL :=  0.05;  // 滤波系数       // ----- 常量 -----      LOW_SPEED            : REAL :=  500.0;      // rpm      HIGH_SPEED          : REAL :=  3000.0;      RAMP_TIME            : TIME := T#5s;      LOW_HOLD_TIME      : TIME := T#10s;      HIGH_HOLD_TIME    : TIME := T#30s;      WASH_TIME            : TIME := T#8s;      VIB_LIMIT            : REAL :=  70.0;        // 振动上限 %      VIB_DEBOUNCE_T    : TIME := T#500ms;   // 超限确认延时      LID_LOCK_DELAY    : TIME := T#200ms;   // 锁紧等待时间      IDLE_SPEED          : REAL :=  0.0;      WATER_VALVE_OFF   : BOOL := FALSE;      WATER_VALVE_ON    : BOOL := TRUE;END_VARVAR RETAIN       // 掉电累计运行时间 (秒)      udiTotalRunSeconds : UDINT :=  0;END_VAR//----------------------------------------------------------------// 上升沿预处理rtrStart(CLK := Start AND LidClosed AND EmergencyStop);rtrStop(CLK   := Stop);rtrEStop(CLK := NOT EmergencyStop);rtrReset(CLK := ResetFault);// 振动一阶低通滤波rVibFiltered := rVibFiltered + rFilterAlpha * (VibrationSensor - rVibFiltered);// 振动超限去抖 (持续超过限值才确认)tVibDebounce(IN := rVibFiltered > VIB_LIMIT, PT := VIB_DEBOUNCE_T);// 运行时间累计 (电机运行且非零速反馈)tRunningMeter(IN := MotorRun AND (SpeedFeedback >  10.0), PT := T#1s);IF tRunningMeter.Q THEN      udiTotalRunSeconds := udiTotalRunSeconds +  1;      tRunningMeter(IN := FALSE);  // 手动复位启动下一次      tRunningMeter(IN := TRUE);END_IF;//----------------------------------------------------------------// 斜坡计算函数封装IF tRamp.ET >= RAMP_TIME THEN      rRampElapsed := UDINT_TO_REAL(TIME_TO_UDINT(RAMP_TIME));ELSE      rRampElapsed := UDINT_TO_REAL(TIME_TO_UDINT(tRamp.ET));END_IF;rRampDuration := UDINT_TO_REAL(TIME_TO_UDINT(RAMP_TIME));IF rRampDuration >  0.0  THEN      SpeedSetpoint := rRampStartSpeed +                                  (rRampTargetSpeed - rRampStartSpeed) * (rRampElapsed / rRampDuration);ELSE      SpeedSetpoint := rRampTargetSpeed;END_IF;// 防止过冲IF rRampTargetSpeed >= rRampStartSpeed THEN      SpeedSetpoint := MIN(SpeedSetpoint, rRampTargetSpeed);ELSE      SpeedSetpoint := MAX(SpeedSetpoint, rRampTargetSpeed);END_IF;//----------------------------------------------------------------// 主状态机CASE eState OF      IDLE:            MotorRun := FALSE;            LidLock   := FALSE;            WaterValve := WATER_VALVE_OFF;            SpeedSetpoint := IDLE_SPEED;            IF rtrStart.Q THEN                  eState := LOCKING;                  tRamp(IN := FALSE);  // 复位斜坡计时器            END_IF;      LOCKING:            LidLock := TRUE;            IF LidClosed THEN                  tRamp(IN := FALSE, PT := LID_LOCK_DELAY);                  IF tRamp.Q THEN                         // 设置斜坡初始目标为低速                        rRampStartSpeed :=  0.0;                        rRampTargetSpeed := LOW_SPEED;                        tRamp(IN := TRUE, PT := RAMP_TIME);  // 启动斜坡计时                        eState := ACCEL_TO_LOW;                  END_IF;            ELSE                   // 盖子意外打开, 回到 IDLE                  eState := IDLE;            END_IF;      ACCEL_TO_LOW:            MotorRun := TRUE;            IF tRamp.Q OR (SpeedFeedback >= LOW_SPEED *  0.98) THEN                  SpeedSetpoint := LOW_SPEED;   // 到达                  tLowHold(IN := TRUE, PT := LOW_HOLD_TIME);                  eState := LOW_SPEED_HOLD;            END_IF;      LOW_SPEED_HOLD:            SpeedSetpoint := LOW_SPEED;            IF tLowHold.Q THEN                   // 转高速                  rRampStartSpeed := LOW_SPEED;                  rRampTargetSpeed := HIGH_SPEED;                  tRamp(IN := TRUE, PT := RAMP_TIME);                  eState := ACCEL_TO_HIGH;            ELSIF rtrStop.Q THEN                   // 提前停止                  rRampStartSpeed := LOW_SPEED;                  rRampTargetSpeed := IDLE_SPEED;                  tRamp(IN := TRUE, PT := RAMP_TIME);                  eState := DECELERATING;            END_IF;      ACCEL_TO_HIGH:            MotorRun := TRUE;            IF tRamp.Q OR (SpeedFeedback >= HIGH_SPEED *  0.98) THEN                  SpeedSetpoint := HIGH_SPEED;                  tHighHold(IN := TRUE, PT := HIGH_HOLD_TIME);                  eState := HIGH_SPEED_HOLD;            END_IF;      HIGH_SPEED_HOLD:            SpeedSetpoint := HIGH_SPEED;            IF tHighHold.Q OR rtrStop.Q THEN                   // 工艺结束或收到停止                  rRampStartSpeed := HIGH_SPEED;                  rRampTargetSpeed := IDLE_SPEED;                  tRamp(IN := TRUE, PT := RAMP_TIME);                  eState := DECELERATING;            END_IF;      DECELERATING:            MotorRun := SpeedFeedback >  50.0;  // 惯性停车到低位再关            IF tRamp.Q AND (SpeedFeedback <  50.0) THEN                  MotorRun := FALSE;                  SpeedSetpoint := IDLE_SPEED;                  tWash(IN := TRUE, PT := WASH_TIME);                  WaterValve := WATER_VALVE_ON;                  eState := WASHING;            END_IF;      WASHING:            IF tWash.Q THEN                  WaterValve := WATER_VALVE_OFF;                  eState := UNLOCKING;            END_IF;      UNLOCKING:            LidLock := FALSE;            IF NOT LidClosed THEN                  eState := IDLE;   // 等待盖子打开后回到空闲            END_IF;      FAULT:            MotorRun := FALSE;            WaterValve := WATER_VALVE_OFF;            LidLock := TRUE;            // 故障保持锁紧            SpeedSetpoint := IDLE_SPEED;            Error := TRUE;            IF rtrReset.Q AND NOT EmergencyStop AND (rVibFiltered < VIB_LIMIT) THEN                  Error := FALSE;                  ErrorID :=  0;                  eState := IDLE;            END_IF;END_CASE;//----------------------------------------------------------------// 故障跳转 (独立于 CASE,确保任何状态中急停/振动都有效)IF rtrEStop.Q THEN      ErrorID :=  16#0001;     // 急停故障      eState := FAULT;ELSIF tVibDebounce.Q THEN      ErrorID :=  16#0002;     // 振动异常      eState := FAULT;END_IF;// 状态输出用于 HMICurrentState := INT_TO_WORD(eState);
具体的代码质量如何,还请各位朋友自行判断。AI自己给了个总结:
程序亮点解析(证明能力的部分):
严格的状态机设计

使用  CASE  分支管理 10 个独立状态,转换条件清晰,避免任何“死锁”或“隐藏路径”。故障状态能随时打断正常流程(在 CASE 外触发),符合工业安全要求。
真实的物理信号处理
振动信号采用一阶滞后滤波 (rVibFiltered + alpha * (in - rVibFiltered)) 剔除尖峰干扰。
超限后增加 500ms 延时确认 (tVibDebounce),避免瞬时干扰导致误停机,这是现场防抖的典型做法。
平滑速度斜坡

利用定时器已用时间与总时间的比例计算实时设定值,并对目标进行钳位 (MIN/MAX),避免过冲,同时支持反向减速斜坡。使用了  TIME_TO_UDINT  等 IEC 标准时间转换函数,体现对库函数的熟练运用。
联锁与安全
启动要求盖关闭且无急停(常闭信号判断  EmergencyStop)。
故障和急停强制锁紧盖子,复位时必须无急停且振动恢复才能退出故障态,防止危险重启。
掉电保持运行时间

RETAIN  区域的  udiTotalRunSeconds  能断电记忆,且仅在真实运转时累加(速度反馈 > 10 rpm 防误计),实用且严谨。
代码结构与可维护性
输入/输出分明,配合详细注释和常量定义,参数集中,易于调校。
边沿检测、定时器、滤波全部用标准功能块实例化,没有“手工烧烤”的低效写法。
集成  ErrorID  和  CurrentState  输出,方便上位 HMI/SCADA 诊断。
这段程序集中展示了实际项目中处理复杂设备控制所需的  状态机架构、安全逻辑、信号调理、故障管理和工程封装能力,足以证明 PLC 编程的专业水平。

基本上,我们编程的理念和结构化思维都有了,但是到底能不能符合你心目中专家级别的水平,还请自己去测试评判。

参考链接:

【2】https://www.deepseek.com/

  ▊  阅读更多(戳下方图片)
   

请长按下方二维码关注Hello工控

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

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

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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


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