OBD Source Code -Section 1- Without Car / Section 2 - With car

Dependencies:   mbed

obd_libraries.cpp

Committer:
bala0x07
Date:
2017-03-19
Revision:
1:c23c05b36e33
Parent:
0:e36d80703ed0
Child:
2:49712259aa71

File content as of revision 1:c23c05b36e33:

#include "mbed.h"
#include "obd_libraries.h"
#include "common_definitions.h"

Serial pco(USBTX, USBRX);
Serial OBD_UART(PA_0, PA_1);

char pass = 0;
char reception_complete = 0;

char obd_reset_cmd[]            =   "ATZ\r";
char battery_voltage_cmd[]      =   "ATRV\r";
char protocol_auto_detect_cmd[] =   "ATSP0\r";
char read_CAN_protocol_cmd[]    =   "ATDPN\r";
char allow_long_cmd[]           =   "ATAL\r";
char engine_rpm_cmd[]           =   "010C\r";
char vehicle_speed_cmd[]        =   "010D\r";
char vin_number_cmd[]           =   "0902 5\r";
char check_dtc_cmd[]            =   "03\r";
char check_mil_cmd[]            =   "0101\r";

char no_of_stored_dtc;

float car_battery_voltage;
long vehicle_speed;
char OBD_UART_RX_Buffer[50];
extern char OBD_RxBuffer_End_Pos;
//char OBD_UART_RX_Size = 50;


//Serial pco(USBTX, USBRX);
//Serial OBD_UART(PA_0, PA_1);

void OBD_onDataRx()
{
    //pcm.printf("\r\n ENTERED \r\n");
     if(OBD_UART.readable()) {
       
        pco.putc(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos++] = OBD_UART.getc());
        /*
        if(OBD_RxBuffer_End_Pos >= OBD_UART_RX_Size) {
            // BUFFER OVERFLOW. What goes here depends on how you want to cope with that situation.
            // For now just throw everything away.
            OBD_RxBuffer_End_Pos  = 0;
        }
        */
    }
}


//************************************************************************************************************************

void received_data_verification(char *rcv_data_pointer, char *ref_data_pointer, char num)
{
    char dummy_data[num], count;
    for(count = 0; count < num; count++)
    {
        pco.putc(*rcv_data_pointer);
        if(*rcv_data_pointer++ == *ref_data_pointer++)
            pass = 1;
        else   
        {
            pass = 0;
            return;
        }
    } 
}
      
//************************************************************************************************************************
/*
char* copy_characters(char *copy_char_pointer, char start_position, char end_position)
{
    char total_num;
    char count;
    total_num = end_position - start_position;
    char copied_data[total_num];
    copy_char_pointer += start_position;
    
    for(count = 0; count < total_num; count++)
    {
        copied_data[count] = *copy_char_pointer++;
    }
    
    pco.printf("\r\n%s", copied_data);
    
    copy_char_pointer = copied_data;    // Shifting the pointer to copied_data array
    
    return copy_char_pointer;
}
*/        
    

//************************************************************************************************************************

void process_battery_voltage(char *battery_voltage_pointer)
{
    char battery_voltage_data[4];   // One decimal point precision ( For ex : 12.5 )
    char count;
    battery_voltage_pointer += 5;   // ATRV<CR> counts to 5
    for(count = 0; count < 4; count++)
    {
        battery_voltage_data[count] = *battery_voltage_pointer++;
    }
    car_battery_voltage = atof(battery_voltage_data);   // Converts the Battery Volatge from String to Float data type
    
    printf("\r\nCAR BATTERY VOLTAGE = %f",car_battery_voltage);
}

//************************************************************************************************************************

void process_vehicle_speed(char *vehicle_speed_pointer)
{
    char vehicle_speed_data[2];     // Vehicle speed data is returned by a 2 byte value
    char *strtol_pointer;
    char count;
    //"010D\r41 0D 4F\r\r>"
    vehicle_speed_pointer += 11;
    for(count = 0; count < 2; count++)
    {
        vehicle_speed_data[count] = *vehicle_speed_pointer++;
    }
    
    vehicle_speed =  strtol(vehicle_speed_data, &strtol_pointer, 16);
    
    printf("\r\nVEHICLE SPEED = %ld", vehicle_speed);
}

