question

Karlsson-1564 avatar image
0 Votes"
Karlsson-1564 asked Karlsson-1564 published

C# Problem with receiving all data using serial port

I have a program in C# using windows forms to send data bytes using COM ports. First of all I decided to test the program on 1 computer, on two interconnected USB modules supporting serial communication, so that one transmits, the other receives and vice versa. I run the .exe file twice for this and just set one COM on one port, and the other on the other.
YRZei.png


Here is the first version of code - it allows to send hex numbers from 00 to FF.


 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
 using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Windows.Forms;
    
 using System.IO.Ports;
    
 namespace USB_tester
 {
  /// <summary>
  /// Description of MainForm.
  /// </summary>
  public partial class USB_tester : Form
  {
    
         System.IO.Ports.SerialPort port;
         delegate void Delegat1();
         Delegat1 moj_del1;
  public USB_tester()
  {
             InitializeComponent();
    
             port = new SerialPort();
    
             port.ReadTimeout = 500;
             port.WriteTimeout = 500;
    
             Settings.Enter += new EventHandler(Ustawienia_Enter);
             port.DataReceived += new SerialDataReceivedEventHandler(DataRecievedHandler);
             moj_del1 = new Delegat1(WpiszOdebrane);
  }
  private void DataRecievedHandler(object sender, SerialDataReceivedEventArgs e)
         {
             rtbTerminal.Invoke(moj_del1);
         }
    
         private void WpiszOdebrane()
         {
             ColoredTerminal(rtbTerminal, port.ReadByte().ToString("X") + " ", System.Drawing.Color.Blue);
         }
    
  private void ColoredTerminal(System.Windows.Forms.RichTextBox RichTextBox, string Text, System.Drawing.Color Color)
         {
             var StartIndex = RichTextBox.TextLength;
             RichTextBox.AppendText(Text);
             var EndIndex = RichTextBox.TextLength;
             RichTextBox.Select(StartIndex, EndIndex - StartIndex);
             RichTextBox.SelectionColor = Color;
         }
    
         void Ustawienia_Enter(object sender, EventArgs e)
         {
                
             this.cbName.Items.Clear();
             this.cbParity.Items.Clear();
             this.cbStop.Items.Clear();
             foreach (String s in SerialPort.GetPortNames()) this.cbName.Items.Add(s);
             foreach (String s in Enum.GetNames(typeof(Parity))) this.cbParity.Items.Add(s);
             foreach (String s in Enum.GetNames(typeof(StopBits))) this.cbStop.Items.Add(s);
    
    
             cbName.Text = port.PortName.ToString();
             cbBaud.Text = port.BaudRate.ToString();
             cbData.Text = port.DataBits.ToString();
             cbParity.Text = port.Parity.ToString();
             cbStop.Text = port.StopBits.ToString();
         }
         void ButSendClick(object sender, EventArgs e) 
         { 
             if (port.IsOpen) 
             { 
                 ColoredTerminal(rtbTerminal, ((Int32)numericSend.Value).ToString("X") + " ", System.Drawing.Color.Black); 
                 Byte[] tosend = { (Byte) numericSend.Value}; 
                 port.Write(tosend, 0, 1); 
             } 
             else System.Windows.Forms.MessageBox.Show("Make connection first"); 
         }
            
  void TabPage1Click(object sender, EventArgs e)
  {
    
  }
  void Label1Click(object sender, EventArgs e)
  {
    
  }
  void Label3Click(object sender, EventArgs e)
  {
    
  }
  void Label4Click(object sender, EventArgs e)
  {
    
  }
  void ButDefault(object sender, EventArgs e)
  {
    
  }
  void CbNameSelectedIndexChanged(object sender, EventArgs e)
  {
    
  }
  void CbBaudSelectedIndexChanged(object sender, EventArgs e)
  {
    
  }
  void RtbTerminalTextChanged(object sender, EventArgs e)
  {
    
  }
  void ButRefreshClick(object sender, EventArgs e)
  {
    
  }
  void ButDefaultClick(object sender, EventArgs e)
  {
      this.cbName.Text = "COM3";
             this.cbName.Text = "COM4";
             this.cbBaud.Text = "9600";
             this.cbData.Text = "8";
             this.cbParity.Text = "None";
             this.cbStop.Text = "One";
  }
  void ButCancelClick(object sender, EventArgs e)
  {
          cbName.Text = port.PortName.ToString(); 
             cbBaud.Text = port.BaudRate.ToString(); 
             cbData.Text = port.DataBits.ToString(); 
             cbParity.Text = port.Parity.ToString(); 
             cbStop.Text = port.StopBits.ToString();
  }
  void PbStatusClick(object sender, EventArgs e)
  {
    
             if (port.IsOpen) 
             { 
                 pbStatus.BackColor = System.Drawing.Color.Red; 
                 port.Close(); 
                 labStatus.Text = "No connection"; 
                 ColoredTerminal(rtbTerminal, "\nConnection end - " + port.PortName + "\n", System.Drawing.Color.Orange); 
             } 
    
             { 
                    
                 try 
                 { 
                     port.PortName = this.cbName.Text; 
                     port.BaudRate = Int32.Parse(this.cbBaud.Text); 
                     port.DataBits = Int32.Parse(this.cbData.Text); 
                     port.Parity = (Parity)Enum.Parse(typeof(Parity), this.cbParity.Text); 
                     port.StopBits = (StopBits)Enum.Parse(typeof(StopBits), this.cbStop.Text); 
    
                     port.Open(); 
    
                     pbStatus.BackColor = System.Drawing.Color.Green; 
                     labStatus.Text = "Active connection (port:" + port.PortName.ToString() + ", speed: " + port.BaudRate.ToString() + ", data bits: " + 
                     port.DataBits.ToString() + "\n stop bits: " + port.StopBits.ToString() + ", parity: " + port.Parity.ToString() + ")"; 
                     ColoredTerminal(rtbTerminal, "Connection started - " + port.PortName + "\n", System.Drawing.Color.Orange); 
                 } 
    
                 catch(Exception exc) 
                 { 
                     MessageBox.Show("Connection error:\n" + exc.Message); 
                 } 
             } 
  }
  void LabStatusClick(object sender, EventArgs e)
  {
    
  }
    
    
    
  }
 }

