IndustProg
IndustProg

Reputation: 647

SerialPort.ReadLine does not work correctly

I want to read a sensor by serial port in windows Form. When I send desired sensor command consecutively by RealTerm program I get the expected response as below:

//1st Command
OK                                                                            
sS                                                                             
MAz2000145222                                                                                                                                                                                                                                                                  
MAz2000145222                                                                                                                                 
MAz2000145222                                                                                                                                  
SC
//2nd Command  
OK                                                                             
sS                                                                            
MAz2000145222                                                                                                                                 
MAz2000145222                                                                                                                                                                                                 
MAz2000145222                                                                                                                                   
SC
//3rd Command  
OK                                                                             
sS                                                                             
MAz2000145222                                                                                                                                 
MAz2000145222                                                                                                                                                                                                 
MAz2000145222                                                                                                                                   
SC  

But when I use my windows form application and send desired sensor command by pushing a button I get this:

//Displayed in txtBoxReceived
//1st Command
OK                                                                            
sS                                                                             
MAz2000145222                                                                                                                                                                                                                                                                 
MAz2000145222                                                                                                                                
MAz2000145222
//2nd Command                                                                                                                                    
SC 
OK                                                                            
sS                                                                             
MAz2000145222
//3rd Command                                                                                                                                  
MAz2000145222                                                                                                                                                                                                 
MAz2000145222                                                                                                                                   
SC 
OK                                                                             
sS                                                                             
MAz2000145222                                                                                                                                  
MAz2000145222                                                                                                                                                                                                 

This is my code:

public partial class Form1 : Form
{
    string strRecieved;
    static SerialPort _SerialPort = new SerialPort();

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        _SerialPort = new SerialPort("COM8", 115200, Parity.None, 8, StopBits.One);
        _SerialPort.ReadTimeout = 1000;
        _SerialPort.Open();
        _SerialPort.DataReceived += new SerialDataReceivedEventHandler(_SerialPort_DataReceived);

    }

    private void _SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        strRecieved = _SerialPort.ReadLine();

        this.Invoke(new EventHandler(UpdateVar));
    }

    private void UpdateVar(object sender, EventArgs e)
    {
       txtBoxReceived.Text += (strRecieved + Environment.NewLine);
    }

I am Puzzled! Is there any suggestion?

Edit according to comments: I press the button three times to send the three commands and there is sufficient time for the data to be received and the form to be updated. All strings sent by sensor are terminated by "\n" 0x0A. Please notice that the responses are correct in RealTerm. It seems to me that all characters are received correctly to input buffer, but ones which have not read yet, will come in next command!

Upvotes: 1

Views: 7164

Answers (1)

Baddack
Baddack

Reputation: 2053

In your DataRecieved event you should build a string until you have the whole line. All your responses end in CR LF, great, we can use that to determine when we have the whole string.

StringBuilder sb = new StringBuilder();
char LF = (char)10;

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    string Data = serialPort1.ReadExisting();

    foreach (char c in Data)
    {
        if (c == LF)
        {
            sb.Append(c);

            CurrentLine = sb.ToString();
            sb.Clear();

            //do something with your response 'CurrentLine'
            Eval_String(CurrentLine);
        }
        else
        {
            sb.Append(c);
        }
    }
}

Once you have the CurrentLine, you can evaluate your response. I'm not sure what you need to do with it, but from the example below you should be able to get your value.

private void Eval_String(string s)
{
    txtBoxReceived.Text += (s + Environment.NewLine);
}

Note that you may have to invoke updating the textbox because it's being called in your serial port thread.

Upvotes: 2

Related Questions