Skip to content

Commit 259b0d7

Browse files
authored
Merge pull request #282 from jimwhitelaw/new-calculators
Implement new calculators
2 parents 286023d + f898b86 commit 259b0d7

5 files changed

Lines changed: 896 additions & 213 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ test/README
4343
.vscode/extensions.json
4444
platformio.ini
4545
.gitignore
46+
.vscode/settings.json
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
3+
This example shows how to query and process OBD2 standard PIDs that
4+
return a multiline response and require custom processing.
5+
6+
Processing Response with a custom calculation function
7+
In this example, we manually extract the data value from the query response and perform
8+
some post-processing to calculate the correct value.
9+
10+
Managing Query State
11+
We also demonstrate managing the query state used by the loop() method. This is typically
12+
managed internally by ELMduino for standard PID methods.
13+
14+
*/
15+
16+
#include "BluetoothSerial.h"
17+
#include "ELMduino.h"
18+
19+
BluetoothSerial SerialBT;
20+
#define ELM_PORT SerialBT
21+
#define DEBUG_PORT Serial
22+
23+
ELM327 myELM327;
24+
25+
int nb_query_state = SEND_COMMAND; // Set the inital query state ready to send a command
26+
27+
28+
// Applies calculation formula for PID 0x22 (Fuel Rail Pressure)
29+
double calcDPF() {
30+
double B = myELM327.payload[6];
31+
double C = myELM327.payload[5];
32+
return ((B * 256) + C) / 100;
33+
}
34+
35+
void setup()
36+
{
37+
DEBUG_PORT.begin(115200);
38+
// SerialBT.setPin("1234");
39+
ELM_PORT.begin("ArduHUD", true);
40+
41+
if (!ELM_PORT.connect("OBDII"))
42+
{
43+
DEBUG_PORT.println("Couldn't connect to ELM327 device.");
44+
while (1);
45+
}
46+
47+
if (!myELM327.begin(ELM_PORT, true, 2000))
48+
{
49+
Serial.println("ELM327 device couldn't connect to ECU.");
50+
while (1);
51+
}
52+
53+
Serial.println("Connected to ELM327");
54+
55+
}
56+
57+
void loop()
58+
{
59+
if (nb_query_state == SEND_COMMAND) // We are ready to send a new command
60+
{
61+
myELM327.sendCommand("017A"); // Send the PID commnad
62+
nb_query_state = WAITING_RESP; // Set the query state so we are waiting for response
63+
}
64+
else if (nb_query_state == WAITING_RESP) // Our query has been sent, check for a response
65+
{
66+
myELM327.get_response(); // Each time through the loop we will check again
67+
}
68+
69+
if (myELM327.nb_rx_state == ELM_SUCCESS) // Our response is fully received, let's get our data
70+
{
71+
double dpf = myELM327.conditionResponse(calcDPF); // Apply the formula for dpf
72+
Serial.println(dpf); // Print the adjusted value
73+
nb_query_state = SEND_COMMAND; // Reset the query state for the next command
74+
delay(5000); // Wait 5 seconds until we query again
75+
}
76+
77+
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
78+
{ // If state == ELM_GETTING_MSG, response is not yet complete. Restart the loop.
79+
nb_query_state = SEND_COMMAND; // Reset the query state for the next command
80+
myELM327.printError();
81+
delay(5000); // Wait 5 seconds until we query again
82+
}
83+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#include "BluetoothSerial.h"
2+
#include "ELMduino.h"
3+
4+
BluetoothSerial SerialBT;
5+
#define ELM_PORT SerialBT
6+
#define DEBUG_PORT Serial
7+
8+
ELM327 myELM327;
9+
uint8_t current_pid = 0;
10+
int nb_query_state = SEND_COMMAND;
11+
12+
// Define a list of PIDs to test
13+
const uint16_t pidsToTest[] = {
14+
SUPPORTED_PIDS_1_20, // 0x00
15+
MONITOR_STATUS_SINCE_DTC_CLEARED, // 0x01
16+
FREEZE_DTC, // 0x02
17+
FUEL_SYSTEM_STATUS, // 0x03
18+
ENGINE_LOAD, // 0x04
19+
ENGINE_COOLANT_TEMP, // 0x05
20+
SHORT_TERM_FUEL_TRIM_BANK_1, // 0x06
21+
LONG_TERM_FUEL_TRIM_BANK_1, // 0x07
22+
SHORT_TERM_FUEL_TRIM_BANK_2, // 0x08
23+
LONG_TERM_FUEL_TRIM_BANK_2, // 0x09
24+
FUEL_PRESSURE, // 0x0A
25+
INTAKE_MANIFOLD_ABS_PRESSURE, // 0x0B
26+
ENGINE_RPM, // 0x0C
27+
VEHICLE_SPEED, // 0x0D
28+
TIMING_ADVANCE, // 0x0E
29+
INTAKE_AIR_TEMP, // 0x0F
30+
MAF_FLOW_RATE, // 0x10
31+
THROTTLE_POSITION, // 0x11
32+
COMMANDED_SECONDARY_AIR_STATUS, // 0x12
33+
OXYGEN_SENSORS_PRESENT_2_BANKS, // 0x13
34+
OXYGEN_SENSOR_1_A, // 0x14
35+
OXYGEN_SENSOR_2_A, // 0x15
36+
OXYGEN_SENSOR_3_A, // 0x16
37+
OXYGEN_SENSOR_4_A, // 0x17
38+
OXYGEN_SENSOR_5_A, // 0x18
39+
OXYGEN_SENSOR_6_A, // 0x19
40+
OXYGEN_SENSOR_7_A, // 0x1A
41+
OXYGEN_SENSOR_8_A, // 0x1B
42+
OBD_STANDARDS, // 0x1C
43+
OXYGEN_SENSORS_PRESENT_4_BANKS, // 0x1D
44+
AUX_INPUT_STATUS, // 0x1E
45+
RUN_TIME_SINCE_ENGINE_START, // 0x1F
46+
SUPPORTED_PIDS_21_40, // 0x20
47+
DISTANCE_TRAVELED_WITH_MIL_ON, // 0x21
48+
FUEL_RAIL_PRESSURE, // 0x22
49+
FUEL_RAIL_GUAGE_PRESSURE, // 0x23
50+
OXYGEN_SENSOR_1_B, // 0x24
51+
OXYGEN_SENSOR_2_B, // 0x25
52+
OXYGEN_SENSOR_3_B, // 0x26
53+
OXYGEN_SENSOR_4_B, // 0x27
54+
OXYGEN_SENSOR_5_B, // 0x28
55+
OXYGEN_SENSOR_6_B, // 0x29
56+
OXYGEN_SENSOR_7_B, // 0x2A
57+
OXYGEN_SENSOR_8_B, // 0x2B
58+
COMMANDED_EGR, // 0x2C
59+
EGR_ERROR, // 0x2D
60+
COMMANDED_EVAPORATIVE_PURGE, // 0x2E
61+
FUEL_TANK_LEVEL_INPUT, // 0x2F
62+
WARM_UPS_SINCE_CODES_CLEARED, // 0x30 - count
63+
DIST_TRAV_SINCE_CODES_CLEARED, // 0x31 - km
64+
EVAP_SYSTEM_VAPOR_PRESSURE, // 0x32 - Pa
65+
ABS_BAROMETRIC_PRESSURE, // 0x33 - kPa
66+
OXYGEN_SENSOR_1_C, // 0x34 - ratio mA
67+
OXYGEN_SENSOR_2_C, // 0x35 - ratio mA
68+
OXYGEN_SENSOR_3_C, // 0x36 - ratio mA
69+
OXYGEN_SENSOR_4_C, // 0x37 - ratio mA
70+
OXYGEN_SENSOR_5_C, // 0x38 - ratio mA
71+
OXYGEN_SENSOR_6_C, // 0x39 - ratio mA
72+
OXYGEN_SENSOR_7_C, // 0x3A - ratio mA
73+
OXYGEN_SENSOR_8_C, // 0x3B - ratio mA
74+
CATALYST_TEMP_BANK_1_SENSOR_1, // 0x3C - °C
75+
CATALYST_TEMP_BANK_2_SENSOR_1, // 0x3D - °C
76+
CATALYST_TEMP_BANK_1_SENSOR_2, // 0x3E - °C
77+
CATALYST_TEMP_BANK_2_SENSOR_2, // 0x3F - °C
78+
SUPPORTED_PIDS_41_60, // 0x40 - bit encoded
79+
MONITOR_STATUS_THIS_DRIVE_CYCLE, // 0x41 - bit encoded
80+
CONTROL_MODULE_VOLTAGE, // 0x42 - V
81+
ABS_LOAD_VALUE, // 0x43 - %
82+
FUEL_AIR_COMMANDED_EQUIV_RATIO, // 0x44 - ratio
83+
RELATIVE_THROTTLE_POSITION, // 0x45 - %
84+
AMBIENT_AIR_TEMP, // 0x46 - °C
85+
ABS_THROTTLE_POSITION_B, // 0x47 - %
86+
ABS_THROTTLE_POSITION_C, // 0x48 - %
87+
ABS_THROTTLE_POSITION_D, // 0x49 - %
88+
ABS_THROTTLE_POSITION_E, // 0x4A - %
89+
ABS_THROTTLE_POSITION_F, // 0x4B - %
90+
COMMANDED_THROTTLE_ACTUATOR, // 0x4C - %
91+
TIME_RUN_WITH_MIL_ON, // 0x4D - min
92+
TIME_SINCE_CODES_CLEARED, // 0x4E - min
93+
MAX_VALUES_EQUIV_V_I_PRESSURE, // 0x4F - ratio V mA kPa
94+
MAX_MAF_RATE, // 0x50 - g/s
95+
FUEL_TYPE, // 0x51
96+
ETHANOL_FUEL_PERCENT, // 0x52
97+
ABS_EVAP_SYS_VAPOR_PRESSURE, // 0x53
98+
EVAP_SYS_VAPOR_PRESSURE, // 0x54
99+
SHORT_TERM_SEC_OXY_SENS_TRIM_1_3, // 0x55
100+
LONG_TERM_SEC_OXY_SENS_TRIM_1_3, // 0x56
101+
SHORT_TERM_SEC_OXY_SENS_TRIM_2_4, // 0x57
102+
LONG_TERM_SEC_OXY_SENS_TRIM_2_4, // 0x58
103+
FUEL_RAIL_ABS_PRESSURE, // 0x59
104+
RELATIVE_ACCELERATOR_PEDAL_POS, // 0x5A
105+
HYBRID_BATTERY_REMAINING_LIFE, // 0x5B
106+
ENGINE_OIL_TEMP, // 0x5C
107+
FUEL_INJECTION_TIMING, // 0x5D
108+
ENGINE_FUEL_RATE, // 0x5E
109+
EMISSION_REQUIREMENTS, // 0x5F
110+
SUPPORTED_PIDS_61_80, // 0x60
111+
DEMANDED_ENGINE_PERCENT_TORQUE, // 0x61
112+
ACTUAL_ENGINE_TORQUE, // 0x62
113+
ENGINE_REFERENCE_TORQUE, // 0x63
114+
ENGINE_PERCENT_TORQUE_DATA // 0x64
115+
};
116+
const uint8_t responseBytes[0xA9] =
117+
{
118+
4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2,
119+
4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
120+
4, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1,
121+
4, 1, 1, 2, 5, 2, 5, 3, 3, 7, 5, 5, 5, 11, 9, 3, 10, 6, 5, 5, 5, 7, 7, 5, 9, 9, 7, 7, 9, 1, 1, 13,
122+
4, 41, 41, 9, 1, 10, 5, 5, 13, 41, 41, 7, 17, 1, 1, 7, 3, 5, 2, 3, 12, 9, 9, 6, 4, 17, 4, 2, 9
123+
};
124+
125+
void setup()
126+
{
127+
DEBUG_PORT.begin(115200);
128+
// SerialBT.setPin("1234");
129+
ELM_PORT.begin("ArduHUD", true);
130+
131+
if (!ELM_PORT.connect("OBDII"))
132+
{
133+
DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 1");
134+
while (1)
135+
;
136+
}
137+
138+
if (!myELM327.begin(ELM_PORT, true, 2000))
139+
{
140+
DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 2");
141+
while (1)
142+
;
143+
}
144+
145+
DEBUG_PORT.println("Connected to ELM327");
146+
}
147+
148+
149+
150+
void loop() {
151+
if (current_pid > (sizeof(pidsToTest)/sizeof(uint16_t)) - 1)
152+
{
153+
current_pid = 0;
154+
}
155+
uint16_t pid = pidsToTest[current_pid];
156+
double result = myELM327.processPID(0x01, pid, 1, responseBytes[current_pid], 1, 0);
157+
158+
if (myELM327.nb_rx_state == ELM_SUCCESS) // Our response is fully received, let's get our data
159+
{
160+
nb_query_state = SEND_COMMAND;
161+
DEBUG_PORT.print("Result: ");
162+
DEBUG_PORT.println(result);
163+
current_pid++; // Reset the query state for the next command
164+
delay(500); // Wait 0.5 seconds until we query again
165+
}
166+
167+
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
168+
{ // If state == ELM_GETTING_MSG, response is not yet complete. Restart the loop.
169+
nb_query_state = SEND_COMMAND; // Reset the query state for the next command
170+
myELM327.printError();
171+
delay(500); // Wait 0.5 seconds until we query again
172+
}
173+
}

0 commit comments

Comments
 (0)