线程之间的串口通信
本文关键字:通信 串口 之间 线程 | 更新日期: 2023-09-27 18:02:07
在做了很多研究之后,我还是很困惑。我有一个连续读取数据的串行端口对象。我所能做的就是生成dataReceived事件,与端口通信,并将接收到的值输出到调试窗口。所以,我很确定这都是身体上的作用。问题是当我试图将串口输出传递到我的原始线程时,我得到一个错误。它说我不能有线程串音(或类似的东西)。我一直在尝试使用背景工作者,但我不确定这是我想要的解决方案,加上我的新手技能,这有点超出我的理解。我试图使用调用,但方法似乎不可用。(我可能从错误的对象调用?)下面是部分。
namespace Photometer
{
class csRadiometerILT1700
{
//manufacturer specs for baud rate, databits, and stop bits
static string portName="COM1";
static int baudRate = 1200;
static int dataBits = 8;
//instantialize a serial port object for the Radiometer
private SerialPort RadiometerSerial = new SerialPort(portName, baudRate, Parity.None, dataBits, StopBits.One);
//constructor
//public csRadiometerILT1700(Form ParentForm, Chart outputChart)
public csRadiometerILT1700()
{
//two handshaking properties of the ILT1700. Handshaking is enabled and
//http://stackoverflow.com/questions/6277619/problem-reading-serial-port-c-net-2-0-to-get-weighing-machine-output
RadiometerSerial.Handshake= Handshake.RequestToSend;
RadiometerSerial.DtrEnable = true;
RadiometerSerial.DataReceived += new SerialDataReceivedEventHandler(RadiometerSerial_DataReceived);
}
public void openPort()
{
if (!RadiometerSerial.IsOpen)
{
RadiometerSerial.Open();
}
}
public void closePort()
{
RadiometerSerial.Close();
}
string RadiometerVoltageReadingString;
int RadiometerVoltageReadingInt;
private void RadiometerSerial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//It's here that this.invoke()... cannot be called.
RadiometerVoltageReadingString= (RadiometerSerial.ReadExisting().ToString()); //y-value
Debug.Print(RadiometerVoltageReadingString.ToString());
makeRadioReadingDouble(RadiometerVoltageReadingString);
}
private void makeRadioReadingDouble(string inputVoltageString)
{
List<double> outputVoltageDouble=new List<double>(2);
if (!(inputVoltageString == "'r'n" || inputVoltageString == ""))
{
string[] voltageValAndExpo = inputVoltageString.Split(new string[] { "e", "'r'n" }, StringSplitOptions.RemoveEmptyEntries);
for (int inCounter = 0; inCounter < voltageValAndExpo.Count(); inCounter=inCounter+2)
{
double voltageVal = Convert.ToDouble(voltageValAndExpo[inCounter]);
double voltageExpo = Convert.ToDouble(voltageValAndExpo[inCounter + 1]);
outputVoltageDouble.Add(Math.Pow(voltageVal, voltageExpo));
}
}
}
}
}
这些都是在我用代码
进行form加载时调用的 csRadiometerILT1700 Radiometer;
...
Radiometer = new csRadiometerILT1700();
Radiometer.openPort();
任何有见地的都欢迎。
编辑:我将csRadiometerILT1700构造函数更改为
public csRadiometerILT1700(Form inputForm)
{
//inputForm.Invoke(
//two handshaking properties of the ILT1700. Handshaking is enabled and
//http://stackoverflow.com/questions/6277619/problem-reading-serial-port-c-net-2-0-to-get-weighing-machine-output
RadiometerSerial.Handshake= Handshake.RequestToSend;
RadiometerSerial.DtrEnable = true;
RadiometerSerial.DataReceived += new SerialDataReceivedEventHandler(RadiometerSerial_DataReceived);
inputForm.Invoke(DataReceived);
}
和声明
public event Delegate DataReceived;
在csRadiometerILT1700类。但这给了我"Datareceived必须是委托类型"的错误。我现在该如何解决这个问题?我的思路对吗?
- 你的
RadiometerILT1700
类需要一个event
来报告它收到(和处理)的数据。 - 你的表单订阅了那个事件 表单事件处理程序使用
this.Invoke()
来克服交叉线程问题。Invoke
是Delegate
或Form
或Control
上的方法,因为csRadiometerILT1700
不是这些,它不继承这些类的调用实现。
您将需要为csRadiometerILT1700
的调用者引发另一个事件,并在GUI上某处处理该事件(以及任何跨线程问题)。或者,你可以为csRadiometerILT1700
提供一个委托,它可以用来回调,有点像手摇事件。
一旦你有了数据在你的表单中,你可以使用Control.InokeRequired
来检测交叉线程情况和Control.Invoke
来进行交叉线程调用。
任何时候您尝试从其他线程发送到主线程,您将得到此错误。你需要在你想从非主窗体线程的线程中调用的控件上使用委托和Invoke。
假设错误实际上是:
Control控件名称,从它所在线程以外的线程访问创建于。
问题是你不能从另一个线程影响你的GUI。您需要调用表单或控件来传递控件,以便对其进行修改。您应该能够与大多数其他元素交互,但不包括表单。
你不应该在那里调用this.Invoke
,你这样做的方式就像试图与你自己的线程同步,而不是与UI同步。你应该调用formhandle.Invoke
,或者内部表单类注册事件,然后你可以使用this.invoke