西门子PLC S7-1200程序实例,博图版本V15,仅供电气编程者学习借鉴 1,西门子1200与安川机器人TCP/IP通讯,包含机器人GSD文件; 2,西门子1200控制6轴伺服电机,四台台脉冲控制台达B2伺服,两台PN通讯控制西门子V90伺服电机; 3,两台西门子1200开放式通讯交互数据联动; 4,与4台位移传感器modbus485轮询读取参数;

最近在研究西门子PLC S7 - 1200的一些应用案例,正好整理出来分享给各位电气编程的小伙伴,希望能给大家的学习和工作带来一些帮助。本次分享基于博图版本V15,涵盖了多个常见且实用的功能模块。

1. 西门子1200与安川机器人TCP/IP通讯

在自动化生产场景中,PLC与机器人的通讯至关重要。实现西门子1200与安川机器人的TCP/IP通讯,首先需要导入安川机器人的GSD文件。GSD文件就像是一把钥匙,它包含了机器人设备的各种信息,让PLC能够识别并与之通讯。

在博图软件中,导入GSD文件后,就可以在硬件组态中添加安川机器人设备。接下来就是编写通讯程序部分啦。以下是一个简单的通讯代码示例(以OB1为例):

// 定义变量
VAR
    tcp_connect : TCON;
    tcp_send : TSEND_C;
    tcp_receive : TRCV_C;
    send_data : ARRAY[1..100] OF BYTE;
    receive_data : ARRAY[1..100] OF BYTE;
END_VAR

// 初始化TCP连接
tcp_connect.CONNECT.PEER_ADDR := '192.168.1.10'; // 机器人IP地址
tcp_connect.CONNECT.PEER_PORT := 8080;
tcp_connect.ID := W#16#1234;
tcp_connect.CONNECT.TIME_OUT := T#10S;
CALL "TCON" (REQ := TRUE, CONNECT := tcp_connect.CONNECT, ID := tcp_connect.ID, DONE => tcp_connect.DONE, ERROR => tcp_connect.ERROR, STATUS => tcp_connect.STATUS);

// 发送数据
tcp_send.ID := tcp_connect.ID;
tcp_send.CONNECT := tcp_connect.CONNECT;
tcp_send.REQ := TRUE;
tcp_send.DATA := PEEK(send_data);
CALL "TSEND_C" (REQ := tcp_send.REQ, ID := tcp_send.ID, CONNECT := tcp_send.CONNECT, DATA := tcp_send.DATA, DONE => tcp_send.DONE, ERROR => tcp_send.ERROR, STATUS => tcp_send.STATUS);

// 接收数据
tcp_receive.ID := tcp_connect.ID;
tcp_receive.CONNECT := tcp_connect.CONNECT;
tcp_receive.NDR := TRUE;
tcp_receive.DATA := POKE(receive_data);
CALL "TRCV_C" (NDR := tcp_receive.NDR, ID := tcp_receive.ID, CONNECT := tcp_receive.CONNECT, DATA := tcp_receive.DATA, LEN => tcp_receive.LEN, DONE => tcp_receive.DONE, ERROR => tcp_receive.ERROR, STATUS => tcp_receive.STATUS);

在这段代码中,首先定义了用于TCP连接、发送和接收的相关变量。TCON指令用于初始化TCP连接,设置机器人的IP地址和端口号等参数。TSENDC指令负责数据发送,TRCVC指令用于数据接收。在实际应用中,senddatareceivedata数组里的数据需要根据具体的通讯需求来填充和解析。

2. 西门子1200控制6轴伺服电机

这里我们采用了两种不同的方式来控制6轴伺服电机,四台通过脉冲控制台达B2伺服,两台通过PN通讯控制西门子V90伺服电机。

脉冲控制台达B2伺服

以其中一台为例,在博图中,使用高速脉冲输出功能来控制伺服电机的位置和速度。下面是一段简单的代码片段:

// 定义高速脉冲输出变量
VAR
    pto1 : PTO;
    position : DINT := 10000; // 目标位置
    speed : DINT := 5000;    // 速度
END_VAR

// 配置高速脉冲输出
pto1.PERIOD := 1000; // 脉冲周期,单位ns
pto1.PULSE := 0;
pto1.STATE := 0;
pto1.DIR := 1; // 方向
pto1.UPDATE := 1;

// 启动高速脉冲输出
pto1.REQ := TRUE;
pto1.POSITION := position;
pto1.SPEED := speed;
CALL "PTO_CTRL" (REQ := pto1.REQ, PTO := pto1, DONE => pto1.DONE, ERROR => pto1.ERROR, STATUS => pto1.STATUS);

