/// <summary>Creates an instance of a derived class of <see cref="AbstractObdMode" />.</summary>
        /// <param name="elm">A reference to the ELM327 core driver.</param>
        /// <param name="obdModeIdentifier">The OBD mode identifier as a hexadecimal string (i.e., "01", "02", etc.).</param>
        internal AbstractObdMode(ElmDriver elm, string obdModeIdentifier)
        {
            // Note: In the full .NET framework, it would probably be better to tag the derived class with a custom attribute that contained the OBD mode identifier, but that functionality is not
            // currently available in MF

            this.Elm            = elm;
            this.ModeIdentifier = obdModeIdentifier;
        }
Example #2
0
        /// <summary>Attempts to connect to the ECU.</summary>
        /// <param name="protocolType">The protocal type to use.</param>
        /// <param name="measurementUnitType">The measurement type to use.</param>
        public void Connect(ElmDriver.ElmObdProtocolType protocolType, ElmDriver.ElmMeasuringUnitType measurementUnitType)
        {
            this.elm = new ElmDriver(this.serialPortName, protocolType, measurementUnitType);

            switch (elm.Connect())
            {
            case ElmDriver.ElmConnectionResultType.NoConnectionToElm:
                throw new InvalidOperationException("Failed to connect to the ELM327.");

            case ElmDriver.ElmConnectionResultType.NoConnectionToObd:
                throw new InvalidOperationException("Failed to connect to the vehicle's ECU.");

            case ElmDriver.ElmConnectionResultType.Connected:
                this.connected    = true;
                this.protocalType = this.GetFriendlyObdProtocolModeTypeName(this.elm.ProtocolType);
                this.fuelType     = this.GetFriendlyFuelTypeName(this.elm.ObdMode01.FuelType);
                this.vin          = this.elm.ObdMode09.VehicleIdentificationNumber;

                break;
            }
        }
        /// <summary>
        /// Attempts to connect to the ECU. If successful, will retrieve one time information from the ECU.
        /// </summary>
        public void Connect(ElmDriver.ElmObdProtocolType protocolType = ElmDriver.ElmObdProtocolType.Automatic, ElmDriver.ElmMeasuringUnitType measurementUnitType = ElmDriver.ElmMeasuringUnitType.English)
        {
            elm = new ElmDriver(serialPortName, protocolType, measurementUnitType);

            ElmDriver.ElmConnectionResultType connectionResult = elm.Connect();

            if (connectionResult == ElmDriver.ElmConnectionResultType.NoConnectionToElm)
            {
                throw new Exception("Failed to connect to the ELM327");
            }
            else if (connectionResult == ElmDriver.ElmConnectionResultType.NoConnectionToObd)
            {
                throw new Exception("Failed to connect to the vehicle's ECU");
            }
            else
            {
                connected = true;

                // Get the currently used OBD protocol type
                OBDProtocolType = GetFriendlyObdProtocolModeTypeName(elm.ProtocolType);
                VehicleFuelType = GetFriendlyFuelTypeName(elm.ObdMode01.FuelType);
                VIN             = elm.ObdMode09.VehicleIdentificationNumber;
            }
        }
Example #4
0
 /// <summary>
 /// Creates an instance of <see cref="ObdGenericMode01"/>.
 /// </summary>
 /// <param name="elm">A reference to the ELM327 driver.</param>
 internal ObdGenericMode01(ElmDriver elm)
     : base(elm, "01")
 {
 }
 /// <summary>Creates an instance of <see cref="ObdGenericMode09" />.</summary>
 /// <param name="elm">A reference to the ELM327 driver.</param>
 internal ObdGenericMode09(ElmDriver elm)
     : base(elm, "09")
 {
 }
Example #6
0
        public void ReadData()
        {
            try
            {
                Log($"Opening port {_port}...");

                using (var driver = new ElmDriver(_port, ElmDriver.ElmObdProtocolType.Automatic, ElmDriver.ElmMeasuringUnitType.Metric))
                {
                    _lastData = null;
                    Log($"Connecting to OBDII...");

                    var result = driver.Connect();
                    driver.ProtocolType = ElmDriver.ElmObdProtocolType.Iso9141_2;

                    Log($"Connection result = {result}");

                    if (result == ElmDriver.ElmConnectionResultType.Connected)
                    {
                        _lastData = DateTime.UtcNow;

                        /*for (int i = 0; i < 53; i++)
                         * {
                         *  Console.WriteLine($"PID: {i} - {i.ToString("x")}");
                         *
                         *  var response = driver.ObdMode01.GetPidResponse(i.ToString("x"));
                         *  Console.WriteLine("*****************************");
                         *  Console.WriteLine(String.Join(Environment.NewLine, response));
                         * }*/

                        var counter = 0;

                        while (_isRunning)
                        {
                            //var rpm = driver.ObdMode01.EngineRpm;
                            //var temp = driver.ObdMode01.EngineCoolantTemperature;
                            //var intakeManifoldPressure = driver.ObdMode01.IntakeManifoldPressure;

                            //rpm = ;
                            //var engineLoad = driver.ObdMode01.EngineLoad;
                            //var massAirflow = driver.ObdMode01.MassAirFlowRate;



                            var signalKData = new Dictionary <string, Func <int, double?> >
                            {
                                { $"propulsion.engine.{_engineName}.revolutions", c =>
                                  {
                                      var rpm = driver.ObdMode01.EngineRpm;

                                      if (rpm == 0.0)
                                      {
                                          return(null);
                                      }

                                      Log($"RPM={rpm}");
                                      return(RoundToTen(rpm) / 60.0);
                                  } },
                                { $"propulsion.engine.{_engineName}.temperature", c =>
                                  {
                                      if (c % 5 == 0)
                                      {
                                          var temp = driver.ObdMode01.EngineCoolantTemperature;

                                          if (temp == 0.0)
                                          {
                                              return(null);
                                          }

                                          return(Math.Round(temp + 273.15));
                                      }

                                      return(null);
                                  } },
                                { $"propulsion.engine.{_engineName}.boostPressure", c =>
                                  {
                                      if (c % 5 == 0)
                                      {
                                          var pressure = driver.ObdMode01.IntakeManifoldPressure;

                                          if (pressure == 0.0)
                                          {
                                              return(null);
                                          }

                                          return(Math.Round(pressure * 1000.0));
                                      }

                                      return(null);
                                  } }
                            };

                            counter++;

                            if (counter > 100000)
                            {
                                counter = 0;
                            }

                            var data = signalKData.Select(k => new { key = k.Key, value = k.Value(counter) })
                                       .Where(k => k.value != null)
                                       .ToDictionary(k => k.key, v => (object)v.value.Value);

                            var line = $"{DateTime.Now.ToShortTimeString()}\t{string.Join(";", data.Select(i => $"{i.Key}={i.Value}"))}, Last data: {(_lastData != null ? (DateTime.UtcNow - _lastData.Value).ToString() : "never")}";

                            Log(line);

                            if (data.Any(i => i.Value != null))
                            {
                                _lastData = DateTime.UtcNow;
                            }


                            SendToSignalK(data);

                            Thread.Sleep(_readInterval);

                            if (_lastData != null && _lastData.Value.AddMilliseconds(_noDataTimeout) < DateTime.UtcNow)
                            {
                                Log($"Connection timeout, disconnecting...");
                                break;
                            }
                        }
                    }
                    else
                    {
                        Log($"Connection failed: {result}");
                    }
                }
            }
            catch (Exception ex)
            {
                Log($"Reader failed: {ex}");
            }
        }