PLC(Programmable Logic Controller)即可编程逻辑控制器,可以理解为一个微型计算机,广泛应用于工业控制领域中,包括楼宇智控、精密机床、汽车电子等等。

随着物联网的兴起,越来越多的传统工业设备需要和外界通信,但很多情况下,类似PLC的微控制器经常会由于自身硬件因素而无法与外界直接互联互通。PC作为一个中介桥梁,为PLC与外界的沟通打开了一扇门。

而Python作为当前最火的语言,不仅在AI、云计算等诸多方面都能看到它的身影,在工业控制中也不能少了它。本文就来分享下如何使用Python构建PC与PLC的通信,也算展示一把Python在工控领域的风采。


Snap7简介

当前市场上主流的PLC通信方式为网络通信和串行通信。网络通信这块主要协议有profinet,modbus-tcp等,串行通信主要是基于RS232/485的modbus。

本次接触到的是西门子S7系列的PLC,通信方式都为网络型的,而Snap7(http://snap7.sourceforge.net/)正是一个开源的、32/64位的、多平台的以太网通讯库:

  • 支持多硬件体系结构(i386/x86_64、ARM/ARM64、Sun Sparc、Mips);

  • 支持多系统(Windows、Linux、BSD、Solaris);

  • 支持多语言(C/C++、Phyton、Node.js、Pascal、C#、VB)。

Python对其进行了封装,具体可以参见:https://github.com/gijzelaerr/python-snap7。

开发环境搭建


这里主要从Windows和Linux(Ubuntu)两个平台,说说如何搭建Python环境下的Snap7开发环境。Python的安装这里就不再赘述,环境搭建主要就是Snap7和python-snap7两个库的安装。

1、安装Snap7

Windows下,需要根据Python的结构版本(32位/64位),将下载的Snap7的发布库copy到对应的Python安装根目录下即可。

如上图所示,我的Python是32bit,所以需要将Snap7中Win32目录下的文件Copy到Python的安装根目录下,如下图所示:

Linux(Ubuntu)下安装相对简单些,按如下命令即可:

$ sudo -s
$ add-apt-repository ppa:gijzelaar/snap7
$ apt-get update
$ apt-get install libsnap71 libsnap7-dev

2、安装python-snap7

Snap7的Python库安装就简单很多了,不管是Windows还是Linux,直接pip安装即可。

$ pip install python-snap7

经过上面两步,环境就算搭建好了。通过一个连接测试代码试试,判断下环境是否搭建正常。

import snap7
client = snap7.client.Client()
client.connect('192.168.0.1', 0, 1)
client.disconnect()

如果是下图提示,则环境正常(192.168.0.1的PLC不存在)。

如果是下图提示,则环境异常(snap7库安装不正确)。


读写PLC

环境搭建正常后,在正式建立通信前PLC还需做些配置工作,主要是开发自身的读写权限。具体参照下图配置:

通过上述配置,PLC可以正常通信了。

1、python-snap7读写分析

结合python-snap7的文档API和源码分析,python-sna7重要的两个方法是read_area和write_area,通过这两个方法就能读和写PLC的对应存储地址。

def read_area(self, area, dbnumber, start, size):
       """This is the main function to read data from a PLC.
       With it you can read DB, Inputs, Outputs, Merkers, Timers and Counters.

:param dbnumber: The DB number, only used when area= S7AreaDB
       :param start: offset to start writing
       :param size: number of units to read
       """
       assert area in snap7.snap7types.areas.values()
       wordlen = snap7.snap7types.S7WLByte
       type_ = snap7.snap7types.wordlen_to_ctypes[wordlen]
       logger.debug("reading area: %s dbnumber: %s start: %s: amount %s: "
                     "wordlen: %s" % (area, dbnumber, start, size, wordlen))
       data = (type_ * size)()
       result = self.library.Cli_ReadArea(self.pointer, area, dbnumber, start,
                               size, wordlen, byref(data))
       check_error(result, context="client")
       return bytearray(data)

@error_wrap
   def write_area(self, area, dbnumber, start, data):
       """This is the main function to write data into a PLC. It's the
       complementary function of Cli_ReadArea(), the parameters and their
       meanings are the same. The only difference is that the data is
       transferred from the buffer pointed by pUsrData into PLC.

:param dbnumber: The DB number, only used when area= S7AreaDB
       :param start: offset to start writing
       :param data: a bytearray containing the payload
       """
       wordlen = snap7.snap7types.S7WLByte
       type_ = snap7.snap7types.wordlen_to_ctypes[wordlen]
       size = len(data)
       logger.debug("writing area: %s dbnumber: %s start: %s: size %s: "
                     "type: %s" % (area, dbnumber, start, size, type_))
       cdata = (type_ * len(data)).from_buffer_copy(data)
       return self.library.Cli_WriteArea(self.pointer, area, dbnumber, start,
                              size, wordlen, byref(cdata))

从参数可见,需要提供PLC的区域地址、起始地址、读和写的数据长度。PLC能提供如下信息:

2、PLC数据存储和地址

通过阅读PLC的手册获取到如下信息:

PLC的数据存储通过Tag的形式与存储区间关联,分为输入(I)、输出(O)、位存储(M)和数据块(DB)。程序在访问对应(I/O)tag时,是通过访问CPU的Process Image Out对相应地址进行操作的。具体对应关系如下:

到这里就能明白python-snap7中定义的areas地址是什么含义了。

areas = ADict({
   'PE': 0x81,  #input
   'PA': 0x82,  #output
   'MK': 0x83,  #bit memory
   'DB': 0x84,  #DB
   'CT': 0x1C,  #counters
   'TM': 0x1D,  #Timers
})

现在离读写PLC还差最后一步,就是起始地址如何确定呢?

从上可见对于M3.4,对应的就是M(0x83),起始地址是3,对应bit位是4。

实战

经过上面的精心准备,下面就来一波实战。通过读写PLC的M10.1、MW201来具体看看如何读写PLC。

import struct
import time

import snap7

def plc_connect(ip, rack=0, slot=1):
   """
   连接初始化
   :param ip:
   :param rack: 通常为0
   :param slot: 根据plc安装,一般为0或1
   :return:
   """
   client = snap7.client.Client()
   client.connect(ip, rack, slot)
   return client

def plc_con_close(client):
   """
   连接关闭
   :param client:
   :return:
   """
   client.disconnect()

def test_mk10_1(client):
   """
   测试M10.1
   :return:
   """
   area = snap7.snap7types.areas.MK
   dbnumber = 0
   amount = 1
   start = 10
   print(u'初始值')
   mk_data = client.read_area(area, dbnumber, start, amount)
   print(struct.unpack('!c', mk_data))

print(u'置1')
   client.write_area(area, dbnumber, start, b'')
   print(u'当前值')
   mk_cur = client.read_area(area, dbnumber, start, amount)
   print(struct.unpack('!c', mk_cur))

def test_mk_w201(client):
   """
   测试MW201,数据类型为word
   :param client:
   :return:
   """
   area = snap7.snap7types.areas.MK
   dbnumber = 0
   amount = 2
   start = 201
   print(u'初始值')
   mk_data = client.read_area(area, dbnumber, start, amount)
   print(struct.unpack('!h', mk_data))

print(u'置12')
   client.write_area(area, dbnumber, start, b'')
   print(u'当前值')
   mk_cur = client.read_area(area, dbnumber, start, amount)
   print(struct.unpack('!h', mk_cur))

time.sleep(3)
   print(u'置3')
   client.write_area(area, dbnumber, start, b'')
   print(u'当前值')
   mk_cur = client.read_area(area, dbnumber, start, amount)
   print(struct.unpack('!h', mk_cur))

if __name__ == "__main__":
   client_fd = plc_connect('192.168.0.1')
   test_mk10_1(client_fd)
   test_mk10_1(client_fd)
   plc_con_close(client_fd)

从代码可见,MW201,根据M确定area为MK,根据W确定数据amount为2Btye,根据201确定start为201,读出来的数据根据数据长度用struct进行unpack,写数据对应strcut的pack。

这里给出PLC变量类型和大小,这样对应确定读写的amount。

最后给出一段视频,Python操作PLC来个跑马灯。

声明:本文为作者投稿,原载于个人公众号chafezhou,版权归作者所有。

如何使用 Python 构建 PC 通信?相关推荐

  1. 如何使用 Python 构建 PLC 通信?

    转自:https://www.toutiao.com/a6589203413941092868/?tt_from=mobile_qq&utm_campaign=client_share& ...

  2. 如何使用 Python 构建 西门子PLC Snap7通信

    如何使用 Python 构建西门子 PLC Snap7通信 PLC(Programmable Logic Controller)即可编程逻辑控制器,可以理解为一个微型计算机,广泛应用于工业控制领域中, ...

  3. python零基础教学plc_利用Python构建电脑和PLC通信的方法

    PLC(Programmable Logic Controller)即可编程逻辑控制器,可以理解为一个微型计算机,广泛应用于工业控制领域中,包括楼宇智控.精密机床.汽车电子等等. 随着物联网的兴起,越 ...

  4. python构建json_如何使用Python构建JSON API

    python构建json The JSON API specification is a powerful way for enabling communication between client ...

  5. 使用python构建数据库_使用Python构建(半)自主无人机

    使用python构建数据库 They might not be delivering our mail (or our burritos) yet, but drones are now simple ...

  6. python中串口通信的步骤及实现

    python内置的库函数确实很强大,serial库中包含了串口通信所用到的一些函数.本文用python实现了串口的一种简单通信. 代码实现: import serial#导入串口通信库 from ti ...

  7. Jetson Nano串口通信----Nano与PC通信

    Jetson Nano串口通信(一) 一.Nano与PC通信 1.Nano端: 要使用Nano上的串口,用Python控制,先安装Python3版本的py-serial库 sudo apt-get i ...

  8. 用Python构建网页抓取器

    借助使用Python构建的尖端网页抓取技术,启动您的大数据项目 Scrape the Planet! Building Web Scrapers with Python 你会学到什么 如何理论化和开发 ...

  9. 一文告诉你,如何使用Python构建一个“谷歌搜索”系统 | 内附代码

    来源 | hackernoon 编译 | 武明利 责编 | Carol 出品 | AI科技大本营(ID:rgznai100) 在这篇文章中,我将向您展示如何使用Python构建自己的答案查找系统.基本 ...

最新文章

  1. div背景图 等比缩放
  2. matlab 计算大型距离方阵,distance matrix
  3. UA MATH523A 实分析1 集合论基础7 一些度量空间基本概念
  4. Gentoo 安装日记 12 (配置内核 :电源和bios)
  5. nginx日志分析脚本
  6. 模拟导入系统通讯录5000+手机号 校验大量数据处理
  7. 统计学习方法第二版知识点合集 - 自用笔记
  8. pthread条件变量函数的使用
  9. 通俗易懂!视觉slam第二部分——salm过程简介
  10. centos7 开机启动脚本
  11. php图片遍历,php – 如何遍历图像的所有像素?
  12. 写于Silverlight整装待发之际【瞿杰】
  13. python批量图片自动编码
  14. 利用Python批量修改多个ass字幕文件
  15. Egret 配置主题
  16. 做网站必备!该文介绍下国内服务器与国外服务器的区别
  17. 华为p50不会用鸿蒙系统,华为p50会不会预装鸿蒙系统_华为p50会预装鸿蒙系统吗...
  18. 2022年全球与中国超快激光器市场现状及未来发展趋势
  19. 导航栏不变 页面切换 最简单的方法
  20. 削皮刀的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

热门文章

  1. Golang的GC和内存逃逸
  2. Material Design设计技巧
  3. 中国水稻种子行业市场供需与战略研究报告
  4. MySQL比较两个表数据差异,在t2表而不在t1表的数据
  5. ubuntu 版mysql客户端工具_使用Ubuntu 20.04作为日常办公主力使用体验(远程维护工具)...
  6. 前端诸神大战,Vue、React 依旧笑傲江湖
  7. 领英·影响力2020:职场人再定位,千里马伯乐新论
  8. 风靡业内的跨端开源框架 uni-app 入驻 GitCode
  9. 不再惧怕!二叉树结构相关算法总结 | 原力计划
  10. 漫画:跑上百万次代码验证三门问题