Serial communication in C# too slow - c#

I've got an issue with serial communication. My computer communicates with microcontroller via Bluetooth (HC-05) which should send some bytes of data. Everything works okay except speed of receiving data. It is late, sometimes one second, sometimes even 5-10 seconds. Baud rate was checked. Here is full code.
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.PortName = comboBox1.Text;
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Parity = Parity.None;
serialPort1.Open();
}
private void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
serialPort1.Close();
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//dataIN = serialPort1.ReadExisting();
this.Invoke(new EventHandler(ShowData));
int count = serialPort1.Read(buffer, 0, 1);
dataIN = Convert.ToInt32(buffer[0]);
}
private void ShowData(object sender, EventArgs e)
{
textBox1.Text += dataIN.ToString();
br++;
if(br == 300)
{
textBox1.Text = "";
br = 0;
}
}
}
}

Related

Scoreboard data transfer Serial Port c#

There's some outdated software that's used to control the scoreboard at my local athletics track and I've been tasked with creating a new advanced one. However, I cannot seem to get the scoreboard to do what I ask it to do.
I've installed the original software to the my laptop and it works fine, however, when I run my test software that sends data to the board through the serial port, it isn't doing what I want.
I have the "Scoreboard Data Protocol" supplied by the manufacturer and I've been following this. I will supply the code to my test program that I've been using to see if I can get it to work and I will also supply the Data Protocol.
In the text box, I type 010D0201SPAIN and 003C630 and send it to the board and this doesn't work.
public partial class Form1 : Form
{
private SerialPort m_port;
public Form1()
{
InitializeComponent();
m_list.Items.AddRange(SerialPort.GetPortNames()); // Adds ports to combobox
m_port = new SerialPort();
m_port.BaudRate = 9600;
m_port.DataBits = 8;
m_port.Parity = Parity.Even;
m_port.StopBits = StopBits.One;
//m_port.Handshake = Handshake.None;
m_port.Encoding = new ASCIIEncoding();
m_port.RtsEnable = true;
m_port.DtrEnable = true;
m_port.ReceivedBytesThreshold = 1;
m_port.DataReceived += DataReceivedEvent;
}
private void button1_Click(object sender, EventArgs e)
{
m_port.Close();
m_port.PortName = (string)m_list.SelectedItem;
try
{
m_port.Open();
m_sendbutton.Enabled = true;
button2.Enabled = true;
}catch(UnauthorizedAccessException ex)
{
MessageBox.Show(ex.Message);
}
}
private void m_sendbutton_Click(object sender, EventArgs e)
{
m_port.Write(m_textbox.Text);
}
private void DataReceivedEvent(object sender, SerialDataReceivedEventArgs args)
{
Invoke(new EventHandler(DoUpdate));
}
private void DoUpdate(object s, EventArgs e)
{
label1.Text += m_port.ReadLine();
}
private void button2_Click(object sender, EventArgs e)
{
byte[] r_bytes = Encoding.ASCII.GetBytes(m_textbox.Text);
m_port.Write(r_bytes, 0, r_bytes.Length);
}
}
}
Scoreboard Data Protocol
Code: https://hastebin.com/epirobuduv.cs
Here's how to add STX and ETX around your message, in a byte array.
private void button2_Click(object sender, EventArgs e)
{
var msg = Encoding.ASCII.GetBytes(m_textbox.Text).ToList();
msg.Insert(0, 0x02); // STX at the start
msg.Add(0x03); // ETX at the end
m_port.Write(msg.ToArray(), 0, msg.Count);
}

Serial-port Datareceive

