private void timerOut_Tick(object sender, EventArgs e) { lock (_timerCheck) { var result = CheckData(_bytesReadArray); switch (result.Status) { case ModBusStatus.PresetMultipleRegistersOK: case ModBusStatus.ReadHoldingRegistersOK: case ModBusStatus.CustomFunctionOk: _waitResponse = false; ReceiveCounter++; _timerCheck.Stop(); RaisePacketDetected(_bytesReadArray); _eventArgument = result; OnExchangeEnd(); break; default: ErrorCounter++; if (!CheckRepeat()) { _eventArgument = new ModBusEventArg() { Status = result.Status }; OnExchangeEnd(); } break; } } }
/// <summary> /// проверяем полученные данные /// </summary> private ModBusEventArg CheckData(byte[] buffer) { if (buffer == null || buffer.Length == 0) { return(new ModBusEventArg { Status = ModBusStatus.TimeOutError }); } if (buffer.Length <= 2) { return(new ModBusEventArg { Status = ModBusStatus.UnknowPacket }); } if (buffer[0] != _addressSlave) { return(new ModBusEventArg { Status = ModBusStatus.AddressSlaveError }); } var function = buffer[1] & ~0x80; var error = (buffer[1] & 0x80) == 0x80; if (_requestFunction != function) { return(new ModBusEventArg { Status = ModBusStatus.InvalidFunction }); } if (_endingSymbolEnable && buffer[buffer.Length - 1] != EndingSymbol) { return(new ModBusEventArg { Status = ModBusStatus.NoEndingSymbol }); } if (!CRC.CheckCRC(buffer, 0, buffer.Length - (_endingSymbolEnable ? 3 : 2), buffer, buffer.Length - (_endingSymbolEnable ? 3 : 2))) { return(new ModBusEventArg { Status = ModBusStatus.CRCError }); } if (error) { return(new ModBusEventArg { Status = ModBusStatus.FunctionError, Function = buffer[1], data = new short[] { buffer[2] }, }); } // RecieveCounter++; var ea = new ModBusEventArg { Function = buffer[1] }; // Определяем тип функции switch (function) { // Read Holding Registers case 3: ea.data = new short[buffer[2] / 2]; if (ea.Data.Length == _waitRegs) { ea.Status = ModBusStatus.ReadHoldingRegistersOK; } else { ea.Status = ModBusStatus.InvalidResponse; } int i = 0; while (i != ea.data.Length) { ea.data[i] = (short)(buffer[i * 2 + 3] << 8); ea.data[i] += buffer[i * 2 + 1 + 3]; i++; } break; // Preset Multiple Registers case 0x10: ea.data = new short[0]; ea.Status = ModBusStatus.PresetMultipleRegistersOK; break; default: ea.data = new short[buffer[2] / 2]; ea.Status = ModBusStatus.CustomFunctionOk; i = 0; while (i != ea.data.Length) { ea.data[i] = (short)(buffer[i * 2 + 3] << 8); ea.data[i] += buffer[i * 2 + 1 + 3]; i++; } break; } return(ea); }
private void timerCheck_Tick(object sender, EventArgs e) { lock (_timerCheck) { try { var count = _serialPort.BytesToRead; if (count != 0) { if (_bytesReadArray == null || _bytesReadArray.Length == 0) { _bytesReadArray = new byte[count]; _serialPort.Read(_bytesReadArray, 0, count); } else { var bytesArray = new byte[count]; _serialPort.Read(bytesArray, 0, count); var oldLength = _bytesReadArray.Length; Array.Resize(ref _bytesReadArray, _bytesReadArray.Length + count); Array.Copy(bytesArray, 0, _bytesReadArray, oldLength, count); } var result = CheckData(_bytesReadArray); _timerOut.Stop(); switch (result.Status) { case ModBusStatus.PresetMultipleRegistersOK: case ModBusStatus.ReadHoldingRegistersOK: case ModBusStatus.CustomFunctionOk: _waitResponse = false; ReceiveCounter++; RaisePacketDetected(_bytesReadArray); _eventArgument = result; OnExchangeEnd(); break; case ModBusStatus.CRCError: case ModBusStatus.UnknowPacket: case ModBusStatus.None: case ModBusStatus.NoEndingSymbol: case ModBusStatus.TimeOutError: _timerCheck.Start(); _timerOut.Reset(); break; default: ErrorCounter++; RaisePacketDetected(_bytesReadArray); if (!CheckRepeat()) { _waitResponse = false; _eventArgument = result; OnExchangeEnd(); } break; } return; } } catch (InvalidOperationException exc) { if (CatchSerialException(exc)) { return; } } _timerCheck.Start(); } }