rafi_chris

ModBus_read.py

Sep 28th, 2020
908
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import serial
  2. import random
  3.  
  4. #Sub Program
  5. #CRC Calculation
  6. def CRCcal(msg):
  7.     #CRC (Cyclical Redundancy Check) Calculation
  8.     CRC = 0xFFFF
  9.     CRCHi = 0xFF
  10.     CRCLo = 0xFF
  11.     CRCLSB = 0x00
  12.     for i in range(0, len(msg)-2,+1):
  13.         CRC = (CRC ^ msg[i])
  14.         for j in range(0, 8):
  15.             CRCLSB = (CRC & 0x0001);
  16.             CRC = ((CRC >> 1) & 0x7FFF)
  17.  
  18.             if (CRCLSB == 1):
  19.                 CRC = (CRC ^ 0xA001)
  20.     CRCHi = ((CRC >> 8) & 0xFF)
  21.     CRCLo = (CRC & 0xFF)
  22.     return (CRCLo,CRCHi)  
  23.  
  24.  
  25. #CRC Valdation
  26. def CRCvalid(resp):
  27.     CRC = CRCcal(resp)
  28.     if (CRC[0]==resp[len(resp)-2]) & (CRC[1]==resp[len(resp)-1]):return True
  29.     return False
  30.  
  31.  
  32. #Modbus Function Code 16 = Preset Multiple Registers    
  33. def Func16Modbus(slave,start,values):
  34.     Slave_Address = slave
  35.     Function = 16
  36.     Starting_Address = start
  37.     NumberofRegisters = len(values)
  38.     Byte_Count = NumberofRegisters * 2
  39.     message = [0 for i in range(9 + 2 * NumberofRegisters)]  
  40.  
  41.     #index0 = Slave Address
  42.     message[0] = (Slave_Address & 0xFF)
  43.     #index1 = Function
  44.     message[1] = (Function & 0xFF)
  45.     #index2 = Starting Address Hi
  46.     message[2] = ((Starting_Address >> 8) & 0xFF)
  47.     #index3 = Starting Address Lo
  48.     message[3] = (Starting_Address & 0xFF)
  49.     #index4 = Number of Registers Hi
  50.     message[4] = ((NumberofRegisters >> 8) & 0xFF)
  51.     #index5 = Number of Registers Lo
  52.     message[5] = (NumberofRegisters & 0xFF)
  53.     #index6 = Byte Count
  54.     message[6] = (Byte_Count & 0xFF)
  55.  
  56.     for i in range(0, NumberofRegisters):
  57.         #Data Hi, index7 and index9
  58.         message[7 + 2 * i] = ((values[i] >> 8) & 0xFF)
  59.         #Data Lo, index8 and index10
  60.         message[8 + 2 * i] = values[i] & 0xFF
  61.  
  62.     #CRC (Cyclical Redundancy Check) Calculation
  63.     CRC = CRCcal(message)
  64.    
  65.     #index11= CRC Lo
  66.     message[len(message) - 2] = CRC[0]#CRCLo
  67.     #index12 = CRC Hi
  68.     message[len(message) - 1] = CRC[1]#CRCHi
  69.  
  70.     if ser.isOpen:        
  71.         ser.write("".join(chr(h) for h in message))
  72.         reading = ser.read(8)
  73.         response = [0 for i in range(len(reading))]
  74.         for i in range(0, len(reading)):
  75.             response[i] = ord(reading[i])
  76.  
  77.         if len(response)==8:
  78.             CRCok = CRCvalid(response)
  79.             if CRCok & (response[0]==slave) & (response[1]==Function):return True
  80.     return False
  81.  
  82.  
  83. #Modbus Function Code 03 = Read Holding Registers
  84. def Func03Modbus(slave,start,NumOfPoints):
  85.     #Function 3 request is always 8 bytes
  86.     message = [0 for i in range(8)]  
  87.     Slave_Address = slave
  88.     Function = 3
  89.     Starting_Address = start
  90.     Number_of_Points = NumOfPoints
  91.  
  92.     #index0 = Slave Address
  93.     message[0] = Slave_Address
  94.     #index1 = Function
  95.     message[1] = Function
  96.     #index2 = Starting Address Hi
  97.     message[2] = ((Starting_Address >> 8)& 0xFF)
  98.     #index3 = Starting Address Lo
  99.     message[3] = (Starting_Address& 0xFF)
  100.     #index4 = Number of Points Hi
  101.     message[4] = ((Number_of_Points >> 8)& 0xFF)
  102.     #index5 = Number of Points Lo
  103.     message[5] = (Number_of_Points& 0xFF)
  104.  
  105.     #CRC (Cyclical Redundancy Check) Calculation
  106.     CRC = CRCcal(message)
  107.    
  108.     #index6= CRC Lo
  109.     message[len(message) - 2] = CRC[0]#CRCLo
  110.     #index7 = CRC Hi
  111.     message[len(message) - 1] = CRC[1]#CRCHi
  112.    
  113.     if ser.isOpen:        
  114.         ser.write("".join(chr(h) for h in message))
  115.         responseFunc3total = 5 + 2 * Number_of_Points
  116.         reading = ser.read(responseFunc3total)
  117.         response = [0 for i in range(len(reading))]
  118.         for i in range(0, len(reading)):
  119.             response[i] = ord(reading[i])
  120.        
  121.         if len(response)==responseFunc3total:
  122.             CRCok = CRCvalid(response)
  123.             if CRCok & (response[0]==slave) & (response[1]==Function):
  124.                 #Byte Count in index 3 = responseFunc3[2]
  125.                 #Number of Registers = byte count / 2 = responseFunc3[2] / 2
  126.                 registers = ((response[2] / 2)& 0xFF)
  127.                 values = [0 for i in range(registers)]
  128.                 for i in range(0, len(values)):
  129.                     #Data Hi and Registers1 from Index3
  130.                     values[i] = response[2 * i + 3]
  131.                     #Move to Hi
  132.                     values[i] <<= 8
  133.                     #Data Lo and Registers1 from Index4
  134.                     values[i] += response[2 * i + 4]
  135.                     negatif = values[i]>>15
  136.                     if negatif==1:values[i]=values[i]*-1
  137.                 return values
  138.     return ()
  139.  
  140.  
  141. #Main Program
  142. #Serial Port 9600,8,E,1
  143. #Serial Open
  144. try:
  145.         ser = serial.Serial(
  146.                 port = '/dev/serial0',
  147.                 baudrate = 9600,
  148.                 bytesize = serial.EIGHTBITS,
  149.                 parity = serial.PARITY_EVEN,
  150.                 stopbits = serial.STOPBITS_ONE,
  151.                 timeout = 0.2
  152.         )
  153. except Exception, e:
  154.         raise ValueError(e)
  155.  
  156.  
  157. print "START"
  158. while 1:
  159.     #Serial Open Check
  160.     if not ser.isOpen:ser.open()
  161.  
  162.     #Read of Registers
  163.     Func03ArrayValue = Func03Modbus(100,1,32);#slave,start,number of registers
  164.     if len(Func03ArrayValue)>0:
  165.         for i in range(0, len(Func03ArrayValue)):
  166.             print "Read of Registers" + str(i) + " = " + str(Func03ArrayValue[i])
  167.  
  168.     #Fill Random Value for Write
  169.     #totalvalue=2
  170.     #val = [0 for i in range(totalvalue)]
  171.     #for i in range(0, len(val)):
  172.     #    val[i] = random.randrange(-32767,32767) #Random Valiue from -32767 to max 32767
  173.     print "Alive: " + str(random.randrange(-32767,32767))
  174.     #Write of Registers
  175.     #WriteValid = Func16Modbus(1,2,val)#slave,start,array value
  176.     #if WriteValid:
  177.     #    for i in range(0, len(val)):
  178.     #        print "Write of Registers" + str(i) + " = " + str(val[i])
  179.     print "#################################"
RAW Paste Data