C# : serialPort reading new numbers each time - c#

The problem is complicated, and my code is large, but let me try to explain it.
See the code below:
private void button13_Click(object sender, EventArgs e)
{
serialPort1.Write("0800"); // Write to serial port for reading
Thread.Sleep(1);
serialPort1.Write("0800"); // Write to serial port for reading
in_data = serialPort1.ReadLine();
textBox7.Text = in_data;
Console.WriteLine(in_data);
in_data = "";
serialPort1.DiscardInBuffer();
serialPort1.DiscardOutBuffer();
}
Let me explain it:
I implemented a button in C# form. When i press the button, it sends 0800 towards an arduino through serialPort1. It sends it two times. After each command sent, Arduino writes to serial port through Serial.println(receivedData, HEX). This data from Arduino is read by C#(the function above through in_data = serialPort1.ReadLine() line and is displayed in textBox7. In last of the function, I am clearing both buffers.
The problem however is, whenever I am pressing this button, some new data is being display in textbox.
And I don't understand the reason, because the circuit connected to arduino should always respond with same code. I have tested the circuit with other fixtures, and otherwise that circuit is working fine.
Writing into serialport is working just fine. For example this function:
private void button6_Click(object sender, EventArgs e)
{
serialPort1.Write("EXTADC"); // Write to serial port
Console.WriteLine("EXTADC");
}
Please note: sending two commands each time is necessary in order to get the desired output from the circuit. Also, I am pretty new to Arduino and C# (you might be having an idea from my post).

Related

Garbage Value Reading Serial Port Data

I am working on making GUI for a Smart Water flow meter whose communication protocol is RS485,
as per instructions from Communication Manual i am sending an inquiry packet and i am receiving proper response in serial port terminal. But when i am trying to do it on my C# app.
Things are happening oppositely.
string data = "[H201815000081]";
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Write(data);
incoming_data = serialPort1.ReadExisting();
text_reciever.Text = incoming_data;
}
// text_reciver is the text box of my gui where i want to display the
// values from flow meter.Data Type of incoming_data is string
Here is the code, i am sending an inquiry code to the device and in return i am getting garbage values on my text box. Some times it is stream of Question mark symbol (?), some time it shows nothing.
But when i revert myself to serial port terminal (Real Term).
It is showing proper values as mentioned in communication manual.
Please assist in this regards.
After looking around i just found the answer to my question.
The point is previously i was communicating with serial port teminal, where everything was working fine, but when it comes to interacting with peripherals one need to make sure that Serialport.DTRProperty is enabled.
When opening the serial port one must enable the DTR property by:
serialPort1.DtrEnable = true;
Otherwise the windows form will read the garbage value.
the incoming data would be serial number of device (ASCII Format) and Water flow values

Read bytes from serial port

