1

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!

IndustProg
  • 627
  • 1
  • 13
  • 33
  • maybe your sensor does not the data with new lines separated, you can try and use `ReadExisting()` to check which delimiter is being actually used – styx Apr 12 '18 at 11:22
  • @styx, All strings sent by sensor are terminated by "\n" `0x0A`. Please notice that the responses are correct in RealTerm. – IndustProg Apr 12 '18 at 11:24
  • 1
    It is unclear what your problem is - the data in both cases looks the same - so are you saying the timing is not what you expect? Do you press the button three times to send the three commands - with sufficient time for the data to be received and the form to be updated? Note that the DataReceived event is raised when any data is received, not when the "\n" character arrives, so as styx has said, you should use the ReadExisting method rather than ReadLine. – PaulF Apr 12 '18 at 11:33
  • @PaulF, You are correct. I edited my post. – IndustProg Apr 12 '18 at 11:46
  • Have you tried using ReadExisting (or Read in conjunction with BytesToRead) - neither strip the newline character so can be appended to the textbox without adding another.? See https://stackoverflow.com/questions/636758/serial-port-readline-vs-readexisting-or-how-to-read-the-data-from-serial-port-pro – PaulF Apr 12 '18 at 12:10
  • 1
    Note that the DataReceived event occurs as data is received - and not guaranteed for each byte. ReadLine will only read up to the first newline byte, if the processing takes any significant time data may be left in the input buffer & not be extracted until the next event. Data being left in the buffer will not cause another data received event, so you could possibly have multiple lines of data being buffered. – PaulF Apr 12 '18 at 12:19
  • @PaulF. I think It is what really occurs. What is the solution?The returned data length is 3 or 14 characters, including the terminating character `\n`. How can I check which one is coming? – IndustProg Apr 12 '18 at 12:25
  • Check the answer in the link I gave you. If you want to use the DataReceived event then this should just collect all the received data (using ReadExisting) into a local buffer & process it on another thread. Alternatively - do not use event processing - it looks like you know you will get 6 strings after each command - so after sending the command have for loop getting each line with ReadLine. You definitely should NOT use ReadLine inside the event. – PaulF Apr 12 '18 at 14:35

1 Answers1

2

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.

Baddack
  • 1,947
  • 1
  • 24
  • 33