带相机PLC1200 SCL梯形图混编立体库机器人码垛机伺服视觉程序 包括2台西门子PLC1215程序和2台西门子触摸屏TP700程序 PLC和基恩士相机视觉定位Modbus TCP通讯(SCL语言) PLC和ABB机器人Modbus TCP通讯(SCL语言) PLC和码垛机Modbus TCP通讯(SCL语言) PLC和4台G120变频器Profinet通讯 1个伺服轴 SCL语言和梯形图混编,经典程序,知识点丰富,注释全。

【工业自动化朋克现场】最近整了个硬核项目——用西门子1200玩转立体仓库+机器人码垛的全套交互。两台PLC1215配TP700触摸屏,带着基恩士视觉、ABB机械臂、四台G120变频器还有伺服轴蹦迪,这酸爽必须记录下。

先说最刺激的通讯局。ModbusTCP这老伙计被我们玩出花,三个不同厂家的设备全走这个协议对接。SCL写通讯就是香,比梯形图那堆触点直观多了。看这段相机数据解析的硬核代码:

//基恩士CV-X200视觉系统数据接收
FUNCTION "VisionDataProcess" : Void
VAR_INPUT
    hConnection : TCP_CONNECT;  //TCP连接句柄
END_VAR
VAR_TEMP
    rawData : ARRAY[1..20] OF Byte;  //原始字节流
    coordX : REAL := 0.0;  //视觉坐标X
    coordY : REAL := 0.0;  //视觉坐标Y
    statusWord : WORD;     //状态字
BEGIN
    TCON_Receive(//收取报文
        ID := hConnection,
        DATA := P#rawData[1] Byte,  
        LEN := 20,
        RCVD_LEN => ); 
        
    //大端转小端处理(基恩士协议特性)
    coordX := DWORD_TO_REAL(SWAP(UNION(IN:=rawData[5..8])).DInt);
    coordY := DWORD_TO_REAL(SWAP(UNION(IN:=rawData[9..12])).DInt);
    
    //状态位解析
    statusWord := BYTE_TO_WORD(rawData[3], rawData[4]);
    IF (statusWord.15) THEN  //Bit15为就绪标志
        RobotTargetPos := (coordX, coordY, 0);  //更新机械臂坐标
    END_IF;
END_FUNCTION;

这波操作有几个暗坑:1.视觉数据是大端格式要字节翻转 2.状态字第15位才是有效位 3.浮点数转换必须用DWORD中间过渡。当年调试时在这栽过跟头,现在变量名直接写成注释,防止后人踩雷。

跟ABB机械臂的交互更有意思。他们家的Modbus地址映射特立独行,控制字得按特定时序触发:

//机械臂控制状态机
CASE robotState OF
    0: //等待就绪
        IF robotStatus.ready THEN
            robotState := 10;
        END_IF;
    10: //发送移动指令
        MB_CLIENT.Req := TRUE;
        MB_CLIENT.MB_ADDR := 40001;  //目标地址
        MB_CLIENT.DATA_ADDR := P#DB5.DBX0.0 REAL; //存放目标坐标的DB块
        IF MB_CLIENT.DONE THEN
            robotState := 20;
        END_IF;
    20: //等待到位
        IF robotStatus.in_position THEN
            robotState := 30;
        END_IF;
    //...后续状态省略
END_CASE;

这里用了状态机模式处理异步通信,比单纯用定时器轮询可靠得多。注意MB_CLIENT功能块的Req信号必须脉冲触发,所以每次发完指令要立即复位请求信号。

带相机PLC1200 SCL梯形图混编立体库机器人码垛机伺服视觉程序 包括2台西门子PLC1215程序和2台西门子触摸屏TP700程序 PLC和基恩士相机视觉定位Modbus TCP通讯(SCL语言) PLC和ABB机器人Modbus TCP通讯(SCL语言) PLC和码垛机Modbus TCP通讯(SCL语言) PLC和4台G120变频器Profinet通讯 1个伺服轴 SCL语言和梯形图混编,经典程序,知识点丰富,注释全。

