当前位置:   article > 正文

利用Snap7完成上位机对plc数据的读写_基于snap7读取plc

基于snap7读取plc

1.读单个储存区域

read_area(area,dbnumber,start,size)

area:区分读写区域

  1. areas = ADict({
  2. 'PE': 0x81, #input 输入区
  3. 'PA': 0x82, #output 输出区
  4. 'MK': 0x83, #bit memory 中间存储区(M区)
  5. 'DB': 0x84, #DB区
  6. 'CT': 0x1C, #counters
  7. 'TM': 0x1D, #Timers
  8. })

dbnumber:只有在对DB块使用时才有用,默认设置为0

start:起始地址为Q0.4的这个0(也就是输出的第几个字节)

size:选择读取的数据类型,下表(为什么选择地址这里没有说要给出Q0.4的4呢?是因为读取数据类型以byte(字节,即至少读取8位)起步,由参数size决定,要对位进行操作可以在读取后采用其他指令对具体某一位做读写

        位bit,音译为“比特”,表示二进制位

        字节Byte,音译为“拜特”,习惯上用大写的“B”表示,一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit),1个字节可以存入一个ASCII码,2个字节可以存放一个汉字国标码

        字(word),计算机进行数据处理时,一次存取、加工和传送的数据长度,一个字通常由一个或多个(一般是字节的整数位)字节构成

2、采用snap7 对PLC的输出进行读写

一个专门用来构建读取和改写的函数,另一个则是用使用构造的函数进行读写操作,比较推荐这种,下次要用直接调用,一行代码实现读写

读取---置换---写入

  1. from snap7.util import * #对位操作的函数要导入该库
  2. #定义的函数可直接对QX.X一个位进行操作
  3. def Writeoutput(dev,byte,bit,cmd):
  4. data=dev.read_area(0x82,0,byte,1)#0x82表示输出Q,byte表示起始地址(Q0),1表示类型为byte,cmd位置的值(True或False)
  5. set_bool(data,byte,bit,cmd) #置Qbyte.bit(即Q0.4)为cmd(即True)
  6. dev.write_area(0x82,0,byte,data)#同样,进行写数据操作
  7. #该函数只进行了读操作
  8. def Readoutput(dev,byte,bit):
  9. data=dev.read_area(0x82,0,byte,1)
  10. status=get_bool(data,byte,bit) #获取位状态
  11. return status
  1. import snap7
  2. import plc as PLC #导入前面的plc.py文件(注意两个py文件在一个文件夹)
  3. myplc=snap7.client.Client()
  4. myplc.connect('192.168.0.1', rack=0,slot=1) #建立连接(相关信息去TIA看,IP,机架和插槽)
  5. print(myplc.get_connected()) # 测试是否通讯成功
  6. #使用plc.py里构建的两个函数(写、读)
  7. PLC.Writeoutput(myplc,0,4,True) #该函数效果就是写Q0.4为True
  8. status=PLC.Readoutput(myplc,0,4) #该函数效果就是读取Q0.4的值
  9. print(status)

