Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. COM port send/receive

COM port send/receive

Scheduled Pinned Locked Moved C#
comannouncement
15 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mprice214
    wrote on last edited by
    #1

    Hi all, I am communicating to a COM port where I send a string to the device and it returns a string. A button event triggers a string to be written and a text box is populated with the read value. What I ultimately am trying to do is to have the text box automatically update with the returned value from the device. I initially thought a timer event should be employed, but I'm not sure if this would be the most robust way to do this. Thanks.

    P R 2 Replies Last reply
    0
    • M mprice214

      Hi all, I am communicating to a COM port where I send a string to the device and it returns a string. A button event triggers a string to be written and a text box is populated with the read value. What I ultimately am trying to do is to have the text box automatically update with the returned value from the device. I initially thought a timer event should be employed, but I'm not sure if this would be the most robust way to do this. Thanks.

      P Offline
      P Offline
      PIEBALDconsult
      wrote on last edited by
      #2

      The same TextBox? What if the user is typing in it when the result comes along? I would wrap the serial port in a class that provides an event for response and update the TextBox when the event fires. (Being me, I'd write a class that I can use with my CommScript[^].) If it's one TextBox, I might also disable the TextBox and Button when the Button is clicked, and re-enable them when the event fires.

      M 1 Reply Last reply
      0
      • P PIEBALDconsult

        The same TextBox? What if the user is typing in it when the result comes along? I would wrap the serial port in a class that provides an event for response and update the TextBox when the event fires. (Being me, I'd write a class that I can use with my CommScript[^].) If it's one TextBox, I might also disable the TextBox and Button when the Button is clicked, and re-enable them when the event fires.

        M Offline
        M Offline
        mprice214
        wrote on last edited by
        #3

        I'll be using a label instead. Sorry for the confusion. Presently there is a text box, but I won't be allowing text input in the application. The device will require that a string be written to it as it doesn't transmit continuously.

        P 1 Reply Last reply
        0
        • M mprice214

          I'll be using a label instead. Sorry for the confusion. Presently there is a text box, but I won't be allowing text input in the application. The device will require that a string be written to it as it doesn't transmit continuously.

          P Offline
          P Offline
          PIEBALDconsult
          wrote on last edited by
          #4

          Well, at least this gives me an excuse to write a SerialCommunicator... :sigh:

          M 1 Reply Last reply
          0
          • P PIEBALDconsult

            Well, at least this gives me an excuse to write a SerialCommunicator... :sigh:

            M Offline
            M Offline
            mprice214
            wrote on last edited by
            #5

            I have pasted below the code that I am now using. As I am new to this, I thought a timer could be relatively easy to implement instead of the btnStart_Click event. Also, I know timing could really mess things up, but not sure how to deal with that either...

            private void btnStart_Click(object sender, EventArgs e)
            {
            //Makes sure serial port is open before trying to write
            try
            {
            if (!sp1.IsOpen)
            sp1.Open();

                        sp1.Write("\*X01\\r");
            
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
                    }
                }
            
                private void Form1\_Load(object sender, EventArgs e)
                {
                    // all of the options for a serial device
                    // can be sent through the constructor of the SerialPort class
                    // PortName = "COM1", Baud Rate = 9600, Parity = odd, 
                    // Data Bits = 7, Stop Bits = One, Handshake = None
                    sp1 = new SerialPort("COM1", 9600, Parity.Odd, 7, StopBits.One);
                    sp1.Handshake = Handshake.None;
                    sp1.DataReceived += new SerialDataReceivedEventHandler(sp\_DataReceived);
                    sp1.ReadTimeout = 500;
                    sp1.WriteTimeout = 500;
                    sp1.Open();
                }
            
                void sp\_DataReceived(object sender, SerialDataReceivedEventArgs e)
                {
                    Thread.Sleep(100);
                    string data = sp1.ReadExisting();
                    this.BeginInvoke(new SetTextDeleg(si\_DataReceived), new object\[\] { data });
                }
            
                private void si\_DataReceived(string data)
                {
                    char\[\] charsToTrim = {'X','0','1'};
                    textBox1.Text = data.TrimStart(charsToTrim);
                    
                }
            
            P 1 Reply Last reply
            0
            • M mprice214

              I have pasted below the code that I am now using. As I am new to this, I thought a timer could be relatively easy to implement instead of the btnStart_Click event. Also, I know timing could really mess things up, but not sure how to deal with that either...

              private void btnStart_Click(object sender, EventArgs e)
              {
              //Makes sure serial port is open before trying to write
              try
              {
              if (!sp1.IsOpen)
              sp1.Open();

                          sp1.Write("\*X01\\r");
              
                      }
                      catch (Exception ex)
                      {
                          MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
                      }
                  }
              
                  private void Form1\_Load(object sender, EventArgs e)
                  {
                      // all of the options for a serial device
                      // can be sent through the constructor of the SerialPort class
                      // PortName = "COM1", Baud Rate = 9600, Parity = odd, 
                      // Data Bits = 7, Stop Bits = One, Handshake = None
                      sp1 = new SerialPort("COM1", 9600, Parity.Odd, 7, StopBits.One);
                      sp1.Handshake = Handshake.None;
                      sp1.DataReceived += new SerialDataReceivedEventHandler(sp\_DataReceived);
                      sp1.ReadTimeout = 500;
                      sp1.WriteTimeout = 500;
                      sp1.Open();
                  }
              
                  void sp\_DataReceived(object sender, SerialDataReceivedEventArgs e)
                  {
                      Thread.Sleep(100);
                      string data = sp1.ReadExisting();
                      this.BeginInvoke(new SetTextDeleg(si\_DataReceived), new object\[\] { data });
                  }
              
                  private void si\_DataReceived(string data)
                  {
                      char\[\] charsToTrim = {'X','0','1'};
                      textBox1.Text = data.TrimStart(charsToTrim);
                      
                  }
              
              P Offline
              P Offline
              PIEBALDconsult
              wrote on last edited by
              #6

              If it's woking that way, then leave it alone. But now I'm confused as to what you're writing and how.

              M 1 Reply Last reply
              0
              • P PIEBALDconsult

                If it's woking that way, then leave it alone. But now I'm confused as to what you're writing and how.

                M Offline
                M Offline
                mprice214
                wrote on last edited by
                #7

                The device I am using (a Newport meter) requires a string *X01\r in order to return the value that is on the display. When the button is clicked, it writes that string to the com port and then returns a series of characters, some of which are the actual value on the display. The problem is the button needs to be clicked. I want to have a start button and a stop button that begins and ends a thread used for automatically reading and writing to the com port, displaying the read value in a form label. Since I'm just learning C#, this is not an easy task. If anyone has any pointers, that would be greatly appreciated. Thanks,Mike

                P 1 Reply Last reply
                0
                • M mprice214

                  The device I am using (a Newport meter) requires a string *X01\r in order to return the value that is on the display. When the button is clicked, it writes that string to the com port and then returns a series of characters, some of which are the actual value on the display. The problem is the button needs to be clicked. I want to have a start button and a stop button that begins and ends a thread used for automatically reading and writing to the com port, displaying the read value in a form label. Since I'm just learning C#, this is not an easy task. If anyone has any pointers, that would be greatly appreciated. Thanks,Mike

                  P Offline
                  P Offline
                  PIEBALDconsult
                  wrote on last edited by
                  #8

                  I would likely use a System.Timers.Timer; the Elapsed event handler would handle the writing, the code you have above would deal with the incoming data.

                  M 1 Reply Last reply
                  0
                  • P PIEBALDconsult

                    I would likely use a System.Timers.Timer; the Elapsed event handler would handle the writing, the code you have above would deal with the incoming data.

                    M Offline
                    M Offline
                    mprice214
                    wrote on last edited by
                    #9

                    I tried that without success. If I move the button click event to a timer tick event, nothing happens. I have even set the timer tick time to be >>Timer.Sleep (100) to make sure that there are no timing issues, but still nothing happens. However, if it did "work", seems that there would be a better way than a Timer.Sleep method....., but I'd take a successful timer function, if it would work. Thoughts?

                    P 1 Reply Last reply
                    0
                    • M mprice214

                      Hi all, I am communicating to a COM port where I send a string to the device and it returns a string. A button event triggers a string to be written and a text box is populated with the read value. What I ultimately am trying to do is to have the text box automatically update with the returned value from the device. I initially thought a timer event should be employed, but I'm not sure if this would be the most robust way to do this. Thanks.

                      R Offline
                      R Offline
                      Rajesh Anuhya
                      wrote on last edited by
                      #10

                      why are you going for timer to read the comport buffer, i used stopwatch for this one , see the below code this may help u

                      Stopwatch ObjStopWatch = new Stopwatch();
                      ObjStopWatch.Start();
                      long StDelay = ObjStopWatch.ElapsedMilliseconds;
                      try
                      {
                      string FromModem = "";
                      Comport.ClearInputBuffer();
                      Comport.Write(Command);
                      Comport.Write(new byte[] { 0x0D, 0x0A });
                      do
                      {
                      if (Comport.InBufferCount>0)
                      {
                      Comport.Read(Comport.InBufferCount);
                      FromModem += Comport.InputStreamString;
                      if (FromModem.Contains("OK"))
                      break;
                      }
                      } while ((StDelay + 5000) > ObjStopWatch.ElapsedMilliseconds);

                      Frommodem holds the value of the comport buffer. here my timeout is 5000 milliseconds.. Thanks

                      Rajesh B --> A Poor Workman Blames His Tools <--

                      M 1 Reply Last reply
                      0
                      • M mprice214

                        I tried that without success. If I move the button click event to a timer tick event, nothing happens. I have even set the timer tick time to be >>Timer.Sleep (100) to make sure that there are no timing issues, but still nothing happens. However, if it did "work", seems that there would be a better way than a Timer.Sleep method....., but I'd take a successful timer function, if it would work. Thoughts?

                        P Offline
                        P Offline
                        PIEBALDconsult
                        wrote on last edited by
                        #11

                        I've never had trouble with timers. You start the timer? And set it to AutoReset? Does it elapse at least once?

                        M 1 Reply Last reply
                        0
                        • P PIEBALDconsult

                          I've never had trouble with timers. You start the timer? And set it to AutoReset? Does it elapse at least once?

                          M Offline
                          M Offline
                          mprice214
                          wrote on last edited by
                          #12

                          :~ I checked the timer again.....Would help if it were enabled. Sometimes I wonder. Seems that a stopwatch, as Rajesh suggest, may be the better way to handle this?

                          P 1 Reply Last reply
                          0
                          • M mprice214

                            :~ I checked the timer again.....Would help if it were enabled. Sometimes I wonder. Seems that a stopwatch, as Rajesh suggest, may be the better way to handle this?

                            P Offline
                            P Offline
                            PIEBALDconsult
                            wrote on last edited by
                            #13

                            mprice214 wrote:

                            enabled

                            Yes, but that's what Start does anyway. I prefer the Timer Elapsed handler for sending and the event handler for receiving.

                            1 Reply Last reply
                            0
                            • R Rajesh Anuhya

                              why are you going for timer to read the comport buffer, i used stopwatch for this one , see the below code this may help u

                              Stopwatch ObjStopWatch = new Stopwatch();
                              ObjStopWatch.Start();
                              long StDelay = ObjStopWatch.ElapsedMilliseconds;
                              try
                              {
                              string FromModem = "";
                              Comport.ClearInputBuffer();
                              Comport.Write(Command);
                              Comport.Write(new byte[] { 0x0D, 0x0A });
                              do
                              {
                              if (Comport.InBufferCount>0)
                              {
                              Comport.Read(Comport.InBufferCount);
                              FromModem += Comport.InputStreamString;
                              if (FromModem.Contains("OK"))
                              break;
                              }
                              } while ((StDelay + 5000) > ObjStopWatch.ElapsedMilliseconds);

                              Frommodem holds the value of the comport buffer. here my timeout is 5000 milliseconds.. Thanks

                              Rajesh B --> A Poor Workman Blames His Tools <--

                              M Offline
                              M Offline
                              mprice214
                              wrote on last edited by
                              #14

                              Hi Rajesh, The issue I'm now having is that using a timer doesn't seem to be the most deterministic approach. In other words, I have a string that is written to the device at certain intervals. The serial data received method (SerialDataReceivedEventArgs) then Invokes the function that writes the returned string to a text box. However, to make sure the entire string is sitting in the buffer to be read, there is the Thread.Sleep. This seems very ineffecient and I'm trying to verify if that assumption is correct. What I would like to do is to write and read as fast as possible without the thread getting all tied up with timing issues. The device I'm talking to sends a carriage return at the end of the string. It seems that the fastest way to do this would be if I have a loop that writes a command string/waits for the string ending with a cr/writes that read value to whatever (textbox, etc) and writes the command string again. Since I am new to this, I'm not sure if the stopwatch is the way to go, but I think a timer/thread.sleep combination is asking for crashing problems when I'm trying to do this a fast as possible. Thoughts?

                              M 1 Reply Last reply
                              0
                              • M mprice214

                                Hi Rajesh, The issue I'm now having is that using a timer doesn't seem to be the most deterministic approach. In other words, I have a string that is written to the device at certain intervals. The serial data received method (SerialDataReceivedEventArgs) then Invokes the function that writes the returned string to a text box. However, to make sure the entire string is sitting in the buffer to be read, there is the Thread.Sleep. This seems very ineffecient and I'm trying to verify if that assumption is correct. What I would like to do is to write and read as fast as possible without the thread getting all tied up with timing issues. The device I'm talking to sends a carriage return at the end of the string. It seems that the fastest way to do this would be if I have a loop that writes a command string/waits for the string ending with a cr/writes that read value to whatever (textbox, etc) and writes the command string again. Since I am new to this, I'm not sure if the stopwatch is the way to go, but I think a timer/thread.sleep combination is asking for crashing problems when I'm trying to do this a fast as possible. Thoughts?

                                M Offline
                                M Offline
                                mprice214
                                wrote on last edited by
                                #15

                                Here is what I have:

                                    private void DisplayText(object sender, EventArgs e)
                                    {
                                
                                        textBox1.Text = RxString;
                                        serialPort1.DiscardInBuffer();
                                        while (serialPort1.BytesToRead == 0)
                                        
                                            serialPort1.WriteLine("\*X01\\r");
                                        
                                
                                    }
                                
                                    private void serialPort1\_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
                                    {
                                        RxString = "";
                                
                                
                                        try
                                        {
                                            RxString = serialPort1.ReadTo("\\r");
                                            
                                        }
                                        catch (Exception Exception)
                                        {
                                            return;
                                        }
                                                 
                                        this.Invoke(new EventHandler(DisplayText));
                                    }
                                
                                    private void textBox1\_TextChanged(object sender, EventArgs e)
                                    {
                                
                                    }
                                
                                    private void timer1\_Tick(object sender, EventArgs e)
                                    {
                                        //timer1.Interval = 50;
                                        //if (!serialPort1.IsOpen) return;
                                        //serialPort1.WriteLine("\*X01\\r");
                                    }
                                

                                I want to get rid of the timer and have a while loop that writes the ("*X01\r") once the buffer is empty. Then I won't need the timer. However, I can't get a while loop to work.

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups