Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | /** | |||
2 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
3 | * | |||
4 | * EGO Exhaust Gas Oxygen, also known as AFR Air/Fuel Ratio :) connectet over analog input | |||
5 | * | |||
6 | */ | |||
7 | #include "pch.h" | |||
8 | ||||
9 | StoredValueSensor smoothedLambda1Sensor(SensorType::SmoothedLambda1, MS2NT(500)); | |||
10 | StoredValueSensor smoothedLambda2Sensor(SensorType::SmoothedLambda2, MS2NT(500)); | |||
11 | ||||
12 | ExpAverage expAverageLambda1; | |||
13 | ExpAverage expAverageLambda2; | |||
14 | ||||
15 | #include "cyclic_buffer.h" | |||
16 | ||||
17 | ✗ | bool hasAfrSensor() { | ||
18 | ✗ | if (engineConfiguration->enableAemXSeries) { | ||
19 | ✗ | return true; | ||
20 | } | |||
21 | ||||
22 | ✗ | return isAdcChannelValid(engineConfiguration->afr.hwChannel); | ||
23 | } | |||
24 | ||||
25 | ✗ | float getAfr(SensorType type) { | ||
26 | ✗ | afr_sensor_s * sensor = &engineConfiguration->afr; | ||
27 | ||||
28 | ✗ | if (!isAdcChannelValid(type == SensorType::Lambda1 ? engineConfiguration->afr.hwChannel : engineConfiguration->afr.hwChannel2)) { | ||
29 | ✗ | return 0; | ||
30 | } | |||
31 | ||||
32 | ✗ | auto volts = adcGetScaledVoltage("ego", type == SensorType::Lambda1 ? sensor->hwChannel : sensor->hwChannel2); | ||
33 | ||||
34 | ✗ | float interpolatedAfr = interpolateMsg("AFR", sensor->v1, sensor->value1, sensor->v2, sensor->value2, volts.value_or(0)); | ||
35 | ||||
36 | ✗ | switch (type) { | ||
37 | ✗ | case SensorType::Lambda1: { | ||
38 | ✗ | expAverageLambda1.setSmoothingFactor(engineConfiguration->afrExpAverageAlpha); | ||
39 | ✗ | smoothedLambda1Sensor.setValidValue(expAverageLambda1.initOrAverage(interpolatedAfr), getTimeNowNt()); | ||
40 | ✗ | break; | ||
41 | } | |||
42 | ✗ | case SensorType::Lambda2: { | ||
43 | ✗ | expAverageLambda2.setSmoothingFactor(engineConfiguration->afrExpAverageAlpha); | ||
44 | ✗ | smoothedLambda2Sensor.setValidValue(expAverageLambda2.initOrAverage(interpolatedAfr), getTimeNowNt()); | ||
45 | ✗ | break; | ||
46 | } | |||
47 | ✗ | default: | ||
48 | ✗ | break; | ||
49 | } | |||
50 | ||||
51 | ✗ | return interpolateMsg("AFR", sensor->v1, sensor->value1, sensor->v2, sensor->value2, volts.value_or(0)) | ||
52 | ✗ | + engineConfiguration->egoValueShift; | ||
53 | } | |||
54 | ||||
55 | // this method is only used for canned tunes now! User-facing selection is defined in tunerstudio.template.ini using settingSelector | |||
56 | 589 | static void initEgoSensor(afr_sensor_s *sensor, ego_sensor_e type) { | ||
57 | ||||
58 |
2/6✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 586 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
589 | switch (type) { | |
59 | ✗ | case ES_BPSX_D1: | ||
60 | /** | |||
61 | * This decodes BPSX D1 Wideband Controller analog signal | |||
62 | */ | |||
63 | ✗ | sensor->v1 = 0; | ||
64 | ✗ | sensor->value1 = 9; | ||
65 | ✗ | sensor->v2 = 5; | ||
66 | ✗ | sensor->value2 = 19; | ||
67 | ✗ | break; | ||
68 | ||||
69 | ✗ | case ES_Innovate_MTX_L: | ||
70 | ✗ | sensor->v1 = 0; | ||
71 | ✗ | sensor->value1 = 7.35; | ||
72 | ✗ | sensor->v2 = 5; | ||
73 | ✗ | sensor->value2 = 22.39; | ||
74 | ✗ | break; | ||
75 |
1/1✓ Decision 'true' taken 586 times.
|
586 | case ES_14Point7_Free: | |
76 | 586 | sensor->v1 = 0; | ||
77 | 586 | sensor->value1 = 9.996; | ||
78 | 586 | sensor->v2 = 5; | ||
79 | 586 | sensor->value2 = 19.992; | ||
80 | 586 | break; | ||
81 | // technically 14Point7 and PLX use the same scale | |||
82 |
1/1✓ Decision 'true' taken 3 times.
|
3 | case ES_PLX: | |
83 | 3 | sensor->v1 = 0; | ||
84 | 3 | sensor->value1 = 10; | ||
85 | 3 | sensor->v2 = 5; | ||
86 | 3 | sensor->value2 = 20; | ||
87 | 3 | break; | ||
88 | ✗ | case ES_AEM: | ||
89 | ✗ | sensor->v1 = 0.5; | ||
90 | ✗ | sensor->value1 = 8.5; | ||
91 | ✗ | sensor->v2 = 4.5; | ||
92 | ✗ | sensor->value2 = 18; | ||
93 | ✗ | break; | ||
94 | ✗ | default: | ||
95 | ✗ | firmwareError(ObdCode::CUSTOM_EGO_TYPE, "Unexpected EGO %d", type); | ||
96 | ✗ | break; | ||
97 | } | |||
98 | 589 | } | ||
99 | ||||
100 | 589 | void setEgoSensor(ego_sensor_e type) { | ||
101 | 589 | engineConfiguration->afr_type = type; | ||
102 | 589 | initEgoSensor(&engineConfiguration->afr, type); | ||
103 | 589 | } | ||
104 |