Python_Example_modbus协议 串口 _接收_处理_响应 实现程序

2018-09-13

Author: 楚格

IDE: Pycharm2018.02   Python 3.7   

KeyWord : 串口数据发送与接收 modbus  CAN

Explain:

 思路:

1.打开串口 (Function_Serial_Info() # 打开串口)

2.循环接收数据 (Function_Receive_Data() # 接收函数)

3.处理数据(暂时是赋值,未作读取Excel处理)[数据的modbus以及添加]

4.响应数据(Function_Handle_Reveice() # 处理函数)

5发送数据(Function_Send_Data()#发送函数)

1------------------------------------------------------------------------------------------------------------------

  1 __all__ = []
  2 
  3 import sys
  4 import os
  5 
  6 import re
  7 import string
  8 import binascii
  9 import array
 10 import signal
 11 import serial
 12 import time
 13 from time import sleep
 14 
 15 # =========================================
 16 
 17 
 18 '''
 19 # ------------------------------------------
 20 # 导入:本文件夹中 .py 模块
 21 # 直接引用模块名称
 22 # ------------------------------------------
 23 '''
 24 # preject module
 25 from Testing_CRC import *
 26 
 27 
 28 # ============================================================================
 29 
 30 
 31 
 32 '''
 33 # ============================================================================
 34 # Function:   串口设置  函数
 35 # Explain : 
 36 #         :
 37 # ============================================================================
 38 '''
 39 def Function_Serial_Info():
 40     print('串口初始化  Function_Serial_Info')
 41     # -----------------------------
 42 
 43     global global_var_serial_init
 44     global global_var_serial_band
 45 
 46     # 必须设置串口
 47     local_var_serial_func = True
 48 
 49     while local_var_serial_func:
 50 
 51         print("默认请输入:1  
重新输入为:2")
 52 
 53         # default = input('您的请选择:  ')
 54         default = "1"     # debug
 55 
 56         if default == "1":
 57             global_var_serial_init = serial.Serial(port="COM5", baudrate=115200, timeout=1)  # 端口控制
 58             local_var_serial_func = False     # 结束执行
 59 
 60         elif default == "2":
 61             port = input('串口号(数字): ', )   # 端口号
 62 
 63             local_var_serial_nunber = True
 64 
 65             while local_var_serial_nunber:
 66                 print('可选波特率:1 = 9600 
		 2 = 115200')
 67                 global_var_serial_band = input('波特率序号: ')
 68 
 69                 if global_var_serial_band == "1":
 70                     global_var_serial_band = 9600
 71                     local_var_serial_nunber = False
 72 
 73                 elif global_var_serial_band == "2":
 74                     global_var_serial_band = 115200
 75                     local_var_serial_nunber = False
 76 
 77                 else:
 78                     print('超出范围:请重新选择波特率!')
 79                     local_var_serial_nunber = True
 80 
 81                 # 组装成串口初设信息
 82             global_var_serial_init = serial.Serial(port="COM" + port, baudrate=global_var_serial_band, timeout=1)  # 端口控制
 83 
 84             local_var_serial_func = False  # 结束执行
 85 
 86         else:
 87             print('超出选择范围,请重新选择序号!')
 88             local_var_serial_func = True  # 返回继续执行
 89 
 90     # ------------------------------------------------------
 91 
 92 
 93 '''
 94 # ============================================================================
 95 # Function:   接受数据  函数
 96 # Explain :   接受串口收到的数据
 97 #         :
 98 # ============================================================================
 99 '''
100 def Function_Receive_Data():
101     print('Function_Receive_Data :')
102     # ======================================
103     global global_var_receive_string  # 作为获取到的数据
104 
105     # 接收单次数据,外部进行处理 SINGLE    #循环接收数据,内部进行处理 LOOP
106     FREQUENCY = True
107     SINGLE    = False
108     LOOP      = True
109 
110     if FREQUENCY == SINGLE:
111         print(SINGLE)
112         # 待开发模块
113 
114     elif FREQUENCY ==LOOP:
115         print('LOOP: ')
116         # ------------------------------------------------------
117         line = global_var_serial_init.readline()  # 读取全部内容
118         print("Len     :", len(line), " Type :", type(line), "    readline : %s" % line)
119 
120         # 字节变成字符串,目的是方便处理数据
121         types_transform_string = line.hex()  # 字节变成字符串
122         print("Len     :", len(types_transform_string), type(types_transform_string), types_transform_string)
123 
124         # ------------------------------------------------------
125         # 数据名称变换 目的是作为全局变量
126         global_var_receive_string = types_transform_string
127 
128         # return global_var_receive_string
129 
130     else:
131         pass
132     # ------------------------------------------------------
133 
134 '''
135 # ============================================================================
136 # Function:  发送数据  函数
137 # Explain :  发送数据到串口 
138 #          golal_var_result_send_data
139 # ============================================================================
140 '''
141 def Function_Send_Data(send_data):
142     print('发送指令函数  Function_Send_Data')
143     # ---------------------------
144     print('''
145             ---- Info of Send Data Parameter ----        
146                 Send   data    : %s
147                 Serial Port    : %s 
148             ''' % ( send_data,global_var_serial_init.port)
149           )
150 
151     #  判断是字符串还是字节
152     #  or define b'string',bytes should be used not str
153     # serInstance.write(atCmdStr.encode('utf-8'))
154 
155     local_var_send_data_buff =send_data
156     #--------------------------------------
157     # 发送函数 核心语句 输出接口
158     global_var_serial_init.write(local_var_send_data_buff)
159     #--------------------------------------
160 
161     # global_var_serial_init.close() # 关闭串口
162     # global_var_serial_init.open()  # 打开端口
163     # global_var_serial_init.isOpen() #串口是否被打开
164 # ---------------------------------------------------------
165 '''
166 # ============================================================================
167 # Function: 数据处理   函数
168 # Explain:  接收数据进行处理
169 #           global_var_receive_string
170 # ============================================================================
171 '''
172 def Function_Handle_Reveice():
173     print('Function_Handle_Reveice : ')
174     # ======================================
175     # global global_var_send_data
176     global global_var_crc_value
177 
178     local_var_handle_data = global_var_receive_string
179 
180     # 字符串重新规整 剪断拼接字符串
181     DIVISION = 24
182     local_var_handle_data = local_var_handle_data[10:] +local_var_handle_data[:10]
183     local_var_Temp_1 =local_var_handle_data[ :DIVISION]        # 新划分的数据 local_var_Temp_1
184     local_var_Temp_2 =local_var_handle_data[DIVISION: ]        # 新划分的数据 local_var_Temp_2
185 
186     print('''
187             ---- info of new string ----
188                 local_var_Temp_1  : %s
189                 CAN_ID            : %s
190                 Modbus_data       : %s
191                 local_var_Temp_2  : %s
192                 CAN_ID            : %s
193                 Modbus_data       : %s
194             ''' % (local_var_Temp_1,local_var_Temp_1[:8],local_var_Temp_1[8:],
195                    local_var_Temp_2, local_var_Temp_2[:8], local_var_Temp_2[8:]
196                    )
197           )
198 
199     # 结果存留区
200     '''
201     #---------------------------------------------------------------------------------------
202     #                     0x04 功能码请求报文格式说明
203     # 
204     # 数据含义    设备地址    功能码     寄存器起始地址     寄存器数量       CRC校验码
205     # 字节数        1         1          2               2               2       (Bytes)
206     # 说明        0-255     0x04    0x0000-0xFFFF      1-125(0x7D)
207     # 
208     #                     0x04 功能码请求正常回复报文格式说明
209     #                     
210     #  数据含义    设备地址    功能码     字节数        数据内容           CRC校验码                 
211     #  字节数        1         1        1            2xN                 2       (Bytes)       
212     #  说明        0-255     0x04    2×N :2-250     N 为被请求的寄存器数      
213     # ---------------------------------------------------------------------------------------      
214     '''
215     # request data format
216     L_DIVI = 0
217     result_CAN_ID         = local_var_Temp_1[(L_DIVI +  0):(L_DIVI +  8)]
218     result_slave_address  = local_var_Temp_1[(L_DIVI +  8):(L_DIVI + 10)]
219     result_slave_function = local_var_Temp_1[(L_DIVI + 10):(L_DIVI + 12)]
220     result_slave_register = local_var_Temp_1[(L_DIVI + 12):(L_DIVI + 16)]
221     result_slave_number   = local_var_Temp_1[(L_DIVI + 16):(L_DIVI + 20)]
222 
223     # 根据不同 result_CAN_ID 进行处理,包括组包  response data
224 
225     if result_CAN_ID == '00000001':
226         print(result_CAN_ID,result_slave_register,result_slave_number)
227         '''
228         # 保存CANID addr function REG && NUM (需要判断进行处理) 然后进行CRC
229         # 进行处理,先赋值,后变量读取,最后读取Excel
230         '''
231         if (result_slave_register == '09c3') and (result_slave_number == '0052' ):
232 
233             # 这里是Excel接口 后期可以读取data 填充
234             Local_temp_value   = '080102030405060708'# CRC = 0x D4C9
235 
236             #--------------------
237             # 预处理目的:添加 CRC码
238             local_var_modbus_data = result_slave_address + result_slave_function + Local_temp_value
239             Pack_modbus_data = Function_HexString_Trans(local_var_modbus_data)
240             Pack_Buff_modbus_data = Function_Modbus_CRC(Pack_modbus_data,0)
241 
242             Pack_Buff_CAN_data = result_CAN_ID      # 作为格式对称保留
243 
244             local_var_result_send_data = Function_HexString_Trans(Pack_Buff_CAN_data) + Pack_Buff_modbus_data
245 
246             # * *************************
247             if BOOT_DEBUG :     # 开发层
248                 print('result_return_data: ', local_var_result_send_data)
249 
250             #--------------------------
251             # handle data finish got together package
252             # 这是处理完成后,组包发送给串口
253             #-------------------------------------------------------------------
254             Function_Send_Data(local_var_result_send_data)   # 核心 函数
255             #-------------------------------------------------------------------
256 
257     elif result_CAN_ID == '00000002':
258         print('2'*111)
259 
260     else:
261         pass
262 
263 
264     # ========================================================
265 
266 # ---------------------------------------------------------
267 
268 '''
269 # ============================================================================
270 # Function: Modbus CRC 校验   函数
271 # Explain:  输入参数  列表 [1, 4, 8, 1, 2, 3, 4, 5, 6, 7, 8          ]
272 #           输出参数  列表 [1, 4, 8, 1, 2, 3, 4, 5, 6, 7, 8, 212, 201]
273 #           check    right: 1   wrong: 0
274 #           
275 # ============================================================================
276 '''
277 def Function_Modbus_CRC(Pack_modbus_data,test_type):
278     print('Function_Modbus_CRC : ',)
279     #------------------------------------
280     global global_var_modbus_data_buff
281     global global_var_modbus_check
282 
283     if test_type == 0 :
284         # # CRC 校验 添加校验码
285         temp_crc_translate = CalCRC16(Pack_modbus_data, len(Pack_modbus_data))  # 核心步骤
286         # ****************
287         if BOOT_DEBUG:   # 开发层
288             print('crc_transformation: ', temp_crc_translate, type(temp_crc_translate))  # Int没有Len
289         # -------------------------
290         # # 注意添加先后顺序 先低 后高
291         Pack_modbus_data.append(int(hex(temp_crc_translate & 0xFF), 16))
292         Pack_modbus_data.append(int(hex((temp_crc_translate >> 8) & 0xFF), 16))
293         # print('Pack_Buff_modbus_data : ', len(Pack_modbus_data), type(Pack_modbus_data),Pack_modbus_data)  # calculation value   CRC
294         # -------------------------
295         global_var_modbus_data_buff = Pack_modbus_data  # 重新命名
296 
297         return global_var_modbus_data_buff
298 
299     # ---------------------------------------------------------
300     # CRC 校验检查 check
301     elif test_type == 1 :
302 
303         temp_CRC_check = CheckCRC(Pack_modbus_data, len(Pack_modbus_data), 0)
304 
305         if temp_CRC_check == 1:
306             print('Result    :', temp_CRC_check)  # check calculation value
307             print('CRC_Check : Right')
308             global_var_modbus_check = temp_CRC_check    # 重新命名
309 
310             return global_var_modbus_check
311 
312         else:
313             print('Result    :', temp_CRC_check)  # check calculation value
314             print('CRC_Check : wrong')
315             global_var_modbus_check = temp_CRC_check    # 重新命名
316 
317             return global_var_modbus_check
318 
319     # ---------------------------------------------------------
320 # ---------------------------------------------------------
321 '''
322 # ============================================================================
323 #   函数    数据转换
324 # Explain: 输入参数:data_trans
325 #          输出参数:global_var_trans_data
326 #   功能  :hex string转换为整形列表
327 # example: AT = '01F2AA0405'
328 #          SEND_AT = Function_HexString_Trans(AT)
329 #          print(SEND_AT)
330 #          Function_Send_Data(SEND_AT)
331 #          time.sleep(2)
332 # ============================================================================
333 '''
334 def Function_HexString_Trans(data_trans):
335     print('Function_HexString_Trans : ',)
336     #------------------------------------
337     global global_var_trans_data
338 
339     temp = bytearray.fromhex(data_trans)
340     global_var_trans_data= list(temp)
341     # print(global_var_trans_data)
342 
343     return global_var_trans_data
344 
345     # --------------------------------------------
346 
347 
348 
349 # ============================================================================
350 
351 
352 '''
353 # ============================================================================
354 #   测试专用
355 # ============================================================================
356 '''
357 if __name__ == '__main__':
358     print('-------------------------------------')
359     print('=		 欢迎进入   测试环境  			=')
360     print('-------------------------------------
')
361 
362     Function_Serial_Info()  # 打开串口
363     # 需要关闭窗口
364     # global_var_serial_init.close() # 关闭串口
365     # global_var_serial_init.open()  # 打开端口
366     print(global_var_serial_init.isOpen())
367 
368 
369     TEST_RUN   = True   # 测试层演示
370     USER_DEBUD = True   # 用户层调试 False
371     BOOT_DEBUG = True   # 开发层调试 False
372 
373     # 一直收到数据
374     while True:
375 
376         Function_Receive_Data()     # 接收函数
377         Function_Handle_Reveice()   # 处理函数
378 
379         if TEST_RUN:
380             print('USER_DEBUD')
381             # --------------------------
382         else:
383             pass
384 
385     # global_var_serial_init.colse()
386     # ===============================================================
  1 __all__ = ["CalCRC16","CheckCRC"]
  2 
  3 # ===============================================================
  4 import crcmod
  5 
  6 
  7 
  8 # ===============================================================
  9 '''
 10 # ======================================
 11 # 校验函数  函数
 12 # ======================================
 13 '''
 14 def CalCRC16(data, length):
 15     print(' 校验函数     CalCRC16')
 16     print('显示输入参数:',data,'	', length)
 17 
 18     crc=0xFFFF      # 初始值 变量申明
 19     if length == 0:
 20         length = 1
 21     ## for j in data:
 22     ##     crc ^= j
 23 
 24     j = 0
 25     while length != 0:
 26         crc ^= list.__getitem__(data, j)
 27         #print('j=0x%02x, length=0x%02x, crc=0x%04x' %(j,length,crc))
 28         for i in range(0,8):
 29             if crc & 1:
 30                 crc >>= 1
 31                 crc ^= 0xA001
 32             else:
 33                 crc >>= 1
 34         length -= 1
 35         j += 1
 36         ##if length == 0:
 37         ##         break
 38 
 39     return crc
 40 
 41 # ===============================================================
 42 def CheckCRC(data, length, crctype):
 43     print('校验CRC  CheckCRC')
 44     print('Length | Type | Data : ',length, type(data), data)
 45 
 46     if length < 3:
 47         print('The data len(%d) is less than 3!!!', length)
 48         return 0
 49 
 50     crc_res = 0
 51     tmp=[0,0,0,0]
 52 
 53     if crctype == 0:
 54         crc_res = CalCRC16(data, length-2)
 55         tmp[0] = crc_res & 0xFF
 56         tmp[1] = (crc_res >> 8) & 0xFF
 57 
 58         if data[length-2] == tmp[0] and data[length-1] == tmp[1]:
 59             return 1
 60     elif crctype == 1:
 61         print('CRC32 is not support...')
 62 
 63     return 0
 64 # ===============================================================
 65 
 66 
 67 
 68 
 69 
 70 # ===============================================================
 71 '''
 72 #===============================================================
 73 #   测试专用
 74 #===============================================================
 75 '''
 76 if __name__ == '__main__':
 77 
 78     ## Name Identifier-name, Poly  Reverse Init-value XOR-out Check
 79     ## ['modbus','CrcModbus',0x18005,REVERSE,0xFFFF,0x0000,0x4B37]
 80     ## crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF,  xorOut=0x0000) # rev=True,False
 81 
 82     crc16 = crcmod.mkCrcFun(0x18005,  initCrc=0xFFFF,rev=True,  xorOut=0x0000) # rev=True,False
 83     crc_array = b'0xFE 0xFD'
 84     crc_calc = crc16(crc_array) #计算得到的CRC
 85     a=hex(crc_calc)
 86     print(crc_calc,a)
 87     print('
')
 88 
 89     # =========================================
 90     crc_value = [0x01, 0x04, 0x13, 0x87, 0x00, 0x30]
 91     crc_transformation = CalCRC16(crc_value,len(crc_value))
 92     crc_calculation    = hex(crc_transformation)
 93     # print('crc_calculation:',crc_calculation)
 94     tasd = [0x00,0x00]
 95     tasd[0]  = crc_transformation & 0xFF
 96     tasd[1] = (crc_transformation >> 8) & 0xFF
 97     H =hex(tasd[0])
 98     L =hex(tasd[1])
 99     H_value = int(H,16)
100     L_value = int(L,16)
101     crc_value.append(H_value)
102     crc_value.append(L_value)
103     print(crc_value)          # calculation value   CRC
104 
105     # ========================================================
106     print('
')
107     # crc_value2 = [0x01, 0x04, 0x13, 0x87, 0x00, 0x30,0x44,0xB3]
108     # print('crc_value2:',crc_value2)
109     # crc_cheak=CheckCRC(crc_value2,len(crc_value2),0)
110 
111     crc_check=CheckCRC(crc_value,len(crc_value),0)
112     if crc_check == 1:
113         print('Right')
114     else:
115         print('wrong')
116 
117     print(crc_check)    # check calculation value
 
原文地址:https://www.cnblogs.com/caochucheng/p/9643127.html