Click here to Skip to main content
15,878,748 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to write a holding register(16 bit) by below code.but i have not got success. 'Time out' exception occures. Please suggest me where i am wrong.
Code is given below.



C#
byte address = Convert.ToByte("127");
                ushort start = Convert.ToUInt16("15");
                short[] value = new short[1];
                value[0] = Convert.ToInt16("1");

                try
                {
                    while (!mb.SendFc16(address, start, (ushort)1, value)) ;
                }
                catch (Exception err)
                {
                    lblConfigurationBlockStatus.Text= err.Message;
                }
                lblConfigurationBlockStatus.Text=(mb.modbusStatus);



C#
public bool SendFc16(byte address, ushort start, ushort registers, short[] values)
       {
           //Ensure port is open:
           if (sp.IsOpen)
           {
               //Clear in/out buffers:
               sp.DiscardOutBuffer();
               sp.DiscardInBuffer();
               //Message is 1 addr + 1 fcn + 2 start + 2 reg + 1 count + 2 * reg vals + 2 CRC
               byte[] message = new byte[9 + 2 * registers];
               //Function 16 response is fixed at 8 bytes
               byte[] response = new byte[8];

               //Add bytecount to message:
               message[6] = (byte)(registers * 2);
               //Put write values into message prior to sending:
               for (int i = 0; i < registers; i++)
               {
                   message[7 + 2 * i] = (byte)(values[i] >> 8);
                   message[8 + 2 * i] = (byte)(values[i]);
               }
               //Build outgoing message:
               BuildMessage(address, (byte)16, start, registers, ref message);

               //Send Modbus message to Serial Port:
               try
               {
                   sp.Write(message, 0, message.Length);
                   GetResponse(ref response);
               }
               catch (Exception err)
               {
                   modbusStatus = "Error in write event: " + err.Message;
                   return false;
               }
               //Evaluate message:
               if (CheckResponse(response))
               {
                   modbusStatus = "Write successful";
                   return true;
               }
               else
               {
                   modbusStatus = "CRC error";
                   return false;
               }
           }
           else
           {
               modbusStatus = "Serial port not open";
               return false;
           }
       }
Posted
Comments
Suvendu Shekhar Giri 27-Feb-15 3:47am    
I don't know the solution but a suggestion, you can try debugging by adding a breakpoint and trying to find out where the control stuck.
Richard MacCutchan 27-Feb-15 3:59am    
Why are you using all those convert functions (byte address = Convert.ToByte("127");)?
Why not just use the numbers in the first place (byte address = 127;)?

1 solution

Basically, it means that your SendFc16 method is continually returning false.
And the simplest reason why that might happen is that the serial port is not open. It may not be that - it could be any of the other errors you report - but that's where I'd start. Use the debugger, and follow the code through to find out why it is returning false.

And instead of just continual retries, limit the number to a "sensible" amount: 3, 5, or 10 perhaps:
C#
try
    {
    int retries = 3;
    while (!mb.SendFc16(address, start, (ushort)1, value)) 
        {
        if (--retries == 0) break;
        }
    }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900