Работа с Modbus C # - PullRequest
       8

Работа с Modbus C #

0 голосов
/ 10 мая 2018

Есть контроллер, работающий по протоколу 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

...