//************************************************************************************************************************

void process_mil_data(char *mil_data_pointer)
{
    char mil_data[2], mil_data_converted;
    char count;
    
    // char virtual_mil_buffer = "0101\r41 01 00 04 60 00 \r\r";
    mil_data_pointer += 11;
    
    for(count = 0; count < 2; count++)
    {
        mil_data[count] = *mil_data_pointer++;
    }
    
    mil_data_converted = (((mil_data[0] - 0x30)<<4) + (mil_data[1] - 0x30)); // Converting the ASCII data to the Hex data
    
    // The following code lines checks for the number of Mal function indicator lamp enabled by tghe CAN ECU
    
    if(mil_data_converted & 0x80) // Checks for the MSB bit enabled or not which inc=dicates that the MIL is On or NOT
    {
        pco.printf("\r\nMIL (MALFUNCTION INDICATOR LAMP) IS ON");
        no_of_stored_dtc = (mil_data_converted & 0b01111111);
        pco.printf("\r\n NO OF STORED DYNAMIC TROUBLE CODE = %d", no_of_stored_dtc);
    }
    else
        pco.printf("\r\nMIL (MALFUNCTION INDICATOR LAMP) IS OFF");
}

//************************************************************************************************************************

void process_dtc_data(char *dtc_data_pointer)   // Incomplete Code block
{
/*
     char i;
     for(i = 0; i<14; i++)
     {
         pco.printf("\r\nData = %c", *(dtc_data_pointer+i));
     }
*/     
     // char virtual_dtc_buffer[] = "03\r43 00 85\r\r>";
     char count1, count2, count_bytes = 0; 
     //char dtc_data_raw[5];
     char dtc_data[2];                  // Since each DTC needs 2 bytes to make the code
     //pco.printf("\r\n String Length = %d", strlen(dtc_data_pointer));
     dtc_data_pointer += 6;             // Neglecting the preceding data to scroll to the actual data having some meaning 
     
     //char dtc_codes[no_of_stored_dtc * 5]; // Since each DTC requires 5 characters to display
     
     char dtc_codes[5];
     
     //pco.printf("\r\n String Length = %d", strlen(dtc_data_pointer));
     for(count1 = 0; count1 < (strlen(dtc_data_pointer)); count1++)
     {
         
         if(*(dtc_data_pointer + count1) != '\r'){
            count_bytes++;
            pco.printf("\r\nData = %c Count Bytes = %d", *(dtc_data_pointer+count1), count_bytes); }   // To be commented
         else
            break;
     }
     pco.printf("\r\nDATA POINTER POINTING TO : %c", *dtc_data_pointer);
     //pco.printf("\r\nCount Bytes = %d", count_bytes);   // To be commented
/*

FORMULA:
t = total bytes of returned data
n = no of dtc

t = 2n + (n -1) , where (n-1) indicates the added spaces between two bytes
t = 3n -1

Therefore, n = (t + 1) / 3
     
*/  
     if(((count_bytes + 1)/3) == no_of_stored_dtc)
        pco.printf("\r\nNO OF STORED DTC MATCHES WITH THE DTC CODE RETURNED");
     else
        pco.printf("\r\nNO OF STORED DTC DOESNT MATCH WITH THE DTC DATA RETURNED");
    
     pco.printf("\r\n %d", ((*dtc_data_pointer) - 0x30)); dtc_data_pointer++;
     pco.printf("\r\n %d", ((*dtc_data_pointer) - 0x30)); dtc_data_pointer++;
     pco.printf("\r\n %d", ((*dtc_data_pointer) - 0x30)); dtc_data_pointer++;
     pco.printf("\r\n %d", ((*dtc_data_pointer) - 0x30)); dtc_data_pointer++;
     pco.printf("\r\n %d", ((*dtc_data_pointer) - 0x30));
     
     dtc_data_pointer -= 4;
     
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//                VERIFIED UPTO THIS LEVEL      

 for(count1 = 0; count1 < no_of_stored_dtc; count1++)
     {
         for(count2 = 0; count2 < 2; count2++)
         {
            //dtc_data[count1] = (*(dtc_data_pointer + count1)) - 0x30; // Converts to integer and stores in dtc_data
            dtc_data[count1] = *dtc_data_pointer++;
            pco.printf("\r\nData = %c", dtc_data[count1]);
         }
         char a[2];
         a[0] = 'B';
         a[1] = 'G';
         pco.printf("\r\nData = %s", a);
         //dtc_data_pointer += 2;
         dtc_data_pointer++;


/*     
     for(count1 = 0; count1 < no_of_stored_dtc; count1++)
     {
         for(count2 = 0; count2 < 3; count2++)
         {
            if((*(dtc_data_pointer + count1)) != ' ') {
                dtc_data[count1] = (*(dtc_data_pointer + count1)) - 0x30; // Converts to integer and stores in dtc_data
                pco.printf("\r\nData = %c", *(dtc_data_pointer + count1)); }
            else {
                dtc_data_pointer += 3;
                break; }
         }
*/  
     
/*
     for(count1 = 0; count1 < count_bytes; count1++)
        pco.printf("\r\n DTC Bytes = %c+%d", *dtc_data_pointer, (*(dtc_data_pointer++) - 0x30));
     
     // The following lines of code copy the data pointed by dtc_data_pointer to the dtc_data array
     for(count1= 0; count1 < no_of_stored_dtc; count1++)
     {
         for(count2 = 0; count2 < 2; count2++)
         {
            dtc_data[count2] = *(dtc_data_pointer + count2);
         }
         pco.printf("\r\nDTC DATA >>>> %c", dtc_data[1]);
         dtc_data_pointer += 1; // To skip the space present between two DTC data
*/         
         switch((dtc_data[0] & 0x11000000) >> 6)
         {
             case 0:
             dtc_codes[count1*5] = 'P';
             break;
             
             case 1:
             dtc_codes[count1*5] = 'C';
             break;
             
             case 2:
             dtc_codes[count1*5] = 'B';
             break;
             
             case 3:
             dtc_codes[count1*5] = 'U';
             break;
         }
         
//         dtc_codes[(count1*5)+1] = (((dtc_data[0] & 0b00110000) >> 4) + 0x30); 
//         dtc_codes[(count1*5)+2] = ((dtc_data[0] & 0b00001111) + 0x30);
//         dtc_codes[(count1*5)+3] = (((dtc_data[1] & 0b11110000) >> 4) + 0x30);
//         dtc_codes[(count1*5)+4] = ((dtc_data[1] & 0b00001111) + 0x30);
         dtc_codes[1] = (((dtc_data[0] & 0b00110000) >> 4) + 0x30); 
         dtc_codes[2] = ((dtc_data[0] & 0b00001111) + 0x30);
         dtc_codes[3] = (((dtc_data[1] & 0b11110000) >> 4) + 0x30);
         dtc_codes[4] = ((dtc_data[1] & 0b00001111) + 0x30);
         
         pco.printf("\r\n DTC CODE NO %d : %s", count1+1, dtc_codes);    
         
     }   
}


