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
}
//************************************************************************************************************************