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. }