//************************************************************************************************************************

void fetch_battery_voltage()
{
    OBD_UART.printf(battery_voltage_cmd);
    wait(1);
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, battery_voltage_cmd, (strlen(battery_voltage_cmd)-1));
    
    process_battery_voltage(OBD_UART_RX_Buffer);

    if(pass == 1)
        printf("\r\nOBD READ BATTERY VOLTAGE SUCCESSFUL \r\n\r\n");
    else
        printf("\r\nOBD READ BATTERY VOLTAGE FAILED \r\n\r\n");
    reception_complete = 0;     // Disabling the reception complete flag
    OBD_RxBuffer_End_Pos = 0;   // Rx Buffer will be overwritten in the next data reception
}
    
//************************************************************************************************************************   

void fetch_vehicle_speed()
{
    char virtual_rx_speed_buffer[] = "010D\r41 0D 4F \r\r>";     
    /*
    OBD_UART.printf(vehicle_speed_cmd);
    wait(1);
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, vehicle_speed_cmd, (strlen(vehicle_speed_cmd)-1));
    */
    process_vehicle_speed(virtual_rx_speed_buffer);

    if(pass == 1)
        printf("\r\nVEHICLE SPEED DATA RECEIVED SUCCESSFULLY \r\n\r\n");
    else
        printf("\r\nVEHICLE SPEED DATA RECEPTION FAILED\r\n\r\n");
    reception_complete = 0;     // Disabling the reception complete flag
    OBD_RxBuffer_End_Pos = 0;   // Rx Buffer will be overwritten in the next data reception

}  

