• 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
     
  • 相关阅读:
    全排列算法的全面解析
    排序算法系列:插入排序算法
    MySQL多表查询核心优化
    Python代码优化及技巧笔记(二)
    深入理解Lambda
    Unity游戏逻辑服务器实践
    Java设计模式——迭代器模式
    Java设计模式——原型模式
    insert 加的锁
    区间锁
  • 原文地址:https://www.cnblogs.com/caochucheng/p/9643127.html
Copyright © 2020-2023  润新知