Click here to Skip to main content
12,952,725 members (45,838 online)
Rate this:
Please Sign up or sign in to vote.
See more:
I have to create an aplication which reads the registers from a PLC at each 200ms. To do that I am using something like:

 SerialPort port=new SerialPort();
    bool dataRecieved=false;
    private void Form1_Load(object sender, EventArgs e)
       port.RecievedBytesThrescold=21; //always the incoming message has to have 21 bytes
    private void ProcesTimier_Tick(object sender, EventArgs e)
       //Do something else based on the translated values
       if(port.IsOpen && connectected)
          port.Write(buffer_tx,0,lengh);   //sends the command for a new reading
    private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            Invoke(new EventHandler(DoUpdate));
    void DoUpdate(object sender, EventArgs e)
            dataRecieved = true;

The problem is that from time to time, at random moments, my application freezies and when I go with the debug to see the execution line at which the application freezes, it points me to the port.Read(), but it doesn't retun any exeption. I have tried to use a try-catch block, but it didn't catch anything. I made time1.Interval=2000, but it didn't work either.
My question is if you know why my application freezies and points me to the port.Read(), but it doesn't catch any exception and how could I get over it?
Posted 6-Jun-12 20:47pm
Updated 6-Jun-12 22:31pm
__John_ 7-Jun-12 5:10am
The port is probably waiting for 21 bytes to be received.
Myn92 7-Jun-12 5:15am
The port.RecievedBytesThrescold=21 means that the DataRecieved event should fire only when the port has recieved 21 bytes, so I do the reading only if I already have recieved 21 bytes
Ruard 8-Jun-12 1:15am
I think you'd better try another approach. Remove the Timer and dataRecieved boolean and in the port_DataReceived event rad the port and start another thread to process the data. In that case the port is read only when data is received.

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Your timer should not be necessary, and let port.RecievedBytesThrescold=1 (default). The only thing you can be sure of if you set it to 21, is that it will be at least 21 long. My suggestion is to do the buffering your self:
byte[] buffer = new byte[50];
int endOfBuffer = 0;
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
  int dataLength = _serialPort.BytesToRead;
  byte[] data = new byte[dataLength];
  int nbrDataRead = _serialPort.Read(data, 0, dataLength);
  if (nbrDataRead == 0)
  // Do some buffering
  Buffer.BlockCopy(data, 0, buffer, endOfBuffer, nbrDataRead);
  endOfBuffer += nbrDataRead;
  // Check if you got 21 bytes
  if(endOfBuffer >= 21)
    byte[] plcDataArray = new byte[21];
    Buffer.BlockCopy(buffer, 0, plcDataArray, 0, 21);
    endOfBuffer -= 21;
    if(endOfBuffer != 0)
      Buffer.BlockCopy(buffer, 0, buffer, 21, endOfBuffer);
    // Signal your code that you got a complete data package from the plc
    if(SignalCompletePackageEvent != null)
      SignalCompletePackageEvent(this, EventArgsTakingYourByteArray(plcDataArray));   

I have shared a very simple serial port app, and you're free to look at it Basic serial port listening application.
Good luck. NB: Always happy if you vote on the solution ;)
SoMad 8-Jun-12 15:52pm
My 5. Good answer and nice little serial port listener.

Soren Madsen

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    Print Answers RSS
Top Experts
Last 24hrsThis month
OriginalGriff 6,289
CHill60 3,490
Maciej Los 3,103
Jochen Arndt 1,975
ppolymorphe 1,900

Advertise | Privacy | Mobile
Web02 | 2.8.170525.1 | Last Updated 8 Jun 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100