/// <summary> /// Task for processing received data running in thread /// </summary> private void ModbusRtuLinkTask() { while (true) { Thread.Sleep(0); int value; switch (ActualState) { case ModbusRtuLinkState.INIT: // Init mode, wait for first 3.5 char framing timeout break; case ModbusRtuLinkState.IDLE: // Idle mode, wait for incoming message value = PHY.Receive(); if (value != -1) { byte ReceivedByte = Convert.ToByte(value); ActualFrameIndex = 0; ActualFrame[ActualFrameIndex++] = ReceivedByte; ActualState = ModbusRtuLinkState.RECEIVING; FramingTimer.Start(); } break; case ModbusRtuLinkState.RECEIVING: // Receive all message bytes until framing timeout value = PHY.Receive(); if (value != -1) { FramingTimer.Stop(); byte ReceivedByte = Convert.ToByte(value); ActualFrame[ActualFrameIndex++] = ReceivedByte; FramingTimer.Start(); } break; case ModbusRtuLinkState.PROCESSING: // Process message ProcessReceivedData(); ActualState = ModbusRtuLinkState.IDLE; break; } } }
/// <summary> /// Handler for 3.5 character framing timer - should retun as fast as possible /// </summary> private void FramingTimeoutHandler(object sender) { switch (ActualState) { case ModbusRtuLinkState.INIT: // Init state timeout elapsed, set state to idle Debug.WriteLine("LINK - SYNC_OK"); ActualState = ModbusRtuLinkState.IDLE; break; case ModbusRtuLinkState.RECEIVING: // Message reception timed out, process received data ActualState = ModbusRtuLinkState.PROCESSING; break; case ModbusRtuLinkState.IDLE: case ModbusRtuLinkState.PROCESSING: // Link is idle or processing message, wait break; } return; }