private void run()
        {
            byte[] dataBuffer     = new byte[256];
            int    bufferPosition = 0;

            timeoutTimer          = new System.Timers.Timer();
            timeoutTimer.Interval = 200;
            timeoutTimer.Elapsed += TimeoutTimer_Elapsed;

            try
            {
                serialPort.Open();

                ConnectionStateChanged?.Invoke(this, null);

                while (serialPort.IsOpen)
                {
                    int bytesToRead = serialPort.BytesToRead;
                    if (state == State.Idle)
                    {
                        if (bytesToRead > 0)
                        {
                            timeoutTimer.Start();
                            state = State.Receiving;
                        }
                        else if (commandToSend != null)
                        {
                            state = State.Sending;
                        }
                    }

                    switch (state)
                    {
                    case State.Receiving:
                    {
                        if (bytesToRead > 0)
                        {
                            if ((bytesToRead + bufferPosition) < dataBuffer.Length)
                            {
                                serialPort.Read(dataBuffer, bufferPosition, bytesToRead);
                                bufferPosition += bytesToRead;
                            }
                            else
                            {
                                serialPort.Read(dataBuffer, bufferPosition, (dataBuffer.Length - bufferPosition));
                                bufferPosition += (dataBuffer.Length - bufferPosition);
                            }


                            while (CheckDataBuffer(dataBuffer, bufferPosition))
                            {
                                MGBTCommandData data = MGBTCommandData.FromArray(dataBuffer);
                                if (data.VerifyCRC())
                                {
                                    rxQueue.Enqueue(data);
                                    NewDataArrived?.Invoke(this, null);
                                }
                                else
                                {
                                }
                                if (bufferPosition > (data.dataLength + 8))
                                {
                                    byte[] newDataBuffer = new byte[dataBuffer.Length];
                                    Array.Copy(dataBuffer, (data.dataLength + 8), newDataBuffer, 0, dataBuffer.Length - (data.dataLength + 8));
                                    dataBuffer      = newDataBuffer;
                                    bufferPosition -= (data.dataLength + 8);
                                }
                                else
                                {
                                    Array.Clear(dataBuffer, 0, dataBuffer.Length);
                                    bufferPosition = 0;
                                    state          = State.Idle;
                                }
                            }
                        }
                        break;
                    }

                    case State.Sending:
                    {
                        byte[] data = null;
                        lock (lockObj)
                        {
                            commandToSend.UpdateCRC();
                            data          = commandToSend.ToArray(false);
                            commandToSend = null;
                            state         = State.Idle;
                        }

                        if (data != null)
                        {
                            serialPort.Write(data, 0, data.Length);
                        }

                        break;
                    }

                    default:
                    {
                        break;
                    }
                    }

                    Thread.Sleep(10);
                }
            }
            catch (Exception e)
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                }
            }
            ConnectionStateChanged?.Invoke(this, null);
        }