none
Serial port with trigger and wait maximum time RRS feed

  • Question


  • Hello,
    //Send trigger      -->   <STX>Trigger<ETX>
    //Receive message   -->   <STX>gd,3200FFFF1!FFFF\r\n

    I have to send that, wait until the answer comes or timeout.
    Configuration COM1, 8, NONE, 1

    Can somebody gives me a good example
      Problems check the end character and the timeout. Do I need a own thread or a event. Manual or auto?

      Next, it can be I received not the whole message, step by step.

    Thanks.
    Many greetings Markus
    Monday, January 14, 2019 5:28 PM

Answers

  • Hi Markus,

    There is a lot of discussion about the .Net serial port giving an exception while in use although myself I have not experienced this problem, I even read at one time that the problem had been fixed but again I can not vouch for that one way or the other.

    This link explains what a lot have trouble with

    and this is how Microsoft docs describe SerialPort.Close() and Dispose()

    Calling this method closes the SerialPort object and clears both the receive and transmit buffers. This method calls the Component.Dispose() method, which invokes the protected SerialPort.Dispose(Boolean) method with the disposing parameter set to true.

    The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly.

    EDIT The link here is the one I thought you might be interested in, the same blog and subject but a different article.

    • Edited by Jeff_T_1234 Saturday, January 19, 2019 5:06 PM
    • Marked as answer by Markus Freitag Sunday, January 20, 2019 2:06 PM
    Saturday, January 19, 2019 4:06 PM

