f211

Dependencies:   mbed-dev1

Fork of OBD21121 by Surendar S

main.cpp

Committer:
takeuz
Date:
2017-02-25
Revision:
2:d58ef72b4ab0
Parent:
1:1d9a04a21027
Child:
4:3e1e2b161403

File content as of revision 2:d58ef72b4ab0:

#include "mbed.h"
#include "functions.h"

#define ENGINE_RPM          0x0C
#define VEHICLE_SPEED       0x0D
#define PID_REQUEST         0x7DF
#define PID_REPLY           0x7E8

//??USE ARRAYLIST Of Int
#define CANSPEED_500      500000        // CAN speed at 500 kbps
#define CANSPEED_250      250000        // CAN speed at 250 kbps
#define CANSPEED_125      125000        // CAN speed at 125 kbps
#define sendDebugMessage  1
#define pushDebugData 1

const int canSpeeds[3]={CANSPEED_500,CANSPEED_250,CANSPEED_125};


DigitalOut myled(LED2);
Serial serialPorts[3] = {Serial(P0_26,P0_6),Serial(P0_22,P0_23),Serial(USBTX,USBRX)};
//Serial pc(P0_9,P0_29);

CAN canBus(P0_24, P0_25);
//AnalogIn batteryVoltage(P0_20);
//DigitalOut indicatorLEDs[3] = {P0_22,P0_23,P0_6};


//UART Counters
int kLine=0;
int interFace=1;
int debug=2;


int currentOBDProtocol=0;
const int protkLine=2;
const int protCan=1;
int canFrequency;
//LED Counters

Ticker timeCounter;
char can_msg[8];
Timer OBDTimer;

//Data Storage for incoming data on Interface
char *incomingDataInInterFace;
const int incomingDataInInterFaceSize=256;
int incomingDataInInterFaceCounter=0;

//Data Storage for incoming data on OBD
char *incomingDataInOBD;
const int incomingDataInOBDSize=256;
CANMessage can_MsgRx;
int incomingDataInOBDCounter=0;


//OBD Command data
char* charPid;
char* charID;
int pid;
int ID;



//Wait Duration for OBD comm
const int waitTimeForOBDComm=2000;
//Sleep time between commands
const int sleepTime=25000;
//Time to send chip to power save mode
const int powerSaveTime=120;

//Global Variables
//New Data receivd on OBD or Interface
int OBDCmdReceived=0;
int interfaceCmdReceived=0;

//Last activity time on OBD Interface
int lastOBDCmdRcvdTime=0;
int lastInterfaceCmdRcvdTime=0;

void readInterface()
{
    char c;
    while(serialPorts[interFace].readable()) {
        lastInterfaceCmdRcvdTime=0;
        c = serialPorts[interFace].getc();
        if(incomingDataInInterFaceCounter<incomingDataInInterFaceSize){
            incomingDataInInterFace[incomingDataInInterFaceCounter] = c;
        }
        incomingDataInInterFaceCounter++;
        
        if(c=='\n') {
            interfaceCmdReceived=1;
        }

    }
}
void readKLine()
{
    char c;
    while(serialPorts[kLine].readable()) {
        lastOBDCmdRcvdTime=0;
        c = serialPorts[kLine].getc();
        if(incomingDataInOBDCounter<incomingDataInOBDSize){
            incomingDataInOBD[incomingDataInOBDCounter]=c;
        }
        incomingDataInOBDCounter++;
        if(c=='\n') {
            OBDCmdReceived=1;
        }

    }
}



void canReader(){
    if (canBus.read(can_MsgRx)) {
        //Setting 
        lastOBDCmdRcvdTime=0;
        
        if ((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == ENGINE_RPM)) {
            serialPorts[debug].puts("HRHK");
            for (int i = 0; i < (int)can_MsgRx.len; i++) {
                serialPorts[debug].printf("%d:%x , ", i, can_MsgRx.data[i]);
            }
        }
    }
}

void timeCounterFunction(){
    lastInterfaceCmdRcvdTime++;
    lastOBDCmdRcvdTime++;
    //IF timout is over certain amount just shutdown
    
    
}

int main() {

    serialPorts[debug].puts("f2114\r\n");

    //Initialization
    incomingDataInInterFace=(char *)malloc(incomingDataInInterFaceSize*sizeof(char));
    incomingDataInOBD=(char *)malloc(incomingDataInOBDSize*sizeof(char));

    clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize);
    clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize);    
    
    timeCounter.attach(&timeCounterFunction, 1.0);
    serialPorts[interFace].attach(&readInterface);

    serialPorts[interFace].puts("ELM327 v1.0\r\n");
    
    while(1) {
        if(!currentOBDProtocol){
            #if sendDebugMessage
                serialPorts[debug].puts("Going to figure protocol\r\n");
            #endif
            serialPorts[kLine].attach(NULL);
            canBus.attach(NULL);
            serialPorts[interFace].puts("Searching...\r\n");
            serialPorts[debug].puts("Searching...\r\n");
            checkCommunicationProtocol();
            if(currentOBDProtocol==protkLine){
                serialPorts[kLine].attach(&readKLine);
            } 
            if(currentOBDProtocol==protCan){
                canBus.attach(&canReader);
            } 
            //??Shall we do somehitng when receive a specific commnad
            
            //?? Do this !Unknown only once.
            if(!currentOBDProtocol){
                serialPorts[interFace].puts("!UnknownProtocol\r\n");
                #if sendDebugMessage
                    serialPorts[debug].puts("!Unknownprotocol\r\n");
                #endif
                //Goto Sleep?
            }
        }


        if(interfaceCmdReceived){
            checkForLocalInterfaceCommand();
        }
        if(interfaceCmdReceived){
            OBDTimer.reset();
            OBDCmdReceived=0;
            sendCommand();
            OBDTimer.start();
            while(OBDTimer.read_ms() < waitTimeForOBDComm){
                if(OBDCmdReceived){
                    sendResponseToInterface();
                    break;
                }
            }
            OBDTimer.stop();
            if(!OBDCmdReceived){
                serialPorts[interFace].puts("?\r\n");
            }
            OBDCmdReceived=0;
            interfaceCmdReceived=0;

        //issueRegularCommands();    
        }
        myled=0;
        sleepProcess();
        if(lastOBDCmdRcvdTime> powerSaveTime && lastInterfaceCmdRcvdTime> powerSaveTime ){
            powerSaveMode();
        }
        myled=1;
        
    
    }
}

void checkCommunicationProtocol(){
    #if sendDebugMessage
        serialPorts[debug].puts("check Communication protocal ENT\r\n");
    #endif
    int i=0;
    do{
        #if sendDebugMessage
        serialPorts[debug].puts("CanBusCheck\r\n");
        #endif
        canBus.reset();
        clearCanMessage();
        canBus.frequency(canSpeeds[i]);
        OBDTimer.reset();
        OBDTimer.start();
        OBDCmdReceived=0;
        if (canBus.write(CANMessage(PID_REQUEST, can_msg, 8))) {
        #if sendDebugMessage
            serialPorts[debug].printf("OBDTIMER:%d\r\n",OBDTimer.read_ms());
        #endif
            while(OBDTimer.read_ms() < waitTimeForOBDComm){
                if(OBDCmdReceived){
                    currentOBDProtocol=protCan;
                    canFrequency=i;    
                    #if sendDebugMessage
                        serialPorts[debug].puts("check Communication protocal SET\r\n");
                    #endif
                    return;     
                }
            }
        }
        wait_ms(200);
        i++;        
    }while(i<3);
    OBDTimer.stop();
    #if sendDebugMessage
    serialPorts[debug].puts("check Communication protocal EXT\r\n");
    #endif
}

void clearMemoryLocation( char *base, int _size)
{
    for(int forCount=0; forCount<_size; forCount++) {
        base[forCount]='\0';
    }
}
void clearCanMessage(){
        can_msg[0] = 0x02;
        can_msg[1] = 0x01;
        can_msg[2] = 0;
        can_msg[3] = 0;
        can_msg[4] = 0;
        can_msg[5] = 0;
        can_msg[6] = 0;
        can_msg[7] = 0;
}

void sendCommand(){

}


void sleepProcess() {
    
#if pushDebugData
    serialPorts[debug].puts("SPe\r\n");
#endif
    OBDTimer.reset();
    OBDTimer.start();
    while(OBDTimer.read_ms()<sleepTime && !interfaceCmdReceived){
        wait_ms(50);
    }
    OBDTimer.stop();

}

void powerSaveMode(){
#if pushDebugData
    serialPorts[debug].puts("PowerSaveOn\r\n");
#endif
    //Remove pin allocaitons
    
    wait(20);
    
    //Make pin allocaitons
    lastOBDCmdRcvdTime=0;
    lastInterfaceCmdRcvdTime=0;
    
#if pushDebugData
    serialPorts[debug].puts("PowerSaveOff\r\n");
#endif

}

void tprintf( char* str, int num){
    int i2aCounter=0;
    if (num == 0)
    {
        str[i2aCounter++] = '0';
        str[i2aCounter] = '\0';
        return;
    }
    int tempNum=num;
    while(tempNum!=0){
        tempNum/=10;
        i2aCounter++;
    }
    str[i2aCounter]='\0';
    i2aCounter--;
    while(i2aCounter>=0){
        str[i2aCounter--] = (num % 10) + '0';
        num = num/10;
    }
    return;
}

void checkForLocalInterfaceCommand(){
    if(strstr(incomingDataInInterFace,"AT")==0){
        return;
    }
    if(strstr(incomingDataInInterFace,"ATZ")>0){
        NVIC_SystemReset();
    }    
    if(strstr(incomingDataInInterFace,"ATRV")>0){
        serialPorts[interFace].puts("Gointoreport bat vol\r\n");        
        interfaceCmdReceived=0;
        return;
    }    
    serialPorts[interFace].puts("?\r\n");
    
}
void sendResponseToInterface(){

}