因项目需要PLC与PC连接,传输一些状态和控制信息。为了最快的响应速度,保险的方式是采用I/O直接连接。但这需要额外增加I/O卡,而且和PLC的I/O功能有些重复。那么,网络通信是否可行呢?本文将进行一些实验。

图:西门子S7-1200

概述

使用的PLC是目前主流的西门子S7-1200. 它支持的网络标准/协议很多,比如PROFINET, PROFIBUS等,还可以间接连接Modbus设备。每个标准下都有很多服务/协议,详情可以参考Communication with SIMATIC。但这些标准有些是用于西门子的设备互联的,不一定适用于PC。

下图是 TIA Portal V14 中通信相关的指令,也可以作为线索。

图:PLC通信指令

和PC的通信,一种方式是使用OPC server,但它是基于OLE/COM的,只能用于Windows。有些软件比如LabView提供了和西门子PLC通信的支持。跨平台的开源的方案,有一个是Snap7。我们可以先试试这个。另外可以尝试最原始的TCP协议。

Snap7

Snap7是针对西门子S7协议的。PLC不需任何配置就是S7的server,而我们只需要利用Snap7 lib,就可以让PC作为S7 client,读/写服务器端的数据块。

数据块映射

数据块分为输入区(DI, AI),输出区(DQ, AQ),程序数据块(DB)等等。下图中,DB3是测试程序的数据块。

图:数据块及监测值

用Snap7包中自带的(编译好的)测试程序可以查看/修改它的值。

图:Snap7测试程序

访问设置

在读写前需要进行配置和权限的设置:禁用块优化,给予完全访问权限,详见 Snap7的文档。

还有一个文档中没提到的设置:允许来自远程对象的PUT/GET通信访问。否则会出现 "Function not available", "function refused by CPU"之类的错误。

图:Snap7通信的访问设置

Python版的Snap7

有时使用脚本语言会更方便一些。python-snap7就是一个Snap7 lib的Python封装。因为只是接口层的封装,对速度的影响很小。

安装时需要先安装Snap7的库,再用pip安装python-snap7。有些平台没有现成的Snap7的库,需要自己编译。反正树莓派上我是自己编译的。 实测Python2和Python3都可以工作。

核心调用代码如下。因为I/O只有两字节,就直接读/写两字节了。

import snap7

from snap7.snap7types import S7AreaDB, S7AreaPA, S7AreaPE

class S7Client:

def __init__(self, ip, slot=1, rack=0):

self.client = snap7.client.Client()

self.client.connect(ip, rack, slot)

def readDI(self):

area = S7AreaPE

db = 0

start = 0

amount = 2

ba = self.client.read_area(area, db, start, amount)

d = ba[1]

d <<= 8

d |= ba[0]

return d

def writeDQ(self, data):

area = S7AreaPA

db = 0

start = 0

amount = 2

ba = bytearray(amount)

ba[0] = data & 0xff

ba[1] = data >> 8

self.client.write_area(area, db, start, ba)

速度测试

循环读/写DQ,看看总耗时。示意代码如下:

def testWriteLoop(self, count):

d = 0

self.log.info("Write DQ from: %04x", d)

t1 = time.time()

while d < count:

self.plc.writeDQ(d)

d += 1

t2 = time.time()

self.log.info("Write DQ till: %04x. Average: %.2fms",

(d - 1), (t2 - t1) * 1000 / d)

可以看到单次读/写的平均时间略高于9ms.

图:读写测试结果

下图是最低位的波形。10个周期对应于20次写,耗时约182ms。高低电平不对称的问题后面再说。

图:递增写DQ时DQ0.0的波形

反向通信

如果PC做Snap7的服务器,则PLC需要使用GET/PUT指令读/写PC端的数据。既然都是S7协议,我们假设它的速度和正向是相当的,暂且跳过,先试试另一类型的通信。

原始的TCP通信

S7-1200支持开放式用户通信,即基于TCP,但不属于任何标准应用层协议的,完全由用户自己定义的协议。

实验设计

PC端作为服务器:实际测试使用树莓派充当PC的角色。

PLC端发送数据:由一个DI来触发数据发送。

