/// <summary>
        /// Click the Start button.
        /// </summary>
        /// <param name="sender">The evented object</param>
        /// <param name="e">Additional event information</param>
        /// <remarks>
        /// Start scenario.
        /// </remarks>
        private void btnStart_Click(object sender, EventArgs e)
        {
            // Start scenario
            this._enumProcess = EnumProcess.Running;
            // Button control
            this.btnDisconnect.Enabled = false;
            this.btnStart.Enabled      = false;
            this.btnStop.Enabled       = true;
            // Scenario creation
            this.SetScenario();
            // Send command
            this._indexSendCommandID = EnumSenario.StartMeasurement;
            TOFCommand command = this._listCommand[(int)this._indexSendCommandID];

            this.AsyncSerialPort(command);
        }
        /// <summary>
        /// Callback processing after receiving data.
        /// </summary>
        /// <remarks>
        /// </remarks>
        async private void CallbackSerialPort()
        {
            byte[] data         = this._serialPort.ReceiveDataBuffer;
            int    length       = this._serialPort.ReceivedDataLength;
            bool   isError      = this._serialPort.IsError;
            byte   responseCode = 0x00;

            try
            {
                TOFCommand command = this._listCommand[(int)this._indexSendCommandID];
                if (6 <= length && data[0] == 0xFE)
                {
                    responseCode = data[1];
                    // When the synchronization code is 0xFE and the received data length is 6 or more.
                    int dataLength = (data[2] << 24) + (data[3] << 16) + (data[4] << 8) + data[5];
                    if (length == dataLength + 6)
                    {
                        // When all data can be received,
                        // Write received data information to log area.
                        this.txtLog.AppendText(string.Format("{0}  {1}  {2}  {3}\r\n"
                                                             , DateTime.Now.ToString("HH:mm:ss.fff")
                                                             , length.ToString("D7")
                                                             , "Receive"
                                                             , BitConverter.ToString(data, 0, 20 <= length ? 20 : length)));
                        this.txtLog.ScrollToCaret();

                        // Command processing
                        switch (command.CommandID)
                        {
                        case 0x80:
                            // Start measurement command
                            // To get imager temperature
                            this._indexSendCommandID = EnumSenario.GetImagerTemperature;
                            break;

                        case 0x9B:
                            // Get imager temperature
                            // Get upper left temperature
                            double curImagerUL = ((data[6] << 8) + data[7]) / 10d;
                            this.txtCurrentImagerUL.Text = string.Format("{0:F1}", curImagerUL);
                            // Get upper right temperature
                            double curImagerUR = ((data[8] << 8) + data[9]) / 10d;
                            this.txtCurrentImagerUR.Text = string.Format("{0:F1}", curImagerUR);
                            // Get lower left temperature
                            double curImagerLL = ((data[10] << 8) + data[11]) / 10d;
                            this.txtCurrentImagerLL.Text = string.Format("{0:F1}", curImagerLL);
                            // Get lower right temperature
                            double curImagerLR = ((data[12] << 8) + data[13]) / 10d;
                            this.txtCurrentImagerLR.Text = string.Format("{0:F1}", curImagerLR);
                            // Get imager start temperature
                            double startImager = (double)this.nudStartImager.Value;
                            // Get imager stop temperature
                            double stopImager = (double)this.nudStopImager.Value;
                            if (stopImager < curImagerUL || stopImager < curImagerUR || stopImager < curImagerLL || stopImager < curImagerLR)
                            {
                                // When Current temperature is larger than Stop temperature
                                // To stop measurement
                                this._indexSendCommandID = EnumSenario.StopMeasurement;
                                // Detect Abnormal
                                this._isAbnormalTemperatureImager = true;
                            }
                            else
                            {
                                if (this._isAbnormalTemperatureImager &&
                                    (startImager < curImagerUL || startImager < curImagerUR || startImager < curImagerLL || startImager < curImagerLR))
                                {
                                    // When Current temperature is larger than Start temperature
                                    // To stop measurement
                                    this._indexSendCommandID = EnumSenario.StopMeasurement;
                                    // Detect Abnormal
                                    this._isAbnormalTemperatureImager = true;
                                }
                                else
                                {
                                    // When Current temperature is less than Start temperature
                                    // To get LED temperature
                                    this._indexSendCommandID = EnumSenario.GetLEDTemperature;
                                    // Release Abnormal
                                    this._isAbnormalTemperatureImager = false;
                                }
                            }
                            break;

                        case 0x9C:
                            // Get LED temperature
                            double curLED = ((data[6] << 8) + data[7]) / 10d;
                            this.txtCurrentLED.Text = string.Format("{0:F1}", curLED);
                            // Get LED start temperature
                            double startLED = (double)this.nudStartLED.Value;
                            // Get LED stop temperature
                            double stopLED = (double)this.nudStopLED.Value;
                            if (stopLED < curLED)
                            {
                                // When Current temperature is larger than Stop temperature
                                // To stop measurement
                                this._indexSendCommandID = EnumSenario.StopMeasurement;
                                // Detect Abnormal
                                this._isAbnormalTemperatureLED = true;
                            }
                            else
                            {
                                if (this._isAbnormalTemperatureLED && startLED < curLED)
                                {
                                    // When Current temperature is larger than Start temperature
                                    // To stop measurement
                                    this._indexSendCommandID = EnumSenario.StopMeasurement;
                                    // Detect Abnormal
                                    this._isAbnormalTemperatureLED = true;
                                }
                                else
                                {
                                    // When Current temperature is less than Start temperature
                                    // To get imager temperature
                                    this._indexSendCommandID = EnumSenario.GetImagerTemperature;
                                    // Release Abnormal
                                    this._isAbnormalTemperatureLED = false;
                                }
                            }
                            break;

                        case 0x81:
                            // Stop measurement command
                            // Set time interval
                            command.WaitTime = (int)this.nudInterval.Value * 1000;
                            // To start measurement
                            this._indexSendCommandID = EnumSenario.StartMeasurement;
                            break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        // When some data could not be received,
                        // Write received data information to log area.
                        this.txtLog.AppendText(string.Format("Failed to receive data. The received data length is {0} bytes.\r\n"
                                                             , length));
                        this.txtLog.ScrollToCaret();
                    }
                }
                else
                {
                    responseCode = 0x99;
                    if (isError)
                    {
                        // When some data could not be received,
                        // Write received data information to log area.
                        this.txtLog.AppendText(string.Format("Failed to send data.\r\n"));
                    }
                    else
                    {
                        // When some data could not be received,
                        // Write received data information to log area.
                        this.txtLog.AppendText(string.Format("Failed to receive data.\r\n"));
                    }
                    this.txtLog.ScrollToCaret();
                }

                // Processing steps
                if (this._enumProcess == EnumProcess.Stopping)
                {
                    // To stop measurement
                    this._indexSendCommandID = EnumSenario.StopMeasurement;
                    this._enumProcess        = EnumProcess.Stopped;
                }
                else if (this._enumProcess == EnumProcess.Stopped)
                {
                    // End of scenario.
                    MessageBox.Show("End of scenario.", "End", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.ChangeEnabledButton(false);
                    return;
                }

                // Wait processing
                await Task.Run(() => this.Wait(command.WaitTime));

                // Send command
                command = this._listCommand[(int)this._indexSendCommandID];
                this.AsyncSerialPort(command);
            }
            catch (ObjectDisposedException)
            {
                // Do nothing until the object is destroyed.
            }
        }