SerialPort + CF 2.0 prevent losing data

Can anyone tell my why the code below would be missing or dropping data. I have been googling all night but can’t find any pointers. the serial port is using the following settings; 38400,n,8,1 xon/xoff flow control. ReceivedBytesThreshold = 1.

isReceiving and stockReceived are both members of the form

       private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string dataReceived = serialPort1.ReadExisting();
        bytecount += dataReceived.Length;
        processSerialData(dataReceived);
    }

    private void processSerialData(string dataReceived)
    {
        if (isReceiving == false)
        {
            int stxpos = dataReceived.IndexOf('\x02');
            if (stxpos != -1)
            {
                dataReceived = dataReceived.Replace("\x02", "");
                labelcaption = "Receiving... ";
                this.Invoke(new EventHandler(SetLabel));
                isReceiving = true;
            }
        }

        int etxpos = dataReceived.IndexOf('\x03');
        if (etxpos != -1)
        {
            dataReceived = dataReceived.Replace("\x03", "");
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
            tmpFile.Close();
            isReceiving = false;
            stockReceived = true;
        }

        // Now we need to write the data to file
        if (isReceiving == true)
        {
            if ((bytecount / recordSize) % 100 == 0)
            {
                labelcaption = "Receiving... " + (bytecount / recordSize);
                this.Invoke(new EventHandler(SetLabel));
            }
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
        }
    }

3 thoughts on “SerialPort + CF 2.0 prevent losing data

  1. user

    As serialPort1_DataReceived is a triggered event, it only ever occurs in the main thread. Therefore it cannot be entered by 2 threads simultaneously. To prove it, print out the thread ID of the executing thread (Thread.CurrentThread.ManagedThreadId).

    You can stick to spooling the data in the serialPort1_DataReceived call. If you can guarantee a “down-time” in activity in the serial link, spool until you know when that will be then fire off your processing.

    E.g. data will come in of up to X bytes/chars. Then another set of chars won’t come in for 500ms. You then have the 500ms to process the received bytes.

    Reply
  2. user

    A couple potential problems (not saying they are the problem, but they raise red flags for me) are:

    • You’re using a string and then looking for non-printable character data. This is a suspect processing idea IMO. You should be receiving bytes and then looking for byte values. Who know what the underlying encoding might do, but loss of some characters, especially if it’s using ASCII encoding, wouldn’t surprise me a bit.
    • This looks like a potential thread issue as well. When you get a DataRecieved event, you read the data and then go on and process the data in the context of the receive handler. What happens if you get another event while you’re still processing the last? I’m betting the byteCount variable gets hosed. Personally I’d have a thread dedicated to receiving the data and another for processing it. At the very least I’d add some sort of synchronization object in there.
    Reply

Leave a Reply

Your email address will not be published.