News:

Let's find out together what makes a PIC Tick!

Main Menu

Modbus testing

Started by RGV250, Jul 05, 2022, 04:27 PM

Previous topic - Next topic

RGV250

Hi,
I have a Modbus device I am considering using, I recall several people have communicated over \ modbus so I was wondering what software/hardware they used to test things out first.
I have USB / RS485 converter and using the serial communicator program but do not seem to be able to connect to the device.

Regards,
Bob

ricardourio

Hello Bob,

   My main projects uses RS485 with MODBUS protocol. How can I help you ?

Regards

Ricardo Urio

RGV250

Hi Ricardo,
At the moment I am just trying to use a terminal program and USB / RS485 converter to see if the device works and to set it up.
I have tried Modbus Poll, Realterm and the serial commumicator but no response. I have seen something being returned in Modbus Poll but not sure what it is as I cannot find what it is sending.

Bob 

Pepe


RGV250

Hi Pepe,
Thanks for the code but the issue I have at the moment is I do not have any circuit, just the device and a USB converter. I had hoped to make sure the device works first before looking at spending time building a board if the device does not work.
I have 2 devices and neither give the response I am expecting according to the (not very helpful) information I found. They do seem to connect but that is about it.

Regards,
Bob
 

Giuseppe

Some time ago I tried to control a commercial card via mod-bus protocol.
Below is a piece of code to take as a starting point
There was a sequence of bytes to send and receive between the master and the slave

'At 9600 baud it takes 1ms to transmit 1 byte (104uS per bit) approx
'We need to calculate the transmission time to evaluate the delay to be entered just below
'transmission.This is because if we return en_485 = 0 without having finished the TX it goes to RX and cuts the bytes to be transmitted

tx:

Select codes    'According to the function code I go to set the 5 and 6 Bytes to be transmitted

 Case = 01
 buf[4] = n_outputs.HighByte
 buf[5] = n_outputs.LowByte
 
 Case = 02
 buf[4] = n_inputs.HighByte
 buf[5] = n_inputs.LowByte
 
 Case = 05
 buf[4] = value_output.HighByte
 buf[5] = value_output.LowByte
 
End Select
 
buf[0] = add_slave
buf[1] = codes
buf[2] = indirizzo.HighByte
buf[3] = indirizzo.LowByte


crc_fine = 5
GoSub  Calcul_CRC      'Routine  crc ok

buf[6] = crc.LowByte
buf[7] = crc.HighByte

en_485 = 1
 HSerOut [buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]] 
 
stai_qui:
If TXSTA1.1 = 0 Then stai_qui     'it stops until it has transmitted all the bytes

en_485 = 0                        'Re-enabled the Master serial reception (Pin RE e DE linked together Max485)
 
Clear buf                         ' i clean the buf i use for both Tx and Rx
buft = 0                          ' I clean the index of the buf
INTCON.7 = 1                      ' I enable the interrupt to receive response from the slave
 
DelayMS 10                        'To give the interrupt time to receive the 8 buf

'---------------------------------------------------------------------
rx:

If flag.1 = 1 Then   'I put flag.1 = 1 in the interrupt when I am sure I have received all 8 bytes             
                     ''or from buf [0] to buf [7]. I always use the array variable buf si for Tx and Rx             
     