这段代码中,PTO指令用于配置和控制高速脉冲输出。通过设置PERIOD确定脉冲周期,从而控制速度,POSITION设定目标位置。PTO_CTRL指令启动脉冲输出,根据设定的参数驱动台达B2伺服电机运转。

PN通讯控制西门子V90伺服电机

对于通过PN通讯控制西门子V90伺服电机,首先要在硬件组态中正确配置V90设备,并建立PN连接。在程序中,通过FB284功能块来实现控制。

// 定义FB284功能块变量
VAR
    fb284_1 : FB284;
    axis_pos : DINT;
END_VAR

// 调用FB284功能块
fb284_1.CONTROL_MODE := 1; // 绝对定位模式
fb284_1.POSITION := 20000;
fb284_1.VELOCITY := 10000;
fb284_1.OVER_VELOCITY := 15000;
fb284_1.OVER_ACCEL := 20000;
fb284_1.OVER_DECEL := 20000;
fb284_1.POS_TYPE := 1;
fb284_1.ACT_POS := axis_pos;
CALL "FB284" (FB284 := fb284_1, MOTION_MODE := 1, POSITION := fb284_1.POSITION, VELOCITY := fb284_1.VELOCITY, OVER_VELOCITY := fb284_1.OVER_VELOCITY, OVER_ACCEL := fb284_1.OVER_ACCEL, OVER_DECEL := fb284_1.OVER_DECEL, POS_TYPE := fb284_1.POS_TYPE, ACT_POS := fb284_1.ACT_POS, DONE => fb284_1.DONE, ERROR => fb284_1.ERROR, STATUS => fb284_1.STATUS);

在这段代码里,FB284功能块的CONTROLMODE设置为绝对定位模式,通过设置POSITIONVELOCITY等参数来控制V90伺服电机的运动。ACTPOS可以获取电机当前的实际位置。

3. 两台西门子1200开放式通讯交互数据联动

两台西门子1200之间进行开放式通讯交互数据,能够实现更复杂的自动化控制逻辑。这里我们使用ISO-on-TCP通讯方式。

在发送端PLC程序中:

// 定义发送相关变量
VAR
    iso_send_connect : TCON;
    iso_send : TSEND_C;
    send_data2 : ARRAY[1..50] OF BYTE;
END_VAR

// 初始化ISO-on-TCP连接
iso_send_connect.CONNECT.PEER_ADDR := '192.168.1.20'; // 接收端PLC IP
iso_send_connect.CONNECT.PEER_PORT := 102;
iso_send_connect.ID := W#16#5678;
iso_send_connect.CONNECT.TIME_OUT := T#10S;
CALL "TCON" (REQ := TRUE, CONNECT := iso_send_connect.CONNECT, ID := iso_send_connect.ID, DONE => iso_send_connect.DONE, ERROR => iso_send_connect.ERROR, STATUS => iso_send_connect.STATUS);

// 发送数据
iso_send.ID := iso_send_connect.ID;
iso_send.CONNECT := iso_send_connect.CONNECT;
iso_send.REQ := TRUE;
iso_send.DATA := PEEK(send_data2);
CALL "TSEND_C" (REQ := iso_send.REQ, ID := iso_send.ID, CONNECT := iso_send.CONNECT, DATA := iso_send.DATA, DONE => iso_send.DONE, ERROR => iso_send.ERROR, STATUS => iso_send.STATUS);

接收端PLC程序:

// 定义接收相关变量
VAR
    iso_receive_connect : TCON;
    iso_receive : TRCV_C;
    receive_data2 : ARRAY[1..50] OF BYTE;
END_VAR

// 初始化ISO-on-TCP连接
iso_receive_connect.CONNECT.PEER_ADDR := '192.168.1.10'; // 发送端PLC IP
iso_receive_connect.CONNECT.PEER_PORT := 102;
iso_receive_connect.ID := W#16#5678;
iso_receive_connect.CONNECT.TIME_OUT := T#10S;
CALL "TCON" (REQ := TRUE, CONNECT := iso_receive_connect.CONNECT, ID := iso_receive_connect.ID, DONE => iso_receive_connect.DONE, ERROR => iso_receive_connect.ERROR, STATUS => iso_receive_connect.STATUS);

// 接收数据
iso_receive.ID := iso_receive_connect.ID;
iso_receive.CONNECT := iso_receive_connect.CONNECT;
iso_receive.NDR := TRUE;
iso_receive.DATA := POKE(receive_data2);
CALL "TRCV_C" (NDR := iso_receive.NDR, ID := iso_receive.ID, CONNECT := iso_receive.CONNECT, DATA := iso_receive.DATA, LEN => iso_receive.LEN, DONE => iso_receive.DONE, ERROR => iso_receive.ERROR, STATUS => iso_receive.STATUS);

