Search code examples
c#serial-portstepper

Serial data receiving multiple data


I have a C# application that is trying to read two motor positions from a stepper controller and seems to be getting confused - or at least I am. It works well if I am only asking for one motor position.

To get the controller to send data I have to send it a command @00PX for X position and @00PY for Y position. The controller returns a 28 bit number of the position - followed by a .

I need to get this information in real time as the motors are moving and distinguish which data is X and which is Y for a text box.

I have used the timer tick event to send the @00PX command and then the @00PY command every 50 msec. The data received event (reading up to a CR character) seems to get confused and places the data in either text box randomly. I have also tried to apply flags for Xpos and Ypos before the data call and then reset after the data read, but it doesn't seem to work consistently.

I may be doing this all wrong, but eventually want to also get the encoder values so that will be even more distinct data. I could use any suggestions to make this work.

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");

Solution

  • I removed the DataReceived event and programmed in the send and receive events sequentially in a separate module that is called from the timer_tick. The timer is stopped at the start of the SendReceive module and then started at the end. Thanks for the confirmation Stephen and steering me in the right direction.