使用python-snap7连接西门子1500 PLC读写数据时遇TypeError求助
问题
使用Python的snap7库连接西门子CPU 1500 PLC,连接成功,但读写内存时出现如下错误:
readbit = ReadMemory(plc, 0, 0, S7WLBit) #read m0.0 File c:\users\rachid\.spyder-py3\sps.py:22 in ReadMemory result = plc.read_area(areas['MK'],0,byte,datatype) File ~\anaconda3\Lib\site-packages\snap7\client\__init__.py:390 in read_area if area not in Areas: File ~\anaconda3\Lib\enum.py:740 in __contains__ raise TypeError( TypeError: unsupported operand type(s) for 'in': 'int' and 'EnumType'
原代码如下:
import snap7 from snap7.util import* from snap7.types import* import time def ReadMemory(plc,byte,bit,datatype): result = plc.read_area(areas['MK'],0,byte,datatype) if datatype==S7WLBit: return get_bool(result,0,1) elif datatype==S7WLByte or datatype==S7WLWord: return get_int(result,0) elif datatype==S7WLReal: return get_real(result,0) elif datatype==S7WLDWord: return get_dword(result,0) else: return None def WriteMemory(plc,byte,bit,datatype,value): result = plc.read_area(areas['MK'],0,byte,datatype) if datatype==S7WLBit: set_bool(result,0,bit,value) elif datatype==S7WLByte or datatype==S7WLWord: set_int(result,0,value) elif datatype==S7WLReal: set_real(result,0,value) elif datatype==S7WLDWord: set_dword(result,0,value) plc.write_area(areas['MK'],0,byte,result) # Verbindung zur SPS herstellen plc = snap7.client.Client() plc.connect(spshost, 0, 1) #IP, RACK , SLOT state = plc.get_cpu_state() print(f'State:{state}') a = 0 b = 0 c = 0 while True: readbit = ReadMemory(plc, 0, 0, S7WLBit) #read m0.0 print('readbit: ', readbit) readword = ReadMemory(plc, 10, 0, S7WLWord) #read mw10 print('readbyte: ',readword) readreal = ReadMemory(plc, 15, 0, S7WLReal) #read md15 print('readreal: ',readreal) readDword = ReadMemory(plc, 20, 0, S7WLDWord) #read md20 print('readDword: ', readDword) a = a+1 b = b+2.4 c = c+10 #write memory WriteMemory(plc, 0, 3, S7WLBit, True) #write m0.3 True time.sleep(1) WriteMemory(plc, 0, 3, S7WLBit, False) #write m0.3 False time.sleep(1) WriteMemory(plc, 30, 0, S7WLWord, a) #write mw30 valuefrom a variable WriteMemory(plc, 40, 0, S7WLReal, b) #write md40 value WriteMemory(plc, 50, 0, S7WLDWord, c) #write md50 value
修复方案
错误根源是snap7新版本中Areas为枚举类型,不再兼容旧版本的整数传参方式,结合代码其他问题,修复点如下:
- 替换内存区域参数:用
snap7.types.Areas枚举值替代旧的areas['MK']写法,比如Areas.MK - 修正位读取索引:原代码中读取位时固定用
get_bool(result,0,1),改为使用传入的bit参数,确保读取指定位 - 补充PLC地址定义:原代码中
spshost未定义,需添加实际PLC的IP地址
修改后的完整代码:
import snap7 from snap7.util import * from snap7.types import * import time def ReadMemory(plc, byte, bit, datatype): # 使用Areas枚举替代旧字典写法 result = plc.read_area(Areas.MK, 0, byte, datatype) if datatype == S7WLBit: # 修复位索引,使用传入的bit参数 return get_bool(result, 0, bit) elif datatype == S7WLByte or datatype == S7WLWord: return get_int(result, 0) elif datatype == S7WLReal: return get_real(result, 0) elif datatype == S7WLDWord: return get_dword(result, 0) else: return None def WriteMemory(plc, byte, bit, datatype, value): # 使用Areas枚举替代旧字典写法 result = plc.read_area(Areas.MK, 0, byte, datatype) if datatype == S7WLBit: set_bool(result, 0, bit, value) elif datatype == S7WLByte or datatype == S7WLWord: set_int(result, 0, value) elif datatype == S7WLReal: set_real(result, 0, value) elif datatype == S7WLDWord: set_dword(result, 0, value) plc.write_area(Areas.MK, 0, byte, result) # 定义PLC实际IP地址 spshost = "192.168.0.1" # 替换为你的PLC IP plc = snap7.client.Client() plc.connect(spshost, 0, 1) # IP, RACK , SLOT state = plc.get_cpu_state() print(f'State:{state}') a = 0 b = 0.0 c = 0 while True: readbit = ReadMemory(plc, 0, 0, S7WLBit) # read m0.0 print('readbit: ', readbit) readword = ReadMemory(plc, 10, 0, S7WLWord) # read mw10 print('readword: ', readword) readreal = ReadMemory(plc, 15, 0, S7WLReal) # read md15 print('readreal: ', readreal) readDword = ReadMemory(plc, 20, 0, S7WLDWord) # read md20 print('readDword: ', readDword) a += 1 b += 2.4 c += 10 # write memory WriteMemory(plc, 0, 3, S7WLBit, True) # write m0.3 True time.sleep(1) WriteMemory(plc, 0, 3, S7WLBit, False) # write m0.3 False time.sleep(1) WriteMemory(plc, 30, 0, S7WLWord, a) # write mw30 value from variable WriteMemory(plc, 40, 0, S7WLReal, b) # write md40 value WriteMemory(plc, 50, 0, S7WLDWord, c) # write md50 value
内容的提问来源于stack exchange,提问作者mzr97
相关产品推荐
相关产品推荐

