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

python

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 \n重新输入为: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 \n\t\t 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(\'=\t\t 欢迎进入 测试环境 \t\t\t=\')

360 print(\'-------------------------------------\n\')

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,\'\t\', 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(\'\n\')

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(\'\n\')

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

 

 

以上是 Python_Example_modbus协议 串口 _接收_处理_响应 实现程序 的全部内容, 来源链接: utcz.com/z/388809.html

回到顶部