65.9K
CodeProject is changing. Read more.
Home

ModBus for Delta DVP Series PLC

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (6 votes)

Mar 31, 2009

CPOL

2 min read

viewsIcon

104517

downloadIcon

12829

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