我有arduino uno,我正在使用它像A / D转换器。我的arduino信号1-5V,我将其转换为数字并发送到我的端口。我在C#WFA中申请了。以下是该应用程序的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace na_posla
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = false;
getAvailablePorts();
}
void getAvailablePorts()
{
String[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
try
{
if (comboBox1.Text == "" || comboBox2.Text == "")
{
MessageBox.Show("Please select port settings");
}
else
{
serialPort1.PortName = comboBox1.Text;
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
serialPort1.Open();
progressBar1.Value = 100;
button1.Enabled = false;
button2.Enabled = true;
button3.Enabled = true;
}
}
catch (UnauthorizedAccessException)
{
textBox1.Text = "Unauthorized Access";
}
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.Close();
progressBar1.Value = 0;
textBox1.Text = "";
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = false;
}
private void button3_Click(object sender, EventArgs e)
{
double y = 0;
double doubleval;
string stringVal;
stringVal = serialPort1.ReadLine();
if (stringVal.Contains("."))
stringVal = stringVal.Replace(".", ",");
doubleval = System.Convert.ToDouble(stringVal);
y = (doubleval / 5) * 40;
textBox1.Text = y.ToString();
//for (; ; )
//{
// stringVal = serialPort1.ReadLine();
// if (stringVal.Contains("."))
// stringVal = stringVal.Replace(".", ",");
// doubleval = System.Convert.ToDouble(stringVal);
// y = (doubleval / 5) * 40;
// textBox1.Text = y.ToString();
//}
}
}
}
在表格中我有2个组合框,3个按钮,进度条和文本框。按钮一个打开端口按钮,按钮2关闭端口按钮。当我按下按钮3(读取)时,我从arduino接收数据,然后将其写入文本框。当我有这个代码并且我点击阅读时我会收到新数据。当我想在循环中读取数据时,问题就开始了。循环在代码中注释。我无法点击任何按钮,我无法停止阅读。我已阅读有关backgroundworker但我不知道如何在我的代码中应用它。有人可以帮助我吗?
答案 0 :(得分:0)
你必须使用一个线程来读取(我希望我在代码中没有忘记):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace na_posla
{
public partial class Form1 : Form
{
Thread readThread = null;
bool threadCanRun = false;
public Form1()
{
InitializeComponent();
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = false;
getAvailablePorts();
}
void getAvailablePorts()
{
String[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
try
{
if (comboBox1.Text == "" || comboBox2.Text == "")
{
MessageBox.Show("Please select port settings");
}
else
{
serialPort1.PortName = comboBox1.Text;
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
serialPort1.Open();
progressBar1.Value = 100;
button1.Enabled = false;
button2.Enabled = true;
button3.Enabled = true;
}
}
catch (UnauthorizedAccessException)
{
textBox1.Text = "Unauthorized Access";
}
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.Close();
progressBar1.Value = 0;
textBox1.Text = "";
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = false;
}
private void button3_Click(object sender, EventArgs e)
{
StopReadThread();
StartReadThread();
}
private void SetTextBoxText(TextBox txtBox, string value)
{
if (txtBox.InvokeRequired)
{
txtBox.Invoke((MethodInvoker)delegate { SetTextBoxText(txtBox, value); });
return;
}
txtBox.Text = value;
}
private void StartReadThread()
{
if (readThread == null)
readThread = new Thread(ReadDataLooped);
if (readThread.ThreadState == ThreadState.Unstarted)
{
threadCanRun = true;
readThread.Start();
}
}
private void StopReadThread()
{
if(readThread != null && readThread.ThreadState != ThreadState.Unstarted)
{
if (readThread.IsAlive)
{
threadCanRun = false;
Thread.Sleep(50);
readThread.Abort();
readThread.Join();
}
}
}
private void ReadDataLooped(object obj)
{
try
{
while (threadCanRun)
{
ReadAndSetData();
Thread.Sleep(1000); //Wait a second between the reads
}
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
}
}
private double ReadValueFromSerialPort()
{
string stringVal = serialPort1.ReadLine();
if (stringVal.Contains("."))
stringVal = stringVal.Replace(".", ",");
double doubleval = System.Convert.ToDouble(stringVal);
double y = (doubleval / 5) * 40;
return y;
}
private void ReadAndSetData()
{
this.SetTextBoxText(textBox1, this.ReadValueFromSerialPort().ToString());
}
}
}
<强>解释强>
您的表单在您的应用程序的STAThread中运行。如果你想做一些工作,你的线程就会被阻止,因为工作完成了。因此,如果要永久更新数据,则必须在单独的线程中运行此代码,并且UI可以在第一个STAThread中更新和响应。有很多方法可以做到这一点。我决定使用一个简单的Thread,因为它与.Net 3.5兼容。从.Net 4.0开始实现任务和等待(并且更容易/更少工作)。