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. Reading from serial port

Reading from serial port

Scheduled Pinned Locked Moved C#
help
12 Posts 4 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.
  • A alfie max15

    I am trying to make a serial port terminal and i have succesfully made it except for some problems that i am facing. i have a button pressing which the terminal starts and the data from the serial port start to get displayed on the textbox. when i press the button again the serial port closes. Also i have put the code to read from the serial port in a timer with a time of 1 millisecond. So it automatically works like a loop and the data can be displayed continuously. Case 1. when i try reading from the serial port using

    _SerialPort.ReadLine ()

    what happens is that the data is getting displayed perfectly, but i am not able to press the button again to close the serial port, also i cant even close the application. I would have to use the task manager to kill the process. Case 2. when i try reading from the serial port using

    _SerialPort.ReadExisting ()

    what happens is that the earlier issue is resolved, but the data that is received is not continuous, that is some values are not recieved.

    OriginalGriffO Offline
    OriginalGriffO Offline
    OriginalGriff
    wrote on last edited by
    #3

    Don't use either of them like that. Instead, handle the SerialPort.DataReceived[^] event, and get the data in that using ReadExisting - you can then add the data to the textbox in the event handler and you should never lose any data, nor should your UI freeze up. Remember, Serial ports are very slow devices - data transfer is not instantaneous, nor is it packet based. if you are running your serial port as 9600 baud for example, it will receive one character about every millisecond (7 data bits, 1 parity, 1 start and one stop bit == 10 bits, 9600/10 = 960 characters per second.) So if you just read once, you will get whatever characters are in teh buffer at that moment, and nevr get any more.

    The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

    "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
    "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

    A 1 Reply Last reply
    0
    • J jschell

      ReadLine() blocks until a new line character occurs so you can't expect it to do anything immediately based on a key press unless the key causes a end of line. If your source for the characters are human input is human than it seems unlikely that ReadExisting() would lose anything. What would be more likely in that case is that your output code is not correctly handling what ReadExisting is returning.

      A Offline
      A Offline
      alfie max15
      wrote on last edited by
      #4

      jschell wrote:

      If your source for the characters are human input is human than it seems unlikely that ReadExisting() would lose anything.

      the characters are not human input. its source is a micro controller ADC output. So it continuously sends data to the serial port. Parity - Even Databits - 8 Stopbits - 2 Baudrate - 4800

      jschell wrote:

      ReadLine() blocks until a new line character occurs so you can't expect it to do anything immediately based on a key press unless the key causes a end of line.

      The button press calls the

      serialport.Close();

      so then it shouldn't matter what the

      ReadLine()

      function gets.

      1 Reply Last reply
      0
      • OriginalGriffO OriginalGriff

        Don't use either of them like that. Instead, handle the SerialPort.DataReceived[^] event, and get the data in that using ReadExisting - you can then add the data to the textbox in the event handler and you should never lose any data, nor should your UI freeze up. Remember, Serial ports are very slow devices - data transfer is not instantaneous, nor is it packet based. if you are running your serial port as 9600 baud for example, it will receive one character about every millisecond (7 data bits, 1 parity, 1 start and one stop bit == 10 bits, 9600/10 = 960 characters per second.) So if you just read once, you will get whatever characters are in teh buffer at that moment, and nevr get any more.

        The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

        A Offline
        A Offline
        alfie max15
        wrote on last edited by
        #5

        OriginalGriff wrote:

        Instead, handle the SerialPort.DataReceived[^] event, and get the data in that using ReadExisting - you can then add the data to the textbox in the event handler

        Sorry forgot to mention, i had tried that too... Same problem. losing data....

        OriginalGriffO 1 Reply Last reply
        0
        • A alfie max15

          OriginalGriff wrote:

          Instead, handle the SerialPort.DataReceived[^] event, and get the data in that using ReadExisting - you can then add the data to the textbox in the event handler

          Sorry forgot to mention, i had tried that too... Same problem. losing data....

          OriginalGriffO Offline
          OriginalGriffO Offline
          OriginalGriff
          wrote on last edited by
          #6

          How did you use it? Do you still have the code?

          The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

          "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
          "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

          A 1 Reply Last reply
          0
          • OriginalGriffO OriginalGriff

            How did you use it? Do you still have the code?

            The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

            A Offline
            A Offline
            alfie max15
            wrote on last edited by
            #7

            private void Start_Click (object sender, EventArgs e)
            {
            if(Start.Text == "Start")
            {
            Start.Text = "Stop";
            _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
            }
            else
            {
            Start.Text = "Start";
            }
            }

                private void Port\_DataReceived (object sender, SerialDataReceivedEventArgs e)
                {
                    string data = \_SerialPort.ReadExisting ();
                    rtbTerminal.AppendText (data);
                    rtbTerminal.ScrollToCaret ();
                }
            

            private void Start_Click (object sender, EventArgs e)
            {
            if(Start.Text == "Start")
            {
            Start.Text = "Stop";
            _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
            }
            else
            {
            Start.Text = "Start";
            }
            }

                private void Port\_DataReceived (object sender, SerialDataReceivedEventArgs e)
                {
                    string data = \_SerialPort.ReadExisting ();
            
                    rtbTerminal.Invoke (new EventHandler (delegate
                    {
                        rtbTerminal.SelectedText = string.Empty;
                        rtbTerminal.AppendText (data);
                        rtbTerminal.ScrollToCaret ();
                    }));
                }
            

            I have tried both ways above.

            OriginalGriffO 1 Reply Last reply
            0
            • A alfie max15

              private void Start_Click (object sender, EventArgs e)
              {
              if(Start.Text == "Start")
              {
              Start.Text = "Stop";
              _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
              }
              else
              {
              Start.Text = "Start";
              }
              }

                  private void Port\_DataReceived (object sender, SerialDataReceivedEventArgs e)
                  {
                      string data = \_SerialPort.ReadExisting ();
                      rtbTerminal.AppendText (data);
                      rtbTerminal.ScrollToCaret ();
                  }
              

              private void Start_Click (object sender, EventArgs e)
              {
              if(Start.Text == "Start")
              {
              Start.Text = "Stop";
              _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
              }
              else
              {
              Start.Text = "Start";
              }
              }

                  private void Port\_DataReceived (object sender, SerialDataReceivedEventArgs e)
                  {
                      string data = \_SerialPort.ReadExisting ();
              
                      rtbTerminal.Invoke (new EventHandler (delegate
                      {
                          rtbTerminal.SelectedText = string.Empty;
                          rtbTerminal.AppendText (data);
                          rtbTerminal.ScrollToCaret ();
                      }));
                  }
              

              I have tried both ways above.

              OriginalGriffO Offline
              OriginalGriffO Offline
              OriginalGriff
              wrote on last edited by
              #8

              Um. You do realize that each time you click the "Start" button, you add another handler to the existing list? So when a character arrives, the same handler method will be called twice, then three times, then four, etc... And that DataReceived is likely to be called each time a character arrives, since your PC runs rather faster than the serial port does, most of the time? How I would start: Add the handler once, when you first construct the SerialPort instance. Add a bool to enable / disable receive. When you press the Start button, clear the text from the RTB, then set the bool to enabled. When you press the Stop button, set the bool to disabled. In the DataReceived Handler, read the data available. Then, check the bool. If it is enabled, Append the data to the RTB and scroll to the caret. (You shouldn't need an invoke, I don't think). Do not clear the RTB. If it is disabled, throw the data away! Try that...

              The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

              "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
              "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

              A 1 Reply Last reply
              0
              • A alfie max15

                I am trying to make a serial port terminal and i have succesfully made it except for some problems that i am facing. i have a button pressing which the terminal starts and the data from the serial port start to get displayed on the textbox. when i press the button again the serial port closes. Also i have put the code to read from the serial port in a timer with a time of 1 millisecond. So it automatically works like a loop and the data can be displayed continuously. Case 1. when i try reading from the serial port using

                _SerialPort.ReadLine ()

                what happens is that the data is getting displayed perfectly, but i am not able to press the button again to close the serial port, also i cant even close the application. I would have to use the task manager to kill the process. Case 2. when i try reading from the serial port using

                _SerialPort.ReadExisting ()

                what happens is that the earlier issue is resolved, but the data that is received is not continuous, that is some values are not recieved.

                P Online
                P Online
                PIEBALDconsult
                wrote on last edited by
                #9

                I use:

                stream = port.BaseStream ;
                ...
                byte[] buffer = new byte [ port.ReadBufferSize ] ;
                ...
                stream.Read ( buffer , 0 , buffer.Length ) ;

                And I run the reader in a thread that raises events.

                1 Reply Last reply
                0
                • OriginalGriffO OriginalGriff

                  Um. You do realize that each time you click the "Start" button, you add another handler to the existing list? So when a character arrives, the same handler method will be called twice, then three times, then four, etc... And that DataReceived is likely to be called each time a character arrives, since your PC runs rather faster than the serial port does, most of the time? How I would start: Add the handler once, when you first construct the SerialPort instance. Add a bool to enable / disable receive. When you press the Start button, clear the text from the RTB, then set the bool to enabled. When you press the Stop button, set the bool to disabled. In the DataReceived Handler, read the data available. Then, check the bool. If it is enabled, Append the data to the RTB and scroll to the caret. (You shouldn't need an invoke, I don't think). Do not clear the RTB. If it is disabled, throw the data away! Try that...

                  The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

                  A Offline
                  A Offline
                  alfie max15
                  wrote on last edited by
                  #10

                  I have two forms, the first one is the main form and creates the serial port instance and then i pass the serial port object into the second form which is the terminal form. The following code is the contents of the namespace of the second form

                  bool Receive_Enable = false;

                  public Terminal (SerialPort Serial_Port)
                  {
                  InitializeComponent ();
                  _SerialPort = Serial_Port;
                  _SerialPort.Close ();
                  _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
                  }

                  private void Start_Click (object sender, EventArgs e)
                  {
                  if(Start.Text == "Start")
                  {
                  Start.Text = "Stop";
                  _SerialPort.Open ();
                  Receive_Enable = true;
                  }
                  else
                  {
                  Receive_Enable = false;
                  _SerialPort.Close ();
                  Start.Text = "Start";
                  }
                  }

                  private void Port_DataReceived (object sender, SerialDataReceivedEventArgs e)
                  {
                  if(Receive_Enable)
                  {
                  rtbTerminal.AppendText (Convert.ToString (_SerialPort.ReadLine ()));
                  rtbTerminal.ScrollToCaret ();
                  }
                  }

                  Tried this.... Also tried with

                  _SerialPort.ReadExisting ()

                  The application freezes after few seconds.... :wtf: What to do???? :confused: Am i doing this right???

                  OriginalGriffO 1 Reply Last reply
                  0
                  • A alfie max15

                    I have two forms, the first one is the main form and creates the serial port instance and then i pass the serial port object into the second form which is the terminal form. The following code is the contents of the namespace of the second form

                    bool Receive_Enable = false;

                    public Terminal (SerialPort Serial_Port)
                    {
                    InitializeComponent ();
                    _SerialPort = Serial_Port;
                    _SerialPort.Close ();
                    _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
                    }

                    private void Start_Click (object sender, EventArgs e)
                    {
                    if(Start.Text == "Start")
                    {
                    Start.Text = "Stop";
                    _SerialPort.Open ();
                    Receive_Enable = true;
                    }
                    else
                    {
                    Receive_Enable = false;
                    _SerialPort.Close ();
                    Start.Text = "Start";
                    }
                    }

                    private void Port_DataReceived (object sender, SerialDataReceivedEventArgs e)
                    {
                    if(Receive_Enable)
                    {
                    rtbTerminal.AppendText (Convert.ToString (_SerialPort.ReadLine ()));
                    rtbTerminal.ScrollToCaret ();
                    }
                    }

                    Tried this.... Also tried with

                    _SerialPort.ReadExisting ()

                    The application freezes after few seconds.... :wtf: What to do???? :confused: Am i doing this right???

                    OriginalGriffO Offline
                    OriginalGriffO Offline
                    OriginalGriff
                    wrote on last edited by
                    #11

                    First off, stop opening and closing it - just leave it open. That ensures that nothing else can get at the port, since serial ports need exclusive locks. ReadLine is also unhelpful - it will always block until a newline is received, so if whatever device is on the other end of the connection doesn't use the same newline as your PC, it will never return. So, try this:

                    bool Receive_Enable = false;

                    public Terminal (SerialPort Serial_Port)
                    {
                    InitializeComponent ();
                    _SerialPort = Serial_Port;
                    _SerialPort.Open (); // **** IF IT ISN'T ALREADY OPENED BY THE CALLING CODE.
                    _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
                    }

                    private void Start_Click (object sender, EventArgs e)
                    {
                    if(Start.Text == "Start")
                    {
                    Start.Text = "Stop";
                    Receive_Enable = true;
                    }
                    else
                    {
                    Receive_Enable = false;
                    Start.Text = "Start";
                    }
                    }

                    private void Port_DataReceived (object sender, SerialDataReceivedEventArgs e)
                    {
                    if(Receive_Enable)
                    {
                    int bytes = _SerialPort.BytesToRead;
                    byte[] data = new byte[bytes];
                    _SerialPort.Read(data, 0, bytes);
                    string s = System.Text.Encoding.ASCII.GetString(data);
                    Console.WriteLine(s);
                    rtbTerminal.AppendText(s);
                    rtbTerminal.ScrollToCaret();
                    }
                    }

                    You may want to play with the Encoding later, but that should be pretty safe. The Console output is just for debugging - it shows you what is received, in what chunks.

                    The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

                    "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                    "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                    A 1 Reply Last reply
                    0
                    • OriginalGriffO OriginalGriff

                      First off, stop opening and closing it - just leave it open. That ensures that nothing else can get at the port, since serial ports need exclusive locks. ReadLine is also unhelpful - it will always block until a newline is received, so if whatever device is on the other end of the connection doesn't use the same newline as your PC, it will never return. So, try this:

                      bool Receive_Enable = false;

                      public Terminal (SerialPort Serial_Port)
                      {
                      InitializeComponent ();
                      _SerialPort = Serial_Port;
                      _SerialPort.Open (); // **** IF IT ISN'T ALREADY OPENED BY THE CALLING CODE.
                      _SerialPort.DataReceived += new SerialDataReceivedEventHandler (Port_DataReceived);
                      }

                      private void Start_Click (object sender, EventArgs e)
                      {
                      if(Start.Text == "Start")
                      {
                      Start.Text = "Stop";
                      Receive_Enable = true;
                      }
                      else
                      {
                      Receive_Enable = false;
                      Start.Text = "Start";
                      }
                      }

                      private void Port_DataReceived (object sender, SerialDataReceivedEventArgs e)
                      {
                      if(Receive_Enable)
                      {
                      int bytes = _SerialPort.BytesToRead;
                      byte[] data = new byte[bytes];
                      _SerialPort.Read(data, 0, bytes);
                      string s = System.Text.Encoding.ASCII.GetString(data);
                      Console.WriteLine(s);
                      rtbTerminal.AppendText(s);
                      rtbTerminal.ScrollToCaret();
                      }
                      }

                      You may want to play with the Encoding later, but that should be pretty safe. The Console output is just for debugging - it shows you what is received, in what chunks.

                      The only instant messaging I do involves my middle finger. English doesn't borrow from other languages. English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.

                      A Offline
                      A Offline
                      alfie max15
                      wrote on last edited by
                      #12

                      Did just that as you said now, Removed all the

                      SerialPort.Close()

                      No change, output is good, but the application freezes after a while. When i try to make the terminal as earlier without event handler i am getting a perfect output with

                      ReadExisting()

                      But using the eventhandler, it just doesn't work as expected

                      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