Small project to display some OBD values from the Toyota GT86/ Subaru BRZ/ Scion FRS on an OLED display.
Dependencies: Adafruit_GFX MODSERIAL mbed-rtos mbed
PidDecoder.cpp@3:eb807d330292, 2014-04-27 (annotated)
- Committer:
- chrta
- Date:
- Sun Apr 27 17:11:32 2014 +0000
- Revision:
- 3:eb807d330292
- Child:
- 5:0b229ba8ede5
Working pid decoder
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
chrta | 3:eb807d330292 | 1 | #include "PidDecoder.h" |
chrta | 3:eb807d330292 | 2 | #include "MODSERIAL.h" |
chrta | 3:eb807d330292 | 3 | |
chrta | 3:eb807d330292 | 4 | extern MODSERIAL pc; |
chrta | 3:eb807d330292 | 5 | |
chrta | 3:eb807d330292 | 6 | class PidValue |
chrta | 3:eb807d330292 | 7 | { |
chrta | 3:eb807d330292 | 8 | public: |
chrta | 3:eb807d330292 | 9 | PidValue(const char* name, const char* unit); |
chrta | 3:eb807d330292 | 10 | virtual bool decode(const uint8_t* data, uint16_t length) = 0; |
chrta | 3:eb807d330292 | 11 | void print(); |
chrta | 3:eb807d330292 | 12 | const char* getName(); |
chrta | 3:eb807d330292 | 13 | protected: |
chrta | 3:eb807d330292 | 14 | unsigned int m_value; |
chrta | 3:eb807d330292 | 15 | const char* m_unit; |
chrta | 3:eb807d330292 | 16 | const char* m_name; |
chrta | 3:eb807d330292 | 17 | }; |
chrta | 3:eb807d330292 | 18 | |
chrta | 3:eb807d330292 | 19 | class EngineRpm : public PidValue |
chrta | 3:eb807d330292 | 20 | { |
chrta | 3:eb807d330292 | 21 | public: |
chrta | 3:eb807d330292 | 22 | EngineRpm(); |
chrta | 3:eb807d330292 | 23 | virtual bool decode(const uint8_t* data, uint16_t length); |
chrta | 3:eb807d330292 | 24 | }; |
chrta | 3:eb807d330292 | 25 | |
chrta | 3:eb807d330292 | 26 | |
chrta | 3:eb807d330292 | 27 | class EngineCoolantTemp : public PidValue |
chrta | 3:eb807d330292 | 28 | { |
chrta | 3:eb807d330292 | 29 | public: |
chrta | 3:eb807d330292 | 30 | EngineCoolantTemp(); |
chrta | 3:eb807d330292 | 31 | virtual bool decode(const uint8_t* data, uint16_t length); |
chrta | 3:eb807d330292 | 32 | }; |
chrta | 3:eb807d330292 | 33 | |
chrta | 3:eb807d330292 | 34 | |
chrta | 3:eb807d330292 | 35 | class VehicleSpeed : public PidValue |
chrta | 3:eb807d330292 | 36 | { |
chrta | 3:eb807d330292 | 37 | public: |
chrta | 3:eb807d330292 | 38 | VehicleSpeed(); |
chrta | 3:eb807d330292 | 39 | virtual bool decode(const uint8_t* data, uint16_t length); |
chrta | 3:eb807d330292 | 40 | }; |
chrta | 3:eb807d330292 | 41 | |
chrta | 3:eb807d330292 | 42 | class Throttle : public PidValue |
chrta | 3:eb807d330292 | 43 | { |
chrta | 3:eb807d330292 | 44 | public: |
chrta | 3:eb807d330292 | 45 | Throttle(); |
chrta | 3:eb807d330292 | 46 | virtual bool decode(const uint8_t* data, uint16_t length); |
chrta | 3:eb807d330292 | 47 | }; |
chrta | 3:eb807d330292 | 48 | |
chrta | 3:eb807d330292 | 49 | class OilTemperature : public PidValue |
chrta | 3:eb807d330292 | 50 | { |
chrta | 3:eb807d330292 | 51 | public: |
chrta | 3:eb807d330292 | 52 | OilTemperature(); |
chrta | 3:eb807d330292 | 53 | virtual bool decode(const uint8_t* data, uint16_t length); |
chrta | 3:eb807d330292 | 54 | }; |
chrta | 3:eb807d330292 | 55 | |
chrta | 3:eb807d330292 | 56 | PidValue::PidValue(const char* name, const char* unit) |
chrta | 3:eb807d330292 | 57 | : m_value(0) |
chrta | 3:eb807d330292 | 58 | , m_unit(unit) |
chrta | 3:eb807d330292 | 59 | , m_name(name) |
chrta | 3:eb807d330292 | 60 | { |
chrta | 3:eb807d330292 | 61 | } |
chrta | 3:eb807d330292 | 62 | |
chrta | 3:eb807d330292 | 63 | void PidValue::print() |
chrta | 3:eb807d330292 | 64 | { |
chrta | 3:eb807d330292 | 65 | pc.printf("%d %s\r\n", m_value, m_unit); |
chrta | 3:eb807d330292 | 66 | } |
chrta | 3:eb807d330292 | 67 | |
chrta | 3:eb807d330292 | 68 | const char* PidValue::getName() |
chrta | 3:eb807d330292 | 69 | { |
chrta | 3:eb807d330292 | 70 | return m_name; |
chrta | 3:eb807d330292 | 71 | } |
chrta | 3:eb807d330292 | 72 | |
chrta | 3:eb807d330292 | 73 | EngineRpm::EngineRpm() |
chrta | 3:eb807d330292 | 74 | : PidValue("Engine RPM", "rpm") |
chrta | 3:eb807d330292 | 75 | { |
chrta | 3:eb807d330292 | 76 | } |
chrta | 3:eb807d330292 | 77 | |
chrta | 3:eb807d330292 | 78 | bool EngineRpm::decode(const uint8_t* data, uint16_t length) |
chrta | 3:eb807d330292 | 79 | { |
chrta | 3:eb807d330292 | 80 | if (length < 2) |
chrta | 3:eb807d330292 | 81 | { |
chrta | 3:eb807d330292 | 82 | return false; |
chrta | 3:eb807d330292 | 83 | } |
chrta | 3:eb807d330292 | 84 | |
chrta | 3:eb807d330292 | 85 | if ((data[1] != 0x0C) || length != 4) |
chrta | 3:eb807d330292 | 86 | { |
chrta | 3:eb807d330292 | 87 | return false; |
chrta | 3:eb807d330292 | 88 | } |
chrta | 3:eb807d330292 | 89 | |
chrta | 3:eb807d330292 | 90 | m_value = ((data[2] << 8) | data[3]) >> 2; //rpm |
chrta | 3:eb807d330292 | 91 | return true; |
chrta | 3:eb807d330292 | 92 | } |
chrta | 3:eb807d330292 | 93 | |
chrta | 3:eb807d330292 | 94 | EngineCoolantTemp::EngineCoolantTemp() |
chrta | 3:eb807d330292 | 95 | : PidValue("Engine Coolant Temperature", "deg C") |
chrta | 3:eb807d330292 | 96 | { |
chrta | 3:eb807d330292 | 97 | } |
chrta | 3:eb807d330292 | 98 | |
chrta | 3:eb807d330292 | 99 | bool EngineCoolantTemp::decode(const uint8_t* data, uint16_t length) |
chrta | 3:eb807d330292 | 100 | { |
chrta | 3:eb807d330292 | 101 | if (length < 2) |
chrta | 3:eb807d330292 | 102 | { |
chrta | 3:eb807d330292 | 103 | return false; |
chrta | 3:eb807d330292 | 104 | } |
chrta | 3:eb807d330292 | 105 | |
chrta | 3:eb807d330292 | 106 | if ((data[1] != 0x05) || length != 3) |
chrta | 3:eb807d330292 | 107 | { |
chrta | 3:eb807d330292 | 108 | return false; |
chrta | 3:eb807d330292 | 109 | } |
chrta | 3:eb807d330292 | 110 | |
chrta | 3:eb807d330292 | 111 | m_value = data[2] - 40; // degree celcius |
chrta | 3:eb807d330292 | 112 | return true; |
chrta | 3:eb807d330292 | 113 | } |
chrta | 3:eb807d330292 | 114 | |
chrta | 3:eb807d330292 | 115 | VehicleSpeed::VehicleSpeed() |
chrta | 3:eb807d330292 | 116 | : PidValue("Speed", "km/h") |
chrta | 3:eb807d330292 | 117 | { |
chrta | 3:eb807d330292 | 118 | } |
chrta | 3:eb807d330292 | 119 | |
chrta | 3:eb807d330292 | 120 | bool VehicleSpeed::decode(const uint8_t* data, uint16_t length) |
chrta | 3:eb807d330292 | 121 | { |
chrta | 3:eb807d330292 | 122 | if (length < 2) |
chrta | 3:eb807d330292 | 123 | { |
chrta | 3:eb807d330292 | 124 | return false; |
chrta | 3:eb807d330292 | 125 | } |
chrta | 3:eb807d330292 | 126 | |
chrta | 3:eb807d330292 | 127 | if ((data[1] != 0x0D) || length != 3) |
chrta | 3:eb807d330292 | 128 | { |
chrta | 3:eb807d330292 | 129 | return false; |
chrta | 3:eb807d330292 | 130 | } |
chrta | 3:eb807d330292 | 131 | |
chrta | 3:eb807d330292 | 132 | m_value = data[2]; // km/h |
chrta | 3:eb807d330292 | 133 | return true; |
chrta | 3:eb807d330292 | 134 | } |
chrta | 3:eb807d330292 | 135 | |
chrta | 3:eb807d330292 | 136 | Throttle::Throttle() |
chrta | 3:eb807d330292 | 137 | : PidValue("Throttle", "%") |
chrta | 3:eb807d330292 | 138 | { |
chrta | 3:eb807d330292 | 139 | } |
chrta | 3:eb807d330292 | 140 | |
chrta | 3:eb807d330292 | 141 | bool Throttle::decode(const uint8_t* data, uint16_t length) |
chrta | 3:eb807d330292 | 142 | { |
chrta | 3:eb807d330292 | 143 | if (length < 2) |
chrta | 3:eb807d330292 | 144 | { |
chrta | 3:eb807d330292 | 145 | return false; |
chrta | 3:eb807d330292 | 146 | } |
chrta | 3:eb807d330292 | 147 | |
chrta | 3:eb807d330292 | 148 | if ((data[1] != 0x11) || length != 3) |
chrta | 3:eb807d330292 | 149 | { |
chrta | 3:eb807d330292 | 150 | return false; |
chrta | 3:eb807d330292 | 151 | } |
chrta | 3:eb807d330292 | 152 | |
chrta | 3:eb807d330292 | 153 | m_value = data[2] * 100 / 255; // % |
chrta | 3:eb807d330292 | 154 | return true; |
chrta | 3:eb807d330292 | 155 | } |
chrta | 3:eb807d330292 | 156 | |
chrta | 3:eb807d330292 | 157 | |
chrta | 3:eb807d330292 | 158 | OilTemperature::OilTemperature() |
chrta | 3:eb807d330292 | 159 | : PidValue("Oil Temperature", "deg C") |
chrta | 3:eb807d330292 | 160 | { |
chrta | 3:eb807d330292 | 161 | } |
chrta | 3:eb807d330292 | 162 | |
chrta | 3:eb807d330292 | 163 | bool OilTemperature::decode(const uint8_t* data, uint16_t length) |
chrta | 3:eb807d330292 | 164 | { |
chrta | 3:eb807d330292 | 165 | if (length < 2) |
chrta | 3:eb807d330292 | 166 | { |
chrta | 3:eb807d330292 | 167 | return false; |
chrta | 3:eb807d330292 | 168 | } |
chrta | 3:eb807d330292 | 169 | |
chrta | 3:eb807d330292 | 170 | if ((length != 31) || (data[0] != 0x61) || (data[1] != 0x01)) |
chrta | 3:eb807d330292 | 171 | { |
chrta | 3:eb807d330292 | 172 | return false; |
chrta | 3:eb807d330292 | 173 | } |
chrta | 3:eb807d330292 | 174 | |
chrta | 3:eb807d330292 | 175 | m_value = data[30] - 40; // deg C |
chrta | 3:eb807d330292 | 176 | return true; |
chrta | 3:eb807d330292 | 177 | } |
chrta | 3:eb807d330292 | 178 | |
chrta | 3:eb807d330292 | 179 | static VehicleSpeed speed; |
chrta | 3:eb807d330292 | 180 | static EngineRpm rpm; |
chrta | 3:eb807d330292 | 181 | static EngineCoolantTemp temp; |
chrta | 3:eb807d330292 | 182 | static Throttle throttle; |
chrta | 3:eb807d330292 | 183 | OilTemperature oilTemperature; |
chrta | 3:eb807d330292 | 184 | static PidValue* pids[] = |
chrta | 3:eb807d330292 | 185 | { &speed, &rpm, &temp, &throttle, &oilTemperature |
chrta | 3:eb807d330292 | 186 | }; |
chrta | 3:eb807d330292 | 187 | |
chrta | 3:eb807d330292 | 188 | void PidDecoder::decode(const uint8_t* data, uint16_t length) |
chrta | 3:eb807d330292 | 189 | { |
chrta | 3:eb807d330292 | 190 | for (unsigned int i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) |
chrta | 3:eb807d330292 | 191 | { |
chrta | 3:eb807d330292 | 192 | if (pids[i]->decode(data, length)) |
chrta | 3:eb807d330292 | 193 | { |
chrta | 3:eb807d330292 | 194 | pc.printf("New Value for %s: ", pids[i]->getName()); |
chrta | 3:eb807d330292 | 195 | pids[i]->print(); |
chrta | 3:eb807d330292 | 196 | } |
chrta | 3:eb807d330292 | 197 | } |
chrta | 3:eb807d330292 | 198 | } |
chrta | 3:eb807d330292 | 199 | |
chrta | 3:eb807d330292 | 200 | #if 0 |
chrta | 3:eb807d330292 | 201 | if((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == pid)) |
chrta | 3:eb807d330292 | 202 | { |
chrta | 3:eb807d330292 | 203 | |
chrta | 3:eb807d330292 | 204 | |
chrta | 3:eb807d330292 | 205 | case MAF_SENSOR: // ((256*A)+B) / 100 [g/s] |
chrta | 3:eb807d330292 | 206 | engine_data = ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/100; |
chrta | 3:eb807d330292 | 207 | sprintf(buffer,"%d g/s",(int) engine_data); |
chrta | 3:eb807d330292 | 208 | |
chrta | 3:eb807d330292 | 209 | break; |
chrta | 3:eb807d330292 | 210 | |
chrta | 3:eb807d330292 | 211 | case O2_VOLTAGE: // A * 0.005 (B-128) * 100/128 (if B==0xFF, sensor is not used in trim calc) |
chrta | 3:eb807d330292 | 212 | engine_data = can_MsgRx.data[3]*0.005; |
chrta | 3:eb807d330292 | 213 | sprintf(buffer,"%d v ",(int) engine_data); |
chrta | 3:eb807d330292 | 214 | |
chrta | 3:eb807d330292 | 215 | #endif |