//************************************************************************************************************************

void fetch_vin_number()
{
    char virtual_rx_vin_buffer[] = "0902 5\r014 \r0: 49 02 01 54 4D 42 \r1: 46 4B 4A 35 4A 32 43 \r2: 47 30 31 34 37 33 33 \r\r>"; 
    char vin_buffer[100], count;
    char *vin_data_pointer;
    char internal_counter = 0;
    char small_buffer[2];
    long ascii_converted_data;
    char *vin_conv_pointer;
    char vin_number[17];
    
    vin_data_pointer = virtual_rx_vin_buffer;
    vin_data_pointer += 23;
    
    int length;
    for(count = 0; count < (strlen(virtual_rx_vin_buffer) - 1); count++)
    {
        if((*vin_data_pointer == '\r') | (*vin_data_pointer == ' ') | (*vin_data_pointer == '>'))
        {
            printf("\r\ncount1 = %c", *vin_data_pointer); 
            vin_data_pointer++;
            continue;
        }
        else if(*(vin_data_pointer + 1) == ':')
        {
            vin_data_pointer += 2;
            continue;
        }
        else
        {
            printf("\r\ncount2 = %d", count); 
            vin_buffer[internal_counter] = *vin_data_pointer;
            internal_counter++;
        }
        vin_data_pointer++;
    }
    
    length = strlen(vin_buffer);
    printf("\r\n VIN BUFFER LENGTH = %d", length);
    
    printf("\r\n VIN NUMBER : %s", vin_buffer);
    
    internal_counter = 0;
    
    for(count = 0; count < strlen(vin_buffer); count+=2)
    {
        small_buffer[0] = vin_buffer[count];
        small_buffer[1] = vin_buffer[count+1];
        ascii_converted_data =  strtol(small_buffer, &vin_conv_pointer, 16);
        vin_number[internal_counter] = ascii_converted_data;
        internal_counter++;
    }
    printf("\r\n\r\nVEHICLE CHASSIS NUMBER : %s", vin_number);
    
    /*
    Chassis Number : TMBFKJ5J2CG014733
     
    [TX] - 0902 5<CR>

    [RX] - 0902 5<CR>
    014 <CR>
    0: 49 02 01 54 4D 42 <CR>
    1: 46 4B 4A 35 4A 32 43 <CR>
    2: 47 30 31 34 37 33 33 <CR>
    <CR>
    >
    */
    /*
    OBD_UART.printf(vin_number_cmd);
    wait(1);
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, vin_number_cmd, (strlen(vin_number_cmd)-1));
    */
}
    
    

//************************************************************************************************************************

void check_for_MIL()
{
    char virtual_mil_buffer[] = "0101\r41 01 82 04 60 00 \r\r";
    /*
    OBD_UART.printf(check_mil_cmd);
    wait(1);
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, check_mil_cmd, (strlen(check_mil_cmd)-1));
    */
    
    //process_dtc_data(OBD_UART_RX_Buffer);
    process_mil_data(virtual_mil_buffer);
    
    if(pass == 1)
        printf("\r\VEHICLE MIL DATA RECEIVED SUCCESSFULLY \r\n\r\n");
    else
        printf("\r\nVEHICLE MIL DATA RECEPTION FAILED\r\n\r\n");
    reception_complete = 0;     // Disabling the reception complete flag
    OBD_RxBuffer_End_Pos = 0;   // Rx Buffer will be overwritten in the next data reception
}
 

