diff --git a/Source/Meadow.Foundation.Core/Simulation/SimulatedTemperatureSensor.cs b/Source/Meadow.Foundation.Core/Simulation/SimulatedTemperatureSensor.cs index 781a7ddb4..5ed40eb3a 100644 --- a/Source/Meadow.Foundation.Core/Simulation/SimulatedTemperatureSensor.cs +++ b/Source/Meadow.Foundation.Core/Simulation/SimulatedTemperatureSensor.cs @@ -131,7 +131,7 @@ public void StartUpdating(TimeSpan? updateInterval = null) { UpdateInterval = updateInterval ?? TimeSpan.FromSeconds(1); IsSampling = true; - _reportTimer = new Timer(ReportTimerProc, null, updateInterval!.Value, updateInterval.Value); + _reportTimer = new Timer(ReportTimerProc, null, UpdateInterval, UpdateInterval); } /// diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Body.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Body.cs new file mode 100644 index 000000000..eba4bae69 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Body.cs @@ -0,0 +1,13 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public partial class Dtc +{ + private string GetReadableBodyErrorCode(int code) + { + return code switch + { + // TODO + _ => $"B{code:N4}" + }; + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Chassis.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Chassis.cs new file mode 100644 index 000000000..3ebf7f85a --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Chassis.cs @@ -0,0 +1,13 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public partial class Dtc +{ + private string GetReadableChassisErrorCode(int code) + { + return code switch + { + // TODO + _ => $"C{code:N4}" + }; + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Network.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Network.cs new file mode 100644 index 000000000..c15f7f279 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Network.cs @@ -0,0 +1,13 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public partial class Dtc +{ + private string GetReadableNetworkErrorCode(int code) + { + return code switch + { + // TODO + _ => $"U{code:N4}" + }; + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Powertrain.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Powertrain.cs new file mode 100644 index 000000000..f1f85784d --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.Powertrain.cs @@ -0,0 +1,626 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public partial class Dtc +{ + private string GetReadablePowertrainErrorCode(int code) + { + return code switch + { + 1 => "Fuel Volume Regulator Control Circuit / Open", + 2 => "Fuel Volume Regulator Control Circuit Range / Performance", + 3 => "Fuel Volume Regulator Control Circuit Low", + 4 => "Fuel Volume Regulator Control Circuit High", + 5 => "Fuel Shutoff Valve Control Circuit / Open", + 6 => "Fuel Shutoff Valve Control Circuit Low", + 7 => "Fuel Shutoff Valve Control Circuit High", + 8 => "Fuel Shutoff Valve Control Circuit Intermittent", + 9 => "Fuel Pressure Regulator 1 Performance", + 10 => "Intake Valve Control Solenoid Circuit", + 11 => "Intake Valve Timing Control Performance", + 12 => "Camshaft Position Timing Over-Retarded", + 13 => "Exhaust Valve Control Solenoid Circuit", + 14 => "Exhaust Valve Timing Control Performance", + 15 => "Camshaft Position Timing Over-Advanced", + 16 => "Crankshaft Position - Camshaft Position Correlation", + 17 => "Camshaft Position Timing Over-Retarded Bank 1", + 18 => "Crankshaft Position - Camshaft Position Correlation Bank 2", + 19 => "Camshaft Position Timing Over-Retarded Bank 2", + 20 => "Intake Valve Control Solenoid Circuit Bank 2", + 21 => "Intake Valve Timing Control Performance Bank 2", + 22 => "Camshaft Position Timing Over-Retarded Bank 2", + 23 => "Exhaust Valve Control Solenoid Circuit Bank 2", + 24 => "Exhaust Valve Timing Control Performance Bank 2", + 25 => "Camshaft Position Timing Over-Advanced Bank 2", + 26 => "Intake Valve Control Solenoid Circuit Range / Performance", + 27 => "Exhaust Valve Control Solenoid Circuit Range / Performance", + 28 => "Intake Valve Control Solenoid Circuit Range / Performance Bank 2", + 29 => "Exhaust Valve Control Solenoid Circuit Range / Performance Bank 2", + 30 => "Heated Oxygen Sensor (HO2S) Heater Control Circuit", + 31 => "HO2S Heater Control Circuit Low", + 32 => "HO2S Heater Control Circuit High", + 33 => "Turbocharger Bypass Valve Control Circuit", + 34 => "Turbocharger Bypass Valve Control Circuit Low", + 35 => "Turbocharger Bypass Valve Control Circuit High", + 36 => "HO2S Heater Control Circuit Bank 1 Sensor 2", + 37 => "HO2S Heater Control Circuit Low Bank 1 Sensor 2", + 38 => "HO2S Heater Control Circuit High Bank 1 Sensor 2", + 39 => "HO2S Heater Control Circuit Bank 2 Sensor 2", + 40 => "HO2S Heater Control Circuit Low Bank 2 Sensor 2", + 41 => "HO2S Heater Control Circuit High Bank 2 Sensor 2", + 42 => "HO2S Heater Control Circuit Bank 1 Sensor 3", + 43 => "HO2S Heater Control Circuit Low Bank 1 Sensor 3", + 44 => "HO2S Heater Control Circuit High Bank 1 Sensor 3", + 45 => "HO2S Heater Control Circuit Bank 2 Sensor 3", + 46 => "HO2S Heater Control Circuit Low Bank 2 Sensor 3", + 47 => "HO2S Heater Control Circuit High Bank 2 Sensor 3", + 48 => "Manifold Absolute Pressure / Barometric Pressure Circuit", + 49 => "Manifold Absolute Pressure / Barometric Pressure Circuit Range / Performance", + 50 => "Manifold Absolute Pressure / Barometric Pressure Circuit Low", + 51 => "Manifold Absolute Pressure / Barometric Pressure Circuit High", + 52 => "Manifold Absolute Pressure / Barometric Pressure Circuit Intermittent", + 53 => "Oxygen Sensor Circuit", + 54 => "Oxygen Sensor Circuit Low Voltage", + 55 => "Oxygen Sensor Circuit High Voltage", + 56 => "Oxygen Sensor Circuit Intermittent", + 57 => "Oxygen Sensor Heater Circuit", + 58 => "Oxygen Sensor Heater Circuit Low", + 59 => "Oxygen Sensor Heater Circuit High", + 60 => "Manifold Absolute Pressure / Barometric Pressure Circuit Low Input", + 61 => "ECT Sensor Circuit", + 62 => "ECT Sensor Circuit Low", + 63 => "ECT Sensor Circuit High", + 64 => "ECT Sensor Circuit Intermittent", + 65 => "Cylinder 1 Misfire Detected", + 66 => "Cylinder 2 Misfire Detected", + 67 => "Cylinder 3 Misfire Detected", + 68 => "Cylinder 4 Misfire Detected", + 69 => "Cylinder 5 Misfire Detected", + 70 => "Cylinder 6 Misfire Detected", + 71 => "Cylinder 7 Misfire Detected", + 72 => "Cylinder 8 Misfire Detected", + 73 => "Random/Multiple Cylinder Misfire Detected", + 74 => "System Too Lean (Bank 1)", + 75 => "System Too Rich (Bank 1)", + 76 => "System Too Lean (Bank 2)", + 77 => "System Too Rich (Bank 2)", + 78 => "Throttle/Pedal Position Sensor/Switch A Circuit", + 79 => "Throttle/Pedal Position Sensor/Switch A Circuit Low", + 80 => "Throttle/Pedal Position Sensor/Switch A Circuit High", + 81 => "Throttle/Pedal Position Sensor/Switch B Circuit", + 82 => "Throttle/Pedal Position Sensor/Switch B Circuit Low", + 83 => "Throttle/Pedal Position Sensor/Switch B Circuit High", + 84 => "Throttle/Pedal Position Sensor/Switch C Circuit", + 85 => "Throttle/Pedal Position Sensor/Switch C Circuit Low", + 86 => "Throttle/Pedal Position Sensor/Switch C Circuit High", + 87 => "Throttle/Pedal Position Sensor/Switch D Circuit", + 88 => "Throttle/Pedal Position Sensor/Switch D Circuit Low", + 89 => "Throttle/Pedal Position Sensor/Switch D Circuit High", + 90 => "Throttle/Pedal Position Sensor/Switch E Circuit", + 91 => "Throttle/Pedal Position Sensor/Switch E Circuit Low", + 92 => "Throttle/Pedal Position Sensor/Switch E Circuit High", + 93 => "Throttle/Pedal Position Sensor/Switch F Circuit", + 94 => "Throttle/Pedal Position Sensor/Switch F Circuit Low", + 95 => "Throttle/Pedal Position Sensor/Switch F Circuit High", + 96 => "Evaporative Emission System Leak Detected (large leak)", + 97 => "Evaporative Emission System Leak Detected (small leak)", + 98 => "Evaporative Emission System Pressure Sensor/Switch Range/Performance", + 99 => "Evaporative Emission System Pressure Sensor/Switch Low", + 100 => "Evaporative Emission System Pressure Sensor/Switch High", + 101 => "Fuel Level Sensor Circuit", + 102 => "Fuel Level Sensor Circuit Low", + 103 => "Fuel Level Sensor Circuit High", + 104 => "Fuel Level Sensor Circuit Intermittent", + 105 => "Fuel Rail Pressure Sensor Circuit", + 106 => "Fuel Rail Pressure Sensor Circuit Range/Performance", + 107 => "Fuel Rail Pressure Sensor Circuit Low", + 108 => "Fuel Rail Pressure Sensor Circuit High", + 109 => "Fuel Rail Pressure Sensor Circuit Intermittent", + 110 => "Fuel Temperature Sensor A Circuit", + 111 => "Fuel Temperature Sensor A Circuit Range/Performance", + 112 => "Fuel Temperature Sensor A Circuit Low", + 113 => "Fuel Temperature Sensor A Circuit High", + 114 => "Fuel Temperature Sensor A Circuit Intermittent", + 115 => "Fuel Temperature Sensor B Circuit", + 116 => "Fuel Temperature Sensor B Circuit Range/Performance", + 117 => "Fuel Temperature Sensor B Circuit Low", + 118 => "Fuel Temperature Sensor B Circuit High", + 119 => "Fuel Temperature Sensor B Circuit Intermittent", + 120 => "Intake Air Temperature Sensor 1 Circuit", + 121 => "Intake Air Temperature Sensor 1 Circuit Range/Performance", + 122 => "Intake Air Temperature Sensor 1 Circuit Low", + 123 => "Intake Air Temperature Sensor 1 Circuit High", + 124 => "Intake Air Temperature Sensor 1 Circuit Intermittent", + 125 => "Intake Air Temperature Sensor 2 Circuit", + 126 => "Intake Air Temperature Sensor 2 Circuit Range/Performance", + 127 => "Intake Air Temperature Sensor 2 Circuit Low", + 128 => "Intake Air Temperature Sensor 2 Circuit High", + 129 => "Intake Air Temperature Sensor 2 Circuit Intermittent", + 130 => "Manifold Air Temperature Sensor Circuit", + 131 => "Manifold Air Temperature Sensor Circuit Range/Performance", + 132 => "Manifold Air Temperature Sensor Circuit Low", + 133 => "Manifold Air Temperature Sensor Circuit High", + 134 => "Manifold Air Temperature Sensor Circuit Intermittent", + 135 => "O2 Sensor Heater Circuit", + 136 => "O2 Sensor Heater Circuit Low", + 137 => "O2 Sensor Heater Circuit High", + 138 => "O2 Sensor Heater Circuit Malfunction", + 139 => "Catalyst Temperature Sensor Circuit", + 140 => "Catalyst Temperature Sensor Circuit Range/Performance", + 141 => "Catalyst Temperature Sensor Circuit Low", + 142 => "Catalyst Temperature Sensor Circuit High", + 143 => "Catalyst Temperature Sensor Circuit Intermittent", + 144 => "Turbocharger Boost Control Position Sensor Circuit", + 145 => "Turbocharger Boost Control Position Sensor Circuit Range/Performance", + 146 => "Turbocharger Boost Control Position Sensor Circuit Low", + 147 => "Turbocharger Boost Control Position Sensor Circuit High", + 148 => "Turbocharger Boost Control Position Sensor Circuit Intermittent", + 149 => "Wastegate Regulator Valve Control Circuit", + 150 => "Wastegate Regulator Valve Control Circuit Range/Performance", + 151 => "Wastegate Regulator Valve Control Circuit Low", + 152 => "Wastegate Regulator Valve Control Circuit High", + 153 => "Throttle Actuator Control Module", + 154 => "Throttle Actuator Control Module Circuit Range/Performance", + 155 => "Throttle Actuator Control Module Circuit Low", + 156 => "Throttle Actuator Control Module Circuit High", + 157 => "Throttle Actuator Control Module Circuit Intermittent", + 158 => "Throttle Actuator Control Module Throttle Body Angle Sensor Circuit", + 159 => "Throttle Actuator Control Module Throttle Body Angle Sensor Circuit Range/Performance", + 160 => "Throttle Actuator Control Module Throttle Body Angle Sensor Circuit Low", + 161 => "Throttle Actuator Control Module Throttle Body Angle Sensor Circuit High", + 162 => "Throttle Actuator Control Module Throttle Body Angle Sensor Circuit Intermittent", + 163 => "Throttle Actuator Control Motor Circuit", + 164 => "Throttle Actuator Control Motor Circuit Range/Performance", + 165 => "Throttle Actuator Control Motor Circuit Low", + 166 => "Throttle Actuator Control Motor Circuit High", + 167 => "Throttle Actuator Control Motor Circuit Intermittent", + 168 => "Throttle Control Position Sensor A Circuit", + 169 => "Throttle Control Position Sensor A Circuit Range/Performance", + 170 => "Throttle Control Position Sensor A Circuit Low", + 171 => "Throttle Control Position Sensor A Circuit High", + 172 => "Throttle Control Position Sensor A Circuit Intermittent", + 173 => "Throttle Control Position Sensor B Circuit", + 174 => "Throttle Control Position Sensor B Circuit Range/Performance", + 175 => "Throttle Control Position Sensor B Circuit Low", + 176 => "Throttle Control Position Sensor B Circuit High", + 177 => "Throttle Control Position Sensor B Circuit Intermittent", + 178 => "Throttle Control Position Sensor C Circuit", + 179 => "Throttle Control Position Sensor C Circuit Range/Performance", + 180 => "Throttle Control Position Sensor C Circuit Low", + 181 => "Throttle Control Position Sensor C Circuit High", + 182 => "Throttle Control Position Sensor C Circuit Intermittent", + 183 => "Throttle Control Position Sensor D Circuit", + 184 => "Throttle Control Position Sensor D Circuit Range/Performance", + 185 => "Throttle Control Position Sensor D Circuit Low", + 186 => "Throttle Control Position Sensor D Circuit High", + 187 => "Throttle Control Position Sensor D Circuit Intermittent", + 188 => "Throttle Control Position Sensor E Circuit", + 189 => "Throttle Control Position Sensor E Circuit Range/Performance", + 190 => "Throttle Control Position Sensor E Circuit Low", + 191 => "Throttle Control Position Sensor E Circuit High", + 192 => "Throttle Control Position Sensor E Circuit Intermittent", + 193 => "Throttle Control Position Sensor F Circuit", + 194 => "Throttle Control Position Sensor F Circuit Range/Performance", + 195 => "Throttle Control Position Sensor F Circuit Low", + 196 => "Throttle Control Position Sensor F Circuit High", + 197 => "Throttle Control Position Sensor F Circuit Intermittent", + 198 => "Fuel Rail Pressure Sensor B Circuit", + 199 => "Fuel Rail Pressure Sensor B Circuit Range/Performance", + 200 => "Fuel Rail Pressure Sensor B Circuit Low", + 201 => "Fuel Rail Pressure Sensor B Circuit High", + 202 => "Fuel Rail Pressure Sensor B Circuit Intermittent", + 203 => "Fuel Rail Pressure Sensor A Circuit", + 204 => "Fuel Rail Pressure Sensor A Circuit Range/Performance", + 205 => "Fuel Rail Pressure Sensor A Circuit Low", + 206 => "Fuel Rail Pressure Sensor A Circuit High", + 207 => "Fuel Rail Pressure Sensor A Circuit Intermittent", + 208 => "Fuel Rail Pressure Sensor Circuit", + 209 => "Fuel Rail Pressure Sensor Circuit Range/Performance", + 210 => "Fuel Rail Pressure Sensor Circuit Low", + 211 => "Fuel Rail Pressure Sensor Circuit High", + 212 => "Fuel Rail Pressure Sensor Circuit Intermittent", + 213 => "Fuel Pressure Sensor Circuit", + 214 => "Fuel Pressure Sensor Circuit Range/Performance", + 215 => "Fuel Pressure Sensor Circuit Low", + 216 => "Fuel Pressure Sensor Circuit High", + 217 => "Fuel Pressure Sensor Circuit Intermittent", + 218 => "Fuel Pump Control Module", + 219 => "Fuel Pump Control Module Circuit Range/Performance", + 220 => "Fuel Pump Control Module Circuit Low", + 221 => "Fuel Pump Control Module Circuit High", + 222 => "Fuel Pump Control Module Circuit Intermittent", + 223 => "Fuel Pump Control Circuit", + 224 => "Fuel Pump Control Circuit Range/Performance", + 225 => "Fuel Pump Control Circuit Low", + 226 => "Fuel Pump Control Circuit High", + 227 => "Fuel Pump Control Circuit Intermittent", + 228 => "Fuel Pump Relay Control Circuit", + 229 => "Fuel Pump Relay Control Circuit Range/Performance", + 230 => "Fuel Pump Relay Control Circuit Low", + 231 => "Fuel Pump Relay Control Circuit High", + 232 => "Fuel Pump Relay Control Circuit Intermittent", + 233 => "Secondary Air Injection System Control A Circuit", + 234 => "Secondary Air Injection System Control A Circuit Range/Performance", + 235 => "Secondary Air Injection System Control A Circuit Low", + 236 => "Secondary Air Injection System Control A Circuit High", + 237 => "Secondary Air Injection System Control A Circuit Intermittent", + 238 => "Secondary Air Injection System Control B Circuit", + 239 => "Secondary Air Injection System Control B Circuit Range/Performance", + 240 => "Secondary Air Injection System Control B Circuit Low", + 241 => "Secondary Air Injection System Control B Circuit High", + 242 => "Secondary Air Injection System Control B Circuit Intermittent", + 243 => "Secondary Air Injection System Pressure Sensor Circuit", + 244 => "Secondary Air Injection System Pressure Sensor Circuit Range/Performance", + 245 => "Secondary Air Injection System Pressure Sensor Circuit Low", + 246 => "Secondary Air Injection System Pressure Sensor Circuit High", + 247 => "Secondary Air Injection System Pressure Sensor Circuit Intermittent", + 248 => "Secondary Air Injection System Circuit", + 249 => "Secondary Air Injection System Circuit Range/Performance", + 250 => "Secondary Air Injection System Circuit Low", + 251 => "Secondary Air Injection System Circuit High", + 252 => "Secondary Air Injection System Circuit Intermittent", + 253 => "Fuel Trim Cylinder Balance", + 254 => "System Too Lean at Idle", + 255 => "System Too Rich at Idle", + 256 => "Throttle/Pedal Position Sensor/Switch A/B Voltage Correlation", + 257 => "Throttle/Pedal Position Sensor/Switch A/C Voltage Correlation", + 258 => "Throttle/Pedal Position Sensor/Switch A/D Voltage Correlation", + 259 => "Throttle/Pedal Position Sensor/Switch A/E Voltage Correlation", + 260 => "Throttle/Pedal Position Sensor/Switch A/F Voltage Correlation", + 261 => "Throttle/Pedal Position Sensor/Switch B/C Voltage Correlation", + 262 => "Throttle/Pedal Position Sensor/Switch B/D Voltage Correlation", + 263 => "Throttle/Pedal Position Sensor/Switch B/E Voltage Correlation", + 264 => "Throttle/Pedal Position Sensor/Switch B/F Voltage Correlation", + 265 => "Throttle/Pedal Position Sensor/Switch C/D Voltage Correlation", + 266 => "Throttle/Pedal Position Sensor/Switch C/E Voltage Correlation", + 267 => "Throttle/Pedal Position Sensor/Switch C/F Voltage Correlation", + 268 => "Throttle/Pedal Position Sensor/Switch D/E Voltage Correlation", + 269 => "Throttle/Pedal Position Sensor/Switch D/F Voltage Correlation", + 270 => "Throttle/Pedal Position Sensor/Switch E/F Voltage Correlation", + 271 => "Cylinder Deactivation System - Bank 1", + 272 => "Cylinder Deactivation System - Bank 2", + 273 => "Fuel Rail Pressure Sensor In-Range Too High", + 274 => "Fuel Rail Pressure Sensor In-Range Too Low", + 275 => "Throttle Control System - Forced Engine Shutdown", + 276 => "Throttle Control System - Forced Limited Power", + 277 => "Throttle Control System - Power Limiting Throttle Not Open", + 278 => "Throttle Control System - Cruise Control/Speed Limiter Inhibit", + 279 => "Throttle Control System - High Air Flow Detected", + 280 => "Throttle Control System - Low Air Flow Detected", + 281 => "Throttle Control System - Power Limiting Forced Limited Power", + 282 => "Throttle Control System - Power Limiting Forced Engine Shutdown", + 283 => "Throttle Control System - Power Limiting System Deactivated", + 284 => "Throttle Control System - Power Limiting Data Invalid", + 285 => "Throttle Control System - Power Limiting Data Valid But Above Normal", + 286 => "Throttle Control System - Power Limiting Data Valid But Below Normal", + 287 => "Throttle Control System - Power Limiting No DTCs Present", + 288 => "Throttle Control System - Power Limiting No DTCs Present And Not Commanded Open", + 289 => "Throttle Control System - Power Limiting Set Maximum RPM", + 290 => "Throttle Control System - Power Limiting Set Maximum Throttle Position", + 291 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 1", + 292 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 2", + 293 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 3", + 294 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 4", + 295 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 5", + 296 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 6", + 297 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 7", + 298 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 8", + 299 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 9", + 300 => "Throttle Control System - Power Limiting Set Maximum Throttle Position Sensor 10", + 301 => "Cylinder 1 Misfire Detected", + 302 => "Cylinder 2 Misfire Detected", + 303 => "Cylinder 3 Misfire Detected", + 304 => "Cylinder 4 Misfire Detected", + 305 => "Cylinder 5 Misfire Detected", + 306 => "Cylinder 6 Misfire Detected", + 307 => "Cylinder 7 Misfire Detected", + 308 => "Cylinder 8 Misfire Detected", + 309 => "Cylinder 9 Misfire Detected", + 310 => "Cylinder 10 Misfire Detected", + 311 => "Cylinder 11 Misfire Detected", + 312 => "Cylinder 12 Misfire Detected", + 313 => "Crankshaft Position - Camshaft Position Correlation", + 314 => "Cylinder 3 Misfire Detected", + 315 => "Crankshaft Position - Camshaft Position Correlation Bank 2 Sensor A", + 316 => "Crankshaft Position - Camshaft Position Correlation Bank 2 Sensor B", + 317 => "Engine Misfire Detected With Low Fuel Level", + 318 => "Engine Misfire Detected - Fuel Trim Too Lean", + 319 => "Engine Misfire Detected - Fuel Trim Too Rich", + 320 => "Crankshaft Position - Camshaft Position Correlation Bank 1 Sensor A", + 321 => "Crankshaft Position - Camshaft Position Correlation Bank 1 Sensor B", + 322 => "Crankshaft Position - Camshaft Position Correlation Bank 2 Sensor A", + 323 => "Crankshaft Position - Camshaft Position Correlation Bank 2 Sensor B", + 324 => "Exhaust Gas Recirculation Control Circuit", + 325 => "Exhaust Gas Recirculation Control Circuit Range/Performance", + 326 => "Exhaust Gas Recirculation Control Circuit Low", + 327 => "Exhaust Gas Recirculation Control Circuit High", + 328 => "Exhaust Gas Recirculation Control Circuit Intermittent", + 329 => "Idle Control System - RPM Higher Than Expected", + 330 => "Idle Control System - RPM Lower Than Expected", + 331 => "Idle Control System - Not Reaching Desired RPM", + 332 => "Idle Control System - Not Maintaining Desired RPM", + 333 => "Idle Control System - Unable to Control RPM", + 334 => "Idle Control System - Forced Limited RPM", + 335 => "Idle Control System - Unable to Achieve Desired RPM", + 336 => "Crankshaft Position Sensor A Circuit Range/Performance", + 337 => "Crankshaft Position Sensor A Circuit Low", + 338 => "Crankshaft Position Sensor A Circuit High", + 339 => "Crankshaft Position Sensor A Circuit Intermittent", + 340 => "Camshaft Position Sensor A Circuit Range/Performance", + 341 => "Camshaft Position Sensor A Circuit Low", + 342 => "Camshaft Position Sensor A Circuit High", + 343 => "Camshaft Position Sensor A Circuit Intermittent", + 344 => "Camshaft Position Sensor B Circuit Range/Performance", + 345 => "Camshaft Position Sensor B Circuit Low", + 346 => "Camshaft Position Sensor B Circuit High", + 347 => "Camshaft Position Sensor B Circuit Intermittent", + 348 => "Camshaft Position Sensor C Circuit Range/Performance", + 349 => "Camshaft Position Sensor C Circuit Low", + 350 => "Camshaft Position Sensor C Circuit High", + 351 => "Ignition Coil A Primary/Secondary Circuit", + 352 => "Ignition Coil B Primary/Secondary Circuit", + 353 => "Ignition Coil C Primary/Secondary Circuit", + 354 => "Ignition Coil D Primary/Secondary Circuit", + 355 => "Ignition Coil E Primary/Secondary Circuit", + 356 => "Ignition Coil F Primary/Secondary Circuit", + 357 => "Ignition Coil G Primary/Secondary Circuit", + 358 => "Ignition Coil H Primary/Secondary Circuit", + 359 => "Ignition Coil I Primary/Secondary Circuit", + 360 => "Ignition Coil J Primary/Secondary Circuit", + 361 => "Ignition Coil K Primary/Secondary Circuit", + 362 => "Ignition Coil L Primary/Secondary Circuit", + 363 => "Ignition Coil M Primary/Secondary Circuit", + 364 => "Ignition Coil N Primary/Secondary Circuit", + 365 => "Ignition Coil O Primary/Secondary Circuit", + 366 => "Ignition Coil P Primary/Secondary Circuit", + 367 => "Knock Sensor 1 Circuit", + 368 => "Knock Sensor 1 Circuit Range/Performance", + 369 => "Knock Sensor 1 Circuit Low", + 370 => "Knock Sensor 1 Circuit High", + 371 => "Knock Sensor 1 Circuit Intermittent", + 372 => "Knock Sensor 2 Circuit", + 373 => "Knock Sensor 2 Circuit Range/Performance", + 374 => "Knock Sensor 2 Circuit Low", + 375 => "Knock Sensor 2 Circuit High", + 376 => "Knock Sensor 2 Circuit Intermittent", + 377 => "Knock Sensor 3 Circuit", + 378 => "Knock Sensor 3 Circuit Range/Performance", + 379 => "Knock Sensor 3 Circuit Low", + 380 => "Glow Plug/Heater Circuit A", + 381 => "Glow Plug/Heater Circuit B", + 382 => "Glow Plug/Heater Circuit C", + 383 => "Glow Plug/Heater Circuit D", + 384 => "Glow Plug/Heater Circuit E", + 385 => "Glow Plug/Heater Circuit F", + 386 => "Glow Plug/Heater Circuit G", + 387 => "Glow Plug/Heater Circuit H", + 388 => "Glow Plug/Heater Circuit I", + 389 => "Glow Plug/Heater Circuit J", + 390 => "Glow Plug/Heater Circuit K", + 391 => "Glow Plug/Heater Circuit L", + 392 => "Glow Plug/Heater Circuit M", + 393 => "Glow Plug/Heater Circuit N", + 394 => "Glow Plug/Heater Circuit O", + 395 => "Glow Plug/Heater Circuit P", + 396 => "Engine Oil Temperature Sensor Range/Performance", + 397 => "Engine Oil Temperature Sensor Low", + 398 => "Engine Oil Temperature Sensor High", + 399 => "Engine Oil Temperature Sensor Intermittent", + 400 => "Turbocharger/Supercharger Boost Control A Circuit", + 401 => "Turbocharger/Supercharger Boost Control A Circuit Range/Performance", + 402 => "Turbocharger/Supercharger Boost Control A Circuit Low", + 403 => "Turbocharger/Supercharger Boost Control A Circuit High", + 404 => "Turbocharger/Supercharger Boost Control A Circuit Intermittent", + 405 => "Turbocharger/Supercharger Boost Control B Circuit", + 406 => "Turbocharger/Supercharger Boost Control B Circuit Range/Performance", + 407 => "Turbocharger/Supercharger Boost Control B Circuit Low", + 408 => "Turbocharger/Supercharger Boost Control B Circuit High", + 409 => "Turbocharger/Supercharger Boost Control B Circuit Intermittent", + 410 => "Exhaust Gas Recirculation Sensor A Circuit", + 411 => "Exhaust Gas Recirculation Sensor A Circuit Range/Performance", + 412 => "Exhaust Gas Recirculation Sensor A Circuit Low", + 413 => "Exhaust Gas Recirculation Sensor A Circuit High", + 414 => "Exhaust Gas Recirculation Sensor A Circuit Intermittent", + 415 => "Exhaust Gas Recirculation Sensor B Circuit", + 416 => "Exhaust Gas Recirculation Sensor B Circuit Range/Performance", + 417 => "Exhaust Gas Recirculation Sensor B Circuit Low", + 418 => "Exhaust Gas Recirculation Sensor B Circuit High", + 419 => "Exhaust Gas Recirculation Sensor B Circuit Intermittent", + 420 => "Catalyst System Efficiency Below Threshold (Bank 1)", + 421 => "Warm Up Catalyst Efficiency Below Threshold (Bank 2)", + 422 => "Main Catalyst Efficiency Below Threshold (Bank 1)", + 423 => "Main Catalyst Efficiency Below Threshold (Bank 2)", + 424 => "Heated Catalyst Efficiency Below Threshold (Bank 1)", + 425 => "Heated Catalyst Efficiency Below Threshold (Bank 2)", + 426 => "Low Temperature Catalyst Efficiency Below Threshold (Bank 1)", + 427 => "Low Temperature Catalyst Efficiency Below Threshold (Bank 2)", + 428 => "Heated Catalyst Temperature Below Threshold (Bank 1)", + 429 => "Heated Catalyst Temperature Below Threshold (Bank 2)", + 430 => "Catalyst Temperature Sensor Circuit Range/Performance (Bank 1)", + 431 => "Catalyst Temperature Sensor Circuit Range/Performance (Bank 2)", + 432 => "Catalyst Temperature Sensor Circuit Low (Bank 1)", + 433 => "Catalyst Temperature Sensor Circuit Low (Bank 2)", + 434 => "Catalyst Temperature Sensor Circuit High (Bank 1)", + 435 => "Catalyst Temperature Sensor Circuit High (Bank 2)", + 436 => "Exhaust Gas Recirculation Sensor C Circuit", + 437 => "Exhaust Gas Recirculation Sensor C Circuit Range/Performance", + 438 => "Exhaust Gas Recirculation Sensor C Circuit Low", + 439 => "Exhaust Gas Recirculation Sensor C Circuit High", + 440 => "Evaporative Emission Control System", + 441 => "Evaporative Emission Control System Incorrect Purge Flow", + 442 => "Evaporative Emission Control System Leak Detected (small leak)", + 443 => "Evaporative Emission Control System Leak Detected (large leak)", + 444 => "Evaporative Emission Control System Purge Control Valve Circuit", + 445 => "Evaporative Emission Control System Purge Control Valve Circuit Shorted", + 446 => "Evaporative Emission Control System Vent Control Circuit", + 447 => "Evaporative Emission Control System Vent Control Circuit Open", + 448 => "Evaporative Emission Control System Vent Control Circuit Shorted", + 449 => "Evaporative Emission Control System Vent Valve/Solenoid Circuit", + 450 => "Evaporative Emission Control System Vent Valve/Solenoid Circuit Malfunction", + 451 => "Evaporative Emission Control System Pressure Sensor/Switch Range/Performance", + 452 => "Evaporative Emission Control System Pressure Sensor/Switch Low", + 453 => "Evaporative Emission Control System Pressure Sensor/Switch High", + 454 => "Evaporative Emission Control System Pressure Sensor/Switch Intermittent", + 455 => "Evaporative Emission Control System Leak Detected (gross leak)", + 456 => "Evaporative Emission Control System Leak Detected (very small leak)", + 457 => "Evaporative Emission Control System Leak Detected (fuel cap loose/off)", + 458 => "Evaporative Emission Control System Leak Detected (fuel cap loose/off, very small leak)", + 459 => "Evaporative Emission Control System Pressure Sensor Range/Performance", + 460 => "Evaporative Emission Control System Pressure Sensor Low", + 461 => "Evaporative Emission Control System Pressure Sensor High", + 462 => "Evaporative Emission Control System Pressure Sensor Intermittent", + 463 => "Fuel Level Sensor A Circuit High Input", + 464 => "Fuel Level Sensor A Circuit Low Input", + 465 => "Fuel Level Sensor A Circuit Intermittent/Erratic", + 466 => "Fuel Level Sensor B Circuit High Input", + 467 => "Fuel Level Sensor B Circuit Low Input", + 468 => "Fuel Level Sensor B Circuit Intermittent/Erratic", + 469 => "Throttle Position Sensor D Circuit", + 470 => "Throttle Position Sensor D Circuit Range/Performance", + 471 => "Throttle Position Sensor D Circuit Low", + 472 => "Throttle Position Sensor D Circuit High", + 473 => "Throttle Position Sensor D Circuit Intermittent", + 474 => "Throttle Position Sensor E Circuit", + 475 => "Throttle Position Sensor E Circuit Range/Performance", + 476 => "Throttle Position Sensor E Circuit Low", + 477 => "Throttle Position Sensor E Circuit High", + 478 => "Throttle Position Sensor E Circuit Intermittent", + 479 => "Throttle Position Sensor F Circuit", + 480 => "Throttle Position Sensor F Circuit Range/Performance", + 481 => "Throttle Position Sensor F Circuit Low", + 482 => "Throttle Position Sensor F Circuit High", + 483 => "Throttle Position Sensor F Circuit Intermittent", + 484 => "Throttle Actuator Control Range/Performance", + 485 => "Throttle Actuator Control Low Air Flow Detected", + 486 => "Throttle Actuator Control High Air Flow Detected", + 487 => "Throttle Actuator Control Throttle Position Low", + 488 => "Throttle Actuator Control Throttle Position High", + 489 => "Throttle Actuator Control Throttle Position Range/Performance", + 490 => "Throttle Actuator Control Throttle Position Lower Than Expected", + 491 => "Throttle Actuator Control Throttle Position Higher Than Expected", + 492 => "Throttle Actuator Control Throttle Position Sensor A", + 493 => "Throttle Actuator Control Throttle Position Sensor B", + 494 => "Throttle Actuator Control Throttle Position Sensor C", + 495 => "Throttle Actuator Control Throttle Position Sensor D", + 496 => "Throttle Actuator Control Throttle Position Sensor E", + 497 => "Throttle Actuator Control Throttle Position Sensor F", + 498 => "Throttle Actuator Control Forced Idle", + 499 => "Throttle Actuator Control System - Voltage Low", + 500 => "Throttle Actuator Control System - Voltage High", + 501 => "Fuel Rail Pressure Sensor A Circuit", + 502 => "Fuel Rail Pressure Sensor A Circuit Range/Performance", + 503 => "Fuel Rail Pressure Sensor A Circuit Low", + 504 => "Fuel Rail Pressure Sensor A Circuit High", + 505 => "Idle Control System Circuit", + 506 => "Idle Control System Circuit Range/Performance", + 507 => "Idle Control System Circuit Low", + 508 => "Idle Control System Circuit High", + 509 => "Idle Control System Circuit Intermittent", + 510 => "Speed Control Sensor A Circuit", + 511 => "Speed Control Sensor A Circuit Range/Performance", + 512 => "Speed Control Sensor A Circuit Low", + 513 => "Speed Control Sensor A Circuit High", + 514 => "Speed Control Sensor A Circuit Intermittent", + 515 => "Speed Control Sensor B Circuit", + 516 => "Speed Control Sensor B Circuit Range/Performance", + 517 => "Speed Control Sensor B Circuit Low", + 518 => "Speed Control Sensor B Circuit High", + 519 => "Speed Control Sensor B Circuit Intermittent", + 520 => "Vehicle Speed Sensor Circuit", + 521 => "Vehicle Speed Sensor Range/Performance", + 522 => "Vehicle Speed Sensor Low Input", + 523 => "Vehicle Speed Sensor High Input", + 524 => "Vehicle Speed Sensor Intermittent/Erratic", + 525 => "Clutch Switch Input Circuit", + 526 => "Clutch Switch Input Circuit Range/Performance", + 527 => "Clutch Switch Input Circuit Low", + 528 => "Clutch Switch Input Circuit High", + 529 => "Clutch Switch Input Circuit Intermittent", + 530 => "Brake Switch A Circuit", + 531 => "Brake Switch A Circuit Range/Performance", + 532 => "Brake Switch A Circuit Low", + 533 => "Brake Switch A Circuit High", + 534 => "Brake Switch A Circuit Intermittent", + 535 => "Brake Switch B Circuit", + 536 => "Brake Switch B Circuit Range/Performance", + 537 => "Brake Switch B Circuit Low", + 538 => "Brake Switch B Circuit High", + 539 => "Brake Switch B Circuit Intermittent", + 540 => "Fuel Level Sensor A Circuit", + 541 => "Fuel Level Sensor A Circuit Range/Performance", + 542 => "Fuel Level Sensor A Circuit Low", + 543 => "Fuel Level Sensor A Circuit High", + 544 => "Fuel Level Sensor A Circuit Intermittent", + 545 => "Fuel Level Sensor B Circuit", + 546 => "Fuel Level Sensor B Circuit Range/Performance", + 547 => "Fuel Level Sensor B Circuit Low", + 548 => "Fuel Level Sensor B Circuit High", + 549 => "Fuel Level Sensor B Circuit Intermittent", + 550 => "Fuel Pump Relay Control Circuit", + 551 => "Fuel Pump Relay Control Circuit Range/Performance", + 552 => "Fuel Pump Relay Control Circuit Low", + 553 => "Fuel Pump Relay Control Circuit High", + 554 => "Fuel Pump Relay Control Circuit Intermittent", + 555 => "Fuel Pump Control Module Circuit", + 556 => "Fuel Pump Control Module Circuit Range/Performance", + 557 => "Fuel Pump Control Module Circuit Low", + 558 => "Fuel Pump Control Module Circuit High", + 559 => "Fuel Pump Control Module Circuit Intermittent", + 560 => "Fuel Pump Secondary Circuit", + 561 => "Fuel Pump Secondary Circuit Range/Performance", + 562 => "Fuel Pump Secondary Circuit Low", + 563 => "Fuel Pump Secondary Circuit High", + 564 => "Fuel Pump Secondary Circuit Intermittent", + 565 => "Evaporative Emission System Vent Valve/Solenoid Circuit", + 566 => "Evaporative Emission System Vent Valve/Solenoid Circuit Range/Performance", + 567 => "Evaporative Emission System Vent Valve/Solenoid Circuit Low", + 568 => "Evaporative Emission System Vent Valve/Solenoid Circuit High", + 569 => "Evaporative Emission System Vent Valve/Solenoid Circuit Intermittent", + 570 => "Fuel Temperature Sensor A Circuit", + 571 => "Fuel Temperature Sensor A Circuit Range/Performance", + 572 => "Fuel Temperature Sensor A Circuit Low", + 573 => "Fuel Temperature Sensor A Circuit High", + 574 => "Fuel Temperature Sensor A Circuit Intermittent", + 575 => "Fuel Temperature Sensor B Circuit", + 576 => "Fuel Temperature Sensor B Circuit Range/Performance", + 577 => "Fuel Temperature Sensor B Circuit Low", + 578 => "Fuel Temperature Sensor B Circuit High", + 579 => "Fuel Temperature Sensor B Circuit Intermittent", + 580 => "Crankshaft Position Sensor A Circuit", + 581 => "Crankshaft Position Sensor A Circuit Range/Performance", + 582 => "Crankshaft Position Sensor A Circuit Low", + 583 => "Crankshaft Position Sensor A Circuit High", + 584 => "Crankshaft Position Sensor A Circuit Intermittent", + 585 => "Crankshaft Position Sensor B Circuit", + 586 => "Crankshaft Position Sensor B Circuit Range/Performance", + 587 => "Crankshaft Position Sensor B Circuit Low", + 588 => "Crankshaft Position Sensor B Circuit High", + 589 => "Crankshaft Position Sensor B Circuit Intermittent", + 590 => "Crankshaft Position Sensor C Circuit", + 591 => "Crankshaft Position Sensor C Circuit Range/Performance", + 592 => "Crankshaft Position Sensor C Circuit Low", + 593 => "Crankshaft Position Sensor C Circuit High", + 594 => "Crankshaft Position Sensor C Circuit Intermittent", + 595 => "Camshaft Position Sensor A Circuit", + 596 => "Camshaft Position Sensor A Circuit Range/Performance", + 597 => "Camshaft Position Sensor A Circuit Low", + 598 => "Camshaft Position Sensor A Circuit High", + 599 => "Camshaft Position Sensor A Circuit Intermittent", + 600 => "Camshaft Position Sensor B Circuit", + 601 => "Camshaft Position Sensor B Circuit Range/Performance", + 602 => "Camshaft Position Sensor B Circuit Low", + 603 => "Camshaft Position Sensor B Circuit High", + 604 => "Camshaft Position Sensor B Circuit Intermittent", + 605 => "Camshaft Position Sensor C Circuit", + 606 => "Camshaft Position Sensor C Circuit Range/Performance", + 607 => "Camshaft Position Sensor C Circuit Low", + 608 => "Camshaft Position Sensor C Circuit High", + 609 => "Camshaft Position Sensor C Circuit Intermittent", + 610 => "Oxygen Sensor Heater Circuit", + 611 => "Oxygen Sensor Heater Circuit Range/Performance", + 612 => "Oxygen Sensor Heater Circuit Low", + 613 => "Oxygen Sensor Heater Circuit High", + + _ => $"P{code:N4}" + }; + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.cs new file mode 100644 index 000000000..b713dfddd --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Dtc.cs @@ -0,0 +1,63 @@ +using System; + +namespace Meadow.Foundation.Telematics.OBD2; + +public partial class Dtc +{ + private byte[] _data = new byte[2]; + + public DtcCategory Category + { + get => (DtcCategory)(_data[0] & 0xC0); + set => _data[0] = (byte)((_data[0] & 0x3f) | (byte)value); + } + + public int Code + { + get + { + return ((_data[0] & 0x03) * 100) + + (((_data[1] & 0xf0) >> 4) * 10) + + (_data[1] & 0x0f); + } + set + { + if (value > 0x3ff) throw new ArgumentException("Max code value is 3ff"); + var digit = value / 100; + _data[0] = (byte)(digit & 0x03); + value = value % 100; + digit = value / 10; + _data[1] = (byte)(digit << 4); + value = value % 10; + _data[1] |= (byte)value; + } + } + + public Dtc(byte[] data) + { + if (data.Length != 2) throw new ArgumentException("DTC codes must be exactly 2 bytes"); + _data = data; + } + + public override string ToString() + { + return $"{Category}{Code:N4}"; + } + + public string ToReadableErrorCode() + { + switch (Category) + { + case DtcCategory.P: + return GetReadablePowertrainErrorCode(Code); + case DtcCategory.C: + return GetReadableChassisErrorCode(Code); + case DtcCategory.B: + return GetReadableBodyErrorCode(Code); + case DtcCategory.U: + return GetReadableNetworkErrorCode(Code); + } + + throw new NotImplementedException(); + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/DtcCategory.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/DtcCategory.cs new file mode 100644 index 000000000..8cc718d12 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/DtcCategory.cs @@ -0,0 +1,21 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public enum DtcCategory : byte +{ + /// + /// Powertain + /// + P = 0b0000_0000, + /// + /// Chassis + /// + C = 0b0100_0000, + /// + /// Body + /// + B = 0b1000_0000, + /// + /// Network + /// + U = 0b1100_0000, +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Ecu.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Ecu.cs new file mode 100644 index 000000000..1a0a39d51 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Ecu.cs @@ -0,0 +1,154 @@ +using Meadow.Hardware; +using System; + +namespace Meadow.Foundation.Telematics.OBD2; + +public class Ecu +{ + private readonly ICanBus _bus; + + public PidRequestHandlerCollection PidRequestHandlers { get; } = new(); + + public short Address { get; } + + public Ecu(ICanBus bus, short ecuAddress = 0x7e8) + { + _bus = bus; + Address = ecuAddress; + bus.FrameReceived += OnCanFrameReceived; + } + + private void HandleSupportedPidsRequest(SaeStandardQueryFrame queryFrame) + { + Resolver.Log.Info($"handling {queryFrame.Pid} response frame"); + + switch (queryFrame.Pid) + { + case Pid.SupportedPids_01_20: + case Pid.SupportedPids_21_40: + uint supportBits = 0; + + for (var i = 0; i < 32; i++) + { + if (PidRequestHandlers.GetHandler((ushort)(i + (int)queryFrame.Pid + 1)) != null) + { + supportBits |= (uint)(i << (31 - i)); + } + } + Resolver.Log.Info($"support: {supportBits:x8}"); + var payload = new byte[4]; + payload[0] = (byte)((supportBits & 0xff000000) >> 24); + payload[1] = (byte)((supportBits & 0x00ff0000) >> 16); + payload[2] = (byte)((supportBits & 0x0000ff00) >> 8); + payload[3] = (byte)((supportBits & 0x000000ff) >> 0); + + var supportedFrame = new Obd2ResponseFrame(queryFrame.Service, queryFrame.Pid, payload, Address); + + Resolver.Log.Info($"Sending {queryFrame.Pid} response frame"); + + _bus.WriteFrame(supportedFrame); + + break; + } + } + + private void HandleRequestCurrentData(SaeStandardQueryFrame queryFrame) + { + switch (queryFrame.Pid) + { + case Pid.SupportedPids_01_20: + case Pid.SupportedPids_21_40: + HandleSupportedPidsRequest(queryFrame); + return; + } + + var handler = PidRequestHandlers.GetHandler(queryFrame.Pid); + var pid = (ushort)queryFrame.Pid; + var service = queryFrame.Service; + + if (handler != null) + { + var data = handler.Invoke(pid); + // data cannot be > 4 bytes long + if (data.Length > 4) + { + throw new Exception("Handler data exceeded 4 bytes in length"); + } + + var payload = new byte[8]; + payload[0] = (byte)(2 + data.Length); + payload[1] = (byte)(service + 0x40); + payload[2] = (byte)pid; + data.CopyTo(payload, 3); + + // create a response frame + var response = new Obd2ResponseFrame(queryFrame.Service, queryFrame.Pid, payload, Address); + _bus.WriteFrame(response); + } + } + + private void OnCanFrameReceived(object sender, ICanFrame e) + { + if (e is StandardDataFrame sdf) + { + Obd2Frame? obdFrame = null; + + try + { + obdFrame = Obd2Frame.FromCanFrame(sdf); + } + catch (Exception ex) + { + Resolver.Log.Warn($"Unable to convert CAN frame to OBD2: {ex.Message}"); + return; + } + + PidRequestHandler? handler = null; + ushort pid = 0; + Service service = 0; + + if (obdFrame is SaeStandardQueryFrame sqf) + { + switch (sqf.Service) + { + case Service.Current: + HandleRequestCurrentData(sqf); + break; + case Service.FreezeFrame: + Resolver.Log.Info("Request for Freeze frame"); + break; + case Service.StoredDtcs: + Resolver.Log.Info("Request for stored DTCs"); + break; + case Service.PendingDtcs: + Resolver.Log.Info("Request for pending DTCs"); + break; + case Service.ControlOperations: + Resolver.Log.Info("Request for control ops"); + break; + case Service.PermanentDtcs: + Resolver.Log.Info("Request for permanent DTCs"); + break; + case Service.TestResultsOther: + Resolver.Log.Info("Request for test results"); + break; + case Service.VehicleInfo: + Resolver.Log.Info("Request for vehicle info"); + break; + } + + Resolver.Log.Warn($"Standard OBD2 Frame Received for Service:PID {sqf.Service}:{sqf.Pid}"); + } + else if (obdFrame is VehicleSpecificQueryFrame vqf) + { + handler = PidRequestHandlers.GetHandler(vqf.Pid); + pid = vqf.Pid; + service = vqf.Service; + } + else + { + Resolver.Log.Warn($"OBD2 Frame Received for Service:PID {service}:{pid}"); + } + } + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/IsoTp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/IsoTp.cs new file mode 100644 index 000000000..91d5ea8de --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/IsoTp.cs @@ -0,0 +1,216 @@ +using Meadow.Hardware; +using Meadow.Logging; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Meadow.Foundation.Telematics.OBD2; + +public static class IsoTp +{ + private enum FrameType : byte + { + Single = 0, + First = 1, + Consecutive = 2, + FlowControl = 3 + } + + private enum PduState + { + SendingFirstFrame, + WaitingForFirstFC, + SendingData, + Done, + Error + } + + private class Pdu + { + public ICanBus Bus { get; set; } + public byte[] Data { get; set; } + public PduState State { get; set; } + public Logger? Logger { get; set; } + public int BytesSent { get; set; } = 0; + public byte SequenceID { get; set; } = 0; + } + + public static Task Send(ICanBus bus, byte[] data, Logger? logger = null) + { + var pdu = new Pdu + { + Bus = bus, + Data = data, + State = PduState.SendingFirstFrame, + Logger = logger + }; + + return Task.Run(() => PduSendProc(pdu)); + } + + private static async Task PduSendProc(Pdu pdu) + { + while (true) + { + switch (pdu.State) + { + case PduState.SendingFirstFrame: + if (pdu.Data.Length <= 7) + { + // single packet only + try + { + SendSingleFrameMessage(pdu); + pdu.State = PduState.Done; + } + catch (Exception ex) + { + pdu.Logger?.Error(ex); + pdu.State = PduState.Error; + } + } + else + { + SendFrameMessage(pdu); + } + break; + case PduState.WaitingForFirstFC: + // todo: wait a default amount + await WaitForFCFrame(pdu); + break; + case PduState.Error: + return false; + default: + Thread.Sleep(100); + break; + } + } + } + + private static async Task WaitForFCFrame(Pdu pdu) + { + // listen for a CAN message + // is it from our requested ECU? + // is it a flow-control? + } + + private static void SendFrameMessage(Pdu pdu) + { + byte[] payload; + + if (pdu.BytesSent == 0) // first frame + { + payload = new byte[8]; + // N_PCI: + // Byte 0 = Type(bits 7-4) + DL(bits 3-0 data-length) + // Byte 1 = DL(bits 7-0 rest of data-length) + payload[0] = (byte)(((byte)FrameType.First << 4) | ((pdu.Data.Length & 0x0F00) >> 8)); + payload[1] = (byte)(pdu.Data.Length & 0x00FF); + Array.Copy(pdu.Data, pdu.BytesSent, payload, 2, 6); + + _receivedFCWaits = 0; // Reset counter + } + else + { + var remaining = pdu.Data.Length - pdu.BytesSent; + if (remaining > 7) remaining = 7; + + payload = new byte[remaining]; + payload[0] = (byte)(((byte)FrameType.Consecutive << 4) | (pdu.SequenceID & 0X0F)); + + Array.Copy(pdu.Data, pdu.BytesSent, payload, 1, remaining); + } + + var frame = new StandardDataFrame + { + Payload = payload + }; + + pdu.Bus.WriteFrame(frame); + pdu.SequenceID++; + pdu.BytesSent += payload.Length; + + pdu.State = PduState.WaitingForFirstFC; + } + + private static void SendSingleFrameMessage(Pdu pdu) + { + var payload = new byte[8]; + payload[0] = (byte)(pdu.Data.Length | (byte)FrameType.Single); + Array.Copy(pdu.Data, 0, payload, 1, pdu.Data.Length); + var frame = new StandardDataFrame + { + Payload = payload + }; + pdu.Bus.WriteFrame(frame); + } + + public static ICanFrame[] Encode(byte[] data) + { + var count = data.Length; + if (count == 0) return Array.Empty(); + if (count > 4095) throw new ArgumentException("Maximum of 4096 bytes can be encoded"); + + byte[] payload; + + if (count <= 7) + { + payload = new byte[8]; + payload[0] = (byte)count; + Array.Copy(data, 0, payload, 1, count); + return new ICanFrame[] { + new StandardDataFrame + { + Payload = payload + } + }; + } + + var frames = new List(); + var sourceIndex = 0; + byte frameIndex = 0; + int remaining = count; + + // first frame + payload = new byte[8]; + payload[0] = (byte)((count >> 8) & 0x10); + payload[1] = (byte)(count & 0xff); + Array.Copy(data, sourceIndex, payload, 2, 6); + frames.Add( + new StandardDataFrame + { + Payload = payload + } + ); + sourceIndex += 6; + + while (true) + { + remaining = count - sourceIndex; + if (remaining <= 0) break; + + if (remaining > 7) + { + payload = new byte[8]; + } + else + { + payload = new byte[remaining]; + } + payload[0] = (byte)(0x20 | (frameIndex & 0x0f)); + Array.Copy(data, sourceIndex, payload, 1, payload.Length - 1); + frames.Add( + new StandardDataFrame + { + Payload = payload + } + ); + + frameIndex++; + sourceIndex += 7; + } + + return frames.ToArray(); + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2Client.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2Client.cs new file mode 100644 index 000000000..3813198ec --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2Client.cs @@ -0,0 +1,85 @@ +using Meadow.Hardware; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Meadow.Foundation.Telematics.OBD2; + +public class Obd2Client +{ + private ICanBus _canBus; + + public Obd2Client(ICanBus canBus) + { + _canBus = canBus; + + _canBus.FrameReceived += OnFrameReceived; + } + + public async Task RequestVehicleInfo() + { + // service 9 request - get all supported PIDs + var request = new SaeStandardQueryFrame(Service.VehicleInfo, 0); + + // send and wait for a response + var response = await SendAndWaitForResponse(request, TimeSpan.FromSeconds(5)); + + // TODO: send + } + + public async Task SendAndWaitForResponse(SaeStandardQueryFrame queryFrame, TimeSpan timeout) + { + var cancellationTokenSource = new CancellationTokenSource(timeout); + var tcs = new TaskCompletionSource(); + + _canBus.WriteFrame(queryFrame); + + async Task CheckFrame() + { + try + { + var searchKey = ((int)queryFrame.Pid << 8) | (int)queryFrame.Service; + while (!cancellationTokenSource.Token.IsCancellationRequested) + { + if (_received.ContainsKey(searchKey)) + { + var match = _received[searchKey]; + _received.Remove(searchKey); + tcs.TrySetResult(match); + return; + } + } + tcs.TrySetException(new TimeoutException($"Response not received within {timeout.TotalSeconds} seconds.")); + } + catch (OperationCanceledException) + { + tcs.TrySetException(new TimeoutException($"Response not received within {timeout.TotalSeconds} seconds.")); + } + } + + // Start the frame checking task + _ = CheckFrame(); + + return await tcs.Task; + } + + private Dictionary _received = new(); + + private void OnFrameReceived(object sender, ICanFrame e) + { + if (e is StandardDataFrame sdf) + { + Resolver.Log.Info("SAE Response received"); + var f = new Obd2ResponseFrame(sdf); + + var key = ((int)f.Pid << 8) | (int)f.Service; + + _received.Add(key, f); + } + } +} + +public class EcuListener +{ +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2Frame.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2Frame.cs new file mode 100644 index 000000000..572cb0fa1 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2Frame.cs @@ -0,0 +1,31 @@ +using Meadow.Hardware; +using System; + +namespace Meadow.Foundation.Telematics.OBD2; + +public abstract class Obd2Frame : StandardDataFrame +{ + public const short Obd2RequestID = 0x7df; + + public static Obd2Frame FromCanFrame(StandardDataFrame dataFrame) + { + if (dataFrame.ID == Obd2RequestID) + { + switch ((Obd2FrameType)dataFrame.Payload[0]) + { + case Obd2FrameType.Standard: // SAE STANDARD + return new SaeStandardQueryFrame(dataFrame); + case Obd2FrameType.VehicleSpecific: // VEHICLE SPECIFIC + return new VehicleSpecificQueryFrame(dataFrame); + } + } + + throw new ArgumentException("data frame is not a valid ODB2 frame"); + } + + public virtual StandardDataFrame AsCanFrame(Obd2FrameType frameType, short ecuID) + { + + throw new NotImplementedException(); + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2FrameType.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2FrameType.cs new file mode 100644 index 000000000..9b5fa10ef --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2FrameType.cs @@ -0,0 +1,7 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public enum Obd2FrameType : byte +{ + Standard = 2, + VehicleSpecific = 3 +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2QueryFrame.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2QueryFrame.cs new file mode 100644 index 000000000..466c83016 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Obd2QueryFrame.cs @@ -0,0 +1,54 @@ +using Meadow.Hardware; +using System; + +namespace Meadow.Foundation.Telematics.OBD2; + +public class Obd2ResponseFrame : Obd2Frame +{ + public Service Service + { + get => (Service)(Payload[1] - 0x40); + set => Payload[1] = (byte)((byte)value | 0x40); + } + + public Pid Pid => (Pid)Payload[2]; + + internal Obd2ResponseFrame(StandardDataFrame dataFrame) + { + ID = dataFrame.ID; + Payload = dataFrame.Payload; + } + + internal Obd2ResponseFrame(Service requestService, Pid pid, byte[] data, short ecuAddress) + { + ID = ecuAddress; + Payload = new byte[8]; + + if (data.Length > 4) throw new ArgumentOutOfRangeException(); + + Payload[0] = (byte)(data.Length + 2); + Payload[1] = (byte)((byte)requestService | 0x40); + Payload[2] = (byte)pid; + + for (var i = 0; i < 5; i++) + { + if (data.Length - i > 0) + { + Payload[3 + i] = data[i]; + } + else + { + Payload[3 + i] = 0x55; // empty bytes are stuffed with 0x55, not 0x00 + } + } + } +} + +public abstract class Obd2QueryFrame : Obd2Frame +{ + public Service Service + { + get => (Service)Payload[1]; + set => Payload[1] = (byte)value; + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Pid.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Pid.cs new file mode 100644 index 000000000..36739ae95 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Pid.cs @@ -0,0 +1,1290 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +/// +/// Enumeration for OBD-II PIDs (Parameter IDs). +/// These PIDs are used to request diagnostic data from a vehicle. +/// +public enum Pid : byte +{ + /// + /// PID 0x00 - Supported PIDs 01-20 + /// + SupportedPids_01_20 = 0x00, + + /// + /// PID 0x01 - Monitor status since DTCs cleared + /// + MonitorStatus = 0x01, + + /// + /// PID 0x02 - Freeze DTC + /// + FreezeDtc = 0x02, + + /// + /// PID 0x03 - Fuel system status + /// + FuelSystemStatus = 0x03, + + /// + /// PID 0x04 - Calculated engine load + /// + CalculatedEngineLoad = 0x04, + + /// + /// PID 0x05 - Engine coolant temperature + /// + EngineCoolantTemperature = 0x05, + + /// + /// PID 0x06 - Short term fuel trim - Bank 1 + /// + ShortTermFuelTrimBank1 = 0x06, + + /// + /// PID 0x07 - Long term fuel trim - Bank 1 + /// + LongTermFuelTrimBank1 = 0x07, + + /// + /// PID 0x08 - Short term fuel trim - Bank 2 + /// + ShortTermFuelTrimBank2 = 0x08, + + /// + /// PID 0x09 - Long term fuel trim - Bank 2 + /// + LongTermFuelTrimBank2 = 0x09, + + /// + /// PID 0x0A - Fuel pressure + /// + FuelPressure = 0x0A, + + /// + /// PID 0x0B - Intake manifold absolute pressure + /// + IntakeManifoldPressure = 0x0B, + + /// + /// PID 0x0C - Engine RPM + /// + EngineRpm = 0x0C, + + /// + /// PID 0x0D - Vehicle speed + /// + VehicleSpeed = 0x0D, + + /// + /// PID 0x0E - Timing advance + /// + TimingAdvance = 0x0E, + + /// + /// PID 0x0F - Intake air temperature + /// + IntakeAirTemperature = 0x0F, + + /// + /// PID 0x10 - MAF air flow rate + /// + MafAirFlowRate = 0x10, + + /// + /// PID 0x11 - Throttle position + /// + ThrottlePosition = 0x11, + + /// + /// PID 0x12 - Commanded secondary air status + /// + CommandedSecondaryAirStatus = 0x12, + + /// + /// PID 0x13 - Oxygen sensors present (in 2 banks) + /// + OxygenSensorsPresent = 0x13, + + /// + /// PID 0x14 - Oxygen sensor 1 - Short term fuel trim + /// + OxygenSensor1ShortTermFuelTrim = 0x14, + + /// + /// PID 0x15 - Oxygen sensor 2 - Short term fuel trim + /// + OxygenSensor2ShortTermFuelTrim = 0x15, + + /// + /// PID 0x16 - Oxygen sensor 3 - Short term fuel trim + /// + OxygenSensor3ShortTermFuelTrim = 0x16, + + /// + /// PID 0x17 - Oxygen sensor 4 - Short term fuel trim + /// + OxygenSensor4ShortTermFuelTrim = 0x17, + + /// + /// PID 0x18 - Oxygen sensor 5 - Short term fuel trim + /// + OxygenSensor5ShortTermFuelTrim = 0x18, + + /// + /// PID 0x19 - Oxygen sensor 6 - Short term fuel trim + /// + OxygenSensor6ShortTermFuelTrim = 0x19, + + /// + /// PID 0x1A - Oxygen sensor 7 - Short term fuel trim + /// + OxygenSensor7ShortTermFuelTrim = 0x1A, + + /// + /// PID 0x1B - Oxygen sensor 8 - Short term fuel trim + /// + OxygenSensor8ShortTermFuelTrim = 0x1B, + + /// + /// PID 0x1C - OBD standards this vehicle conforms to + /// + ObdStandards = 0x1C, + + /// + /// PID 0x1D - Oxygen sensors present (in 4 banks) + /// + OxygenSensorsPresent_4Banks = 0x1D, + + /// + /// PID 0x1E - Auxiliary input status + /// + AuxiliaryInputStatus = 0x1E, + + /// + /// PID 0x1F - Run time since engine start + /// + RunTimeSinceEngineStart = 0x1F, + + // Add more PIDs as needed... + + /// + /// PID 0x20 - Supported PIDs 21-40 + /// + SupportedPids_21_40 = 0x20, + + /// + /// PID 0x21 - Distance traveled with malfunction indicator lamp (MIL) on + /// + DistanceWithMilOn = 0x21, + + /// + /// PID 0x22 - Fuel rail pressure (relative to manifold vacuum) + /// + FuelRailPressureRelativeToManifold = 0x22, + + /// + /// PID 0x23 - Fuel rail gauge pressure (diesel, or gasoline direct injection) + /// + FuelRailGaugePressure = 0x23, + + /// + /// PID 0x24 - Oxygen sensor 1 - Fuel/air commanded equivalence ratio + /// + OxygenSensor1EquivalenceRatio = 0x24, + + /// + /// PID 0x25 - Oxygen sensor 2 - Fuel/air commanded equivalence ratio + /// + OxygenSensor2EquivalenceRatio = 0x25, + + /// + /// PID 0x26 - Oxygen sensor 3 - Fuel/air commanded equivalence ratio + /// + OxygenSensor3EquivalenceRatio = 0x26, + + /// + /// PID 0x27 - Oxygen sensor 4 - Fuel/air commanded equivalence ratio + /// + OxygenSensor4EquivalenceRatio = 0x27, + + /// + /// PID 0x28 - Oxygen sensor 5 - Fuel/air commanded equivalence ratio + /// + OxygenSensor5EquivalenceRatio = 0x28, + + /// + /// PID 0x29 - Oxygen sensor 6 - Fuel/air commanded equivalence ratio + /// + OxygenSensor6EquivalenceRatio = 0x29, + + /// + /// PID 0x2A - Oxygen sensor 7 - Fuel/air commanded equivalence ratio + /// + OxygenSensor7EquivalenceRatio = 0x2A, + + /// + /// PID 0x2B - Oxygen sensor 8 - Fuel/air commanded equivalence ratio + /// + OxygenSensor8EquivalenceRatio = 0x2B, + + /// + /// PID 0x2C - Commanded EGR + /// + CommandedEgr = 0x2C, + + /// + /// PID 0x2D - EGR Error + /// + EgrError = 0x2D, + + /// + /// PID 0x2E - Commanded evaporative purge + /// + CommandedEvaporativePurge = 0x2E, + + /// + /// PID 0x2F - Fuel tank level input + /// + FuelTankLevelInput = 0x2F, + + /// + /// PID 0x30 - Warm-ups since codes cleared + /// + WarmUpsSinceCodesCleared = 0x30, + + /// + /// PID 0x31 - Distance traveled since codes cleared + /// + DistanceSinceCodesCleared = 0x31, + + /// + /// PID 0x32 - Evaporative system vapor pressure + /// + EvaporativeSystemVaporPressure = 0x32, + + /// + /// PID 0x33 - Absolute barometric pressure + /// + BarometricPressure = 0x33, + + /// + /// PID 0x34 - Oxygen sensor 1 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor1EquivalenceRatioCurrent = 0x34, + + /// + /// PID 0x35 - Oxygen sensor 2 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor2EquivalenceRatioCurrent = 0x35, + + /// + /// PID 0x36 - Oxygen sensor 3 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor3EquivalenceRatioCurrent = 0x36, + + /// + /// PID 0x37 - Oxygen sensor 4 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor4EquivalenceRatioCurrent = 0x37, + + /// + /// PID 0x38 - Oxygen sensor 5 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor5EquivalenceRatioCurrent = 0x38, + + /// + /// PID 0x39 - Oxygen sensor 6 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor6EquivalenceRatioCurrent = 0x39, + + /// + /// PID 0x3A - Oxygen sensor 7 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor7EquivalenceRatioCurrent = 0x3A, + + /// + /// PID 0x3B - Oxygen sensor 8 - Fuel/air commanded equivalence ratio (current) + /// + OxygenSensor8EquivalenceRatioCurrent = 0x3B, + + /// + /// PID 0x3C - Catalyst temperature bank 1, sensor 1 + /// + CatalystTemperatureBank1Sensor1 = 0x3C, + + /// + /// PID 0x3D - Catalyst temperature bank 2, sensor 1 + /// + CatalystTemperatureBank2Sensor1 = 0x3D, + + /// + /// PID 0x3E - Catalyst temperature bank 1, sensor 2 + /// + CatalystTemperatureBank1Sensor2 = 0x3E, + + /// + /// PID 0x3F - Catalyst temperature bank 2, sensor 2 + /// + CatalystTemperatureBank2Sensor2 = 0x3F, + + /// + /// PID 0x40 - Supported PIDs 41-60 + /// + SupportedPids_41_60 = 0x40, + + /// + /// PID 0x41 - Monitor status this drive cycle + /// + MonitorStatusThisDriveCycle = 0x41, + + /// + /// PID 0x42 - Control module voltage + /// + ControlModuleVoltage = 0x42, + + /// + /// PID 0x43 - Absolute load value + /// + AbsoluteLoadValue = 0x43, + + /// + /// PID 0x44 - Fuel/air commanded equivalence ratio + /// + FuelAirCommandedEquivalenceRatio = 0x44, + + /// + /// PID 0x45 - Relative throttle position + /// + RelativeThrottlePosition = 0x45, + + /// + /// PID 0x46 - Ambient air temperature + /// + AmbientAirTemperature = 0x46, + + /// + /// PID 0x47 - Absolute throttle position B + /// + AbsoluteThrottlePositionB = 0x47, + + /// + /// PID 0x48 - Absolute throttle position C + /// + AbsoluteThrottlePositionC = 0x48, + + /// + /// PID 0x49 - Accelerator pedal position D + /// + AcceleratorPedalPositionD = 0x49, + + /// + /// PID 0x4A - Accelerator pedal position E + /// + AcceleratorPedalPositionE = 0x4A, + + /// + /// PID 0x4B - Accelerator pedal position F + /// + AcceleratorPedalPositionF = 0x4B, + + /// + /// PID 0x4C - Commanded throttle actuator + /// + CommandedThrottleActuator = 0x4C, + + /// + /// PID 0x4D - Time run with MIL on + /// + TimeRunWithMilOn = 0x4D, + + /// + /// PID 0x4E - Time since trouble codes cleared + /// + TimeSinceTroubleCodesCleared = 0x4E, + + /// + /// PID 0x4F - Maximum value for equivalence ratio, oxygen sensor voltage, oxygen sensor current, and intake manifold absolute pressure + /// + MaximumValues = 0x4F, + + /// + /// PID 0x50 - Maximum value for air flow rate from mass air flow sensor + /// + MaximumAirFlowRate = 0x50, + + /// + /// PID 0x51 - Fuel Type + /// + FuelType = 0x51, + + /// + /// PID 0x52 - Ethanol fuel percentage + /// + EthanolFuelPercentage = 0x52, + + /// + /// PID 0x53 - Absolute evaporative system vapor pressure + /// + AbsoluteEvaporativeSystemVaporPressure = 0x53, + + /// + /// PID 0x54 - Evaporative system vapor pressure + /// + EvaporativeSystemVaporPressure2 = 0x54, + + /// + /// PID 0x55 - Short term secondary oxygen sensor trim - Bank 1 and Bank 3 + /// + ShortTermSecondaryOxygenSensorTrimBank1And3 = 0x55, + + /// + /// PID 0x56 - Long term secondary oxygen sensor trim - Bank 1 and Bank 3 + /// + LongTermSecondaryOxygenSensorTrimBank1And3 = 0x56, + + /// + /// PID 0x57 - Short term secondary oxygen sensor trim - Bank 2 and Bank 4 + /// + ShortTermSecondaryOxygenSensorTrimBank2And4 = 0x57, + + /// + /// PID 0x58 - Long term secondary oxygen sensor trim - Bank 2 and Bank 4 + /// + LongTermSecondaryOxygenSensorTrimBank2And4 = 0x58, + + /// + /// PID 0x59 - Fuel rail pressure (absolute) + /// + FuelRailPressureAbsolute = 0x59, + + /// + /// PID 0x5A - Relative accelerator pedal position + /// + RelativeAcceleratorPedalPosition = 0x5A, + + /// + /// PID 0x5B - Hybrid battery pack remaining life + /// + HybridBatteryPackRemainingLife = 0x5B, + + /// + /// PID 0x5C - Engine oil temperature + /// + EngineOilTemperature = 0x5C, + + /// + /// PID 0x5D - Fuel injection timing + /// + FuelInjectionTiming = 0x5D, + + /// + /// PID 0x5E - Engine fuel rate + /// + EngineFuelRate = 0x5E, + + /// + /// PID 0x5F - Emission requirements to which vehicle is designed + /// + EmissionRequirements = 0x5F, + + /// + /// PID 0x60 - Supported PIDs 61-80 + /// + SupportedPids_61_80 = 0x60, + + /// + /// PID 0x61 - Driver's demand engine - percent torque + /// + DriversDemandEnginePercentTorque = 0x61, + + /// + /// PID 0x62 - Actual engine - percent torque + /// + ActualEnginePercentTorque = 0x62, + + /// + /// PID 0x63 - Engine reference torque + /// + EngineReferenceTorque = 0x63, + + /// + /// PID 0x64 - Engine percent torque data + /// + EnginePercentTorqueData = 0x64, + + /// + /// PID 0x65 - Auxiliary input/output supported + /// + AuxiliaryInputOutputSupported = 0x65, + + /// + /// PID 0x66 - Mass air flow sensor + /// + MassAirFlowSensor = 0x66, + + /// + /// PID 0x67 - Engine coolant temperature + /// + EngineCoolantTemperature2 = 0x67, + + /// + /// PID 0x68 - Intake air temperature sensor + /// + IntakeAirTemperatureSensor = 0x68, + + /// + /// PID 0x69 - Commanded EGR and EGR error + /// + CommandedEgrAndEgrError = 0x69, + + /// + /// PID 0x6A - Commanded Diesel intake air flow control and relative intake air flow position + /// + CommandedDieselIntakeAirFlow = 0x6A, + + /// + /// PID 0x6B - Exhaust gas recirculation temperature + /// + ExhaustGasRecirculationTemperature = 0x6B, + + /// + /// PID 0x6C - Commanded throttle actuator control and relative throttle position + /// + CommandedThrottleActuatorControl = 0x6C, + + /// + /// PID 0x6D - Fuel pressure control system + /// + FuelPressureControlSystem = 0x6D, + + /// + /// PID 0x6E - Injection pressure control system + /// + InjectionPressureControlSystem = 0x6E, + + /// + /// PID 0x6F - Turbocharger compressor inlet pressure + /// + TurbochargerCompressorInletPressure = 0x6F, + + /// + /// PID 0x70 - Boost pressure control + /// + BoostPressureControl = 0x70, + + /// + /// PID 0x71 - Variable Geometry Turbo (VGT) control + /// + VariableGeometryTurboControl = 0x71, + + /// + /// PID 0x72 - Wastegate control + /// + WastegateControl = 0x72, + + /// + /// PID 0x73 - Exhaust pressure + /// + ExhaustPressure = 0x73, + + /// + /// PID 0x74 - Turbocharger RPM + /// + TurbochargerRpm = 0x74, + + /// + /// PID 0x75 - Turbocharger temperature 1 + /// + TurbochargerTemperature1 = 0x75, + + /// + /// PID 0x76 - Turbocharger temperature 2 + /// + TurbochargerTemperature2 = 0x76, + + /// + /// PID 0x77 - Charge air cooler temperature (CACT) + /// + ChargeAirCoolerTemperature = 0x77, + + /// + /// PID 0x78 - Exhaust gas temperature (EGT) Bank 1 + /// + ExhaustGasTemperatureBank1 = 0x78, + + /// + /// PID 0x79 - Exhaust gas temperature (EGT) Bank 2 + /// + ExhaustGasTemperatureBank2 = 0x79, + + /// + /// PID 0x7A - Diesel particulate filter (DPF) 1 - differential pressure + /// + Dpf1DifferentialPressure = 0x7A, + + /// + /// PID 0x7B - Diesel particulate filter (DPF) 2 - differential pressure + /// + Dpf2DifferentialPressure = 0x7B, + + /// + /// PID 0x7C - Diesel particulate filter (DPF) temperature + /// + DpfTemperature = 0x7C, + + /// + /// PID 0x7D - NOx NTE (not-to-exceed) control area status + /// + NoxNteControlAreaStatus = 0x7D, + + /// + /// PID 0x7E - PM NTE (not-to-exceed) control area status + /// + PmNteControlAreaStatus = 0x7E, + + /// + /// PID 0x7F - Engine run time + /// + EngineRunTime = 0x7F, + + /// + /// PID 0x80 - Supported PIDs 81-A0 + /// + SupportedPids_81_A0 = 0x80, + + /// + /// PID 0x81 - Engine run time for Auxiliary Emissions Control Device (AECD) + /// + EngineRunTimeForAecd = 0x81, + + /// + /// PID 0x82 - Engine run time for Auxiliary Emissions Control Device (AECD) #2 + /// + EngineRunTimeForAecd2 = 0x82, + + /// + /// PID 0x83 - NOx sensor + /// + NoxSensor = 0x83, + + /// + /// PID 0x84 - Manifold surface temperature + /// + ManifoldSurfaceTemperature = 0x84, + + /// + /// PID 0x85 - NOx reagent system + /// + NoxReagentSystem = 0x85, + + /// + /// PID 0x86 - Particulate matter (PM) sensor + /// + ParticulateMatterSensor = 0x86, + + /// + /// PID 0x87 - Intake manifold absolute pressure + /// + IntakeManifoldAbsolutePressure2 = 0x87, + + /// + /// PID 0x88 - SCR Induce System + /// + ScrInduceSystem = 0x88, + + /// + /// PID 0x89 - Run time for AECD 3 + /// + RunTimeForAecd3 = 0x89, + + /// + /// PID 0x8A - Run time for AECD 4 + /// + RunTimeForAecd4 = 0x8A, + + /// + /// PID 0x8B - Run time for AECD 5 + /// + RunTimeForAecd5 = 0x8B, + + /// + /// PID 0x8C - Run time for AECD 6 + /// + RunTimeForAecd6 = 0x8C, + + /// + /// PID 0x8D - Run time for AECD 7 + /// + RunTimeForAecd7 = 0x8D, + + /// + /// PID 0x8E - Run time for AECD 8 + /// + RunTimeForAecd8 = 0x8E, + + /// + /// PID 0x8F - Run time for AECD 9 + /// + RunTimeForAecd9 = 0x8F, + + /// + /// PID 0x90 - Run time for AECD 10 + /// + RunTimeForAecd10 = 0x90, + + /// + /// PID 0x91 - Exhaust Gas Temperature (EGT) Sensor Bank 1 + /// + EgtSensorBank1 = 0x91, + + /// + /// PID 0x92 - Exhaust Gas Temperature (EGT) Sensor Bank 2 + /// + EgtSensorBank2 = 0x92, + + /// + /// PID 0x93 - Diesel Particulate Filter 1, Differential Pressure Sensor + /// + DieselParticulateFilter1DifferentialPressureSensor = 0x93, + + /// + /// PID 0x94 - Diesel Particulate Filter 2, Differential Pressure Sensor + /// + DieselParticulateFilter2DifferentialPressureSensor = 0x94, + + /// + /// PID 0x95 - Diesel Particulate Filter 1, Temperature Sensor + /// + DieselParticulateFilter1TemperatureSensor = 0x95, + + /// + /// PID 0x96 - Diesel Particulate Filter 2, Temperature Sensor + /// + DieselParticulateFilter2TemperatureSensor = 0x96, + + /// + /// PID 0x97 - Selective Catalytic Reduction (SCR) Catalyst Temperature + /// + ScrCatalystTemperature = 0x97, + + /// + /// PID 0x98 - NOx Emission Rate + /// + NoxEmissionRate = 0x98, + + /// + /// PID 0x99 - Exhaust Gas Recirculation (EGR) Temperature Sensor + /// + EgrTemperatureSensor = 0x99, + + /// + /// PID 0x9A - Oxygen Sensor Monitoring Bank 1 + /// + OxygenSensorMonitoringBank1 = 0x9A, + + /// + /// PID 0x9B - Oxygen Sensor Monitoring Bank 2 + /// + OxygenSensorMonitoringBank2 = 0x9B, + + /// + /// PID 0x9C - Oxygen Sensor Monitoring Bank 3 + /// + OxygenSensorMonitoringBank3 = 0x9C, + + /// + /// PID 0x9D - Oxygen Sensor Monitoring Bank 4 + /// + OxygenSensorMonitoringBank4 = 0x9D, + + /// + /// PID 0x9E - Oxygen Sensor Monitoring Bank 5 + /// + OxygenSensorMonitoringBank5 = 0x9E, + + /// + /// PID 0x9F - Oxygen Sensor Monitoring Bank 6 + /// + OxygenSensorMonitoringBank6 = 0x9F, + + /// + /// PID 0xA0 - Supported PIDs A1-C0 + /// + SupportedPids_A1_C0 = 0xA0, + + /// + /// PID 0xA1 - Fuel System Control Mode + /// + FuelSystemControlMode = 0xA1, + + /// + /// PID 0xA2 - Transmission Actual Gear Ratio + /// + TransmissionActualGearRatio = 0xA2, + + /// + /// PID 0xA3 - Diesel Particulate Filter Temperature Sensor 1 + /// + DpfTemperatureSensor1 = 0xA3, + + /// + /// PID 0xA4 - Diesel Particulate Filter Temperature Sensor 2 + /// + DpfTemperatureSensor2 = 0xA4, + + /// + /// PID 0xA5 - Diesel Particulate Filter Temperature Sensor 3 + /// + DpfTemperatureSensor3 = 0xA5, + + /// + /// PID 0xA6 - Diesel Particulate Filter Temperature Sensor 4 + /// + DpfTemperatureSensor4 = 0xA6, + + /// + /// PID 0xA7 - Selective Catalytic Reduction (SCR) Catalyst Monitoring + /// + ScrCatalystMonitoring = 0xA7, + + /// + /// PID 0xA8 - Diesel Particulate Filter (DPF) Monitoring + /// + DpfMonitoring = 0xA8, + + /// + /// PID 0xA9 - Exhaust Gas Recirculation (EGR) Monitoring + /// + EgrMonitoring = 0xA9, + + /// + /// PID 0xAA - Oxygen Sensor 1, Short-Term Fuel Trim + /// + OxygenSensor1ShortTermFuelTrim_2 = 0xAA, + + /// + /// PID 0xAB - Oxygen Sensor 2, Short-Term Fuel Trim + /// + OxygenSensor2ShortTermFuelTrim_2 = 0xAB, + + /// + /// PID 0xAC - Oxygen Sensor 3, Short-Term Fuel Trim + /// + OxygenSensor3ShortTermFuelTrim_2 = 0xAC, + + /// + /// PID 0xAD - Oxygen Sensor 4, Short-Term Fuel Trim + /// + OxygenSensor4ShortTermFuelTrim_2 = 0xAD, + + /// + /// PID 0xAE - Fuel Trim + /// + FuelTrim = 0xAE, + + /// + /// PID 0xAF - Commanded Diesel Particulate Filter (DPF) Regeneration + /// + CommandedDpfRegeneration = 0xAF, + + /// + /// PID 0xB0 - Requested DPF Regeneration + /// + RequestedDpfRegeneration = 0xB0, + + /// + /// PID 0xB1 - DPF Regen Inhibit Switch Status + /// + DpfRegenInhibitSwitchStatus = 0xB1, + + /// + /// PID 0xB2 - Diesel Oxidation Catalyst (DOC) Temperature Sensor + /// + DocTemperatureSensor = 0xB2, + + /// + /// PID 0xB3 - Diesel Particulate Filter (DPF) Temperature Sensor 5 + /// + DpfTemperatureSensor5 = 0xB3, + + /// + /// PID 0xB4 - Diesel Particulate Filter (DPF) Temperature Sensor 6 + /// + DpfTemperatureSensor6 = 0xB4, + + /// + /// PID 0xB5 - Diesel Particulate Filter (DPF) Temperature Sensor 7 + /// + DpfTemperatureSensor7 = 0xB5, + + /// + /// PID 0xB6 - Diesel Particulate Filter (DPF) Temperature Sensor 8 + /// + DpfTemperatureSensor8 = 0xB6, + + /// + /// PID 0xB7 - Diesel Particulate Filter (DPF) Temperature Sensor 9 + /// + DpfTemperatureSensor9 = 0xB7, + + /// + /// PID 0xB8 - Diesel Particulate Filter (DPF) Temperature Sensor 10 + /// + DpfTemperatureSensor10 = 0xB8, + + /// + /// PID 0xB9 - NOx Reduction Catalyst Monitoring + /// + NoxReductionCatalystMonitoring = 0xB9, + + /// + /// PID 0xBA - Fuel Injection Pressure Control + /// + FuelInjectionPressureControl = 0xBA, + + /// + /// PID 0xBB - SCR Induce System 2 + /// + ScrInduceSystem2 = 0xBB, + + /// + /// PID 0xBC - DOC Temperature Sensor 2 + /// + DocTemperatureSensor2 = 0xBC, + + /// + /// PID 0xBD - Selective Catalytic Reduction (SCR) Catalyst Temperature Sensor 1 + /// + ScrCatalystTemperatureSensor1 = 0xBD, + + /// + /// PID 0xBE - Selective Catalytic Reduction (SCR) Catalyst Temperature Sensor 2 + /// + ScrCatalystTemperatureSensor2 = 0xBE, + + /// + /// PID 0xBF - Diesel Particulate Filter (DPF) Differential Pressure Sensor + /// + DpfDifferentialPressureSensor2 = 0xBF, + + /// + /// PID 0xC0 - Supported PIDs C1-E0 + /// + SupportedPids_C1_E0 = 0xC0, + + /// + /// PID 0xC1 - Engine Oil Temperature 2 + /// + EngineOilTemperature2 = 0xC1, + + /// + /// PID 0xC2 - Fuel Injection Quantity + /// + FuelInjectionQuantity = 0xC2, + + /// + /// PID 0xC3 - Diesel Particulate Filter (DPF) Status + /// + DpfStatus = 0xC3, + + /// + /// PID 0xC4 - Selective Catalytic Reduction (SCR) Efficiency + /// + ScrEfficiency = 0xC4, + + /// + /// PID 0xC5 - Diesel Oxidation Catalyst (DOC) Efficiency + /// + DocEfficiency = 0xC5, + + /// + /// PID 0xC6 - Exhaust Gas Temperature (EGT) Sensor 2 + /// + EgtSensor2 = 0xC6, + + /// + /// PID 0xC7 - Diesel Particulate Filter (DPF) Differential Pressure Sensor 2 + /// + DpfDifferentialPressureSensor3 = 0xC7, + + /// + /// PID 0xC8 - Selective Catalytic Reduction (SCR) Temperature Sensor + /// + ScrTemperatureSensor = 0xC8, + + /// + /// PID 0xC9 - Exhaust Gas Recirculation (EGR) Error + /// + EgrError2 = 0xC9, + + /// + /// PID 0xCA - Intake Air Temperature Sensor 2 + /// + IntakeAirTemperatureSensor2 = 0xCA, + + /// + /// PID 0xCB - Turbocharger Boost Pressure Control + /// + TurbochargerBoostPressureControl = 0xCB, + + /// + /// PID 0xCC - Turbocharger Speed + /// + TurbochargerSpeed = 0xCC, + + /// + /// PID 0xCD - Diesel Particulate Filter (DPF) Temperature + /// + DpfTemperature3 = 0xCD, + + /// + /// PID 0xCE - Diesel Particulate Filter (DPF) Regeneration Inhibit Switch Status + /// + DpfRegenInhibitSwitchStatus2 = 0xCE, + + /// + /// PID 0xCF - Exhaust Pressure Control Valve + /// + ExhaustPressureControlValve = 0xCF, + + /// + /// PID 0xD0 - Diesel Particulate Filter (DPF) Differential Pressure Sensor 3 + /// + DpfDifferentialPressureSensor4 = 0xD0, + + /// + /// PID 0xD1 - Exhaust Gas Recirculation (EGR) Temperature Sensor 2 + /// + EgrTemperatureSensor2 = 0xD1, + + /// + /// PID 0xD2 - Exhaust Gas Recirculation (EGR) Temperature Sensor 3 + /// + EgrTemperatureSensor3 = 0xD2, + + /// + /// PID 0xD3 - Exhaust Gas Temperature (EGT) Sensor 3 + /// + EgtSensor3 = 0xD3, + + /// + /// PID 0xD4 - Exhaust Gas Temperature (EGT) Sensor 4 + /// + EgtSensor4 = 0xD4, + + /// + /// PID 0xD5 - Exhaust Gas Temperature (EGT) Sensor 5 + /// + EgtSensor5 = 0xD5, + + /// + /// PID 0xD6 - Exhaust Gas Temperature (EGT) Sensor 6 + /// + EgtSensor6 = 0xD6, + + /// + /// PID 0xD7 - Oxygen Sensor 7 + /// + OxygenSensor7 = 0xD7, + + /// + /// PID 0xD8 - Oxygen Sensor 8 + /// + OxygenSensor8 = 0xD8, + + /// + /// PID 0xD9 - Oxygen Sensor 9 + /// + OxygenSensor9 = 0xD9, + + /// + /// PID 0xDA - Oxygen Sensor 10 + /// + OxygenSensor10 = 0xDA, + + /// + /// PID 0xDB - Exhaust Gas Recirculation (EGR) Differential Pressure Sensor + /// + EgrDifferentialPressureSensor = 0xDB, + + /// + /// PID 0xDC - Exhaust Gas Recirculation (EGR) Differential Pressure Sensor 2 + /// + EgrDifferentialPressureSensor2 = 0xDC, + + /// + /// PID 0xDD - Diesel Particulate Filter (DPF) Temperature Sensor 11 + /// + DpfTemperatureSensor11 = 0xDD, + + /// + /// PID 0xDE - Diesel Particulate Filter (DPF) Temperature Sensor 12 + /// + DpfTemperatureSensor12 = 0xDE, + + /// + /// PID 0xDF - Exhaust Gas Temperature (EGT) Sensor 7 + /// + EgtSensor7 = 0xDF, + + /// + /// PID 0xE0 - Supported PIDs E1-FF + /// + SupportedPids_E1_FF = 0xE0, + + /// + /// PID 0xE1 - Fuel Injection Pressure Regulator + /// + FuelInjectionPressureRegulator = 0xE1, + + /// + /// PID 0xE2 - Turbocharger Compressor Inlet Temperature + /// + TurbochargerCompressorInletTemperature = 0xE2, + + /// + /// PID 0xE3 - Boost Pressure Control Status + /// + BoostPressureControlStatus = 0xE3, + + /// + /// PID 0xE4 - Turbocharger Turbine Outlet Temperature + /// + TurbochargerTurbineOutletTemperature = 0xE4, + + /// + /// PID 0xE5 - Variable Geometry Turbo (VGT) Control + /// + VgtControl = 0xE5, + + /// + /// PID 0xE6 - Wastegate Control + /// + WastegateControl_E6 = 0xE6, + + /// + /// PID 0xE7 - Exhaust Pressure Regulator Valve Control + /// + ExhaustPressureRegulatorValveControl = 0xE7, + + /// + /// PID 0xE8 - Exhaust Gas Recirculation (EGR) Cooler Bypass Control + /// + EgrCoolerBypassControl = 0xE8, + + /// + /// PID 0xE9 - Fuel Pressure Control Valve + /// + FuelPressureControlValve = 0xE9, + + /// + /// PID 0xEA - Fuel Injection Quantity Balance + /// + FuelInjectionQuantityBalance = 0xEA, + + /// + /// PID 0xEB - Cylinder Deactivation Status + /// + CylinderDeactivationStatus = 0xEB, + + /// + /// PID 0xEC - Exhaust Gas Temperature (EGT) Sensor 8 + /// + EgtSensor8 = 0xEC, + + /// + /// PID 0xED - Diesel Oxidation Catalyst (DOC) Inlet Temperature + /// + DocInletTemperature = 0xED, + + /// + /// PID 0xEE - Diesel Oxidation Catalyst (DOC) Outlet Temperature + /// + DocOutletTemperature = 0xEE, + + /// + /// PID 0xEF - Diesel Particulate Filter (DPF) Inlet Temperature + /// + DpfInletTemperature = 0xEF, + + /// + /// PID 0xF0 - Diesel Particulate Filter (DPF) Outlet Temperature + /// + DpfOutletTemperature = 0xF0, + + /// + /// PID 0xF1 - Selective Catalytic Reduction (SCR) Inlet Temperature + /// + ScrInletTemperature = 0xF1, + + /// + /// PID 0xF2 - Selective Catalytic Reduction (SCR) Outlet Temperature + /// + ScrOutletTemperature = 0xF2, + + /// + /// PID 0xF3 - Exhaust Gas Recirculation (EGR) Temperature Sensor 4 + /// + EgrTemperatureSensor4 = 0xF3, + + /// + /// PID 0xF4 - Exhaust Gas Recirculation (EGR) Temperature Sensor 5 + /// + EgrTemperatureSensor5 = 0xF4, + + /// + /// PID 0xF5 - Turbocharger Speed 2 + /// + TurbochargerSpeed2 = 0xF5, + + /// + /// PID 0xF6 - Cylinder Pressure + /// + CylinderPressure = 0xF6, + + /// + /// PID 0xF7 - Engine Oil Temperature 3 + /// + EngineOilTemperature3 = 0xF7, + + /// + /// PID 0xF8 - Engine Coolant Temperature 2 + /// + EngineCoolantTemperature2_F8 = 0xF8, + + /// + /// PID 0xF9 - Transmission Oil Temperature 2 + /// + TransmissionOilTemperature2 = 0xF9, + + /// + /// PID 0xFA - Fuel Temperature Sensor 2 + /// + FuelTemperatureSensor2 = 0xFA, + + /// + /// PID 0xFB - Intake Air Temperature Sensor 3 + /// + IntakeAirTemperatureSensor3 = 0xFB, + + /// + /// PID 0xFC - Exhaust Gas Temperature (EGT) Sensor 9 + /// + EgtSensor9 = 0xFC, + + /// + /// PID 0xFD - Exhaust Gas Temperature (EGT) Sensor 10 + /// + EgtSensor10 = 0xFD, + + /// + /// PID 0xFE - Commanded Torque + /// + CommandedTorque = 0xFE, + + /// + /// PID 0xFF - Maximum Available Torque + /// + MaximumAvailableTorque = 0xFF, +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/PidRequestHandlerCollection.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/PidRequestHandlerCollection.cs new file mode 100644 index 000000000..f16a62e4b --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/PidRequestHandlerCollection.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Meadow.Foundation.Telematics.OBD2; + +public delegate byte[] PidRequestHandler(ushort pid); + +public class PidRequestHandlerCollection : IEnumerable +{ + private Dictionary _requestHandlers = new(); + + internal PidRequestHandlerCollection() + { + } + + public PidRequestHandler? GetHandler(Pid pid) + { + return GetHandler((ushort)pid); + } + + public PidRequestHandler? GetHandler(ushort pid) + { + lock (_requestHandlers) + { + if (_requestHandlers.ContainsKey(pid)) + { + return _requestHandlers[pid]; + } + return null; + } + } + + public void Add(Pid pid, PidRequestHandler handler) + { + Add((ushort)pid, handler); + } + + public void Add(ushort pid, PidRequestHandler handler) + { + lock (_requestHandlers) + { + if (_requestHandlers.ContainsKey(pid)) + { + throw new ArgumentException($"Handler for PID 0x{(byte)pid:X2} already registered in this ECU"); + } + + _requestHandlers.Add(pid, handler); + } + } + + public int Count => _requestHandlers.Count; + + public void Clear() + { + lock (_requestHandlers) + { + _requestHandlers.Clear(); + } + } + + /// + public IEnumerator GetEnumerator() + { + return _requestHandlers.Values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} \ No newline at end of file diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/SaeStandardQueryFrame.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/SaeStandardQueryFrame.cs new file mode 100644 index 000000000..1451bb623 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/SaeStandardQueryFrame.cs @@ -0,0 +1,37 @@ +using Meadow.Hardware; +using System; + +namespace Meadow.Foundation.Telematics.OBD2; + +public class SaeStandardQueryFrame : Obd2QueryFrame +{ + public Pid Pid + { + get => (Pid)Payload[2]; + } + + private SaeStandardQueryFrame() + { + ID = Obd2RequestID; + Payload = new byte[8]; + Payload[0] = 2; + } + + public SaeStandardQueryFrame(Service service, byte pid) + : this() + { + Payload[1] = (byte)service; + Payload[2] = pid; + } + + internal SaeStandardQueryFrame(StandardDataFrame canFrame) + : this() + { + if (canFrame.Payload[0] != 2) + { + throw new ArgumentException("CAN frame is not a valid SAE standard request frame"); + } + this.ID = canFrame.ID; + this.Payload = canFrame.Payload; + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Service.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Service.cs new file mode 100644 index 000000000..5b03c76f9 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Service.cs @@ -0,0 +1,15 @@ +namespace Meadow.Foundation.Telematics.OBD2; + +public enum Service : byte +{ + Current = 0x01, + FreezeFrame = 0x02, + StoredDtcs = 0x03, + ClearDtcs = 0x04, + TestResusltsO2 = 0x05, + TestResultsOther = 0x06, + PendingDtcs = 0x07, + ControlOperations = 0x08, + VehicleInfo = 0x09, + PermanentDtcs = 0x0a +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Telematics.Obd2.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Telematics.Obd2.csproj new file mode 100644 index 000000000..add4dbfa4 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/Telematics.Obd2.csproj @@ -0,0 +1,27 @@ + + + 1.11.0 + Apache-2.0 + true + Wilderness Labs, Inc + netstandard2.1 + Library + Obd2 + Wilderness Labs, Inc + http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/ + Meadow.Foundation.Telematics.Obd2 + icon.png + https://github.com/WildernessLabs/Meadow.Foundation + Meadow,Meadow.Foundation,OBD2 + true + Lightweight Framework for OBD2 applications + enable + 10.0 + + + + + + + + diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/VehicleSpecificQueryFrame.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/VehicleSpecificQueryFrame.cs new file mode 100644 index 000000000..727f8b60b --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Driver/VehicleSpecificQueryFrame.cs @@ -0,0 +1,20 @@ +using Meadow.Hardware; +using System; + +namespace Meadow.Foundation.Telematics.OBD2; + +public class VehicleSpecificQueryFrame : Obd2QueryFrame +{ + public ushort Pid { get; } + + internal VehicleSpecificQueryFrame(StandardDataFrame canFrame) + { + if (canFrame.Payload[0] != 3) + { + throw new ArgumentException("CAN frame is not a valid vehicle-specific request frame"); + } + + Service = (Service)canFrame.Payload[1]; + Pid = (ushort)((canFrame.Payload[2] << 8) | canFrame.Payload[3]); + } +} diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Ecu_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Ecu_Sample/MeadowApp.cs new file mode 100644 index 000000000..8886b3d17 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Ecu_Sample/MeadowApp.cs @@ -0,0 +1,46 @@ +using Meadow; +using Meadow.Devices; +using Meadow.Foundation.ICs.CAN; +using Meadow.Foundation.Telematics.OBD2; +using System; +using System.Threading.Tasks; + +namespace Obd2.EcuSample; + +public class MeadowApp : App +{ + private Ecu ecu; + private Mcp2515 mcp; + + public override Task Initialize() + { + Resolver.Log.Info("Initialize..."); + mcp = new Mcp2515( + Device.CreateSpiBus(), + Device.Pins.D04.CreateDigitalOutputPort()); + var canBus = mcp.CreateCanBus(Meadow.Hardware.CanBitrate.Can_250kbps); + ecu = new Ecu(canBus); + + // these PIDs are reported only on request + ecu.PidRequestHandlers.Add(Pid.EngineCoolantTemperature, OnCoolantTempRequested); + + return Task.CompletedTask; + } + + private byte[] OnCoolantTempRequested(ushort pid) + { + return new byte[] { 0x00, 0x01 }; + } + + private Obd2Frame GetFuelLevel() + { + throw new NotImplementedException(); + } + + public override async Task Run() + { + + await Task.Delay(1000); + + } +} \ No newline at end of file diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Ecu_Sample/Obd2_Ecu_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Ecu_Sample/Obd2_Ecu_Sample.csproj new file mode 100644 index 000000000..39c5a85b9 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Ecu_Sample/Obd2_Ecu_Sample.csproj @@ -0,0 +1,17 @@ + + + https://github.com/WildernessLabs/Meadow.Foundation + Wilderness Labs, Inc + Wilderness Labs, Inc + true + netstandard2.1 + Library + App + 10 + + + + + + + diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Sample/MeadowApp.cs new file mode 100644 index 000000000..41ab1e4fa --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Sample/MeadowApp.cs @@ -0,0 +1,26 @@ +using Meadow; +using Meadow.Devices; +using System.Threading.Tasks; + +namespace Obd2.ClientSample +{ + public class MeadowApp : App + { + // + + public override Task Initialize() + { + Resolver.Log.Info("Initialize..."); + + + return Task.CompletedTask; + } + + public override async Task Run() + { + + await Task.Delay(1000); + + } + } +} \ No newline at end of file diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Sample/Obd2Client_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Sample/Obd2Client_Sample.csproj new file mode 100644 index 000000000..095eb0cf1 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Samples/Obd2_Sample/Obd2Client_Sample.csproj @@ -0,0 +1,15 @@ + + + https://github.com/WildernessLabs/Meadow.Foundation + Wilderness Labs, Inc + Wilderness Labs, Inc + true + netstandard2.1 + Library + App + + + + + + diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Tests/Obd2.Unit.Tests/Obd2.Unit.Tests.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Tests/Obd2.Unit.Tests/Obd2.Unit.Tests.csproj new file mode 100644 index 000000000..29af93575 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Tests/Obd2.Unit.Tests/Obd2.Unit.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Tests/Obd2.Unit.Tests/UnitTest1.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Tests/Obd2.Unit.Tests/UnitTest1.cs new file mode 100644 index 000000000..53953da89 --- /dev/null +++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Telematics.Obd2/Tests/Obd2.Unit.Tests/UnitTest1.cs @@ -0,0 +1,29 @@ +using Meadow.Foundation.Telematics.OBD2; + +namespace Obd2.Unit.Tests; + +public class UnitTest1 +{ + [Fact] + public void DtcCreationTest() + { + var data = new byte[] { 0b1100_0001, 0b0101_1000 }; + + var dtc = new Dtc(data); + + Assert.Equal(DtcCategory.U, dtc.Category); + Assert.Equal(158, dtc.Code); + Assert.Equal("U0158", dtc.ToString()); + } + + [Fact] + public void DtcSetCodeTest() + { + var dtc = new Dtc([0, 0]); + + dtc.Code = 0263; + dtc.Category = DtcCategory.C; + Assert.Equal(263, dtc.Code); + Assert.Equal(DtcCategory.C, dtc.Category); + } +} \ No newline at end of file diff --git a/Source/Meadow.Foundation.sln b/Source/Meadow.Foundation.sln index 7d69dddc4..8fb2200b7 100644 --- a/Source/Meadow.Foundation.sln +++ b/Source/Meadow.Foundation.sln @@ -1621,6 +1621,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{50BE EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "V10x_Sample", "Meadow.Foundation.Peripherals\Batteries.Voltaic.V10x\Samples\V10x_Sample\V10x_Sample.csproj", "{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Telematics.Obd2", "Telematics.Obd2", "{87FD4406-504F-4BCC-B2EF-801B465C6AD6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{B5F847D6-3E2E-4ECB-A160-9F994281D9EF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Telematics.Obd2", "Meadow.Foundation.Libraries_and_Frameworks\Telematics.Obd2\Driver\Telematics.Obd2.csproj", "{ABB5271E-F6A2-494D-9D5D-8CBE441DC64C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{C79FD13E-29BF-4CF5-A1B3-6CB3E301144B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Obd2Client_Sample", "Meadow.Foundation.Libraries_and_Frameworks\Telematics.Obd2\Samples\Obd2_Sample\Obd2Client_Sample.csproj", "{74844BA7-7B67-43DB-BE50-1615E823B658}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F28F0600-009A-4579-A766-C4C89FD70225}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Obd2.Unit.Tests", "Meadow.Foundation.Libraries_and_Frameworks\Telematics.Obd2\Tests\Obd2.Unit.Tests\Obd2.Unit.Tests.csproj", "{40A559FD-09DB-4F33-A072-9041941C9402}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Obd2_Ecu_Sample", "Meadow.Foundation.Libraries_and_Frameworks\Telematics.Obd2\Samples\Obd2_Ecu_Sample\Obd2_Ecu_Sample.csproj", "{D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ads1263", "Ads1263", "{6D5016B9-7BF5-4E9D-BBA4-A621BAE0E638}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{BEAD51B2-CF51-4836-ACBA-0911841E00F6}" @@ -3925,6 +3940,26 @@ Global {154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Release|Any CPU.ActiveCfg = Release|Any CPU {154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Release|Any CPU.Build.0 = Release|Any CPU {154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Release|Any CPU.Deploy.0 = Release|Any CPU + {ABB5271E-F6A2-494D-9D5D-8CBE441DC64C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABB5271E-F6A2-494D-9D5D-8CBE441DC64C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABB5271E-F6A2-494D-9D5D-8CBE441DC64C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABB5271E-F6A2-494D-9D5D-8CBE441DC64C}.Release|Any CPU.Build.0 = Release|Any CPU + {74844BA7-7B67-43DB-BE50-1615E823B658}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74844BA7-7B67-43DB-BE50-1615E823B658}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74844BA7-7B67-43DB-BE50-1615E823B658}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {74844BA7-7B67-43DB-BE50-1615E823B658}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74844BA7-7B67-43DB-BE50-1615E823B658}.Release|Any CPU.Build.0 = Release|Any CPU + {74844BA7-7B67-43DB-BE50-1615E823B658}.Release|Any CPU.Deploy.0 = Release|Any CPU + {40A559FD-09DB-4F33-A072-9041941C9402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40A559FD-09DB-4F33-A072-9041941C9402}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40A559FD-09DB-4F33-A072-9041941C9402}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40A559FD-09DB-4F33-A072-9041941C9402}.Release|Any CPU.Build.0 = Release|Any CPU + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}.Release|Any CPU.Build.0 = Release|Any CPU + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D}.Release|Any CPU.Deploy.0 = Release|Any CPU {B414A340-EA69-4CD3-AB8B-D0B3835527B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B414A340-EA69-4CD3-AB8B-D0B3835527B2}.Debug|Any CPU.Build.0 = Debug|Any CPU {B414A340-EA69-4CD3-AB8B-D0B3835527B2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU @@ -4744,6 +4779,14 @@ Global {56ADF95A-2ABC-4229-A13B-67CDA6DD1942} = {D0A6D7E9-A1F0-4776-BA5B-202CFDBBB608} {50BE5E08-199B-4D10-9B56-340C799B0E81} = {D0A6D7E9-A1F0-4776-BA5B-202CFDBBB608} {154268C0-1BC6-4A3E-A6CF-13E0FC4721F4} = {50BE5E08-199B-4D10-9B56-340C799B0E81} + {87FD4406-504F-4BCC-B2EF-801B465C6AD6} = {E0384B86-37FC-403C-B1F7-AA5D1B869EB1} + {B5F847D6-3E2E-4ECB-A160-9F994281D9EF} = {87FD4406-504F-4BCC-B2EF-801B465C6AD6} + {ABB5271E-F6A2-494D-9D5D-8CBE441DC64C} = {B5F847D6-3E2E-4ECB-A160-9F994281D9EF} + {C79FD13E-29BF-4CF5-A1B3-6CB3E301144B} = {87FD4406-504F-4BCC-B2EF-801B465C6AD6} + {74844BA7-7B67-43DB-BE50-1615E823B658} = {C79FD13E-29BF-4CF5-A1B3-6CB3E301144B} + {F28F0600-009A-4579-A766-C4C89FD70225} = {87FD4406-504F-4BCC-B2EF-801B465C6AD6} + {40A559FD-09DB-4F33-A072-9041941C9402} = {F28F0600-009A-4579-A766-C4C89FD70225} + {D459B5BE-39EF-4037-A3A0-59C4F5E7BE7D} = {C79FD13E-29BF-4CF5-A1B3-6CB3E301144B} {6D5016B9-7BF5-4E9D-BBA4-A621BAE0E638} = {86B81B21-8C90-4A99-B113-FA71F8A6CD8D} {BEAD51B2-CF51-4836-ACBA-0911841E00F6} = {6D5016B9-7BF5-4E9D-BBA4-A621BAE0E638} {B414A340-EA69-4CD3-AB8B-D0B3835527B2} = {6D5016B9-7BF5-4E9D-BBA4-A621BAE0E638}