发送端和接收端通过TCON指令分别初始化连接,设置对方的IP地址和端口号。发送端使用TSENDC发送数据,接收端使用TRCVC接收数据,从而实现两台PLC之间的数据交互。

4. 与4台位移传感器modbus485轮询读取参数

通过Modbus 485通讯协议与4台位移传感器进行数据交互,实现参数的轮询读取。

首先,在博图中添加Modbus主站指令库。以下是一段简单的轮询读取代码:

// 定义Modbus相关变量
VAR
    mb_master : MB_MASTER;
    sensor1_data : INT;
    sensor2_data : INT;
    sensor3_data : INT;
    sensor4_data : INT;
    poll_count : INT := 0;
END_VAR

// Modbus主站初始化
mb_master.PORT := 2; // 通讯端口
mb_master.BAUD := 9600;
mb_master.PARITY := 0;
mb_master.DATA_BITS := 8;
mb_master.STOP_BITS := 1;
mb_master.TIMEOUT := 1000;

// 轮询读取传感器数据
CASE poll_count OF
    0:
        mb_master.REQ := TRUE;
        mb_master.ID := 1; // 传感器1地址
        mb_master.FUNC := 3;
        mb_master.ADDR := 0;
        mb_master.LENGTH := 2;
        mb_master.DATA_PTR := ADR(sensor1_data);
        CALL "MB_MASTER" (REQ := mb_master.REQ, ID := mb_master.ID, FUNC := mb_master.FUNC, ADDR := mb_master.ADDR, LENGTH := mb_master.LENGTH, DATA_PTR := mb_master.DATA_PTR, DONE => mb_master.DONE, ERROR => mb_master.ERROR, STATUS => mb_master.STATUS);
        IF mb_master.DONE OR mb_master.ERROR THEN
            poll_count := 1;
            mb_master.REQ := FALSE;
        END_IF;
    1:
        mb_master.REQ := TRUE;
        mb_master.ID := 2; // 传感器2地址
        mb_master.FUNC := 3;
        mb_master.ADDR := 0;
        mb_master.LENGTH := 2;
        mb_master.DATA_PTR := ADR(sensor2_data);
        CALL "MB_MASTER" (REQ := mb_master.REQ, ID := mb_master.ID, FUNC := mb_master.FUNC, ADDR := mb_master.ADDR, LENGTH := mb_master.LENGTH, DATA_PTR := mb_master.DATA_PTR, DONE => mb_master.DONE, ERROR => mb_master.ERROR, STATUS => mb_master.STATUS);
        IF mb_master.DONE OR mb_master.ERROR THEN
            poll_count := 2;
            mb_master.REQ := FALSE;
        END_IF;
    2:
        mb_master.REQ := TRUE;
        mb_master.ID := 3; // 传感器3地址
        mb_master.FUNC := 3;
        mb_master.ADDR := 0;
        mb_master.LENGTH := 2;
        mb_master.DATA_PTR := ADR(sensor3_data);
        CALL "MB_MASTER" (REQ := mb_master.REQ, ID := mb_master.ID, FUNC := mb_master.FUNC, ADDR := mb_master.ADDR, LENGTH := mb_master.LENGTH, DATA_PTR := mb_master.DATA_PTR, DONE => mb_master.DONE, ERROR => mb_master.ERROR, STATUS => mb_master.STATUS);
        IF mb_master.DONE OR mb_master.ERROR THEN
            poll_count := 3;
            mb_master.REQ := FALSE;
        END_IF;
    3:
        mb_master.REQ := TRUE;
        mb_master.ID := 4; // 传感器4地址
        mb_master.FUNC := 3;
        mb_master.ADDR := 0;
        mb_master.LENGTH := 2;
        mb_master.DATA_PTR := ADR(sensor4_data);
        CALL "MB_MASTER" (REQ := mb_master.REQ, ID := mb_master.ID, FUNC := mb_master.FUNC, ADDR := mb_master.ADDR, LENGTH := mb_master.LENGTH, DATA_PTR := mb_master.DATA_PTR, DONE => mb_master.DONE, ERROR => mb_master.ERROR, STATUS => mb_master.STATUS);
        IF mb_master.DONE OR mb_master.ERROR THEN
            poll_count := 0;
            mb_master.REQ := FALSE;
        END_IF;
END_CASE;

在这段代码中,MBMASTER指令用于实现Modbus主站功能。通过pollcount变量来实现对4台传感器的轮询读取。每次读取完一台传感器的数据后,根据DONEERROR标志切换到下一台传感器的读取操作。

以上就是本次分享的西门子PLC S7 - 1200在博图V15中的一些程序实例,希望对各位电气编程爱好者有所帮助,大家一起交流学习,共同进步!

以上代码仅为示例,实际应用中需要根据具体设备参数和需求进行调整。

Logo

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

更多推荐