public bool CAN_WritePressureThresholds_Conti(ref string ErrorDesc, ContiPartConfigMessage PartConfig)
        {
            //mLog.Write("CAN_WriteSensorIDs SensorID1=" + SensorID1 + "; SensorID2=" + SensorID2 + "; SensorID3=" + SensorID3 + "; SensorID4=" + SensorID4);
            if (mPort == null) { ErrorDesc = "Port Not Initialized"; return false; }
            if (mPort.IsOpen == false) { ErrorDesc = "Port Not Opened"; return false; }
            if (mSendAddr == null) { ErrorDesc = "Send Address not initialized"; return false; }
            if (Connected == false) { ErrorDesc = "CAN ODBII cable not connected"; return false; }

            try
            {
                lock (mSyncLock)
                {

                    string dataToSend_1stMsg;
                    string dataToSend_2ndMsg;
                    string dataToSend_3rdMsg;
                    string Response_1stMsg;

                    //Convert ints to HEX********************
                    string NumberFrontWheelTeeth_HEX = Convert.ToInt16(PartConfig.FrontWheelTeeth).ToString("X00").PadLeft(2,'0');
                    string NumberRearWheelTeeth_HEX = Convert.ToInt16(PartConfig.RearWheelTeeth).ToString("X00").PadLeft(2, '0');
                    string ThresholdPercentage_HEX = Convert.ToInt16(PartConfig.ThresholdPercentage).ToString("X00").PadLeft(2, '0');
                    string ThresholdMargin_HEX = Convert.ToInt16(PartConfig.ThresholdMargin).ToString("X00").PadLeft(2, '0');
                    string ThresholdMarginCold_HEX = Convert.ToInt16(PartConfig.ThresholdMarginCold).ToString("X00").PadLeft(2, '0');
                    string NominalPressureFront_HEX = Convert.ToInt16(PartConfig.NominalPressureFrontKPa).ToString("X00").PadLeft(4, '0');
                    string NominalPressureRear_HEX = Convert.ToInt16(PartConfig.NominalPressureRearKPa).ToString("X00").PadLeft(4, '0');
                    string ResetThresholdMargin_HEX = Convert.ToInt16(PartConfig.ResetThresholdMarginKPa).ToString("X00").PadLeft(2, '0');
                    string ResetThresholdMarginCold_HEX = Convert.ToInt16(PartConfig.ResetThresholdMarginColdKPa).ToString("X00").PadLeft(2, '0');
                    string LocalisationConfiguration_HEX = Convert.ToInt16(PartConfig.LocalizationConfiguration).ToString("X00").PadLeft(2, '0');
                    string RFHardwareVariantSetting_HEX = Convert.ToInt16(PartConfig.RFHardwareVariantSetting).ToString("X00").PadLeft(2, '0');
                    string AmbientTemperatureCANSignal_HEX = Convert.ToInt16(PartConfig.AmbientTempCANSignalAcquisition).ToString("X00").PadLeft(2, '0');
                    //**************************************

                    //First Message: Front Teeth, Rear Teeth, Thresh %
                    //Second Message: Thresh Margin, Thresh Margin Cold, Nominal Pressure Front (kpa), Nominal Pressure Rear (kpa), Reset Thresh Margin
                    //Third Message: Reset Thresh Margin Cold, Localisation Config, RF Hardware Setting, Ambient Temp
                    //     dataToSend = ":S" + mSendAddr + "N" + "0322F09100000000;";
                    dataToSend_1stMsg = ":S" + mSendAddr + "N" + "10142EF091" + NumberFrontWheelTeeth_HEX + NumberRearWheelTeeth_HEX + ThresholdPercentage_HEX + ";";
                    dataToSend_2ndMsg = ":S" + mSendAddr + "N" + "21" + ThresholdMargin_HEX + ThresholdMarginCold_HEX + NominalPressureFront_HEX + NominalPressureRear_HEX + ResetThresholdMargin_HEX  + ";";
                    dataToSend_3rdMsg = ":S" + mSendAddr + "N" + "22" + ResetThresholdMarginCold_HEX + LocalisationConfiguration_HEX + RFHardwareVariantSetting_HEX + AmbientTemperatureCANSignal_HEX + "000000;";
                    Response_1stMsg = ":S" + mRecvAddrFilter + "N" + "30010E";

                    int timeout = 2000;//ms
                    //clear the buffer
                    string buffer = CANReadExisting();
                    mPort.ReadTimeout = 100;
                    CANWrite(dataToSend_1stMsg);
                    DateTime StartTime = DateTime.Now;
                    while (DateTime.Now.Subtract(StartTime).TotalMilliseconds < timeout)
                    {
                        try
                        {
                            buffer = CANReadLine();
                        }
                        catch (TimeoutException e)
                        {//ignore this error.  It just means that data is not on the line.
                        }
                        catch (Exception ex) { ErrorDesc = ex.ToString(); }
                        if (buffer.Contains(Response_1stMsg))
                        {
                            CANWrite(dataToSend_2ndMsg);
                            CANWrite(dataToSend_3rdMsg);
                            Thread.Sleep(100);
                            buffer = CANReadExisting();

                            return true;
                        }
                        Thread.Sleep(10);
                    }
                    ErrorDesc = "Response not received for Write Sensor Thresholds.";
                    return false;
                }
            }
            catch (Exception ex)
            {
                ErrorDesc = ex.ToString();
            }

            if (ErrorDesc.Length == 0) ErrorDesc = "Vehicle is not responding to Write Pressure Thresholds.";
            return false;
        }
        public bool CAN_ReadPressureThresholds_Conti(ref string ErrorDesc, ref ContiPartConfigMessage PartConfig)
        {
            mLog.Write("CAN_ReadPressureThresholds_Conti");
            if (mPort == null) { ErrorDesc = "Port Not Initialized"; return false; }
            if (mPort.IsOpen == false) { ErrorDesc = "Port Not Opened"; return false; }
            if (mSendAddr == null) { ErrorDesc = "Send Address not initialized"; return false; }
            if (Connected == false) { ErrorDesc = "CAN ODBII cable not connected"; return false; }

            try
            {
                lock (mSyncLock)
                {

                    string dataToSend;
                    string Respone_1stMsg;
                    string expectedResponse_1stMsg;
                    string expectedResponse_2ndMsg;
                    string expectedResponse_3rdMsg;

                    dataToSend = ":S" + mSendAddr + "N" + "0322F09100000000;";
                    Respone_1stMsg = ":S" + mSendAddr + "N" + "30000A0000000000;";
                    expectedResponse_1stMsg = ":S" + mRecvAddrFilter + "N" + "101462F091";
                    expectedResponse_2ndMsg = ":S" + mRecvAddrFilter + "N" + "21";
                    expectedResponse_3rdMsg = ":S" + mRecvAddrFilter + "N" + "22";

                    int timeout = 2000;//ms
                    //clear the buffer
                    string buffer = CANReadExisting();
                    mPort.ReadTimeout = 100;
                    CANWrite(dataToSend);
                    DateTime StartTime = DateTime.Now;
                    while (DateTime.Now.Subtract(StartTime).TotalMilliseconds < timeout)
                    {
                        try
                        {
                            buffer = CANReadLine();
                        }
                        catch (TimeoutException e)
                        {//ignore this error.  It just means that data is not on the line.
                        }
                        catch (Exception ex) { ErrorDesc = ex.ToString(); }
                        if (buffer.Contains(expectedResponse_1stMsg))
                        {
                            int StartPos = buffer.IndexOf(expectedResponse_1stMsg, 0);
                            //Parse out the Continental part information then send 2nd command
                            PartConfig.FrontWheelTeeth = Convert.ToInt32(buffer.Substring(StartPos + 16, 2), 16);
                            PartConfig.RearWheelTeeth = Convert.ToInt32(buffer.Substring(StartPos + 18, 2), 16);
                            PartConfig.ThresholdPercentage = Convert.ToInt32(buffer.Substring(StartPos + 20, 2), 16);
                            CANWrite(Respone_1stMsg);
                        }
                        if (buffer.Contains(expectedResponse_2ndMsg))
                        {
                            int StartPos = buffer.IndexOf(expectedResponse_2ndMsg, 0);
                            PartConfig.ThresholdMargin = Convert.ToInt32(buffer.Substring(StartPos + 8, 2), 16);
                            PartConfig.ThresholdMarginCold = Convert.ToInt32(buffer.Substring(StartPos + 10, 2), 16);
                            PartConfig.NominalPressureFrontKPa = Convert.ToInt32(buffer.Substring(StartPos + 12, 4), 16);
                            PartConfig.NominalPressureRearKPa = Convert.ToInt32(buffer.Substring(StartPos + 16, 4), 16);
                            PartConfig.ResetThresholdMarginKPa = Convert.ToInt32(buffer.Substring(StartPos + 20, 2), 16);
                        }
                        if (buffer.Contains(expectedResponse_3rdMsg))
                        {
                            int StartPos = buffer.IndexOf(expectedResponse_3rdMsg, 0);
                            PartConfig.ResetThresholdMarginColdKPa = Convert.ToInt32(buffer.Substring(StartPos + 8, 2), 16);
                            PartConfig.LocalizationConfiguration = Convert.ToInt32(buffer.Substring(StartPos + 10, 2), 16);

                            if (Convert.ToInt32(buffer.Substring(StartPos + 12, 2), 16) == 0)
                            {
                                PartConfig.RFHardwareVariantSetting = ECUVariantType.Japan_315;
                            }
                            else if (Convert.ToInt32(buffer.Substring(StartPos + 12, 2), 16) == 1)
                            {
                                PartConfig.RFHardwareVariantSetting = ECUVariantType.US_433;
                            }
                            else
                            {
                                PartConfig.RFHardwareVariantSetting = ECUVariantType.EU_433;
                            }

                            PartConfig.AmbientTempCANSignalAcquisition = Convert.ToInt32(buffer.Substring(StartPos + 14, 2), 16);

                            //Write values to log
                            mLog.Write("Front Wheel Teeth = " + Convert.ToString(PartConfig.FrontWheelTeeth) + "; Rear Wheel Teeth = " + Convert.ToString(PartConfig.RearWheelTeeth) + "; Threshold Percentage = " + Convert.ToString(PartConfig.ThresholdPercentage) + "; Threshold Margin = " + Convert.ToString(PartConfig.ThresholdMargin) + "; Threshold Margin Cold = " + Convert.ToString(PartConfig.ThresholdMarginCold) + "; Nominal Front Pressure = " + Convert.ToString(PartConfig.NominalPressureFrontKPa) + "; Nominal Rear Pressure = " + Convert.ToString(PartConfig.NominalPressureRearKPa) + "; Reset Threshold Margin = " + Convert.ToString(PartConfig.ResetThresholdMarginKPa) + "; Reset Threshold Margin Cold = " + Convert.ToString(PartConfig.ResetThresholdMarginColdKPa) + "; Localisation Configuration = " + Convert.ToString(PartConfig.LocalizationConfiguration) + "; RF Hardware Variant Setting = " + Convert.ToString(PartConfig.RFHardwareVariantSetting) + "; Ambient Temperature CAN Signal Acquisition = " + Convert.ToString(PartConfig.AmbientTempCANSignalAcquisition));

                            return true;
                        }
                        Thread.Sleep(10);
                    }
                    //mLog.Write("SensorID1=" + SensorID1 + "; SensorID2=" + SensorID2 + "; SensorID3=" + SensorID3 + "; SensorID4=" + SensorID4);
                    //if (SensorID1.Length == 8 && SensorID2.Length == 8 && SensorID3.Length == 8 && SensorID4.Length == 8)
                    //{
                    //    return true;
                    //}
                    //else
                    //{
                    //    if (SensorID1.Length == 0) { ErrorDesc = "Did not receive 1st sensor ID"; }
                    //    else if (SensorID2.Length == 0) { ErrorDesc = "Did not receive 2nd sensor ID"; }
                    //    else if (SensorID4.Length == 0) { ErrorDesc = "Did not receive 4th sensor ID"; }
                    //    else { ErrorDesc = "Error with recieving Read Sensor ID's"; };
                    //    return false;
                    //}
                }
            }
            catch (Exception ex)
            {
                ErrorDesc = ex.ToString();
            }

            if (ErrorDesc.Length == 0) ErrorDesc = "Vehicle is not responding to Read ID's.";
            return false;
        }
        public bool CAN_ReadVIN_Conti(ref string ErrorDesc, ref ContiPartConfigMessage PartConfig)
        {
            mLog.Write("CAN_ReadVIN_Conti");
            if (mPort == null) { ErrorDesc = "Port Not Initialized"; return false; }
            if (mPort.IsOpen == false) { ErrorDesc = "Port Not Opened"; return false; }
            if (mSendAddr == null) { ErrorDesc = "Send Address not initialized"; return false; }
            if (Connected == false) { ErrorDesc = "CAN ODBII cable not connected"; return false; }

            try
            {
                lock (mSyncLock)
                {

                    string dataToSend;
                    string Respone_1stMsg;
                    string expectedResponse_1stMsg;
                    string expectedResponse_2ndMsg;
                    string expectedResponse_3rdMsg;

                    string tempVIN_HEX = "";

                    //Data Identifier to send for VIN = F090
                    dataToSend = ":S" + mSendAddr + "N" + "0322F09000000000;";
                    Respone_1stMsg = ":S" + mSendAddr + "N" + "30000A0000000000;";
                    expectedResponse_1stMsg = ":S" + mRecvAddrFilter + "N" + "101462F090";
                    expectedResponse_2ndMsg = ":S" + mRecvAddrFilter + "N" + "21";
                    expectedResponse_3rdMsg = ":S" + mRecvAddrFilter + "N" + "22";

                    int timeout = 2000;//ms
                    //clear the buffer
                    string buffer = CANReadExisting();
                    mPort.ReadTimeout = 100;
                    CANWrite(dataToSend);
                    DateTime StartTime = DateTime.Now;
                    while (DateTime.Now.Subtract(StartTime).TotalMilliseconds < timeout)
                    {
                        try
                        {
                            buffer = CANReadLine();
                        }
                        catch (TimeoutException e)
                        {//ignore this error.  It just means that data is not on the line.
                        }
                        catch (Exception ex) { ErrorDesc = ex.ToString(); }
                        if (buffer.Contains(expectedResponse_1stMsg))
                        {
                            int StartPos = buffer.IndexOf(expectedResponse_1stMsg, 0);
                            //Parse out the VIN
                            tempVIN_HEX = buffer.Substring(StartPos + 16, 6);
                            CANWrite(Respone_1stMsg);
                        }
                        if (buffer.Contains(expectedResponse_2ndMsg))
                        {
                            int StartPos = buffer.IndexOf(expectedResponse_2ndMsg, 0);
                            tempVIN_HEX = tempVIN_HEX + buffer.Substring(StartPos + 8, 14);
                        }
                        if (buffer.Contains(expectedResponse_3rdMsg))
                        {
                            int StartPos = buffer.IndexOf(expectedResponse_3rdMsg, 0);
                            tempVIN_HEX = tempVIN_HEX + buffer.Substring(StartPos + 8, 14);
                            string tempVIN_ASCII = ConvertHEXStringToASCII(tempVIN_HEX);
                            PartConfig.VIN = tempVIN_ASCII;
                            ////Write values to log
                            mLog.Write("Read VIN complete. VIN = " + PartConfig.VIN);
                            return true;
                        }
                        Thread.Sleep(10);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorDesc = ex.ToString();
            }

            if (ErrorDesc.Length == 0) ErrorDesc = "Vehicle is not responding to Read VIN.";
            return false;
        }
        public bool CAN_WriteVIN_Conti(ref string ErrorDesc, ContiPartConfigMessage PartConfig)
        {
            //mLog.Write("CAN_WriteSensorIDs SensorID1=" + SensorID1 + "; SensorID2=" + SensorID2 + "; SensorID3=" + SensorID3 + "; SensorID4=" + SensorID4);
            if (mPort == null) { ErrorDesc = "Port Not Initialized"; return false; }
            if (mPort.IsOpen == false) { ErrorDesc = "Port Not Opened"; return false; }
            if (mSendAddr == null) { ErrorDesc = "Send Address not initialized"; return false; }
            if (Connected == false) { ErrorDesc = "CAN ODBII cable not connected"; return false; }

            try
            {
                lock (mSyncLock)
                {

                    string dataToSend_1stMsg;
                    string dataToSend_2ndMsg;
                    string dataToSend_3rdMsg;
                    string Response_1stMsg;

                    //Convert the ASCII VIN into HEX before sending to the ECU.
                    string tmpVIN_HEX = ConvertASCIIStringtoHEX(PartConfig.VIN);
                    string tmpVIN_ASCII = ConvertHEXStringToASCII(tmpVIN_HEX);

                    dataToSend_1stMsg = ":S" + mSendAddr + "N" + "10142EF090" + tmpVIN_HEX.Substring(0, 6) + ";";
                    dataToSend_2ndMsg = ":S" + mSendAddr + "N" + "21" + tmpVIN_HEX.Substring(6, 14) + ";";
                    dataToSend_3rdMsg = ":S" + mSendAddr + "N" + "22" + tmpVIN_HEX.Substring(20, 14) + ";";
                    Response_1stMsg = ":S" + mRecvAddrFilter + "N" + "30010E";

                    int timeout = 2000;//ms
                    //clear the buffer
                    string buffer = CANReadExisting();
                    mPort.ReadTimeout = 100;
                    CANWrite(dataToSend_1stMsg);
                    DateTime StartTime = DateTime.Now;
                    while (DateTime.Now.Subtract(StartTime).TotalMilliseconds < timeout)
                    {
                        try
                        {
                            buffer = CANReadLine();
                            int i = 99;
                        }
                        catch (TimeoutException e)
                        {//ignore this error.  It just means that data is not on the line.
                        }
                        catch (Exception ex) { ErrorDesc = ex.ToString(); }
                        if (buffer.Contains(Response_1stMsg))
                        {
                            CANWrite(dataToSend_2ndMsg);
                            CANWrite(dataToSend_3rdMsg);

                            buffer = CANReadExisting();

                            return true;
                        }
                        Thread.Sleep(10);
                    }
                    ErrorDesc = "Response not received for write VIN.";
                    return false;
                }
            }
            catch (Exception ex)
            {
                ErrorDesc = ex.ToString();
            }

            if (ErrorDesc.Length == 0) ErrorDesc = "Vehicle is not responding to Write VIN.";
            return false;
        }