f211

Dependencies:   mbed-dev1

Fork of OBD21121 by Surendar S

main.cpp

Committer:
takeuz
Date:
2017-02-27
Revision:
5:53d84cbf9890
Parent:
4:3e1e2b161403
Child:
6:741524d110fe

File content as of revision 5:53d84cbf9890:

#include "mbed.h"
#include "functions.h"
#include <string.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_125,CANSPEED_250,CANSPEED_500};


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

CAN canBus(P0_24, P0_25);
AnalogIn batteryVoltage(P0_6);
//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 activityOnCan()
{
}

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("f2117\r\n");

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

    clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize);
    clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize);


    canDriverPowerSave=0;

    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()
{
    //Putting CAn Driver on low power
    //Detect can Activity
    if(currentOBDProtocol==protCan) {
        canDriverPowerSave=1;
    }

#if pushDebugData
    serialPorts[debug].puts("PowerSaveOn\r\n");
#endif
    //Remove pin allocaitons

    //Detect can Activity On Acnbus
    if(currentOBDProtocol==protCan) {
        canActivity.rise(&activityOnCan);
        canActivity.fall(&activityOnCan);
    }


    wait(20);
    if(currentOBDProtocol==protCan) {
        canDriverPowerSave=0;
    }

    //Make pin allocaitons

    //Detect can Activity On Acnbus
    if(currentOBDProtocol==protCan) {
       canActivity.rise(NULL);
       canActivity.fall(NULL);
    }

    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()
{
    
    char temp[2]={incomingDataInInterFace[0],incomingDataInInterFace[1]};
    if(strcmp(temp,"AT")==0){
        serialPorts[interFace].puts("Local Command\r\n");
        return;
    }
    
    /*if(strcmp(incomingDataInInterFace.Substring(0,2),"AT")==0){
        return;
    }*/
//    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;
//    }
}
void sendResponseToInterface()
{

}