/// <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> /// Task for processing received data running in thread /// </summary> private void ModbusAsciiLinkTask() { int threadDelay = 10; while (true) { Thread.Sleep(threadDelay); // Pop byte from receive ring buffer int value = PHY.Receive(); if (value != -1) { byte ReceivedByte = Convert.ToByte(value); switch (ActualState) { // Link is idle, wait for start character case ModbusAsciiLinkState.IDLE: if (ReceivedByte == ':') { // Start character received, start timeout timer and set state to receiving TkickMessageId = ActualMessageId; TimeoutCounter.Start(); // Reset reception buffer index ActualFrameIndex = 0; threadDelay = 0; ActualState = ModbusAsciiLinkState.RECEIVING; } break; case ModbusAsciiLinkState.RECEIVING: // Link is receiving a message if (ReceivedByte == '\n') { // Stop character received, stop timeout timer TimeoutCounter.Stop(); // Check data integrity and notify upper layer ProcessReceivedData(); // Set state to idle ActualState = ModbusAsciiLinkState.IDLE; threadDelay = 10; // Increment message id ActualMessageId++; break; } if (ReceivedByte == '\r') { // do not store CR character break; } if (ActualFrameIndex < ActualFrame.Length) { // Write received byte buffer ActualFrame[ActualFrameIndex++] = ReceivedByte; } // If buffer overflow occured, skip and wait for timeout break; default: break; } } } }