树莓派开启数据发送:通过控制一个GPIO来开关继电器,进而改变PLC端的DI(信号1);

树莓派在收到数据后,改变另一个GPIO的状态(信号2)作为标志;

比较信号2和信号1的时间差。

图:实验器材及连线

PC端

PC端作为服务器,监听某一端口。在Linux上,可以用命令行工具netcat进行调试。

开两个窗口:

netcat -l 2000: 监听端口2000

netcat localhost 2000: 与本机2000端口连接

一个窗口输入字符,另一个窗口就会显示出来。

然后,用Python socket写一个类似的服务器端程序,核心代码如下:

import socket

self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.sock.bind(('', self.args.port))

self.sock.listen(1)

self.conn, addr = self.sock.accept()

data = self.conn.recv(32)

self.log.info("Received: %02X %02X", data[0], data[1])

可以用 netcat 测试这个服务器程序。

图:PC端的TCP server

PLC端

PLC端使用TSEND_C发送数据。

由trigger触发数据发送,trigger对应于数字输入,比如DI0.1.

trigger同时触发一个计数器。TSEND发送这个计数器的值,这样PC每次收到的数据是递增的。

CONT设为TRUE,保持连接,这样速度最快。

图:PLC端程序

在网络连接设置中指定PC端的IP地址和端口号,端口号要和服务器监听的端口号一致。由PLC主动发起连接。

图:PLC端网络连接设置

初步的结果

下图中,黄色为PLC端的输入(信号1),绿色为树莓派上收到数据后的输出(信号2)。

都以上升沿作为标志。两者的时间差不到9ms。

图:通信耗时的波形图

可以更快吗?

通信负载

由通信引起的循环负荷:默认是20%,取值可以从15%到50%。改变这个值,发现对通信时间并没有影响。

输入滤波器

这个值默认是6.4ms,它是用来过滤按键抖动的。但对于电路触发(非人工/机械按键)的情况,这个抖动可以设得很小。

图:PLC输入滤波器

将它调小至0.1ms,整个耗时降低了约6ms. 通信耗时不到3ms了。

图:通信耗时(0.1ms输入滤波)

循环时间

PLC的运行方式是不断循环去读取输入,执行程序块,更新输出的模式。循环周期过长,是否会影响网络通信呢?

通过在线诊断,可以看到循环时间最长为4ms,通常都在1~2ms。

图:PLC循环时间

这说明循环时间并不是瓶颈。而且反过来,循环时间比通信时间还短(即使输入滤波器为6.4ms,通信时间9ms时,循环时间依然是1~2ms),这说明通信和循环似乎是分头执行的。

其它

本来还想试一下中断执行方式的,但把通信程序块放到中断响应里执行并没有成功。考虑到对于PLC的百兆网口,3ms已经够快了,就没再折腾了。

还试验了一下,在PLC上单纯地增加一个计数器或反复翻转输出电平,每次操作耗时大约也是3ms。

顺便说一句,在PLC的数字输出上,却看不到电平的翻转(看到的总是高电平)。前面有一张“递增写DQ时DQ0.0的波形”图,18ms的周期,基本上已看不到电平下降到0了。感觉PLC的输出频率并不高,甚至可能有高频滤波。

结语

从PLC的众多网络通信方式中,本文试验了简单易行并且跨平台的两种方式,用来和PC通信。

使用基于S7协议的Snap7库,在读写PLC时大约耗时9ms.

使用开放式的TCP协议,PLC向PC发送数据最快不到3ms.

考虑到S7-1200只是百兆网络,这个速度应该是不错的,可以满足大部分需要。

