title: Modbus Communication
body: <p>I am using C# to communicate via <code>modbus rs485 rs232</code> to 2 phase meters that among other log the power voltage.</p>
  
  <p>I have to send data over the bus so that i can receive the readings.<br>
  I have connected a normal wire and shorted the send and receive. </p>
  
  <p>The data is recieved and this event is fired:</p>
  
  <pre><code>private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
  {
      SerialPort sp = (SerialPort)sender;
      byte[] buff = new byte[sp.BytesToRead];
  
      //Read the Serial Buffer
      sp.Read(buff, 0, buff.Length);
      string data= sp.ReadExisting();
  
      foreach (byte b in buff)
      {
          AddBuffer(b); //Add byte to buffer
      }
  }
  </code></pre>
  
  <p>Then this buffer is sent to another function which is this one:</p>
  
  <pre><code>private void AddBuffer(byte b)
  {
      buffer.Add(b);
  
      byte[] msg =  buffer.ToArray();
  
      //Make sure that the message integrity is correct
      if (this.CheckDataIntegrity(msg))
      {
          if (DataReceived != null)
          {
              ModbusEventArgs args = new ModbusEventArgs();
              GetValue(msg, args);
              DataReceived(this, args);
          }
          buffer.RemoveRange(0, buffer.Count);
  
      }
  }
  </code></pre>
  
  <p>I think that the problem lies at the data integrity check:</p>
  
  <pre><code>public bool CheckDataIntegrity(byte[] data)
  {
      if (data.Length &lt; 6)
          return false;
      //Perform a basic CRC check:
      byte[] CRC = new byte[2];
      GetCRC(data, ref CRC);
      if (CRC[0] == data[data.Length - 2] &amp;&amp; CRC[1] == data[data.Length - 1])
          return true;
      else
          return false;
  }
  </code></pre>
  
  <p>There is a CRC check and what is strange is that it never becomes true. The CRC calculation:</p>
  
  <pre><code>private void GetCRC(byte[] message, ref byte[] CRC)
  {
  
      ushort CRCFull = 0xFFFF;
      byte CRCHigh = 0xFF, CRCLow = 0xFF;
      char CRCLSB;
  
      for (int i = 0; i &lt; (message.Length) - 2; i++)
      {
          CRCFull = (ushort)(CRCFull ^ message[i]);
  
          for (int j = 0; j &lt; 8; j++)
          {
              CRCLSB = (char)(CRCFull &amp; 0x0001);
              CRCFull = (ushort)((CRCFull &gt;&gt; 1) &amp; 0x7FFF);
  
              if (CRCLSB == 1)
                  CRCFull = (ushort)(CRCFull ^ 0xA001);
          }
      }
      CRC[1] = CRCHigh = (byte)((CRCFull &gt;&gt; 8) &amp; 0xFF);
      CRC[0] = CRCLow = (byte)(CRCFull &amp; 0xFF);
  }
  </code></pre>