views:

5312

answers:

3

I am reading data from serial port. The data comes off the scale. I am now using Readline() and getting data dropped even after I removed DiscardInBuffer(). What is the proper way to read the data from the serial port? There are so few examples online that I feel it's like some holy grail that no one has figured out.

Any help please?

Seems like serial port is a capricious child.

C#, WinCE 5.0, HP thin client, Compact framework 2.0

 private void WeighSample()
    {
        this._processingDone = false;
        this._workerThread = new Thread(CaptureWeight);
        this._workerThread.IsBackground = true;
        this._workerThread.Start();
    } //end of WeighSample()


    private void CaptureWeight()
    {
         globalCounter++;
         string value = "";


          while (!this._processingDone)
          {
              try
              {

                 value = this._sp.ReadLine();

                  if (value != "")
                  {
                      if (value == "ES")
                      {
                          _sp.DiscardInBuffer();
                          value = "";
                      }
                      else
                      {
                          this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
                      }
                  }
              }
              catch (TimeoutException)
              {
                  //catch it but do nothing
              }
              catch
              {
                  //reset the port here?
                  MessageBox.Show("some other than timeout exception thrown while reading serial port");
              }
          }


    } //end of CaptureWeight()

One thing to note about my application is that I start the thread (weighSample) when the cursor jumps onto the textbox. The reason to this is that the weight can also be typed in manually (part of the req's). So I don't know in advance whether a user is going to press PRINT on the balance or type the weight. In either case after the data is acquired, I exit the worker thread. Also, note that I am not using serial port event DataReceived, since I have been told it's not reliable.

Any comments/ ideas welcome. This is my first experience with serial ports.

A: 

Depends on what the end-of-line (EOL) character(s) is for your input data. If your data is line oriented then ReadLine is a valid function to use, but you may want to look at the NewLine property and be sure that it is set appropriately for your input data.

For example, if your scale outputs linefeed for EOL then set port.NewLine = "\n";

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.newline.aspx

joshperry
so does that depend on the device configuration?
gnomixa
I am reading the data from the scale. Does this value (Newline) have to correspond the scale format in this case?I am now settings it to \r\n which is the standard.
gnomixa
A: 

I have never had luck with ReadLine working. Just do a Read into a local buffer whenever data is available and then use a separate thread to scan the data and find line breaks yourself.

ctacke
quick question - i have polling the scale already running in existing thread. Do I still need a separate thread to scan the data? will post the code when I get to work.
gnomixa
Generally I fire up a worker thread that does the port reads and puts them in an app buffer. When it puts data into the buffer, it sets an event that signals the parser thread to go an look for data lines and then raise yet another event to the consuming app. You may already have one of these.
ctacke
so in total you have 2 threads: one main thread and one worker thread?What's the difference between blocking and non-blocking behaviour? Is Read() blocking?
gnomixa
Yes, I generally have 2 threads. Maybe 3 depening on the exact use case, but the workers are usually in a wait state using very little processor. I would assume Read is blocking and the return is based on the driver CommTimeouts (that's how I implemented it in the OpenNETCF serial library anyway).
ctacke
I have read that Read is non-blocking - I am confused , it seems no one really explains HOW it works really. Is it safe to do this: _sp.Read(buffer, 0, _sp.BytesToRead); and buffer is char[]Thanks! i feel overwhelmed by the lack of info about serial ports.
gnomixa
I can't see how it could be non blocking. When you call Read, it has to return data, so it must block until it either fetches data from the serial driver (or the serial driver times out). Under the hood it's calling the ReadFile API, though it's possible that it has an internal thread that does it
ctacke
If you want to know exactly what is happening, I'd recommend you look at the OpenNETCF serial library. It's interface compatible with the CF library and that way you can step through the code all the way to the driver call if you want.
ctacke
do you happen to have any Read working examples? I am afraid I don't have a whole lot of time to step through the library code. I am actually using MS SerialPort not OpenNetCF. All the info I know is from msdn, which can be cryptic.
gnomixa
@gnomixa, ever get an example? or do you have your own demo project with this working now I could take a look at ?
GONeale
yes, I did. i will post its shortly on my blog.
gnomixa
A: 

Hello Guys, Do you guys have sample code which explain how to read the Serial port data in Local buffer and then use a separate thread to scan the data from app buffer.. this is my first time I am doing Serial Port programming. I will Appreciate your help.. Thanks in Advance

Hi CHetah, I will post it shortly on my blog and will put a link here. It's too long for this site to post.
gnomixa