串行数据接收多个数据

时间:2018-02-07 17:21:57

标签: c# serial-port stepper

我有一个C#应用程序试图从步进控制器读取两个电机位置,似乎感到困惑 - 或者至少我是。如果我只要求一个电机位置,它的效果很好。

要让控制器发送数据,我必须发送一个命令@ 00PX表示X位置,@ 00PY表示Y位置。控制器返回28位的位置 - 后跟a。

我需要在电机移动时实时获取这些信息,并区分哪些数据是X,哪个是文本框的Y.

我已经使用计时器tick事件每隔50毫秒发送@00PX命令然后发送@00PY命令。接收到的数据事件(读取CR字符)似乎变得混乱,并将数据随机放入任一文本框中。我还尝试在数据调用之前为Xpos和Ypos应用标志,然后在读取数据后重置,但它似乎并不一致。

我可能做错了这一点,但最终还想获得编码器值,以便更加独特的数据。我可以使用任何建议来完成这项工作。

private void SerialPortController_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {

        SerialPort sp = (SerialPort)sender;
        ControllerData = sp.ReadTo("\r");  //reads up to the <CR> and then outputs data

        {
            labelStatus.Invoke(new MethodInvoker(delegate { labelStatus.Text = ControllerData; ; })); //testing to see what is all output from controller
            Int32 numOnly = 0;

            bool result = int.TryParse(ControllerData, out numOnly); //numOnly should be number only and bool set to true

            if (result == true) //checks to ensure that indata is only numbers - if true, display in text box
            {
                if (XPos == true)
                {

                    if (radioButtonMoveDetector.Checked == true)
                    {
                        textBoxTotalDetectorSteps.Invoke(new MethodInvoker(delegate { textBoxTotalDetectorSteps.Text = ControllerData; ; })); //only place numbers in Text box not control characters
                    }
                    labelXPos.Invoke(new MethodInvoker(delegate { labelXPos.Text = ControllerData; ; })); //Show X position
                    XPos = false;
                    YPos = true;
                    serialPortController.Write("@00PY\r");

                }
                else if (YPos == true)
                {
                    if (radioButtonMoveSource.Checked == true)
                    {
                        textBoxTotalSourceSteps.Invoke(new MethodInvoker(delegate { textBoxTotalSourceSteps.Text = ControllerData; ; })); //only place numbers in Text box not control characters
                    }
                    labelYPos.Invoke(new MethodInvoker(delegate { labelYPos.Text = ControllerData; ; })); //Show Y position
                    YPos = false;

private void timerMotor_Tick(object sender, EventArgs e)
    {
        if (serialPortController.IsOpen)  //Check to ensure serial port is open 
        {
            //timerMotor.Stop();
            XPos = true;
            serialPortController.Write("@00PX\r");//Sends command to retrieve motor X step position - a 28 bit number followed with a CR

            //YPos = true;
            serialPortController.Write("@00PY\r");

1 个答案:

答案 0 :(得分:0)

我删除了DataReceived事件,并在发送和接收事件中按顺序在一个从timer_tick调用的单独模块中编程。计时器在SendReceive模块启动时停止,然后在结束时启动。感谢Stephen的确认并指导我朝着正确的方向前进。