views:

67

answers:

1

Pretty simple question this time around. I have an application that communicates with another copy of the application on another machines. One application sends a pretty constant stream of data, the other receives it.

The code to send data looks like this (where serialPort is an instance of the System.IO.Ports.SerialPorts class in C# .Net 2.0):

private void bgDataWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e){
    try{
        string tempStr = Convert.ToString(String.Format("{0:0.000000}", data));
        serialPort.Write(tempStr); // Write "data" out to 6 decimal places  
    }
    catch (TimeoutException){ }
    catch (InvalidOperationException err){ // Port is obstructed or closed
        this.Invoke((MethodInvoker)delegate{
            MessageBox.Show(this, "Couldn't send wireless data:\n\n" + 
                            err.ToString(), "NanoMETER - Wireless Error (Data)", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
            Global.remoteEna = false;
            serialPort.Close();
            usingBT = false;  
        }); 
    }
}

It's called on a timer. The receive code is even more straightforward:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    string buffer = serialPort.ReadExisting();
    HandleInput(buffer);
}

Data gets sent and handled and it's all fine and dandy, but there's some unwanted choppiness where it's either not reliably sending data at a constant rate, or it's not picking up everything. I'm not sure if this can be fixed in my code, or if it's just the nature of having a few slow machines and a possibly shakey bluetooth connection. Any suggestions?

A: 

It's not uncommon for interns to be assigned to converting old code to a newer platform.

There are a few improvements you can make.

1) The following strategy is good when the bytes sent through the port is meant to be interpreted in blocks, such as commands. Do you have some sort of protocol? Something that dictates the format of the message you are sending. For instance, a specific delimiter to indicate the beginning and the length of the upcoming command. This allows you to quickly determine if the command was only half sent, or if there were missing bytes. Even better is to add a CRC at the end.

2) Instead of reading on a timer, base yourself on the events flagged by your serialport object. Here's an example of what i use:

    //OnReceive event will only fire when at least 9 bytes are in the buffer.
    serialPort.ReceivedBytesThreshold = 9; 
    //register the event handlers
    serialPort.DataReceived += new SerialDataReceivedEventHandler(OnReceive);
    serialPort.PinChanged += new SerialPinChangedEventHandler(OnPinChanged);

In the code above, i set a threshhold of 9, you should change that to whatever fits your context. Also, the Pinchanged event is something good to monitor, it will allow you to quickly identify if the cable has been disconnected. There is more on this, regarding CTSChanged but you can look it up if you are interested.

Lastly, if this doesn't help you get a little further, show an example of the problem that occured so the peolpe here can give you more help.

Lily