3.读取数据块

  1. import snap7
  2. from snap7.util import *
  3. from snap7.snap7types import *
  4. class DBObject(object): #空对象,用于后面__setattr__使用
  5. pass
  6. #offset是字典,其内容代表各类型数据所占字节长度
  7. offset={"Bool":2,"Int":2,"Real":4,"Dint":4,"String":256} #实测所占长度准确
  8. #db表示要读取的信息,由上图得到,中间用Tab隔开,非空格
  9. db=\
  10. """
  11. Temperature Real 0.0
  12. Cold Bool 4.0
  13. RPis_to_Buy Int 6.0
  14. Db_test_String String 8.0
  15. """
  16. #get_db_size用来获取DB块内数据长度,由最后一个数据起始地址和它的数据类型得到(这里是8.0和String,长度就是8+256=264),就这一个作用(苦笑)
  17. def get_db_size(array,bytekey,datatypekey):#bytekey:地址 datatypekey:数据类型
  18. seq,length=[x[bytekey] for x in array],[x[datatypekey] for x in array]
  19. idx=seq.index(max(seq)) #index就来检索位置
  20. lastByte=int(max(seq).split('.')[0])+(offset[length[idx]])
  21. return lastByte #返回DB块内要读取的最末尾位置,这里是264
  22. #DBRead才是用来读取数据的函数,length是获取的最大长度
  23. def DBRead(myplc,db_num,length,items):
  24. data=myplc.read_area(0x84,db_num,0,length)
  25. obj=DBObject()
  26. for item in items:
  27. value=None
  28. offset=int(item['bytebit'].split('.')[0]) #取数据起始位置
  29. ##读取各种数据类型的数据
  30. if item['data']=='Real':
  31. value=get_real(data,offset)
  32. if item['data']=="Bool":
  33. bit=int(item['bytebit'].split('.')[1])
  34. value=get_bool(data,offset,bit)
  35. if item['data']=="Int":
  36. value=get_int(data,offset)
  37. if item['data']=='String':
  38. value=get_string(data,offset,256)
  39. obj.__setattr__(item['name'],value)#构建obj.item['name']=value形式,方便后续输出
  40. return obj
  41. if __name__=="__main__":
  42. myplc=snap7.client.Client()
  43. myplc.connect('192.168.0.1', rack=0,slot=1)
  44. #过滤器函数,把后面list内的东西放入前面的函数判断,生成返回为True的新list
  45. itemlist=list(filter(lambda a:a!='',db.split('\n'))) #提取每行数据(一行一个)
  46. #把每个数据的name(名字)、data(数据类型)bytebit(起始地址)归好类
  47. items=[
  48. {
  49. "name":x.split( )[0], #参数名
  50. "data":x.split( )[1], #数据类型
  51. "bytebit":x.split( )[2] #数据起始地址
  52. } for x in itemlist
  53. ]
  54. #调用函数,先获取数据长度,再读取各个数据的值,放在对象实例里面obj
  55. length=get_db_size(items,'bytebit','data')
  56. meh=DBRead(myplc,10,length,items)
  57. #输出各个数据
  58. print('''
  59. Cold:\t\t\t{}
  60. Tempeature:\t\t{}
  61. Rpis_to_Buy:\t\t{}
  62. Db_test_String:\t{}
  63. '''.format(meh.Cold,meh.Temperature,meh.RPis_to_Buy,meh.Db_test_String))
  64. myplc.disconnect();

4.写入数据块

  1. def DBRead(myplc,db_num,length,items):
  2. data=myplc.read_area(0x84,db_num,0,length)
  3. obj=DBObject()
  4. for item in items:
  5. value=None
  6. offset=int(item['bytebit'].split('.')[0]) #取数据起始位置
  7. ##读取各种数据类型的数据
  8. if item['data']=='Real':
  9. value=get_real(data,offset)
  10. set_real(data,offset,132.032)
  11. if item['data']=="Bool":
  12. bit=int(item['bytebit'].split('.')[1])
  13. value=get_bool(data,offset,bit)
  14. set_bool(data,offset,0,False)
  15. if item['data']=="Int":
  16. value=get_int(data,offset)
  17. set_int(data,offset,312)
  18. if item['data']=='String':
  19. value=get_string(data,offset,256)
  20. print(offset)
  21. set_string(data,offset,'Who I am',256)
  22. myplc.write_area(0x84,db_num,0,data)
  23. obj.__setattr__(item['name'],value) #构建obj.item['name']=value形式,方便后续输出
  24. return obj

5.数据块快速读写

  1. import snap7
  2. from snap7.util import *
  3. from snap7.snap7types import *
  4. myplc=snap7.client.Client()
  5. myplc.connect('192.168.0.1', rack=0,slot=1)
  6. data=myplc.read_area(0x84,10,0,256) #知道是DB10了
  7. value=get_int(data,6) #已经知道6.0 是int型
  8. print(value)
  9. set_int(data,6,112)
  10. myplc.write_area(0x84,10,0,data)

来源:采用snap7实现对PLC1200的I、Q、M、DB区域进行读写_python snap7读写m区-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_41320090/article/details/93708694

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/685285
推荐阅读
相关标签
  

闽ICP备14008679号