python 网络通讯 plc_PLC与PC网络通信实验相关推荐

  1. python 网络通讯 plc_Python TCP通信网络编程

    最近在看廖雪峰老师的基础教程(http://www.liaoxuefeng.com/),今天实现了一下简单Python的Socket的网络编程. 1. Socket网络编程 Socket是网络编程的一 ...

  2. python 网络嗅探实验

    python 网络嗅探实验 #!/usr/bin/env python3.6 # coding: utf-8import socket import struct import binascii# 变 ...

  3. 网络工程师课程---7、网络通信综合实验(做网络基础综合实验 用什么软件)...

    网络工程师课程---7.网络通信综合实验(做网络基础综合实验 用什么软件) 一.总结 一句话总结: cisco packet ['pækɪt]  tracer ['treɪsə] packet 英 [ ...

  4. python实验总结与反思_警示与反思丨什么是Python网络爬虫?看这篇清晰多了!

    原标题:警示与反思丨什么是Python网络爬虫?看这篇清晰多了! 什么是爬虫? 网络爬虫(Web crawler),就是通过网址获得网络中的数据.然后根据目标解析数据.存储目标信息.这个过程可以自动化 ...

  5. python网络爬虫实验报告_Python网络爬虫实例讲解

    聊一聊Python与网络爬虫. 1.爬虫的定义 爬虫:自动抓取互联网数据的程序. 2.爬虫的主要框架 爬虫程序的主要框架如上图所示,爬虫调度端通过URL管理器获取待爬取的URL链接,若URL管理器中存 ...

  6. python网络编程内容_图解Python网络编程

    Python Python开发 Python语言 图解Python网络编程 本篇索引 (1)基本原理 本篇指的网络编程,仅仅是指如何在两台或多台计算机之间,通过网络收发数据包:而不涉及具体的应用层功能 ...

  7. 真良心干货保姆级手把手教你Python网络编程,学不会我去你家教你

    Python网络编程 基本概念(计算机网络基础) IP地址与端口 IP地址 端口 网络通信协议 网络通信协议 网络协议的分层 TCP/UDP 套接字编程 socket()函数介绍 UDP 编程 实现U ...

  8. 客户端程序初步加入网络通讯的功能

    文章目录 1 客户端初步加入网络通讯的功能 1.1 设计方案 1.2 代码实现 1 客户端初步加入网络通讯的功能 1.1 设计方案 在主窗口类中使用客户端类: 初步设计方案: 主窗口通过ClientD ...

  9. python 网络渗透_python 网络编程(渗透与编程一)

    原博文 2016-03-31 18:17 − 0x00 网络一直是黑客们最喜欢的竞技场.通过简单的网络访问,攻击者可以做任何想做的事情.例如主机扫描,数据包注入,远程攻击等.但是当我们通过某种方法进入 ...

最新文章

  1. SSAS系列——【03】多维数据(多维数据集对象)
  2. jQueryh插件imgareaselect
  3. 跟新centos的yum源
  4. 为什么Java在后来的版本中,给接口增加了默认方法、静态方法、私有方法?
  5. 谷歌Colab GPU达到使用量限额解决办法
  6. 前端后台与接口的问题
  7. 版本控制工具(svn)
  8. html无限循环弹出窗代码,html网页弹窗代码(一个IP24小时只弹一次)
  9. 数据库(SQL)面试题,基础知识(超全面)
  10. NFC读卡MS522|CV520
  11. 字节跳动Java金三银四解析:阿里巴巴技术专家之作
  12. 换成Everyone还是访问被拒绝的解决办法
  13. 拉勾网爬取失败?试试这一招
  14. 荆棘鸟(The Thorn bird)
  15. matlab语音识别系统(源代码),matlab语音识别系统(源代码)
  16. 对象可以创建数组吗_企业微信活码如何创建?活码可以统计渠道来源吗?
  17. QT中使用GDAL多线程读取遥感图像到QImage
  18. Arpg战斗系统-技能学习篇
  19. 毕业设计管理系统 数据库设计
  20. bigdata101:Permission denied (publickey .....) 这次的不一样

热门文章

  1. LeetCode-26: 删除排序数组中的重复项
  2. 【PC工具】常用USB转串口芯片CP210x驱动,CH340G驱动安装有可能遇到的问题及解决办法...
  3. 【arduino】ESP32 SPIFFS插件使用报错及解决方法:SPIFFS Error:esptool not found!
  4. android 原生砸金蛋 动画,C4D-砸金蛋动画效果制作
  5. 聊聊flink的logback配置
  6. 导出toolStrip1中的图标
  7. 一句话搞定python六剑客
  8. HDFS 常用操作分类汇总整理
  9. zabbix—安装agent客户端(linux版)
  10. linux将bridge当做hub来用