I have written code to read data as a byte array from a serial port and show it in a textbox. The code compiles fine, but doesn't work properly:
private void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen == false)
serialPort1.Open();
serialPort1.WriteLine(textBox1.Text);
int bytes = serialPort1.BytesToRead;
byte[] byte_buffer = new byte[bytes];
serialPort1.Read(byte_buffer, 0, bytes);
//textBox2.Text = " ";
for (int t = 0; t < bytes; t++)
{
textBox2.Text += (byte_buffer[t]).ToString();
}
}
serialPort1.WriteLine(textBox1.Text);
int bytes = serialPort1.BytesToRead;
The bytes value will always be zero. Unless you debug this code and single-step it to slow it down. It takes time for the bytes you've written with WriteLine() to be transmitted. And it takes time for the device to process them. And it takes time for the response to be received. This adds up to many milliseconds.
You'll need to fix this by looping, repeated calling the Read() method until you get the full response. If you set the SerialPort.NewLine property correctly then you'll have some odds that simply calling ReadLine() is enough to solve your problem.
You are going about this the wrong way.
Clicking a button will open serialPort1; sure. It will then try to read the buffer. But you only opened the port in the same method!
Take a look at this tutorial: http://www.dreamincode.net/forums/topic/35775-serial-port-communication-in-c%23/
It takes you through the entirety of serial communications in C#. You certainly don't want to be opening and reading the port only on a button press event handler.
Use button2 event to send the data to the port. Put the needed code (for sending the data) into a SynchronizationContext (use SynchronizationContext.Post method).
Next, register on the DataReceived event of the SerialPort class and do the reading there (again enclosed into the same SynchronicationContext object, otherwise you'll get a timeout on serial port reading/writing)
Cheers,

Reading from two serial ports at the same

I have a C# program that reads from two serial ports at the same time. The serial port device is a Prolific USD to 4 serial ports adapter and I plug the two hardware on separate ports of the adapter. The problem is when I read from each port one at a time, everything works fine but when I try to read from both ports at the same time, one of the port is not responding. To troubleshoot the problem, I started two instances of the application and was able to read from the two ports at a time (one from each instance of the application). Does anyone know how to read from two separate serial ports in one application at the same time? Thank you.
Adding some codes:
Port 1:
// button to start or stop reading from port 1. Because the hardware requires me to write to it before reading the response, the writing is done in the timer
private void buttonPort1_Click(object sender, EventArgs e)
{
if (buttonPort1.Text == "Start Recording")
{
if (!port1.IsOpen)
{
port1.Open();
}
timerPort1.Start();
buttonPort1.Text = "Stop Recording";
}
else
{
timerPort1.Stop();
buttonPort1.Text = "Start Recording";
}
}
// Write "D" to the hardware each time to receive back the response
private void timerPort1_Tick(object sender, EventArgs e)
{
port1.Write("D");
}
void port1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string result = port1.ReadLine();
oneParamDelegate dg = PHandCondResult; // send back the result to the main thread
this.Invoke(dg, result);
}
catch
{
}
}
Port 2
The code for the second port is similar to the above really, the difference being different port, datareceived event and timer.
I'll try the multiple thread options suggested by Grant Thomas: I didn't try this before because I thought serial ports are already working on separate threads: the datareceived event doesn't block the main thread and you can't access controls created on the main thread but I'll still give it a go using background worker and revert back later. Thank you all for the quick response.
You're going to need to do some reading, specifically on Threading.
If you have, say, some code that looks like this:
ReadDataFromSomePort();
ReadDataFromSomeOtherPort();
Then the first will execute synchronously (blocking) and then the latter. This happens on the same thread, the main application thread. When you want to do asynchronous things, including just doing one thing while keeping a UI interactive/responsive, then you need to delegate work to other threads.
So, you end up with something like this:
var thread1 = new Thread(ReadDataFromSomePort);
var thread2 = new Thread(ReadDataFromSomeOtherPort);
thread1.Start();
thread2.Start();
There's more to it than this, rest assured, so I recommend some research on the concept before proceeding.
MSDN has a tutorial/programming reference for threading that should get you started.
Creating two different objects of SerialPort and different DataReceived events for both should work.

c#: serial data write from read thread

I am sending and receiving data from a device using
c# (serial communication). For receiving my setup is like this.
I am receiving on a separate thread i.e. I have something like this
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
.....
}
To write I push a button which write data to the device.
Now I was thinking to write data automatically when ever I receive some data from device instead of me pushing
the button when ever I receive data. So my q is that can I put
comPort.WriteLine(textBox1.Text + "\r\n"); in the body of
private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
function. Becase when I put write here it stops working. Otherwise write works with separate button push as I mentioned above.
Can somebody tell me whats the correct way. Is there any issue of threads or someting
Thanks !
Any operation with UI controls (including reading and writing properties like Text) should be done in application's main thread. If you are in another thread, you should use the Invoke method to do the operation:
var text = (string)textBox1.Invoke(new Func<string>(() =>
{
return textBox1.Text;
}));
comPort.WriteLine(text + "\r\n");
Read this answer for more information.

Timer and serial port in c#?

I am using an RFID device to read the data from it. After receiving the data from it I am using it in Visual Studio 2008. I use data-receive event of serial port and timer to get data.
The problem is when I get the RFID data and try to put it in a text field on the data receive event.
Continuously getting data because timer is continuously checking the data and putting this in text box. That's why my back end query is always running and inserting the same data continuously. I want to stop the timer and serial port and then want to open the serial again without closing and opening the form again. Is there any other way to get the data from serial port except timer, and after getting data it stop itself..
Here is my code:
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//Serialtimer.Start();
if (sp.IsOpen)
{
data = sp.ReadExisting();
RFIDtB.Text = data;
}
else
{
MessageBox.Show("Please Check the device");
}
}
You can't access form controls from other threads than the UI thread. See this article: http://msdn.microsoft.com/en-us/library/ms171728.aspx for the solution.

Categories