Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ModBus for Delta DVP Series PLC

0.00/5 (No votes)
31 Mar 2009 1  
This project is an easy test for anyone wishing to test modbus communications

Introduction

I was required to connect a small touch screen to a delta PLC and used ModBus as the protocol. This caused me to want to know more about protocols. The project is written using ASCII not RTU as I do not know how to format the code to RTU yet, but be assured I will get there soon.

Background

For a more in depth view of ModBus, there are numerous sites and they will give you more in depth description of modbus. I am only going to explain my code and the functions available. I used the Delta DVP Series PLC communication protocol ver 1.0 as a reference. This is downloadable from their website.

Using the Code

The two main classes that we use here are clsComms and clsInputValidation.

Any ModBus transmit word consists of the following:

 : + Controller Address + Register Address +  
	ModBus Operation + Data Sent + Check Bit + Carriage return + line feed 

When data is entered, it needs to be hex. clsInputValidation.validHex() will make sure of this:

//Check that only valid HEX keys are entered into the text boxes
  public static void ValidHex(string register)
          {
              Regex rx = new Regex("[^A-F|^0-9|^ |^\t]");
              if (rx.IsMatch(register))

                  throw new Exception("Enter a valid HEX number");
          }

The checkbit is the 2's compliment of the total of all the words. clsComms.checkSum() will do this for you:

public static string checkSum(string writeUncheck)
          {
              char[] hexArray = new char[writeUncheck.Length];
              hexArray = writeUncheck.ToCharArray();
              int decNum = 0, decNumMSB= 0, decNumLSB = 0;
              int decByte, decByteTotal = 0;

              bool msb = true;

              for( int t = 0; t <= hexArray.GetUpperBound(0); t++)
              {
                  if((hexArray[t]>= 48) && (hexArray[t] <= 57))

                      decNum = (hexArray[t] - 48);

                  else if ( (hexArray[t] >= 65) & (hexArray[t] <= 70))
                      decNum = 10 + (hexArray[t] - 65);

                  if (msb)
                  {
                      decNumMSB = decNum * 16;
                      msb = false;
                  }
                  else
                  {
                      decNumLSB = decNum;
                      msb = true;
                  }
                  if (msb)
                  {
                      decByte = decNumMSB + decNumLSB;
                      decByteTotal += decByte;
                  }
              }

              decByteTotal = (255 - decByteTotal) + 1;
              decByteTotal = decByteTotal & 255;

              int a, b = 0;

              string hexByte = "", hexTotal = "";
              double i;

              for (i = 0; decByteTotal > 0; i++)
              {
                  b = Convert.ToInt32(System.Math.Pow(16.0, i));
                  a = decByteTotal % 16;
                  decByteTotal /= 16;
                  if (a <= 9)
                      hexByte = a.ToString();
                  else
                  {
                      switch (a)
                      {
                          case 10:
                              hexByte = "A";
                              break;
                          case 11:
                              hexByte = "B";
                              break;
                          case 12:
                              hexByte = "C";
                              break;
                          case 13:
                              hexByte = "D";
                              break;
                          case 14:
                              hexByte = "E";
                              break;
                          case 15:
                              hexByte = "F";
                              break;
                      }
                  }
                  hexTotal = String.Concat(hexByte, hexTotal);
              }

              return hexTotal;
          }

The clsComms.Read() will take the transmit string and send it to the PLC returning either a response from the PLC or an error message, such as time out.

Other features in clsComms include code that will convert strings to a double, in this way you can convert the part of code of interest to you into a decimal value, making it easier to read for the end user and code which converts an integer into a valid HEX number, again making user interfacing easier.

Points of Interest

This project was an excellent learning curve for me as I learned C# as well as the protocol in the process. My intention is to later develop a ModBus IO server which I can use to update tags in a mini SCADA system. I hope there are people out there who have similar projects and can share information with me.

History

  • 31st March, 2009: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here