Example #1
0
        private void btnCreateModbusRTUMsg_Click(object sender, EventArgs e)
        {
            OutputMsg.ClearAll();

            try
            {
                OutputMsg.SlaveAddr = Convert.ToByte(txtSlaveAddr.Text, 16); // Get Slave Address

                switch (cmbFuncCode.SelectedIndex)                           // Get Function Code
                {
                case 0:
                    OutputMsg.FuncCode = 0x03;
                    break;

                case 1:
                    OutputMsg.FuncCode = 0x08;
                    break;

                case 2:
                    OutputMsg.FuncCode = 0x10;
                    break;
                }

                OutputMsg.StartReg = Convert.ToUInt16(txtStartReg.Text, 16);  // Get Starting Register
                OutputMsg.RegCount = Convert.ToUInt16(txtRegCnt.Text);        // Get number of registers to be read or written
            }
            catch
            {
                MessageBox.Show("Entry Error!");
                return;
            }

            if (txtDataBuffer.Text != "")
            {
                OutputMsg.Data = Modbus.CreateDataPayloadUShort(txtDataBuffer.Text);
            }

            OutputMsg = Modbus.CreateMessage(OutputMsg);
            SerialMsg = Modbus.CreateRawMessageBuffer(OutputMsg, true);

            txtDataBuffComplete.Text = CreateModbusRTUDataString(SerialMsg);

            txtBuffSize.Text       = (OutputMsg.Data.Count() * 2).ToString();
            txtModCRC16Result.Text = "0x" + OutputMsg.CRC16.ToString("X4");
            txtModCRC16Upper.Text  = "0x" + ((byte)(OutputMsg.CRC16 & 0x00FF)).ToString("X2");
            txtModCRC16Lower.Text  = "0x" + ((byte)(OutputMsg.CRC16 >> 8)).ToString("X2");
        }
        private void btnCalcModCRC16_Click(object sender, EventArgs e)
        {
            byte            RegSize;
            List <byte>     Payload      = new List <byte>();
            ModbusRTUMaster ModbusMaster = new ModbusRTUMaster();

            MsgBuffer.Clear();

            ModbusMaster.SlaveAddr = Convert.ToByte(txtSlaveAddr.Text, 16); // Get Slave Address

            switch (cmbFuncCode.SelectedIndex)                              // Get Function Code
            {
            case 0:
                ModbusMaster.FuncCode = 0x03;
                break;

            case 1:
                ModbusMaster.FuncCode = 0x08;
                break;

            case 2:
                ModbusMaster.FuncCode = 0x10;
                break;
            }

            ModbusMaster.StartReg = Convert.ToUInt16(txtStartReg.Text, 16); // Get Starting Register
            ModbusMaster.RegCount = Convert.ToUInt16(txtRegCnt.Text);       // Get number of registers to be read or written
            RegSize = Convert.ToByte(txtRegSize.Text);                      // Get size of each register to be read or written

            if (txtDataBuffer.Text != "")
            {
                Payload = CreateDataPayload(txtDataBuffer.Text);
            }


            MsgBuffer = ModbusMaster.CreateRawMessageBuffer(Payload);


            txtDataBuffComplete.Text = CreateModbusRTUDataString(MsgBuffer);

            txtBuffSize.Text       = ModbusMaster.MsgSize.ToString();
            txtModCRC16Result.Text = "0x" + ModbusMaster.CRC16.ToString("X4");
            txtModCRC16Upper.Text  = "0x" + ((byte)(ModbusMaster.CRC16 & 0x00FF)).ToString("X2");
            txtModCRC16Lower.Text  = "0x" + ((byte)(ModbusMaster.CRC16 >> 8)).ToString("X2");
        }
        public int DataTransfer(ref ModbusRTUMsg p_Msg, ref SerialPort p_SPort)
        {
            int delay = 0, readbytes = 0, regcnt = 0, RetCode = 0;

            ModbusRTUMaster Modbus_Data       = new ModbusRTUMaster();
            List <byte>     V1000_Serial_Data = new List <byte>();

            // Verify that the serial port is valid
            if (!p_SPort.IsOpen)
            {
                RetCode = 0x8000;
                goto DataTransferExit;
            }

            switch (p_Msg.FuncCode)
            {
            case ModbusRTUMaster.ReadReg:
                delay     = DelayReadMsgMin + (DelayReadByte * ((p_Msg.RegCount - 1) * 2));
                readbytes = RespReadByteMin + ((p_Msg.RegCount - 1) * p_Msg.RegByteCount);
                break;

            case ModbusRTUMaster.Loopback:
                delay     = 1;
                readbytes = RespLoopbackByte;
                break;

            case ModbusRTUMaster.WriteReg:
                // Check if the write register is one of the Enter command registers or if the register
                // that is being modified is the drive initialization register (A1-03/0x0103) If so, then
                // the delay is set to the maximum write time of 2 seconds to prevent an error for too short
                // of a delay between writing the register and getting a valid response from the drive.
                if ((p_Msg.StartReg == 0x0900) || (p_Msg.StartReg == 0x0910) || (p_Msg.StartReg == 0x0103))
                {
                    delay = DelayEnterMax;
                }
                else
                {
                    // Otherwise set the delay to the minimum write delay response
                    delay = DelayWriteMsgMin;
                }
                readbytes = RespWriteByte;
                regcnt    = p_Msg.RegCount;
                break;
            }

            // Calculate CRC-16 value and create the raw byte separated buffer to send out via the serial bus
            V1000_Serial_Data = Modbus_Data.CreateRawMessageBuffer(p_Msg, true);

            // Send serial data
            byte[] OutBuff = new byte[V1000_Serial_Data.Count];
            for (int i = 0; i < V1000_Serial_Data.Count; i++)
            {
                OutBuff[i] = V1000_Serial_Data[i];
            }
            p_SPort.Write(OutBuff, 0, OutBuff.Count());

            // Wait for response
            Thread.Sleep(delay);

            // Check if there is a valid full message to read of the same size as the number
            // of registers requested. Anything less basically means a fault occurred.
            if (p_SPort.BytesToRead != readbytes)
            {
                if (p_SPort.BytesToRead > 0)
                {
                    p_SPort.DiscardInBuffer();
                }
                RetCode = 0x8002;
                goto DataTransferExit;
            }

            // Get Modbus RTU serial message received back from slave
            byte[] InBuff = new byte[p_SPort.BytesToRead];
            p_SPort.Read(InBuff, 0, p_SPort.BytesToRead);

            // Update actual Modbus RTU message based on raw data received from the serial port
            int stat = Modbus_Data.ExtractMessage(InBuff.ToList(), ref p_Msg);

            if (stat == 0x0001)
            {
                if (p_Msg.FuncCode == ModbusRTUMaster.WriteReg)
                {
                    if (regcnt == p_Msg.RegCount)
                    {
                        RetCode = 0x0001;
                    }
                    else
                    {
                        RetCode = 0x8003;
                    }
                }
                else
                {
                    RetCode = 0x0001;
                }
            }
            else
            {
                p_Msg.ClearAll();
                RetCode = 0x8004;
            }

DataTransferExit:

            return(RetCode); // return the acquired return code from this method.
        }