private void Serial_Event_1(object sender, SerialDataReceivedEventArgs e)
{
bytes1 = 0;
if (received_Sequence == 0)
{
SerialPort sData = sender as SerialPort;
var th1 = new Thread(Serial_Event_Thread1);
try
{
bytes1 = sData.BytesToRead;
}
catch { }
byte[] read_data_ = new byte[bytes1];
linef_1 = new byte[bytes1];
try
{
// sData.Read(read_data_, 0, bytes1);
sData.Read(linef_1, 0, bytes2);
// linef_1 = read_data_;
}
catch
{
MessageBox.Show("1 handle error");
}
Invoke((MethodInvoker)delegate
{
th1.Start();
});
if (port_numbering > 1)
{
received_Sequence ++;
}
}
if (port_numbering == 1)
received_Sequence = 0;
}
private void Serial_Event_2(object sender, SerialDataReceivedEventArgs e)
{
//Same as receivedevent 1
}
private void Serial_Event_Thread1()
{
// The incoming data packets are analyzed and written to the richtextbox.
//Even when using two or more serial communication without `enter code here`analyzing packets, only one port can communicate smoothly.
//The `enter code here`other ports are not well received or do not work.
}
enter code here
The length of the data received is 18 bytes.
I've done it a lot with one Serialport communication.
Please give me a hint if you have implemented two or more Serial communications.
It uses a total of four " ReceivedEvent " and handles data with separate threads.
If you use two or more ports, the data is normally sent from one port to another, and the data is not broken or data is not received.
We try to connect a total of four ports using the " multi-serialport " approach.
You want to receive data sequentially from each number to a sample of 20 ms.
Each " serialdatareceivevent " occurs, and data is displayed once a second.
I'm not sure how to correct it, but please help me.
Thank you for reading it here.
I'll be looking forward to your help.
private void Serial_btn_1_Click(object sender, EventArgs e)
{
Test_Timer.Interval = 15;
Test_Timer.Tick += new System.EventHandler(TimerEventProcessor);
Test_Timer.Start();
}
private void TimerEventProcessor(object sender, EventArgs e)
{
try
{
bytes1 = serialPort1.BytesToRead;
bytes1 = serialPort2.BytesToRead;
bytes1 = serialPort3.BytesToRead;
bytes1 = serialPort4.BytesToRead;
linef_1 = new byte[bytes1];
linef_2 = new byte[bytes2];
linef_3 = new byte[bytes3];
linef_4 = new byte[bytes4];
}
catch { }
try
{
serialPort1.Read(linef_1, 0, bytes1);
serialPort2.Read(linef_2, 0, bytes2);
serialPort3.Read(linef_3, 0, bytes3);
serialPort4.Read(linef_4, 0, bytes4);
}
catch
{
// MessageBox.Show("Read_data no");
}
Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(ByteToHex(linef_1));
richTextBox2.AppendText(ByteToHex(linef_2));
richTextBox3.AppendText(ByteToHex(linef_3));
richTextBox4.AppendText(ByteToHex(linef_4));
});
}
Timer speed 15ms.
Changed to the above source.
Can I get a problem when I receive data using a timer?
Related
I'm receiving in my serial port the message "Hello World!CRLF" (no quotes) at every 1 second, and I'm using ReadExisting() to read the message, but I can't understand why I'm receiving lots of "\0" before every character.
PuTTy seems to handle the messages just fine, so my code must be the problem. Could someone please help me to figure this out?
Part of my code:
void button1_Click(object sender, EventArgs e)
{
try
{
_serialPort = new SerialPort(cbPort.Text);
_serialPort.BaudRate = Int32.Parse(cbBaudrate.SelectedItem.ToString());
_serialPort.Parity = Parity.None;
_serialPort.StopBits = StopBits.One;
_serialPort.DataBits = 8;
_serialPort.ReadTimeout = 500;
_serialPort.Open();
if (_serialPort.IsOpen)
{
try
{
ReadSerialData();
}
catch (TimeoutException) { }
}
}
catch (Exception er){}
}
private void ReadSerialData()
{
try
{
ReadSerialDataThread = new Thread(ReadSerial);
ReadSerialDataThread.Start();
}
catch (Exception e){}
}
private void ReadSerial()
{
try
{
while (_serialPort.BytesToRead >= 0)
{
readserialvalue = _serialPort.ReadExisting();
ShowSerialData(readserialvalue);
Thread.Sleep(1);
}
}
catch (Exception e){}
}
public delegate void ShowSerialDatadelegate(string r);
private void ShowSerialData(string s)
{
if (rtb_msg.InvokeRequired)
{
ShowSerialDatadelegate SSDD = ShowSerialData;
Invoke(SSDD, s);
}
else
{
rtb_msg.AppendText(readserialvalue);
}
}
As sugested by #Hans Passant changing the encoding to BigEndian solved the main issue.
Still getting lots of invalid unicode chars, but I think is best to open another thread. Thank you all for the support.
_serialPort.Encoding = System.Text.Encoding.BigEndianUnicode;
Are you sure that you want to read from the serial port even if there are 0 bytes to be read? If not, you might want to try changing:
while (_serialPort.BytesToRead >= 0)
to
while (_serialPort.BytesToRead > 0)
I suspect you may be reading from the serial port with 0 bytes to be read, which could return a null (\0) value
I'm using com0com to create a part of virtual ports comA/comB, typing the input to comA from hyperterminal and listening on comB in a wpf application. When I run the following code (by triggering Connect), the application successfully connects and is able to get the data from comA, but hangs when I do Disconnect.
public void Connect()
{
readPort = new SerialPort("COMB");
readPort.WriteTimeout = 500;
readPort.Handshake = Handshake.None;
readPort.Open();
readThread = new Thread(Read);
readRunning = true;
readThread.Start();
System.Diagnostics.Debug.Print("connected");
}
public void Disconnect()
{
if (!readRunning)
{
readPort.Close();
}
else
{
readRunning = false;
readThread.Join();
readPort.Close();
}
System.Diagnostics.Debug.Print("disconnected");
}
public void Read()
{
while (readRunning)
{
try
{
int readData = 0;
readData = readPort.ReadByte();
System.Diagnostics.Debug.Print("message: " + readData.ToString());
}
catch (TimeoutException)
{
}
}
}
I tried changing the Read function to a write by using
byte[] writeData = { 1, 2, 3 };
readPort.Write(writeData, 0, 3);
instead of port.readbyte, and it starts working perfectly when disconnecting. Does anyone know if there is anything different about readbyte that could have caused the freeze? Or is it possibly related to com0com?
Just checking back, in case anyone runs into the same issue, I found an alternative way overriding SerialPort.DataReceived like this:
public override void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] buf = new byte[sp.BytesToRead];
sp.Read(buf, 0, buf.Length);
receivedDataDel(buf);
}
I am developing a GUI interface which receives information from an ATmega8A.
The below code from the GUI has to do the following:
Check Header: Here, I am reading data into a Byte Array (byte[] test) which is getting checked against OxFF
If header == 0xFF, read the second byte array (byte[] data)
Please see the code below.
Now, I have the following problem. If I send simply a number, for example 1, that number is getting displayed in the textBox1 without any problems. However, if I am trying to send a number like 433, I am always receiving 4, 33 is getting lost. I assume it is due to my included if-statement, but I cannot explain why that data is being lost.
namespace RS232
{
public partial class fclsRS232Tester : Form
{
string InputData = String.Empty;
string initText = "waiting...";
delegate void SetTextCallback(string text);
public fclsRS232Tester()
{
InitializeComponent();
// Nice methods to browse all available ports:
string[] ports = SerialPort.GetPortNames();
// Add all port names to the combo box:
foreach (string port in ports)
{
cmbComSelect.Items.Add(port);
}
cmbBaud.Items.Add(2400);
cmbBaud.Items.Add(9600);
cmbComSelect.SelectedIndex = 0;
cmbBaud.SelectedIndex = 1;
button4.Enabled = false;
textBox1.Text = initText;
textBox2.Text = initText;
}
private void cmbComSelect_SelectionChangeCommitted(object sender, EventArgs e)
{
if (port.IsOpen) port.Close();
port.PortName = cmbComSelect.SelectedItem.ToString();
stsStatus.Text = port.PortName + ": 9600,8N1";
// try to open the selected port:
try
{
port.Open();
button4.Enabled = true;
textBox1.Clear();
textBox2.Clear();
}
// give a message, if the port is not available:
catch
{
MessageBox.Show("Serial port " + port.PortName + " cannot be opened!", "RS232 tester", MessageBoxButtons.OK, MessageBoxIcon.Warning);
cmbComSelect.SelectedText = "";
stsStatus.Text = "Select serial port!";
}
}
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
int bytenumber;
int bufferSize = port.BytesToRead;
byte[] test = new byte[1];
byte[] data = new byte[bufferSize];
byte[] data2 = new byte[bufferSize];
port.Read(test, 0, 1);
if (test[0] == 0xFF) //Receive X-andY- coordinates from MCU and plot the coordinates
{
bytenumber = port.Read(data, 0, bufferSize);
string info = System.Text.Encoding.ASCII.GetString(data);
this.Invoke((MethodInvoker)delegate
{
this.txtIn.Text += info;
}
}
}
}
The DataReceived handler is called whenever data is available in the received buffer. So read all data in the buffer and then process for validity of header and so forth before the next burst of data is received. Once new data is received the old data is over-written leading to data loss.
In your case you are reading only 1 byte with your call to port.Read(). I would change that to port.Read(test, 0, bufferSize);
Further, I would just store the data in a buffer and have the data processing run on a separate thread. The more time you spend time in the handler, greater are the chances of losing data.
the problem got solved by storing all data into a buffer:
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
int bytenumber;
byte[] data = new byte[10];
bytenumber = port.Read(data, 0, 10);
if (data[0] == 0xFF)
{
}
}
etc.
I have a problem with my TCPIP connection Form programm.
I have a code, where I'm trying to send and receive some data from server.
The main problem of my app is how to reconcile some threads:
myListenThread - to listening data from server
myReadStreamThread - to read data from server
System.Threading.Thread - main thread eg. to write data to server
captureThread - to do another things like capturing images from camera
Part of my code:
private void buttonConnect_Click(object sender, EventArgs e)
{
try
{
Connect();
Connected = true;
this.myListenThread = new Thread(new ThreadStart(Listen));
this.myListenThread.Start();
}
catch
{
MessageBox.Show("Invalid host! Try again.");
}
}
private void Listen()
{
this.myReadStreamThread = new Thread(new ThreadStart(ReadStream));
this.myReadStreamThread.Start();
while (Connected)
{
if (!myReadClient.Connected)
{
Connect();
}
}
}
private void Connect()
{
IPAddress IP = IPAddress.Parse(textboxIP.Text);
int PORT = Convert.ToInt32(textboxPORT.Text);
this.myReadClient = new TcpClient();
this.myReadClient.Connect(IP, PORT);//SOMETIMES HERE'S AN ERROR
this.myStream = this.myReadClient.GetStream();
Properties.Settings.Default.IP = Convert.ToString(IP);
Properties.Settings.Default.PORT = Convert.ToString(PORT);
Properties.Settings.Default.Save();
}
private void ReadStream()
{
while (true)
{
try
{
this.myReadBuffer = new byte[this.myReadClient.ReceiveBufferSize];
this.myBufferSize = myStream.Read(myReadBuffer, 0, this.myReadClient.ReceiveBufferSize);
if (myBufferSize != 0)
{
this.myString = Encoding.ASCII.GetString(myReadBuffer);
//myDelegate myDel;
//myDel = new myDelegate(Print);
//richtextboxRead.Invoke(myDel);
}
}
catch
{
break;
}
}
}
All is working correct when I'm connecting to server, but when I want to send some string the problem appears because of threads.
I decided to send string, by clicking Button3 and waiting until I receive string "1" from server using while loop:
private void button3_Click(object sender, EventArgs e)
{
this.captureThread = new Thread(new ThreadStart(() => this.newGame()));
this.captureThread.Start();
}
private bool newGame()
{
string command = "12345abc";
if (Connected)
{
WriteStream(command);
}
while (myBufferSize == 0 && myString !="1") { }
Thread.Sleep(2000);
...//doing other things
}
private void WriteStream(string command)
{
Connect();
this.myWriteBuffer = Encoding.ASCII.GetBytes(command);
this.myStream.Write(this.myWriteBuffer, 0, command.Length);
}
And the problem with connection and data send/receive problem appears, when it should write my string "command" - it doesn't react. MyBufferSize is always 0 and myString is always null. Sometimes an Error about connection appears when I click Button3 (assigned in code). I think it is because in captureThread I can't see any data from another threads. How to solve it?
I'm working on a project that involves my client software sending data to a Arduino microcontroller, AtMega32U4, through serial communication. I've looked through many answered questions so far yet none of them were specific to my problem. However, I believe my problem may be limited to threading issues or Arduino autoreset problems.
Code 1:
public MainForm()
{
InitializeComponent();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.DtrEnable = true;
//serialPort1.RtsEnable = true;
}
private void button3_Click(object sender, EventArgs e)
{
// Disables button while processing
button3.Enabled = false;
GetDir dir = new App.GetDir();
dir.getCoords(Origin.Text, Destination.Text, Application.StartupPath + #"\temp2.html", "temp2.xml");
dataBrowser.Navigate(Application.StartupPath + #"\temp2.html");
dataBrowser.Update();
waypoints = dir.coordsLat.Length;
counter = dir.coordsLat.Length;
coords = new double[dir.coordsLat.Length, 2];
for (int i = 0; i < counter; i++)
{
coords[i, 0] = (Convert.ToDouble(dir.coordsLat[i]));
coords[i, 1] = (Convert.ToDouble(dir.coordsLon[i]));
}
//serialPort1.Close();
//System.Threading.Thread.Sleep(1000);
if (serialPort1.IsOpen && !doubleClick)
{
serialPort1.Close();
System.Threading.Thread.Sleep(2000);
try
{
serialPort1.Open();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Cannot open serial port");
}
System.Threading.Thread.Sleep(2000);
}
else
{
if (!serialPort1.IsOpen)
{
try
{
serialPort1.Open();
doubleClick = true;
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Cannot open serial port");
}
System.Threading.Thread.Sleep(2000);
serialPort1.Write("^");
System.Threading.Thread.Sleep(1000);
Console.WriteLine('^');
//button3.Enabled = true;
}
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//System.Threading.Thread.Sleep(1000);
readData = serialPort1.ReadLine();
Console.WriteLine(readData);
// If microcontroller sends "&", it is ready to receive next piece of data
if (readData == "&")
{
sendRequest = true;
}
else
{
sendRequest = false;
}
// Write next piece of data to microcontroller if it is ready
if (sendRequest)
{
this.BeginInvoke( new EventHandler (write_serialPort1));
}
}
In during the debugging of code 1, the event handler (serialPort1_DataReceived) never gets called. In this process, somehow button3_click gets called twice as the console outputs '^' twice. Afterwards, the client stalls since there is nothing beind received. Keep in mind that the Arduino will respond with an ampersand ('&') once it has received the circumflex ('^'). The Arduino code has been tested on the Arduino IDE and appears to be working fine. I believe the problem with button3_click being called twice comes from the button3_down and button3_up.
However, I was able to bypass this issue with Code 2. But also hit another brick wall.
Code 2 :
private void button3_Click(object sender, EventArgs e)
{
// Disables button while processing
button3.Enabled = false;
GetDir dir = new App.GetDir();
dir.getCoords(Origin.Text, Destination.Text, Application.StartupPath + #"\temp2.html", "temp2.xml");
dataBrowser.Navigate(Application.StartupPath + #"\temp2.html");
dataBrowser.Update();
waypoints = dir.coordsLat.Length;
counter = dir.coordsLat.Length;
coords = new double[dir.coordsLat.Length, 2];
for (int i = 0; i < counter; i++)
{
coords[i, 0] = (Convert.ToDouble(dir.coordsLat[i]));
coords[i, 1] = (Convert.ToDouble(dir.coordsLon[i]));
}
serialPort1.Close();
try
{
serialPort1.Open();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Cannot open serial port");
}
if (serialPort1.IsOpen)
{
System.Threading.Thread.Sleep(2000);
using (serialPort1)
{
serialPort1.Write("^");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("^");
serialPort1.Close();
System.Threading.Thread.Sleep(5000);
}
}
else
{
button3.Enabled = true;
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//SerialPort sp = (SerialPort)sender;
System.Threading.Thread.Sleep(10000);
/*if (!serialPort1.IsOpen)
{
serialPort1.Close();
System.Threading.Thread.Sleep(10000);
serialPort1.Open();
System.Threading.Thread.Sleep(10000);
}*/
//serialPort1.Open();
//using (sp)
using (serialPort1)
{
serialPort1.Open();
System.Threading.Thread.Sleep(5000);
readData = serialPort1.ReadExisting();
Console.WriteLine(readData);
// If microcontroller sends "&", it is ready to receive next piece of data
if (readData == "&")
{
sendRequest = true;
}
else
{
sendRequest = false;
}
// Write next piece of data to microcontroller if it is ready
if (sendRequest)
{
this.BeginInvoke(new EventHandler(write_serialPort1));
}
}
}
In Code 2, the event handler does get called and the button3_click only runs once. But when it tries to open the port, it returns the error 'Access to Port X denied'. Furthermore, I wish I didn't have to close and open the ports like this, but when the event handler is called (in an earlier code) it returned the error that the COM Port was not opened. In order to satisfy that error, I had to close it and reopen it during button3_click and event handling.
I've added a lot of delay in the code after I read about many problems dealing with the threading issues with serial communication. I had even tried a minute delay in hopes of a thread ending to solve the problem. However, no luck there.
I also specified my serial port in the MainForm designer instead of declaring it in the code (At first I did both and realized it was redundant). I'm not sure if this contributes to the problem, but I've seen examples of both being used.
Lastly, it could definitely deal with the Arduino auto resetting everytime a serial connection has been made (eg. opening and closing a port). In summary, it seems be sending data through serial, but unable to read the incoming data from serial.
Thank you for reading this and if someone could point me in the right direction, it would be very much appreciated.
Edit #1: Even after using BeginInvoke in Code 1, it still deadlocks because the event handler was never called.
Edit #2: Edits to Code 1 as per newbie's suggestions.
Edit #3: Added mainform initialization and updated Code 1 to current state.
Edit #4: Deleted (Commented out) the sleep at the event handler. I was sleeping during the event handler, thus I couldn't receive anything that the microcontroller would send to me. Code works fine as expected now.
Make sure you are using COM1, if you do not COM1 serial port,
change through Computer -> Device Manager -> Ports (COM & LPT) ->
Select the COM to be changed -> Port Settings -> Advanced -> ComPort Number -> select COM1.
Make sure that you have installed jumper / connect with a screwdriver
between pin2 and pin3 of COM1.
Add button1 and textBox1 to Form and run this program
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Text;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
const int MAX_BUFFER = 100;
int i = 0;
byte[] DataReceived = new byte[MAX_BUFFER];
SerialPort serialPort = new SerialPort();
public Form1() {
InitializeComponent();
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
}
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
// wait data ready
Thread.Sleep(500);
// while data ready in buffer
while (serialPort.IsOpen && serialPort.BytesToRead > 0) {
// read data serial
DataReceived[i] = Convert.ToByte(serialPort.ReadByte());
// counter data
i++;
// reset conter if more then maxvalue
if (i >= MAX_BUFFER) {
i = 0;
}
}
if (i == 1 && DataReceived[0] == ASCIIEncoding.ASCII.GetBytes("^")[0]) {
this.textBox1.Invoke(new Action(() => {
this.textBox1.Text = ASCIIEncoding.ASCII.GetString(DataReceived, 0, 1);
}));
}
}
public void InitSerialPort() {
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.ReceivedBytesThreshold = 1;
}
private void Form1_Load(object sender, EventArgs e) {
// initialize serial port
InitSerialPort();
// assure port is closed before open it
if (serialPort != null && serialPort.IsOpen) {
serialPort.Close();
}
serialPort.Open();
}
private void button1_Click(object sender, EventArgs e) {
if (serialPort.IsOpen) {
serialPort.Write("^");
// wait data sent
Thread.Sleep(500);
}
}
}
}
In accordance to my 4th edit, deleted (Commented out) the sleep at the event handler. I was sleeping during the event handler, thus I couldn't receive anything that the microcontroller would send to me. Code works fine as expected now. Nothing was wrong with the serial ports on either components.