Reputation: 81
I am working on code that connects to a serial port of a stepper motor. I send a command to the stepper motor via textBox2
and am attempting to read in the return data from the command to textBox3
. I am able to make a connection, send the command, and receive the data. But after my GUI populates textBox3
with the returned serial data it freezes.
I believe that the code is getting stuck in the try loop
but I don't know how to break out of it. Here is my code:
private void button3_Click(object sender, EventArgs e)
{
if (isConnectedMotor)
{
string command = textBox2.Text;
portMotor.Write(command + "\r\n");
portMotor.DiscardInBuffer();
while (true)
{
try
{
string return_data = portMotor.ReadLine();
textBox3.AppendText(return_data);
textBox3.AppendText(Environment.NewLine);
}
catch(TimeoutException)
{
break;
}
}
}
}
DataReceived Code:
private void connectToMotor()
{
isConnectedMotor = true;
string selectedPort = comboBox2.GetItemText(comboBox2.SelectedItem);
portMotor = new SerialPort(selectedPort, 9600, Parity.None, 8, StopBits.One);
portMotor.RtsEnable = true;
portMotor.DtrEnable = true;
portMotor.Open();
portMotor.DiscardInBuffer();
portMotor.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
button4.Text = "Disconnect";
enableControlsMotor();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
textBox3.AppendText(indata);
textBox3.AppendText(Environment.NewLine);
}
I am getting an error saying:
An object reference is required for the non-static field, method, or property 'Form1.textBox3'
Invoke code:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
portMotor.DiscardInBuffer();
incoming_data = portMotor.ReadExisting();
this.Invoke(new EventHandler(displayText));
}
private void displayText(object o, EventArgs e)
{
textBox3.Text += incoming_data;
}
Upvotes: 3
Views: 500
Reputation: 61646
Instead of looping to read data, use a DataReceived event to get at the incoming bytes asynchronously.
See the documentation and example. Also see this question for troubleshooting.
P.S. Here is a code sample to avoid locking up the UI.
private void ReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
var incoming_data = portMotor.ReadExisting();
// this is executing on a separate thread - so throw it on the UI thread
Invoke(new Action(() => {
textBox3.Text += incoming_data;
}));
}
Upvotes: 3