-3

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");
  • You're not waiting for the response from the hardware. If you cannot detect from the reply content which operation it refers to then you'll have to send command X, process response, then send command Y, and so on. Right now you're likely getting a response to X after you already sent Y! – Stephen Kennedy Feb 07 '18 at 19:15
  • I agree Stephen. I think the above is just a blind crap shoot. I am going to program in a send, read the specific response, send the next command, read response, etc for all 4 values and then repeat. Will try to program tonight. – user8196572 Feb 09 '18 at 02:54

1 Answers1

0

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.