//************************************************************************************************************************

/*
_______________________________________________________________________________________________________________________

NOTE :
-----
THE FOLLOWING CODE O DETERMINE THE DIAGNOSTIC TROUBLE CODE (DTC) IS BASED ON THE INTERPRETATION GIVEN IN WIKIPEDIA
FOR THE  ISO 15765-2 PROTOCOL
DIFFERENT INTERPRETATION METHODOLOGY IS GIVEN IN THE ELM327 DATASHEET FOR SAE PROTOCOL
SO THESE THINGS ARE SUBJECTED TO MODIFICATION AND HAVE NOT BEEN CONFIRMED WITH THE REAL TIME DATA 
_______________________________________________________________________________________________________________________

*/

void check_for_dtc()
{
    char virtual_dtc_buffer[] = "03\r43 00 85\r\r>";
    //char virtual_dtc_buffer[] = "0123456789a\rbc>";
    /*
    OBD_UART.printf(check_dtc_cmd);
    wait(1);
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, check_dtc_cmd, (strlen(check_dtc_cmd)-1));
    */

    //process_dtc_data(OBD_UART_RX_Buffer);
    process_dtc_data(virtual_dtc_buffer);
    
    if(pass == 1)
        printf("\r\VEHICLE DIAGNOSTIC TROUBLE CODE RECEIVED SUCCESSFULLY \r\n\r\n");
    else
        printf("\r\nVEHICLE DIAGNOSTIC TROUBLE CODE DATA RECEPTION FAILED\r\n\r\n");
    reception_complete = 0;     // Disabling the reception complete flag
    OBD_RxBuffer_End_Pos = 0;   // Rx Buffer will be overwritten in the next data reception
}


//************************************************************************************************************************

void initialize_obd()
{
    char data[3];
    char *data_pointer;  

    data_pointer = data;
    
    pco.baud(38400);
    OBD_UART.baud(38400);
    
    OBD_UART.attach(&OBD_onDataRx);
    
    OBD_UART.printf("%s",obd_reset_cmd);

    wait(1);
    
    /*
    pco.printf("Reception not completed");
    pco.printf("\r\n%d",OBD_RxBuffer_End_Pos);
    pco.printf("\r\n%c",OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1]);
    */
    
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, obd_reset_cmd, (strlen(obd_reset_cmd)-1));

    if(pass == 1)
        printf("\r\nOBD RESET SUCCESSFUL \r\n\r\n");
    else
        printf("\r\nOBD RESET FAILED \r\n\r\n");
        
    reception_complete = 0;     // Disabling the reception complete flag
    OBD_RxBuffer_End_Pos = 0;   // Rx Buffer will be overwritten in the next data reception
    
//--------------------------------------------------------------------------------------------------------------------------  

    OBD_UART.printf(allow_long_cmd);
    wait(1);
    while(!(OBD_UART_RX_Buffer[OBD_RxBuffer_End_Pos-1] == '>'));        // Waits here until the reception complete flag has been enabled
    pco.printf("Reception Complete\r\n");
    received_data_verification(OBD_UART_RX_Buffer, allow_long_cmd, (strlen(allow_long_cmd)-1));

    if(pass == 1)
        printf("\r\nLONG DATA RECEPTION ENABLED SUCCESSFULLY \r\n\r\n");
    else
        printf("\r\nLONG DATA RECEPTION ENABLING FAILED\r\n\r\n");
    reception_complete = 0;     // Disabling the reception complete flag
    OBD_RxBuffer_End_Pos = 0;   // Rx Buffer will be overwritten in the next data reception
    
}
        
//************************************************************************************************************************