HSerOut2 [buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]]
DelayMS 3
flag.1 = 0   


    If buf[0] = add_slave And buf[1] = codes Then  'in the various response function codes I always have add_slave and codes

        Select codes

        Case = 01
        'n_byte_stato_output = buf[2]   ' to be developed
                                           
        Case = 05
       
        crc_fine = 5       'If the codes is 05 in the Calcul_CRC routine it must process the first 6 Bytes received in the interrupt
        GoSub Calcul_CRC
 
        If crc.LowByte = buf[6] And crc.HighByte = buf[7] Then   'compare the crc received from the slave with the calculated crc
            If buf[4] = $FF Then  testo="On"                     'with the first 6 Bytes always received by the slave
            If buf[4] = $00 Then  testo="Off"
            Cls
            Print At 1,1,"Rele-",Dec3 indirizzo,"-",testo
            DelayMS 3000
        End If

        Case = 15    ' to be developed

        Case = 02
        max = 3
        pirella = 0
        teresa = 0
       
        For gg = 0 To (buf[2]-1)           'In buf [2] I have the number of Bytes to receive which represent the status of the slave Inputs
        byte_input[pirella] = buf[max]     
        max = max + 1
        pirella = pirella + 1
       
        If pirella = 2  Then               'I put pirella in teresa when pirella is > 2
        teresa = pirella + teresa          '
        pirella = 0
        End If
       
        Next gg   
       
        teresa = pirella + teresa 
        crc_fine = teresa + 2    '2 are the Bytes that I always receive from 0 to 2: Add slave + codes + Byte indicating n_byte Input
        GoSub Calcul_CRC
       
        max_1 = 3 + teresa       'I calculate the place of the Low Byte of crc on the basis of the Bytes received in the buf
        max_2 = 3 + teresa + 1   'I calculate the place of the High Byte of crc on the basis of the Bytes received in the buf
       
        HSerOut2 [crc.LowByte,buf[max_1],crc.HighByte,buf[max_2],teresa,buf[2]]
        DelayMS 3
       
       
        If crc.LowByte = buf[max_1]  And crc.HighByte = buf[max_2] Then
       
           Select byte_input[0]                'I print on the display which inputs are active
           Case = 01
            Print At 1,1,"Input 1 active"
            DelayMS 3000
           Case = 02   
            Print At 1,1,"Input 2 active"
            DelayMS 3000
           Case = 04
            Print At 1,1,"Input 3 active"
            DelayMS 3000
           Case = 08
            Print At 1,1,"Input 4 active"
            DelayMS 3000
           
           Case = 05
            Print At 1,1,"Input 1-3 active"
            DelayMS 3000
           Case = 06
            Print At 1,1,"Input 2-3 active"
            DelayMS 3000
           Case = 07
            Print At 1,1,"Inp 1-2-3 active"
            DelayMS 3000
           Case = 09
            Print At 1,1,"Input 1-4 active"
            DelayMS 3000
           Case = 10
            Print At 1,1,"Input 2-4 active"
            DelayMS 3000
           Case = 11
            Print At 1,1,"Inp 1-2-4 active"
            DelayMS 3000
           Case = 12
            Print At 1,1,"Input 3-4 active"
            DelayMS 3000
           Case = 13
            Print At 1,1,"Inp 1-3-4 active"
            DelayMS 3000
           Case = 14
            Print At 1,1,"Inp 2-3-4 active"
            DelayMS 3000
           Case = 15
            Print At 1,1,"Inp all active"
            DelayMS 3000
           
           
           End Select
        End If   
    End Select
    End If
EndIf


GoTo main11

'------------------------------------------------------------------------------------------------------------------------------
'The crc represents a word variable that is used in the Modbus protocol to check if a correct one has occurred
'transmission or reception between a master and a slave. Usually 8-byte strings are sent between master and slave.
'The master based on the first 6 bytes of the string must calculate the crc and finally add the result in the 7 and 8 bytes to send
'everything to the slave Once the slave has received the 8 bytes, it will have to recalculate the crc using the first 6 bytes and compare the value
'with the crc calculated and sent by the master. If the 2 crc are the same, the command has been received correctly.
'Then subsequently the slave will have to execute the command and formulate the answer always with a crc calculated thanks to the first 6 bytes
'The master received the response will have to recalculate the crc of the response sent by the slave and compare the 2 crc if
'are equal the reception of the answer is correct.

Calcul_CRC:

crc=$FFFF                 
For a = 0 To crc_fine     
                         
  crc = crc^buf[a]       
  For j = 1 To 8         
   If crc.Bit0 = 1 Then
   crc =$A001^(crc>>1)   
   Else
   crc = crc >>1           
   EndIf
  Next j
Next a
Return

'-----------------------------------------Interrupt Routine---------------------------------------------------------------
On_Interrupt GoTo int_routine

int_routine:

Context Save

If PIR1.5 = 1 Then     'PIR1.5 is the Bit 5 of the PIR1 register is the flag of the Interrupt occurred for rx EUSART
                     
 Clear PIR1.5          'With Clear I bring the PIR1.5 to 0 so that other interrupts can occur

 buf[buft] = RCREG1     'RCREG1 register where the Eusart 1 reception data arrive                                       
 Inc buft
 
 If buf[1] = 02 And buf[2]<> 0 And flag.2 = 0 Then   '
   flag.2 = 1
   buft_end = buf[2] + 2 + buft - 1   ' the number 2 represents the Byte crc. Buf [2] indicates the Byte Input slave number
 End If
 
  If buft > buft_end Then    'buft_end = 7 then If there is buf [1] = 02 it can vary according to the Bytes it must receive
   flag.1 = 1
   flag.2 = 0
   buft = 0
   buft_end = 7
   INTCON.7 = 0
  End If
 'Clear PIR1.5
EndIf

Context Restore       
                   


Yasin

Have you tried the computer program "Modbus Poll"?

RGV250

Hi Yasin,
I am trying Modbus Poll, the problem I have is there seems to be a response but I have no idea what is being sent as it does not tie up with the data?? sheet.
If I select Display / Communication there is supposed data coming back but I cannot find out where in the program the data being sent is so I cannot figure our what to try to send. I am also getting 03 Illegal value but the program seems pretty poor to me as there is no indication which value it does not like.

Regards,
Bob



Yasin

Hi @RGV250 . Some modbus devices do not recognize the "H03" function code. Can you try using "H04" as function code.

RGV250

Hi,
Thanks for all the replies, I have just found Simply Modbus https://www.simplymodbus.ca/RTUmaster.htm which is a lot clearer to use and I can now see what it is sending and I am now getting the responses I was expecting.

Bob