Component Test's Software to work with "Universal Controller Box" - Software is an interpreter or "compiler" for programs to be done with a .txt file and read off of the SD Card

Dependencies:   BridgeDriver FrontPanelButtons MCP23017 SDFileSystem TextLCD mbed

Devices/CAN_Device.cpp

Committer:
mehatfie
Date:
2014-10-03
Revision:
16:2482d226cf4d
Parent:
15:c944ee3c8a5b

File content as of revision 16:2482d226cf4d:

#include "CAN_Device.hpp"

//Constructor
CAN_Device::CAN_Device(LineData lineData){
    
    //Order of Line: Command, Local_Name, CAN_DEVICE, selectedCAN(1,2), freq
    //Since we can't return from a constructor, instead we'll flip a flag, and check it after we've added the device in interpretCommand
    if (lineData.numWords != 5)
        this->errorFlag = 1;
        
    string channelstr = lineData.word[3], freqstr = lineData.word[4]; //Parameters are numbers
    int tempChannel = -1, tempFreq = -1;
    int numValuesFound = sscanf(channelstr.c_str(), "%d", &tempChannel);
    if (numValuesFound < 1)
        this->errorFlag = 1;
       
    numValuesFound = sscanf(freqstr.c_str(), "%d", &tempFreq);
    if (numValuesFound < 1)
        this->errorFlag = 1;
    
    //channel must be either CAN1 or CAN2
    //CAN 1 is on the Back of the Box, CAN2 is on the Front of the Box
    if (tempChannel == 1 || tempChannel == 2){
        if (tempChannel == 1){
            this->canDevice = new CAN (p30, p29);
//            this->pinRD = p30;
//            this->pinTD = p29;
        }
        else if (tempChannel == 2){
            this->canDevice = new CAN (p9, p10);
//            this->pinRD = p9;
//            this->pinTD = p10;
        }
        
        this->selectedCAN =  tempChannel;
    }
    
    else
        this->errorFlag = 1;
         
    //should have a frequency greater than 0       
    if (tempFreq > 0)
        this->canDevice->frequency(tempFreq);
    else
        this->errorFlag = 1;
}
    
   
//int CAN_Device::getSelectedCAN(){     
//    return this->selectedCAN;
//}
//
//int CAN_Device::getFreq(){     
//    return this->freq;
//}

//A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on]
int CAN_Device::CAN_Device(LineData &lineData){
//
//    //Initialize the CAN device
//    CAN canDevice(pinRD, pinTD);
//    canDevice.frequency(125000);

    //Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,.......
    string func = lineData.word[1];
        
    /******************************************************************************/
    /***                            <Func: write>                               ***/
    /******************************************************************************/
    if (func.compare("write") == 0){
    //line looks like: Local_Name, write, ID_val, length_val, data 
        if (lineData.numWords < 5){
            ErrorOut("Incorrect number of parameters", lineData.lineNumber);
            return -1;
        }
        
        //Initialize and Convert Parameters
        string _id = lineData.word[2];
        string _length = lineData.word[3];
        string _data = lineData.word[4];
        int _idValue = 0;
        char _lengthValue = 0;
        
        int numValuesFound = sscanf(_id.c_str(), "%d", &_idValue);
        if (numValuesFound < 1){
            ErrorOut("Parameter Unknown, id value can't be converted", lineData.lineNumber);
            return -1;
        }
        
        int numValuesFound = sscanf(_length.c_str(), "%c", &_lengthValue);
        if (numValuesFound < 1){
            ErrorOut("Parameter Unknown, length value can't be converted", lineData.lineNumber);
            return -1;
        }
        
        int numDataVals = numWords - 4; //number of data bytes present in the line
        const char* dataBytes[numDataVals];
        int i = 0;
        for (i = 0; i < numDataVals; i++){
            string thisDataByte = lineData.word[4 + i];
            int numValuesFound = sscanf(thisDataByte.c_str(), "%c", &dataBytes[i]);
            if (numValuesFound < 1){
                ErrorOut("Parameter Unknown, a data byte %d can't be converted", (i + 1), lineData.lineNumber);
                return -1;
            }
        }
        
        //All syntax checking done by this point, if Dummy then return success in order to check the code, no need to perform functionality
        if (DummyMode)
            return 0; //Function operated successfully but doesn't return a value
            
            
        canDevice->write(CANMessage(_idValue, &dataBytes, _lengthValue));
    }
        
    /******************************************************************************/
    /***                           <Func: read>                                 ***/
    /******************************************************************************/
    else if (func.compare("forceBrake") == 0){
        
        if (lineData.numWords != 2){
            ErrorOut("Incorrect number of parameters", lineData.lineNumber);
            return -1;
        }
        
        //All syntax checking done by this point, if Dummy then return success in order to check the code, no need to perform functionality
        if (DummyMode)
            return 0; //Function operated successfully but doesn't return a value
            
        bridges.forceBrake(getMotor());
    }
    
    
    /******************************************************************************/
    /***                           <Func: drive>                                ***/
    /******************************************************************************/
    else if (func.compare("drive") == 0){
        
        if (lineData.numWords != 4){
            ErrorOut("Incorrect number of parameters", lineData.lineNumber);
            return -1;
        }
                
        //Initialize Parameters
        string speed = lineData.word[2];
        string dir = lineData.word[3];
        
        //Initialize Convertion Variables if needed
        float speedValue;
        int dirValue = 0;
        
        //Convert string to usable values
        int numValuesFound = sscanf(speed.c_str(), "%f", &speedValue);
        if (numValuesFound < 1){
            ErrorOut("Parameter Unknown, speed value can't be converted", lineData.lineNumber);
            return -1;
        }
        
        //Speed is given as a percentage of 100, so convert it to the value needed for the bridge.drive function
        speedValue = speedValue / 100;
        
        
        if (speedValue <= 0 && speedValue > 1.0){
            ErrorOut("Speed Value must be between 0 - 100", lineData.lineNumber);
            return -1;
        }
        
        if (dir.compare("CC") == 0 || dir.compare("cc") == 0)
            dirValue = -1; //Turn Clockwise
        else if (dir.compare("C") == 0 || dir.compare("c") == 0)
            dirValue = 1; //Turn CounterClockwise
            
        else{
            ErrorOut("Direction Value must be C or CC", lineData.lineNumber);
            return -1;
        }
        
        //All syntax checking done by this point, if Dummy then return success in order to check the code, no need to perform functionality
        if (DummyMode)
            return 0; //Function operated successfully but doesn't return a value
            
        bridges.drive(getMotor(), dirValue, speedValue); //Turn on the Motor
    }
    
    
    /******************************************************************************/
    /****                           <Func: off>                                ****/
    /******************************************************************************/
    else if (func.compare("off") == 0){
        
        if (lineData.numWords != 2){
            ErrorOut("Incorrect number of parameters", lineData.lineNumber);
            return -1;
        }
        
        //All syntax checking done by this point, if Dummy then return success in order to check the code, no need to perform functionality
        if (DummyMode)
            return 0; //Function operated successfully but doesn't return a value
            
        off();
    }
    
    else {
        ErrorOut("Unknown Command for Motor Class", lineData.lineNumber);
        return -1;
    }
    
    return 0; //Return success as 0 since no condition had to be met
}



//For stopping the entire system if an error occurs, can be called from main
int CAN_Device::off(void){
    bridges.drive(getMotor(), 0, 0); //Turn off the Motor
    return 0;
}