1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
/*************************************************************************
* Arduino Library for Freematics OBD-II UART Adapter
* Distributed under BSD License
* Visit https://freematics.com for more information
* (C)2012-2019 Stanley Huang <stanley@freematics.com.au>
*************************************************************************/
#include <Arduino.h>
#define OBD_TIMEOUT_SHORT 1000 /* ms */
#define OBD_TIMEOUT_LONG 10000 /* ms */
#ifndef OBDUART
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168P__)
#define OBDUART Serial
#else
#define OBDUART Serial1
#endif
#endif
#ifdef ESP32
extern HardwareSerial Serial1;
#endif
// Mode 1 PIDs
#define PID_ENGINE_LOAD 0x04
#define PID_COOLANT_TEMP 0x05
#define PID_SHORT_TERM_FUEL_TRIM_1 0x06
#define PID_LONG_TERM_FUEL_TRIM_1 0x07
#define PID_SHORT_TERM_FUEL_TRIM_2 0x08
#define PID_LONG_TERM_FUEL_TRIM_2 0x09
#define PID_FUEL_PRESSURE 0x0A
#define PID_INTAKE_MAP 0x0B
#define PID_RPM 0x0C
#define PID_SPEED 0x0D
#define PID_TIMING_ADVANCE 0x0E
#define PID_INTAKE_TEMP 0x0F
#define PID_MAF_FLOW 0x10
#define PID_THROTTLE 0x11
#define PID_AUX_INPUT 0x1E
#define PID_RUNTIME 0x1F
#define PID_DISTANCE_WITH_MIL 0x21
#define PID_COMMANDED_EGR 0x2C
#define PID_EGR_ERROR 0x2D
#define PID_COMMANDED_EVAPORATIVE_PURGE 0x2E
#define PID_FUEL_LEVEL 0x2F
#define PID_WARMS_UPS 0x30
#define PID_DISTANCE 0x31
#define PID_EVAP_SYS_VAPOR_PRESSURE 0x32
#define PID_BAROMETRIC 0x33
#define PID_CATALYST_TEMP_B1S1 0x3C
#define PID_CATALYST_TEMP_B2S1 0x3D
#define PID_CATALYST_TEMP_B1S2 0x3E
#define PID_CATALYST_TEMP_B2S2 0x3F
#define PID_CONTROL_MODULE_VOLTAGE 0x42
#define PID_ABSOLUTE_ENGINE_LOAD 0x43
#define PID_AIR_FUEL_EQUIV_RATIO 0x44
#define PID_RELATIVE_THROTTLE_POS 0x45
#define PID_AMBIENT_TEMP 0x46
#define PID_ABSOLUTE_THROTTLE_POS_B 0x47
#define PID_ABSOLUTE_THROTTLE_POS_C 0x48
#define PID_ACC_PEDAL_POS_D 0x49
#define PID_ACC_PEDAL_POS_E 0x4A
#define PID_ACC_PEDAL_POS_F 0x4B
#define PID_COMMANDED_THROTTLE_ACTUATOR 0x4C
#define PID_TIME_WITH_MIL 0x4D
#define PID_TIME_SINCE_CODES_CLEARED 0x4E
#define PID_ETHANOL_FUEL 0x52
#define PID_FUEL_RAIL_PRESSURE 0x59
#define PID_HYBRID_BATTERY_PERCENTAGE 0x5B
#define PID_ENGINE_OIL_TEMP 0x5C
#define PID_FUEL_INJECTION_TIMING 0x5D
#define PID_ENGINE_FUEL_RATE 0x5E
#define PID_ENGINE_TORQUE_DEMANDED 0x61
#define PID_ENGINE_TORQUE_PERCENTAGE 0x62
#define PID_ENGINE_REF_TORQUE 0x63
// non-OBD/custom PIDs (no mode number)
#define PID_ACC 0x20
#define PID_GYRO 0x21
#define PID_COMPASS 0x22
#define PID_MEMS_TEMP 0x23
#define PID_BATTERY_VOLTAGE 0x24
typedef enum {
PROTO_AUTO = 0,
PROTO_ISO_9141_2 = 3,
PROTO_KWP2000_5KBPS = 4,
PROTO_KWP2000_FAST = 5,
PROTO_CAN_11B_500K = 6,
PROTO_CAN_29B_500K = 7,
PROTO_CAN_29B_250K = 8,
PROTO_CAN_11B_250K = 9,
} OBD_PROTOCOLS;
// states
typedef enum {
OBD_DISCONNECTED = 0,
OBD_CONNECTING = 1,
OBD_CONNECTED = 2,
OBD_FAILED = 3
} OBD_STATES;
uint16_t hex2uint16(const char *p);
uint8_t hex2uint8(const char *p);
class COBD
{
public:
// begin serial UART
virtual byte begin();
// terminate communication channel
virtual void end();
// initialize OBD-II connection
virtual bool init(OBD_PROTOCOLS protocol = PROTO_AUTO);
// reset OBD-II connection
virtual void reset();
// un-initialize OBD-II connection
virtual void uninit();
// set serial baud rate
virtual bool setBaudRate(unsigned long baudrate);
// get connection state
virtual OBD_STATES getState() { return m_state; }
// read specified OBD-II PID value
virtual bool readPID(byte pid, int& result);
// read multiple (up to 8) OBD-II PID values, return number of values obtained
virtual byte readPID(const byte pid[], byte count, int result[]);
// set device into low power mode
virtual void enterLowPowerMode();
// wake up device from low power mode
virtual void leaveLowPowerMode();
// send AT command and receive response (return bytes received)
virtual byte sendCommand(const char* cmd, char* buf, byte bufsize, int timeout = OBD_TIMEOUT_LONG);
// read diagnostic trouble codes (return number of DTCs read)
virtual byte readDTC(uint16_t codes[], byte maxCodes = 1);
// clear diagnostic trouble code
virtual void clearDTC();
// get battery voltage (works without ECU)
virtual float getVoltage();
// get VIN as a string, buffer length should be >= OBD_RECV_BUF_SIZE
virtual bool getVIN(char* buffer, byte bufsize);
// initialize MEMS sensor (enable or disable sensor fusion by quanterion algorithm)
virtual bool memsInit(bool fusion = false);
// read out MEMS data (acc for accelerometer, gyr for gyroscope, temp in 0.1 celcius degree)
virtual bool memsRead(int16_t* acc, int16_t* gyr = 0, int16_t* mag = 0, int16_t* temp = 0);
// get computed orientation values
virtual bool memsOrientation(float& yaw, float& pitch, float& roll);
// retrive and parse the response of specifie PID
virtual bool getResult(byte& pid, int& result);
// determine if the PID is supported
virtual bool isValidPID(byte pid);
// get adapter firmware version
virtual byte getVersion();
// set current PID mode
byte dataMode = 1;
// occurrence of errors
byte errors = 0;
// bit map of supported PIDs
byte pidmap[4 * 4] = {0};
protected:
virtual char* getResponse(byte& pid, char* buffer, byte bufsize);
virtual int receive(char* buffer, int bufsize, unsigned int timeout = OBD_TIMEOUT_SHORT);
virtual void write(const char* s);
virtual uint8_t getPercentageValue(char* data);
virtual uint16_t getLargeValue(char* data);
virtual uint8_t getSmallValue(char* data);
virtual int16_t getTemperatureValue(char* data);
virtual int normalizeData(byte pid, char* data);
virtual byte checkErrorMessage(const char* buffer);
virtual char* getResultValue(char* buf);
OBD_STATES m_state = OBD_DISCONNECTED;
private:
void recover();
virtual void idleTasks() {}
bool m_fusion = false;
};
|