Есть контроллер, работающий по протоколу Modbus RTU.Мне нужно написать заявку на опрос.Существует два варианта реализации: один через библиотеку nmodbus, второй без использования библиотек.Проблема в том, что возвращаются разные результаты.Подскажите в чем проблема.
Это версия кода с использованием библиотеки nmodbus.
SerialPort serialPort = new SerialPort();
serialPort.PortName = "COM6";
serialPort.BaudRate = 19200;
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.Open();
ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);
byte slaveID = 2;
ushort startAddress = 0x5E4;
ushort numOfPoints = 1;
ushort[] holding_register = master.ReadHoldingRegisters(slaveID, startAddress, numOfPoints);
for (int i = 0; i < numOfPoints; i++)
{
int tmpStart = Convert.ToInt32(startAddress + i);
String tempStart = Convert.ToString(tmpStart, 16);
int tmpReg = Convert.ToInt32(holding_register[i]);
String tempReg = Convert.ToString(tmpReg, 16);
Console.WriteLine("Register {0}={1}", startAddress + i, holding_register[i]);
}
serialPort.Close();
Выводится, что есть число 7.
Вот втораякод.
static void Main(string[] args)
{
SerialPort mySerialPort = new SerialPort("COM6");
mySerialPort.BaudRate = 19200;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.ReadTimeout = 450;
mySerialPort.WriteTimeout = 3000;
mySerialPort.Open();
mySerialPort.Write(ReadHoldingRegister(02, 0x5E4, 1), 0, 8);
byte[] response = ReadExact(mySerialPort.BaseStream, 1);
for (int i = 0; i < response.Length; i++)
{
Console.WriteLine("Register = {0}", response[i]);
}
mySerialPort.Close();
}
public static byte[] ReadExact(Stream s, int nbytes)
{
var buf = new byte[nbytes];
var readpos = 0;
while (readpos < nbytes)
readpos += s.Read(buf, readpos, nbytes - readpos);
return buf;
}
public static byte[] ReadHoldingRegister(int id, int startAddress, int length)
{
byte[] data = new byte[8];
byte High, Low;
data[0] = Convert.ToByte(id);
data[1] = Convert.ToByte(3);
byte[] _adr = BitConverter.GetBytes(startAddress - 1);
data[2] = _adr[1];
data[3] = _adr[0];
byte[] _length = BitConverter.GetBytes(length);
data[4] = _length[1];
data[5] = _length[0];
myCRC(data, 6, out High, out Low);
data[6] = Low;
data[7] = High;
return data;
}
public static void myCRC(byte[] message, int length, out byte CRCHigh, out byte CRCLow)
{
ushort CRCFull = 0xFFFF;
for (int i = 0; i < length; i++)
{
CRCFull = (ushort)(CRCFull ^ message[i]);
for (int j = 0; j < 8; j++)
{
if ((CRCFull & 0x0001) == 0)
CRCFull = (ushort)(CRCFull >> 1);
else
{
CRCFull = (ushort)((CRCFull >> 1) ^ 0xA001);
}
}
}
CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
CRCLow = (byte)(CRCFull & 0xFF);
}
}
Выводит, что существует число 2.
И старая программа отображает такой ответ: 02 03 05 E4 00 01 02 03 02 00 07