All replies

  • Hi Markus Freitag,

    According to your description, it seems that you want to receive message from serial port. if so, here is a sample for your reference, which use SerialDataReceivedEventHandler

    class SerialPortApplication
      {
        //basic settings
        private SerialPort port = new SerialPort("COM1",
          9600, Parity.None, 8, StopBits.One);
    
        [STAThread]
        static void Main(string[] args)
        { 
          // Instatiate this class
          new SerialPortApplication();
        }
    
        private SerialPortApplication()
        {
          Console.WriteLine("Wait for Data:");
    
          // Attach a method to be called when there
          // is data waiting in the port's buffer
          port.DataReceived += new 
            SerialDataReceivedEventHandler(DataReceived);
    
          // Begin communications
          port.Open();
    
          // Enter an application loop to keep this thread alive
          Application.Run();
        }
    
        private void DataReceived(object sender,
          SerialDataReceivedEventArgs e)
        {
          // Show all the incoming data in the port's buffer
          Console.WriteLine(port.ReadExisting());
        }
      }


    For more information about serial port in c#, please refer to:

    https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=netframework-4.7.2

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Tuesday, January 15, 2019 3:34 AM
    Moderator
  • This might help you get started, it is a Windows Form Application that has two controls on the Form, 1 rich text box and 1 button. The button is for transmitting your "Trgger" string and the code is not included in this example.
    What the example does show is how to add the DataReceived event handler and because this event handler runs on a separate thread from the UI there is also an example of adding a simple delegate so that the incoming data string can be displayed in the rich text box.
    Inside the DataReceived event handler the serial port read timeout is set at 80 mS which can be adjusted depending on the baud setting and the length of the strings expected to be read. At the default port baud of 9600 your example string was captured fine at 80 mS.
    After the timeout comes the Newline character, the default is "\n" (decimal 10) but because your example string terminated with "\r\n" the example code modifies the Newline character to "\r" and the "\n" gets discarded on subsequent reads.
    The next part of code looks for the STX character (decimal 2), if it sees the STX it will read the following string up until it sees "\r" and if it doesn't then it will time out at 80 mS.
    Finally the delegate displays the captured string in the rich text box.

     public partial class Form1 : Form
        {
            SerialPort myport = new SerialPort();
            public delegate void myDelegate(string sData);
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                myport.PortName = "COM1";
                myport.Open();
                myport.DataReceived += new SerialDataReceivedEventHandler(myport_DataReceived);
                myport.ReadExisting();
            }
    
            private void myport_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
    
                string mystring;
                myport.ReadTimeout = 80;
                myport.NewLine = "\r";
    
                while(myport.BytesToRead>0)
                { 
                try
                {
                     byte stxCheck=(byte) myport.ReadByte();
    
                     if (stxCheck == 2)
                        {
                            mystring =myport.ReadLine();
                            this.BeginInvoke((new myDelegate(showString)), mystring);
                        }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                }
    
            }
    
            private void showString(string sData)
            {
                richTextBox1.AppendText(sData );
            }
        }

    Tuesday, January 15, 2019 3:36 AM
  • Hello everybody,
       //Open
        this.serialPort = new SerialPort(this.comStructure.PortName, 
    this.comStructure.BaudRate,
    this.comStructure.Parity, 
    this.comStructure.DataBits, this.comStructure.StopBits);
        this.serialPort.Handshake = this.comStructure.Handshake;
        this.serialPort.DataReceived += this.readDataFromSerialPort;
        this.serialPort.Open();


    I think I do not need a thread here, because I have the event DataReceived, right?
    I  have problems here to send the result to GUI.   (Invoke Problem)
    With best regards Markus
    Thursday, January 17, 2019 5:54 PM
  • Hello Markus

    Yes you are right, the GUI is the main thread and the DataReceived eventhandler gives a second thread that allows you to asynchronously handle the incoming data stream. 

    For the controls on the GUI to safely access the serial data from the secondary thread without an exception I used a simple delegate. The delegate consists of three parts and takes a string as a parameter. The delegate can easily be replicated with different parameters. These are the three parts.

    Declare a delegate
    public delegate void myDelegate(string sData);
    Declare a method with the same signature
    private void showString(string sData)
            {
                richTextBox1.AppendText(sData );
            }
    Finally invoke the delegate
    this.BeginInvoke((new myDelegate(showString)), mystring);
    

    Friday, January 18, 2019 1:48 AM
  • Hello Jeff,
    Thank you for your answer. What is your opinion on "Send Data" "Get Data" or Timeout.
    How would you solve that? AutoResetEvent or Manual? Can you say something about this?
    DiscardInBuffer -- delete it, good or bad?
    Thank you for your answer in advance.
    Many Greetings Markus
    Friday, January 18, 2019 4:10 PM
  • Sending data and receiving data is application specific and can vary in so many ways so there is no real way to answer that without knowing the specifics. 

    The success of serial communications is mainly down to protocol. The protocol that seems apparent in your original post is not complex but may very well be adequate in most cases. Protocol frames data and anything outside of the frame should be discarded, if there is a need to constantly empty data from the receive buffer I would tend to think there was something wrong with the communications or a poorly designed protocol. With regard to DiscardinBuffer if your system is designed right you should not need it, having said that in the example I first gave I used ReadExisting to clear the input buffer immediately after opening the port, there again probably not needed but left over from another time.

    Friday, January 18, 2019 11:43 PM
  • Sending data and receiving data is application specific and can vary in so many ways so there is no real way to answer that without knowing the specifics. 


    Hello Jeff,

    yes you are right, it is specific.

    >DiscardinBuffer    

    Clear, ok.

     AutoResetEvent or Manual? How do you do that? Or do you take Cancellation? Do you have an example, then I can close the thread. Have a nice weekend.

    With best regards Markus



    Saturday, January 19, 2019 10:42 AM
  • Hi Markus,

    There is a lot of discussion about the .Net serial port giving an exception while in use although myself I have not experienced this problem, I even read at one time that the problem had been fixed but again I can not vouch for that one way or the other.

    This link explains what a lot have trouble with

    and this is how Microsoft docs describe SerialPort.Close() and Dispose()

    Calling this method closes the SerialPort object and clears both the receive and transmit buffers. This method calls the Component.Dispose() method, which invokes the protected SerialPort.Dispose(Boolean) method with the disposing parameter set to true.

    The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly.

    EDIT The link here is the one I thought you might be interested in, the same blog and subject but a different article.

    • Edited by Jeff_T_1234 Saturday, January 19, 2019 5:06 PM
    • Marked as answer by Markus Freitag Sunday, January 20, 2019 2:06 PM
    Saturday, January 19, 2019 4:06 PM