I'm having a problem with serial port data. I have designed a form where I have used a datareceived handler event and the whole of data needs to be printed in the RichTextBox placed in the form. The problem is I'm only receiving the last bits of data on the RichTextBox, while the MessageBox that is provided with the code runs the whole of data in part. Please suggest where I'm going wrong.Thanks in advance.
public partial class Form1 : Form
{
char po='\0';
string indata,pi;
string[] buffer;
public Form1()
{
InitializeComponent();
System.ComponentModel.IContainer components = new System.ComponentModel.Container();
serialPort1 = new System.IO.Ports.SerialPort(components);
serialPort1.PortName = "COM1";
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
po = Convert.ToChar(serialPort1.BytesToRead);
indata = sp.ReadExisting();
//return (indata);
//for (int p = 0; p <= 256; p++) ;
//MessageBox.Show(buffer[0]);
//MessageBox.Show(indata);
//richTextBox1.Text += indata;
//richTextBox1.Text = indata;
}
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.WordWrap = true;
richTextBox1.Text = indata;
}
}
It looks like you should be appending the data each time data is received over the serial port, so perhaps you should change
indata = sp.ReadExisting();
to:
indata += sp.ReadExisting();
To hold all of the contents of the Serial Data, including historical data that was previously sent.
Hope this helps!
Trying This Code....
private string StrValue = "";
private void Port_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
double DouRWeight = 0;
try
{
DouRWeight = Val.ToDouble(Port.ReadLine());
if (DouRWeight != 0)
{
this.Invoke((System.Windows.Forms.MethodInvoker)delegate()
{
StrValue = Val.Format(DouRWeight.ToString(), "####0.000");
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.WordWrap = true;
richTextBox1.Text = StrValue ;
}
It's Completely Worked...

Issue in Serial Communication

I have written a code in c# for receiving data through serial communication and display it in a text box. I am able to do that. But I am receiving data in following format, e.g.
1234 2345 3456 5667
or
every byte in next line..
But I want that every incoming byte should overwrite the previous byte and in the text box we should see just 1 byte and then another byte overwriting the previous one.
Please suggest how to do that?
private void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = SerialPort.ReadExisting();
this.Invoke(new EventHandler(DisplayText));
}
private void DisplayText(object sender, EventArgs e)
{
txtIncomingData.AppendText(RxString);
}
You are appending every received data to your textbox! that is an expected behavior. You should rather change your textBox.Text value every time you want to display a new received data.
Change your DisplayText method from :
private void DisplayText(object sender, EventArgs e)
{
txtIncomingData.AppendText(RxString);
}
to
private void DisplayText(object sender, EventArgs e)
{
txtIncomingData.Text = RxString;
}
P.S: I am assuming that txtIncomingData is a textBox control, correct me if I'm wrong
The solution below works, but it gives blank bytes in between data.
SerialPort serialPort;
private delegate void SetTextDeleg(string text);
private void Form1_Load(object sender, EventArgs e)
{
serialPort= new SerialPort("COM6", 4800, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.None;
serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
serialPort.ReadTimeout = 500;
serialPort.WriteTimeout = 500;
serialPort.Open();
}
private void btnStart_Click(object sender, EventArgs e)
{
try
{
if(!serialPort.IsOpen)
serialPort.Open();
}
catch (Exception ex)
{
MessageBox.Show("Could not open Serial Port");
}
}
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
string data = serialPort.ReadLine();
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
}
private void si_DataReceived(string data)
{
txtIncomingData.Text = data.Trim();
}

How to display the data read in DataReceived event handler of serialport

I have the following code which needs the data to be read from port and then display in a textbox. I am using DataReceived event handler for this purpose but donot know how to display this data in textbox. From various sources i learnt that Invoke method should be used for this but donot know how to use it. Suggestions please...
private void Form1_Load(object sender, EventArgs e)
{
//SerialPort mySerialPort = new SerialPort("COM3");
mySerialPort.PortName = "COM3";
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived);
mySerialPort.Open();
}
private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string s= sp.ReadExisting();
// next i want to display the data in s in a textbox. textbox1.text=s gives a cross thread exception
}
private void button1_Click(object sender, EventArgs e)
{
mySerialPort.WriteLine("AT+CMGL=\"ALL\"");
}
The MSDN contains a good article with examples about using control methods and properties from other threads.
In short, what you need is a delegate method that sets the Text property of your text box with a given string. You then call that delegate from within your mySerialPort_DataReceived handler via the TextBox.Invoke() method. Something like this:
public delegate void AddDataDelegate(String myString);
public AddDataDelegate myDelegate;
private void Form1_Load(object sender, EventArgs e)
{
//...
this.myDelegate = new AddDataDelegate(AddDataMethod);
}
public void AddDataMethod(String myString)
{
textbox1.AppendText(myString);
}
private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string s= sp.ReadExisting();
textbox1.Invoke(this.myDelegate, new Object[] {s});
}
Try this (works for me):
private delegate void UpdateUiTextDelegate(string text);
private void Receive(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (mySerialPort.IsOpen)
{
RxString = mySerialPort.ReadLine();
Dispatcher.Invoke(DispatcherPriority.Send, new UpdateUiTextDelegate(DisplayText), RxString);
}
}
private void DisplayText(string RxString)
{
myTextBox.Text = RxString;
}
I'm creating a GUI "Form" for USB COM Ports. This is how I send data to the window without getting a "Cross-Thread" error.
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string inData = serialPort1.ReadLine(); // ReadLine includes the + "\n"
displayToWindow(inData);
}
private void displayToWindow(string inData)
{
BeginInvoke(new EventHandler(delegate
{
richTextBox1.AppendText(inData);
richTextBox1.ScrollToCaret();
}));
}

SerialPort reading problems

I have to create an aplication which reads the registers from a PLC every 200ms. To do that I am using something like:
SerialPort port = new SerialPort();
private void Form1_Load(object sender, EventArgs e)
{
port.ReceivedBytesThreshold = 21;
timer1.Interval = 200;
timer1.Start();
}
private void ProcessTimer_Tick(object sender, EventArgs e)
{
if (dataReceived)
{
dataReceived = false;
port.Read(buffer_rx, 0, 21);
TranslateValues();
}
if (port.IsOpen && connectected)
{
// sends command for a new reading
port.Write(buffer_tx, 0, length);
}
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Invoke(new EventHandler(DoUpdate));
}
void DoUpdate(object sender, EventArgs e)
{
dataReceived = true;
}
The problem is that my application freezes from time to time. When I debug this, the debugger points me to port.Read(), but doesn't throw any exceptions.
I have tried using a try-catch block but nothing was caught, and also made time1.Interval = 2000, but it didn't work either.
My question is, why is my application freezing at port.Read(), but not catching any exceptions? How can I fix this?

Categories