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

main.cpp

Committer:
mehatfie
Date:
2014-09-19
Revision:
4:86d0d04cc055
Parent:
3:078e9a1e8be3
Child:
5:e36e0538a903

File content as of revision 4:86d0d04cc055:


#include "mbed.h"
#include "LocalPinNames.h"
#include "BridgeDriver.h"
#include "FrontPanelButtons.h"
#include "TextLCD.h"
#include "SDFileSystem.h"
#include "Initialization.hpp"
//#include "DeviceClasses.h"
//#include "Device.hpp"
#include "Motor.hpp"
#include "VoltageDriver.hpp"
#include "PinIN.hpp"
#include "TextFile.h"
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <vector>
using std::string;

//const int MAX_LINE_LENGTH = 100;
//struct Line lineData;


//DeviceData devices[15];

FrontPanelButtons buttons(&i2c);

//extern "C" void mbed_reset(); //enable software reset of code
/*
http://stackoverflow.com/questions/3081289/how-to-read-a-line-from-a-text-file-in-c-c
http://stackoverflow.com/questions/12475915/rewind-stream-pointer-to-the-line-back

recurrsive
*/



int interpretCommand(FILE *, Line &);
int loopCommand(FILE *, Line &);

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/***************************                        <FUNCTION: resetLineData>                            **************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
void resetLineData(Line &lineData){
    
    //lineData.fullLine.clear();
    lineData.lineNumber = 0;
    lineData.numWords = 0;
    lineData.lineAddress = 0;
}

    

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************                        <FUNCTION: cyclePrograms>                            *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
   
int cyclePrograms(vector<string> files, int SIZE, int currIndex, int direction){
    
    int nextIndex = 0;
    switch(direction){
        case 0: //Cycle Back one File
            if ((currIndex - 1) < 0)
                nextIndex = SIZE - 1;
            else
                nextIndex = currIndex - 1;
            break;
        case 1: //Cycle Forward one File
            if ((currIndex + 1) >= SIZE)
                nextIndex = 0; 
            else
                nextIndex = currIndex + 1;
            break;
        case -1: //set the selectedFile to the currIndex (used for initialization)
            nextIndex = currIndex;
            break;
    }

    //Output file on Display 
    lcd.setAddress(0,3);
    lcd.printf("                   "); // Clear the Line using Spaces (Emptyness) - Note one line is 20 Characters
    wait(.2);
    lcd.setAddress(0,3);
    lcd.printf("%s", files[nextIndex]);
    
    return nextIndex; // Return the file index in the Array         
}
            
    

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/**************************                        <FUNCTION: loopCommand>                            *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

int loopCommand(FILE *selectedFile, Line &lineData){
        
    //Get the Condition value for number of times to loop
    string loopCondition = lineData.word[1];
    int loopConditionValue = 0;
    sscanf(loopCondition.c_str(), "%d", &loopConditionValue);
    
    int loopStartAddress = 0, loopLineNumber = 0, firstLineOfLoop = 1;
    
    int counter = 0, checkEnd = 0;
    while (counter < loopConditionValue){
        
        getNextLine(selectedFile, lineData);    
        checkEnd = interpretCommand(selectedFile, lineData);
            
        if (firstLineOfLoop){
            loopStartAddress = lineData.lineAddress; //Save the Line Address
            loopLineNumber = lineData.lineNumber;    //Save the Line Number
            firstLineOfLoop = 0;
        }
        
        //Increase the loop counter and go back to the beginning of the loop
        if (checkEnd == 1){
            counter++;
            
            lcd.setAddress(0,2);
            lcd.printf("Loop Cycle %d of %d", counter, loopConditionValue);
            
            fseek(selectedFile, loopStartAddress, SEEK_SET);
            lineData.lineNumber = loopLineNumber - 2;
        }
    }
                
    return 1;
 }   

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/*************************                        <FUNCTION: interpretCommand>                            *************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

int interpretCommand(FILE *selectedFile, Line &lineData){
        
    if (lineData.word[0].compare("device") == 0){

        int i = 0, deviceFound = -1;
        for (i = 0; i < numDevices; i++){
            if (lineData.word[2].compare(DeviceNames[i]) == 0){
                deviceFound = i;
            }
        }
        
        //if the device type does not match any known type, error out
        if (deviceFound == -1){
            //Error Out since the device Name was not matched with anything *************************   
        }
        
        //Add device to the array of devices and initialize it
        else{
            devices.push_back(Device::newDevice(deviceFound, lineData.word[1], lineData));
            devices.back()->name = lineData.word[1];             
        }
    }
    
    else if (lineData.word[0].compare("delay") == 0){
        string duration = lineData.word[1];
        int durationValue = 0;
        sscanf(duration.c_str(), "%d", &durationValue);
        
        if (durationValue){
            timer.reset();
            timer.start();
            while (timer.read_ms() < durationValue); //Do Nothing while the timer has not reached the duration
            timer.stop(); //Stop the Timer
        }
        else{
            //Error Out
            return -1;
        }
    }
    
    else if (lineData.word[0].compare("loop") == 0){
        int checkLoopEnd = loopCommand(selectedFile, lineData);
        if (checkLoopEnd == 1)
            return 1;
    }
            
    else if (lineData.word[0].compare("end") == 0){
        if (lineData.word[1].compare("program") == 0){
            return 0;
        }
        else if (lineData.word[1].compare("loop") == 0){
            return 1;
        }
    }
    
    //not a keyword so check if it's a localName for a device
    else{
    
        int i = 0, deviceFound = -1;
        for (i = 0; i < devices.size(); i++){
            if (lineData.word[0].compare(devices[i]->name) == 0)
                deviceFound = i;
        }
                
        //no device was found that matched the local name, and this is also the last error check, meaning it can match no other potential keywords
        if (deviceFound == -1){
            lcd.setAddress(0,3);
            lcd.printf("Final ERROR!");
            wait(10);
        }
        
        //Local Name matches a device, send line to that device in order to process the functionality
        else{
            //addDevice(deviceFound);
            devices[deviceFound]->interpret(lineData);
        }
    }  
    
    return -1;
}


/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/******************************                        <FUNCTION: main>                            ********************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

int main() {
    
    fullInit(); //Initialize anything that's required to run the code (LCD)
    
    struct Line lineData;
    resetLineData(lineData);

        /******************************************************************************/
        /***                 <Get all the Potential Programs>                       ***/
        /******************************************************************************/
        int numTextFiles = 0;
        vector<string> textFiles; //Assuming Maximum of 25 txt files will be on the SD Card        
        vector<string> filenames = readFileNames("/sd");    
        numTextFiles = getFileNamesWithoutExt(textFiles, filenames);
            
    
        /******************************************************************************/
        /***                   <Select the Program txt File>                        ***/
        /******************************************************************************/
        int fileSelected = 0, selectedFileIndex = 0;
    
        lcd.cls(); //clear the display
        lcd.setAddress(0,1);
        lcd.printf("Select Your Program");
        lcd.setAddress(0,2);
        lcd.printf("Num Programs = %d", numTextFiles);
        
        uint8_t lastButState;
        lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
    
        selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, -1); //Initialize the first file to the screen
        while(!fileSelected) {
            
            uint8_t curButState = buttons.readBus();
            if(curButState != lastButState){
                lastButState = curButState;
                if(buttons.readRight())
                    selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 1);
                else if(buttons.readLeft())
                    selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 0);
                else if(buttons.readSel())
                    fileSelected = 1;
            }
        }
               
        char selectedFileName[50];
        strcpy(selectedFileName, textFiles[selectedFileIndex].c_str());
        
        /******************************************************************************/
        /***                    <Open the Program txt File>                         ***/
        /******************************************************************************/
        
        //Create the string of the full directory and path to the program txt file
        char selectedFileFullName[100] = "/sd/";    //Assuming that no directory and file name will be longer than 100 characters
        strcat(selectedFileFullName, selectedFileName);
        strcat(selectedFileFullName, ".txt");
        
        FILE *selectedFile = fopen(selectedFileFullName, "r");

        lcd.cls(); //clear the display 

        if(selectedFile == NULL) {
            lcd.setAddress(0,0);
            lcd.printf("Invalid");
            wait(10);
        }
    
        
    while(1){  
            
        resetLineData(lineData);
        
        lcd.cls(); //clear the display   
        lcd.setAddress(0,0);
        lcd.printf("Program: %s", selectedFileName);

        
        /******************************************************************************/
        /***          <Start Running through the Program txt File Lines>            ***/
        /******************************************************************************/
  
        int endOfFile = 0;
        
        while (!endOfFile){
        
            getNextLine(selectedFile, lineData);
            int checkEnd = interpretCommand(selectedFile, lineData);   
                    
            if (checkEnd == 0)
                endOfFile = 1;
        }
        
        
        lcd.cls(); //clear the display   
        lcd.setAddress(0,0);
        lcd.printf("END OF PROGRAM");
        lcd.setAddress(0,2);
        lcd.printf("To Restart...");
        lcd.setAddress(0,3);
        lcd.printf("Press BACK");
       
        while(!buttons.readBack());
        
        lcd.setAddress(0,1);
        //rewind(selectedFile);
    }

 } 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   
    /***** Cycle through txt lines and remember last lines ******/
    /*
    int running = 0, selectedFile = 0;
    int locCount = 0, tempSpot = 0;
    int loc[4];
    char line[32];
    uint8_t lastButState;
    
    
    while(1){
        lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
        while(!running) {
            uint8_t curButState = buttons.readBus();
    
            if(curButState != lastButState){
                switch(lastButState = curButState){
                    case 0x1F: //right
                    
                        loc[locCount] = ftell(fp);
                        
                        if (locCount >= 3)
                            locCount = 0;
                        else
                            locCount++;
                        
                        //tempSpot = ftell(fp);
                        fgets(line, 32, fp);
                        
                        lcd.setAddress(0,1);
                        lcd.printf("L: %s", line);
                        wait(0.2);
                        break;
                    case 0x2F: //left
                    
                        if (locCount == 0) {
                            locCount = 3;
                            fseek(fp, loc[locCount], SEEK_SET);
                        }
                        else {
                            fseek(fp, loc[locCount - 1], SEEK_SET);
                            locCount--;
                        }
                        fgets(line, 32, fp);
                        lcd.setAddress(0,1);
                        lcd.printf("L: %s", line);
                        wait(0.2);
                        break;
                }
            }
        } 
    } 
        */   
  
    
    
    /******* Select the Program txt File ***********/
    /*
    int numTextFiles = 0;
    string tempTextFiles[25]; //Assuming Maximum of 25 txt files will be on the SD Card
    lcd.cls(); //clear the display
    readFileNames("/sd");
    numTextFiles = getFileNamesWithoutExt(tempTextFiles);
    
    string *textFiles = resize_StringArr(tempTextFiles, numTextFiles); //Resize Array
    //delete [] tempTextFiles; //free previous array
    

    int running = 0, selectedFile = 0;

    lcd.cls(); //clear the display
    lcd.setAddress(0,1);
    lcd.printf("Select Your Program");
    lcd.setAddress(0,2);
    lcd.printf("Num Programs = %d", numTextFiles);
    
    uint8_t lastButState;
    while(1){
        lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
        while(!running) {
            uint8_t curButState = buttons.readBus();
    
            if(curButState != lastButState){
                switch(lastButState = curButState){
                    case 0x1F: //right
                        selectedFile = cyclePrograms(textFiles, numTextFiles, selectedFile, 1);
                        break;
                    case 0x2F: //left
                        selectedFile = cyclePrograms(textFiles, numTextFiles, selectedFile, 0);
                        break;
                }
            }
        }
    }
    
    */

    /*float speed = 0.5;
    while(1){
        bridges.drive(1, -1*speed);
        wait(2);
        bridges.drive(1, speed);
        wait(2);
    }*/
    
//BridgeDriver::MOTOR_A