Serial Port Communication This is an efficiency question to the following code, written in MS Visual in C#. If any explanation is missing, please let me know and I will add. What this part of the program does is: 


Button is pushed
Motor starts moving (by sending 9-byte array with command)
Waiting for Sensor to register a change in value
Motor stops
Motorposition is saved (command to get position is send and 9-byte array response is send by the motor), to have access to it later on and return there


Calls like rotate() and stop() are commands that write data into a 9-byte-array and write bytearray to serial port.

Now, my main issue is Step 5. I read on Stack Overflow that "if you have to use wait() and there is no point of using the DataReceived implementation". So should I really get rid of this or is there a nice way to handle this? If I do it without the wait() it saves the answer that is send after the stop command (every command also sends an answer).

And would it be more efficient to use DataReceived in step 3? In the beginning I save a value as new 0, and compare the current sensor readout here to this 0 value.

private void button13_Click(object sender, EventArgs e)
{
    //rotate right speed
    string Test = textBox4.Text;
    byte[] A = new byte[9];
    rotate(A, Test);
    //read sensor
    serialPort2.WriteLine("SR,00,002\r\n");
    string b = serialPort2.ReadLine();
    decimal caliber = decimal.Parse(Regex.Split(b, "SR,00,002,")[1]);
    decimal b1 = 0;
    do
    {
        serialPort2.WriteLine("SR,00,002\r\n");
        string z = serialPort2.ReadLine();
        b1 = decimal.Parse(Regex.Split(z, "SR,00,002,")[1]);
    }
    while (b1 &lt;= caliber);
    // stop motor
    byte[] B = new byte[9];
    stop(B);
    //save position
    System.Threading.Thread.Sleep(5000);
    byte[] C = new byte[9];
    getPosi(C);
    System.Threading.Thread.Sleep(5000);
    M = buf;
    //move to 0
    byte[] D = new byte[9];
    MoveTo0(D);
}


In case it is needed for understanding the code above:

//global variables
byte[] buf = new byte[9];
byte[] M = new byte[9];
private void button1_Click(object sender, EventArgs e)      //Ports öffnen
{
    serialPort3 = new SerialPort();
    serialPort3.PortName = "COM6";
    serialPort3.Handshake = Handshake.RequestToSend;
    serialPort3.ReceivedBytesThreshold = 8;
    serialPort3.DataReceived += new SerialDataReceivedEventHandler(DataRecievedHandler);
    serialPort3.Open();
}
private void DataRecievedHandler(object sender, SerialDataReceivedEventArgs e)
{ 
    SerialPort sp = (SerialPort)sender;
    int bytes = serialPort3.BytesToRead;
    byte[] buffer = new byte[bytes];
    sp.Read(buffer, 0, bytes);
    string hex = BitConverter.ToString(buffer);
    hex.Replace("-", "");
    MessageBox.Show(hex);
    buf = buffer;         
}


Other methods:

private void rotate(byte[] A, string Test) //Rotate Motor Right
    {
        A = MB.TMCL_RMR(Test);
        serialPort3.Write(A, 0, A.Length);
    }

    private void stop(byte[] B) // Stop Motor
    {
        B = MB.TMCL_MST();
        serialPort3.Write(B, 0, B.Length);
    }

    private void getPosi(byte[] C) //Get Position
    {
        C = MB.GET_POSI();
        serialPort3.Write(C, 0, C.Length);
    }

    private void MoveTo0(byte[] D) //Move to 0
    {
        D = MB.MoveTo0();
        serialPort3.Write(D, 0, D.Length);
    }


And as example a method from my seperate motorcontrolclass on how the bytearray is created. Each hex-byte references a certain information, last byte is a checksum. If this array is send to the serial port it will request the motorposition as an answer. 

public byte[] GET_POSI()
    {
        byte[] E = new byte[9];
        E[0] = 0x1;
        E[1] = 0x6;
        E[2] = 0x1;
        E[3] = 0x0;
        E[4] = 0x0;
        E[5] = 0x0;
        E[6] = 0x0;
        E[7] = 0x0;
        E[8] = 0x08;
        return E;
    }


The code is working as I want it to for several input tests. I just thought there might be a better way than the Thread.Sleep().
I guess you thought about avoiding of Thread.Sleep() method, not Wait() you mentioned in title. I can't test your code because I don't have either COM port nor motor. I would like to give you some general tips how to improve your code. 
Let's implement some SOLID and DRY principles. I would start with class Motor which will represent your device. You can implement for example singleton class for this purpose. This helps you to separate your motor logic from other logic such is user interface. I can also imagine your port settings as a part of application configuration.

Motor.cs

public sealed class Motor : IDisposable
{
    public static readonly Motor Instance = new Motor();

    private Motor()
    {
        MotorPort = new SerialPort();
        MotorPort.PortName = "COM6";
        MotorPort.Handshake = Handshake.RequestToSend;
        MotorPort.ReceivedBytesThreshold = 8;
        MotorPort.DataReceived += new SerialDataReceivedEventHandler(dataRecievedHandler);
        MotorPort.Open();
    }

    public SerialPort MotorPort { get; private set; }
    public decimal Position { get; private set; }
    public void StopRotate()    { }
    public void StartRotate(string speed) { }
    public void MoveToPosition(int position) { }
    private void dataRecievedHandler(object sender, SerialDataReceivedEventArgs e)
    {
    }
    public void Dispose()
    {
        if (MotorPort.IsOpen)
        {
            MotorPort.Close();
        }
    }
}


Instead of using global fields (M, buf), encapsulate them into object and set the proper access modifier or better create properties. Use meaningful names your fields and properties. Use Capitalization Convention.

You can isolate your repeating strings into separate static class to make your string constant repository which would be more easily maintainable against direct using of particular string.

StringConstants.cs

static class StringConstants
{
    public const string Prefix = "SR,00,002,";
    public const string PrefixCrLf = "SR,00,002\r\n";
}


Extension methods can simplify your code and make it more readable.

Extensions.cs

static class Extensions
{
    public static decimal GetDecimalOutput(this SerialPort port)
    {
        return decimal.Parse(Regex.Split(port.ReadLine(), StringConstants.Prefix)[1]);
    }
    public static void SendCommand(this SerialPort port)
    {
        port.WriteLine(StringConstants.PrefixCrLf);
    }
}


If you have implemented Motor.cs methods, you can use it or extend it.

Form1.cs

private void btnTest_Click(object sender, EventArgs e)
{
    Motor.Instance.StartRotate(speed);
    Thread.Sleep(5000);
    Motor.Instance.StopRotate();
    Motor.Instance.MoveToPosition(0);

    //read sensor
    serialPort2.SendCommand();
    decimal caliber = serialPort2.GetDecimalOutput();

    do
    {
        serialPort2.SendCommand();
        actualValue = serialPort2.GetDecimalOutput();
    }
    while (actualValue &lt;= caliber);
}


I am not experienced in serial port programming, but I am pretty sure that event SerialPort.DataReceived should be used to invoke subscribed method as you do with your serialPort3. I don't know exactly why you are using Thread.Sleep(), because I cannot see getPosi(C); method.