...and it works quite ok - left terminal send hex number - and the right one can receive this.

0FqIK.png

So I decided to modify a code to be able to send random data in series, byte by byte. For example, I wanted to send 100 hex characters one by one - so I modified a code. I replaced:

 void ButSendClick(object sender, EventArgs e) 
 { 
     if (port.IsOpen) 
     { 
         ColoredTerminal(rtbTerminal, ((Int32)numericSend.Value).ToString("X") + " ", System.Drawing.Color.Black); 
         Byte[] tosend = { (Byte) numericSend.Value}; 
         port.Write(tosend, 0, 1); 
     } 
     else System.Windows.Forms.MessageBox.Show("Make connection first"); 
 }

with:

 void ButSendClick(object sender, EventArgs e)
  {
              if (port.IsOpen) 
             { 
              Random rnd = new Random();
              for (int i = 0; i <= 100; i++)
              {
    
              int num = rnd.Next(0,255);
      string hexString = num.ToString("X2");
                 ColoredTerminal(rtbTerminal, hexString + " ", System.Drawing.Color.Black); 
                 Byte[] tosend = BitConverter.GetBytes(num); 
                 port.Write(tosend, 0, 1); 
              }
             } 
             else System.Windows.Forms.MessageBox.Show("Make connection first"); 
  }

... and now something's wrong - only a few characters will be sent after pressing the Send button.

njcak.png

The next "part" of characters will be sent after pressing the Send button again, but the number of characters sent on the left grows much faster:

zxSIj.png

I would like the number of characters on the left after pressing the Send button once to be equal to the number of characters received. Meanwhile, these signs are suppressed somewhere (in a buffer?) along the way and they are sent only after the next button is pressed. What could this be the reason of? I will be grateful for every tip.



dotnet-csharpwindows-formswindows-7ems-advanced-threat-analytics
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

Viorel-1 avatar image
1 Vote"
Viorel-1 answered

Maybe inside the WpiszOdebrane you must use a loop, which checks the value of port.BytesToRead and reads all of available bytes.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It is a good way - it seems to me to mask .DataReceived's imperfections a bit, but at least it works :) Thank you!

0 Votes 0 ·