伺服轴控制部分混用了梯形图和SCL。位置模式用工艺对象挺方便,但速度控制还是自己写算法更灵活:

//速度模式梯形图程序
      MOV  "伺服使能条件"       //自动模式+无故障
      AND  "急停复位状态"
      =    "伺服轴".MC_Power.Enable

      CALL "速度环计算" (      //SCL编写的速度控制器
           ActualPos := "伺服轴".ActualPosition,
           TargetPos := PalletizerPos,
           MaxSpeed := 2000.0,
           Accel := 500.0,
           =>SpeedOut);
      
      "伺服轴".MC_MoveVelocity.Velocity := "SpeedOut";
      "伺服轴".MC_MoveVelocity.Execute := NOT "伺服轴".StatusBits.VelocityReached;

这种混编模式充分发挥各自优势——逻辑控制用梯形图直观,算法计算用SCL高效。注意工艺对象的状态位处理,Execute信号必须用到位状态取反,否则无法持续触发速度指令。

调试时最坑的是Profinet变频器组。G120的参数设置必须严格对应,特别是PZD过程数据映射:

//变频器控制字处理
ControlWord := 16#047E;  //准备运行
IF "启动信号" THEN
    ControlWord.0 := 1;  //ON命令
    ControlWord.1 := 1;  //OFF2无效
    ControlWord.2 := 1;  //OFF3无效
END_IF;
//通过PZD输出到变频器
PQW300 := ControlWord;  //第一个字为控制字
PQW302 := UINT_TO_WORD(SetFrequency);  //第二个字为频率设定

这里有个魔鬼细节:控制字的bit10必须置1才能启用PLC控制权。当初因为漏了这个位,四台变频器集体装死半小时,现场工程师差点暴走...

触摸屏画面设计讲究信息密度。TP700的报警页面做了分级处理,用SCL动态生成报警文本:

//报警文本生成函数
FUNCTION_BLOCK "AlarmTextGenerator"
VAR_INPUT
    ErrorCode : INT;
END_VAR
VAR_OUTPUT
    MessageText : STRING[80];
END_VAR
BEGIN
    CASE ErrorCode OF
        16#7001: MessageText := '视觉超时[CVX200] 检查网线或触发频率';
        16#7010: MessageText := '机械臂急停触发[ABB] 确认安全门状态';
        //...其他代码处理
        ELSE
            MessageText := CONCAT('未知错误码:0x', WORD_TO_HEX(ErrorCode));
    END_CASE;
END_FUNCTION_BLOCK

这种动态解析比固定文本列表维护起来方便得多,特别是跨设备协同的场景。调试时直接扫报警代码就能快速定位故障源,不用翻十层画面找原因。

这套系统现在跑得贼溜,但联调阶段简直是地狱模式——视觉坐标系和机械臂坐标系得做旋转补偿,码垛机的托盘尺寸突然变更导致位置重算,还有最要命的通讯丢包问题。后来在ModbusTCP层加了心跳包机制,用SCL写了个双缓冲数据校验:

//通讯心跳管理
IF NOT TCON_Status.Connected THEN
    //断线重连逻辑
    TCON_Create(
        CONNECT := PalletizerConn,
        IP_ADDR := '192.168.1.20'); 
ELSE
    //每500ms发送心跳
    IF heartTimer.Q THEN
        SendHeartbeat := TRUE;
        heartTimer(IN:=FALSE);
    ELSE
        heartTimer(IN:=TRUE, PT:=T#500ms);
    END_IF;
    
    //超时计数器处理
    IF lastHeartbeat > 3 THEN
        AlarmSet(16#7020);  //码垛机通讯丢失
        TCON_Destroy(PalletizerConn); 
    END_IF;
END_IF;

现在看这些代码就像老战友,每个注释都藏着通宵调试的故事。工业现场编程就是这样,既要懂协议规范,更要会处理现实世界的各种幺蛾子。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