public bool ExecFC(byte FC, ModbusDataStruct DataToSend, ref ModbusDataStruct DataReceived) { bool ResponseOK = false; Modbus.ModbusDataStruct Response = new ModbusDataStruct(); byte[] Message = BuildModbusHeader(0, FC, DataToSend.GetAsBytes()); SendBytes(Message); OnRequestSend(IP, DataToSend); int ResponseLength = GetResponse(Response); ResponseOK = CheckModbusHeader(0, FC, Response.GetAsBytes(), ResponseLength); if (ResponseOK & DataReceived != null) { OnRequestReceived(m_RemoteIpEndPoint.Address.ToString(), Response); RemoveModbusHeader(Response); switch (FC) { case 1: case 2: case 3: case 4: case 23: DataReceived.SetAsBytes(Response.GetAsBytes(1, Response.GetByteCount() - 1), Response.GetByteCount() - 1);//cut off byte length and return only values break; default: DataReceived.SetAsBytes(Response.GetAsBytes(), Response.GetByteCount()); break; } } ; return(ResponseOK); }
protected int GetRequest(ModbusDataStruct Response) { int RecLength = 0; m_Input.Initialize(); try { if (IsConnected()) { m_Input = m_Client.Receive(ref m_RemoteIpEndPoint); //would block on disconnect! RecLength = m_Input.Length; /*IAsyncResult ar = m_Client.BeginReceive(null, null); * System.Threading.WaitHandle wh = ar.AsyncWaitHandle; * //because its not possible to set TO, we work async and terminate after some seconds * if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(5000), false)) * { * m_Input = m_Client.EndReceive(ar, ref m_RemoteIpEndPoint); * //m_Client.Close(); * //throw new TimeoutException(); * ; * } * else * { * m_Input = m_Client.EndReceive(ar, ref m_RemoteIpEndPoint); * RecLength = m_Input.Length; * }*/ Response.SetAsBytes(m_Input, RecLength); } ; } catch (TimeoutException exception) { OnMBusException(ModBusException.ModBusExceptionCodeEnum.NoNetworkConnection); } catch (SocketException exception) { if (exception.ErrorCode == 10061 | exception.ErrorCode == 10060) {//10061 "No connection could be made because the target machine actively refused it" OnMBusException(ModBusException.ModBusExceptionCodeEnum.NoNetworkConnection); } else { OnMBusException(ModBusException.ModBusExceptionCodeEnum.NetworkError); Console.WriteLine(exception.ToString() + " " + exception.ErrorCode.ToString()); //?? } } return(RecLength); }
/// <summary> /// FC16 Write multiple register /// FC16-Lengthfields will be added /// </summary> /// <param name="Register">= StartRegisterOffset</param> /// <param name="Data">2*n byte RegisterData</param> /// <returns></returns> public bool ExecFC16(UInt16 Register, ModbusDataStruct Data) { bool IsOK = false; Modbus.ModbusDataStruct Request = new ModbusDataStruct(); Request.SetAsBytes(Data.GetAsBytes(), Data.GetByteCount()); byte[] FCLengthFields = new byte[5]; FCLengthFields[0] = (byte)((Register >> 8) & 0xFF); FCLengthFields[1] = (byte)((Register >> 8)); FCLengthFields[2] = (byte)((Request.GetWordCount() >> 8) & 0xFF); FCLengthFields[3] = (byte)((Request.GetWordCount()) & 0xFF); FCLengthFields[4] = (byte)Request.GetByteCount(); //insert Byte and Word count between RegisterAddr and Data Request.InsertByte(0, FCLengthFields, FCLengthFields.Length); ModbusDataStruct Answer = new ModbusDataStruct(); IsOK = ExecFC(16, Request, ref Answer); return(IsOK); }
protected int GetResponse(ModbusDataStruct Response) { int RecLength = 0; int Timer = 0; bool RecSomeData = false; bool NoMoreData = false; m_Input.Initialize(); try { if (IsConnected()) { //m_Input = m_Client.Receive(ref m_RemoteIpEndPoint); //would block on disconnect! IAsyncResult ar = m_Client.BeginReceive(null, null); System.Threading.WaitHandle wh = ar.AsyncWaitHandle; //because its not possible to set TO, we work async and terminate after some seconds /*while (!ar.IsCompleted) * { * Thread.Sleep(10); * Timer += 10; * if (Timer > RequestTO) * { * m_Client.Close(); * throw new TimeoutException(); * } * }*/ if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(RequestTO), false)) { m_Client.Close(); throw new TimeoutException(); } m_Input = m_Client.EndReceive(ar, ref m_RemoteIpEndPoint); RecLength = m_Input.Length; Response.SetAsBytes(m_Input, RecLength); /*while (Timer < RequestTO && !NoMoreData) * { * System.Threading.Thread.Sleep(10); * Timer = Timer + (10); * if (m_Stream.DataAvailable) * { * RecLength = RecLength + m_Stream.Read(m_Input, RecLength, m_Input.Length); * RecSomeData = true; * } * else * { * NoMoreData = RecSomeData; //quit Timeout if some Data was received and no more is following * } * };*/ } ; } catch (TimeoutException exception) { OnMBusException(ModBusException.ModBusExceptionCodeEnum.NoNetworkConnection); } catch (SocketException exception) { if (exception.ErrorCode == 10061 | exception.ErrorCode == 10060) {//10061 "No connection could be made because the target machine actively refused it" OnMBusException(ModBusException.ModBusExceptionCodeEnum.NoNetworkConnection); } else { OnMBusException(ModBusException.ModBusExceptionCodeEnum.NetworkError); Console.WriteLine(exception.ToString() + " " + exception.ErrorCode.ToString()); //?? } } finally { // wh.Close(); } return(RecLength); }