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

Committer:
chrta
Date:
2014-04-27
Revision:
3:eb807d330292
Child:
5:0b229ba8ede5

File content as of revision 3:eb807d330292:

#include "PidDecoder.h"
#include "MODSERIAL.h"

extern MODSERIAL pc;

class PidValue
{
public:
    PidValue(const char* name, const char* unit);
    virtual bool decode(const uint8_t* data, uint16_t length) = 0;
    void print();
    const char* getName();
protected:    
    unsigned int m_value;
    const char* m_unit;
    const char* m_name;
};

class EngineRpm : public PidValue
{
public:
    EngineRpm();
    virtual bool decode(const uint8_t* data, uint16_t length);
};


class EngineCoolantTemp : public PidValue
{
public:
    EngineCoolantTemp();
    virtual bool decode(const uint8_t* data, uint16_t length);
};


class VehicleSpeed : public PidValue
{
public:
    VehicleSpeed();
    virtual bool decode(const uint8_t* data, uint16_t length);
};

class Throttle : public PidValue
{
public:
    Throttle();
    virtual bool decode(const uint8_t* data, uint16_t length);
};

class OilTemperature : public PidValue
{
public:
    OilTemperature();
    virtual bool decode(const uint8_t* data, uint16_t length);
};

PidValue::PidValue(const char* name, const char* unit)
: m_value(0)
, m_unit(unit)
, m_name(name)
{
}

void PidValue::print()
{
    pc.printf("%d %s\r\n", m_value, m_unit);
}

const char* PidValue::getName()
{
    return m_name;
}

EngineRpm::EngineRpm()
: PidValue("Engine RPM", "rpm")
{
}

bool EngineRpm::decode(const uint8_t* data, uint16_t length)
{
    if (length < 2)
    {
        return false;
    }
    
    if ((data[1] != 0x0C) || length != 4)
    {
        return false;
    }
    
    m_value = ((data[2] << 8) | data[3]) >> 2; //rpm
    return true;
}

EngineCoolantTemp::EngineCoolantTemp()
: PidValue("Engine Coolant Temperature", "deg C")
{
}

bool EngineCoolantTemp::decode(const uint8_t* data, uint16_t length)
{
    if (length < 2)
    {
        return false;
    }
    
    if ((data[1] != 0x05) || length != 3)
    {
        return false;
    }
    
    m_value = data[2] - 40; // degree celcius
    return true;
}

VehicleSpeed::VehicleSpeed()
: PidValue("Speed", "km/h")
{
}

bool VehicleSpeed::decode(const uint8_t* data, uint16_t length)
{
    if (length < 2)
    {
        return false;
    }
    
    if ((data[1] != 0x0D) || length != 3)
    {
        return false;
    }
    
    m_value = data[2]; // km/h
    return true;
}

Throttle::Throttle()
: PidValue("Throttle", "%")
{
}

bool Throttle::decode(const uint8_t* data, uint16_t length)
{
    if (length < 2)
    {
        return false;
    }
    
    if ((data[1] != 0x11) || length != 3)
    {
        return false;
    }
    
    m_value = data[2] * 100 /  255; // %
    return true;
}


OilTemperature::OilTemperature()
: PidValue("Oil Temperature", "deg C")
{
}

bool OilTemperature::decode(const uint8_t* data, uint16_t length)
{
    if (length < 2)
    {
        return false;
    }
    
    if ((length != 31) || (data[0] != 0x61) || (data[1] != 0x01))
    {
        return false;
    }
    
    m_value = data[30] - 40; // deg C
    return true;
}

static VehicleSpeed speed;
static EngineRpm rpm;
static EngineCoolantTemp temp;
static Throttle throttle;
OilTemperature oilTemperature;
static PidValue* pids[] =
{ &speed, &rpm, &temp, &throttle, &oilTemperature
};                             
                             
void PidDecoder::decode(const uint8_t* data, uint16_t length)
{   
    for (unsigned int i = 0; i < sizeof(pids) / sizeof(pids[0]); i++)
    {
        if (pids[i]->decode(data, length))
        {
            pc.printf("New Value for %s: ", pids[i]->getName());
            pids[i]->print();
        }
    }
}

#if 0
if((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == pid))
        { 
                            
 
                            case MAF_SENSOR:               // ((256*A)+B) / 100  [g/s]
                                engine_data =  ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/100;
                                sprintf(buffer,"%d g/s",(int) engine_data);
                            
                            break;
 
                            case O2_VOLTAGE:            // A * 0.005   (B-128) * 100/128 (if B==0xFF, sensor is not used in trim calc)
                                engine_data = can_MsgRx.data[3]*0.005;
                                sprintf(buffer,"%d v ",(int) engine_data);
     
#endif