线程之间的串口通信

本文关键字:通信 串口 之间 线程 | 更新日期: 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必须是委托类型"的错误。我现在该如何解决这个问题?我的思路对吗?

线程之间的串口通信

  1. 你的RadiometerILT1700类需要一个event来报告它收到(和处理)的数据。
  2. 你的表单订阅了那个事件
  3. 表单事件处理程序使用this.Invoke()来克服交叉线程问题。

InvokeDelegateFormControl上的方法,因为csRadiometerILT1700不是这些,它不继承这些类的调用实现。

您将需要为csRadiometerILT1700的调用者引发另一个事件,并在GUI上某处处理该事件(以及任何跨线程问题)。或者,你可以为csRadiometerILT1700提供一个委托,它可以用来回调,有点像手摇事件。

一旦你有了数据在你的表单中,你可以使用Control.InokeRequired来检测交叉线程情况和Control.Invoke来进行交叉线程调用。

任何时候您尝试从其他线程发送到主线程,您将得到此错误。你需要在你想从非主窗体线程的线程中调用的控件上使用委托和Invoke。

假设错误实际上是:

Control控件名称,从它所在线程以外的线程访问创建于。

问题是你不能从另一个线程影响你的GUI。您需要调用表单或控件来传递控件,以便对其进行修改。您应该能够与大多数其他元素交互,但不包括表单。

你不应该在那里调用this.Invoke,你这样做的方式就像试图与你自己的线程同步,而不是与UI同步。你应该调用formhandle.Invoke,或者内部表单类注册事件,然后你可以使用this.invoke