This is Ben and I's final project for Embedded Systems. Our goal was to create a car diagnostic system that interfaces with the CAN bus in all US sold cars newer than 2008. We aimed to request data such as RPM, Vehicle speed, engine temp, etc and then display our findings. This software was succussful in communicating with the car and reading and writing, however it fails to accomplish it's task when dealing with certain makes of cars, specifically Honda. Included are various PID codes, functions, and files that interface with a car's CAN bus system.

Dependencies:   UniGraphic mbed

ODBII.cpp

Committer:
Nrode17
Date:
2016-01-27
Revision:
0:bb9076ae4c4a

File content as of revision 0:bb9076ae4c4a:

#include "ODBII.h"
#include "globals.h"

DigitalOut myled(LED1);//diagnostic LED, used to see if data is being transmitted
Timer CANTimer;//This is used to determine whether or not the car has taken too long to respond

void set_frequency(int amount)
{
    can2.frequency(amount);//Different ECU's operate at different frequencies, 125kbs, 25kbs, 500kbs
}

float request(char pid)
{
    char can_msg[8];//message to be send to CAN 
    float engine_data = 0;// this is what we get back


    //forming the CAN message payload, uses 8 bytes, first is number of extra bytes, second is mode, third is PID, others are misc
    can_msg[0] = 0x02;//# of extra bytes
    can_msg[1] = 0x01;//mode
    can_msg[2] = pid;
    can_msg[3] = 0;
    can_msg[4] = 0;
    can_msg[5] = 0;
    can_msg[6] = 0;
    can_msg[7] = 0;
    
    if (can2.write(CANMessage(PID_REQUEST, can_msg, 8))) 
    {
        myled = !myled;//diagnostic LED
    }
    CANTimer.reset();
    CANTimer.start();

    while(CANTimer.read_us() < 200)//give it some time to respond
    {
        if (can2.read(can_MsgRx)) {//if you can read back, then go into it
            pc.printf("Message read\n\r");
            
 
            for (int i = 0; i < (int)can_MsgRx.len; i++) {
                pc.printf("can_MsgRx.data[%d]: %x\n\r", i, can_MsgRx.data[i]);//this just prints the contents of the data back
            }



            if ((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == pid)) //if the PID match, then we know we have valid data
            {
                pc.printf("We've made it this far\n\r");
                switch (can_MsgRx.data[2]) //the PID is in [2], so we use that in this switch
                { 
                    case ENGINE_RPM:              //   ((A*256)+B)/4 is the formula for rpm
                        engine_data =  ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/4;
                        break;

                    case ENGINE_COOLANT_TEMP: //C, this is the formula for temp
                        engine_data =  can_MsgRx.data[3] - 40;
                        break;

                    case VEHICLE_SPEED:   //[km], this is the formula for kmph
                        engine_data =  can_MsgRx.data[3];
                        break;
                }

                return engine_data;//whatever we get we return back to the main.cpp

            }

        }
    }

    return 0;
}