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-16
Revision:
1:5731f31f96be
Parent:
0:22618cf06f45
Child:
2:3e7baa3e3fec

File content as of revision 1:5731f31f96be:


#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 "TextFile.h"
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
using std::string;

//const int MAX_LINE_LENGTH = 100;
struct Line lineData;
//Device devices[15];
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 *);
int loopCommand(FILE *);

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

    

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************                        <FUNCTION: cyclePrograms>                            *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
   
int cyclePrograms(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: resize_StringArr>                            ************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
          
string* resize_StringArr(string oldArr[], int newSize) {
    
    string newArr[newSize];
    memcpy(newArr, oldArr, newSize * sizeof(string));
    
    return newArr;
}
    

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

int loopCommand(FILE *selectedFile){
        
    char *loopCondition = lineData.word[1];
    int loopConditionValue = atoi(loopCondition);
    int loopStartAddress = 0, loopLineNumber = 0;
    int firstLineOfLoop = 1;
    
    int counter = 0;
    while (counter < loopConditionValue){
        
        getNextLine(selectedFile);
        /*lcd.setAddress(0,2);
        lcd.printf("wrd1: %s", lineData.word[0]);
        lcd.setAddress(0,3);
        lcd.printf("TEST012   ");*/
    
        int checkEnd = interpretCommand(selectedFile);
        /*lcd.setAddress(0,3);
        lcd.printf("TEST022   ");
        wait(2);*/
            
        if (firstLineOfLoop){
            loopStartAddress = lineData.lineAddress; //Save the Line Address
            loopLineNumber = lineData.lineNumber;    //Save the Line Number
            firstLineOfLoop = 0;
           /* lcd.setAddress(0,2);
            lcd.printf("ldLN: %d, ldLA: %d", lineData.lineNumber, lineData.lineAddress);
            lcd.setAddress(0,3);
            lcd.printf("lln: %d, lsa: %d", loopLineNumber, loopStartAddress);
            wait(3);*/
        }
        
        //Increase the loop counter and go back to the beginning of the loop
        if (checkEnd == 1){
            lcd.setAddress(0,2);
            lcd.printf("%dldLN: %d, ldLA: %d", counter, lineData.lineNumber, lineData.lineAddress);
            lcd.setAddress(0,3);
            lcd.printf("%dlln: %d, lsa: %d", counter, loopLineNumber, loopStartAddress);
            wait(3);
        
            counter++;
            fseek(selectedFile, loopStartAddress, SEEK_SET);
            lineData.lineNumber = loopLineNumber - 1;
        }
    }
    
    lcd.setAddress(0,3);
    lcd.printf("TEST1   ");
            
    return 1;
 }   
    
    /*
    Make LOOP function
    - All you need to do is remember (val = ftell(fp)) the beginning of the line you're currently reading.
    - If it turns out to be a LOOP call, then you simply send that remembered value to the LOOP function, and it will continue to LOOP back to that position until the condition is met.
    
    
    func LOOP (FILE *fp, int loopStart){
        
        string conditions;
        fseek(fp, loopStart, SEEK_SET);
        fgets(conditions, MAX_LINE_LENGTH, fp);
        
        int numCycles = interpretLoopCondtions();
        
        int i = 0;
        int checkEndLoop = 0;
        while (i < numCycles) {
            
            checkEndLoop = interpretLine(fp); //if end Loop return ____ (1?), return 0 on success
            if (checkEndLoop) //if it's not the end of the loop, the counter will not increase and we'll just interpret the next line
                i++;
        }
    } //loop conditions met, return to main code
    
    
    */

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

int interpretCommand(FILE *selectedFile){
    
    if (strncmp(lineData.word[0],"device", 6) == 0){
    
        int i = 0, deviceFound = -1;
        for (i = 0; i < numDevices; i++)
            if (strncmp(lineData.word[2], DeviceNames[i], strlen(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
            addDevice(deviceFound);    
    }
    
    else if (strncmp(lineData.word[0],"delay", 5) == 0){
        char *duration = lineData.word[1];
        int durationValue = atoi(duration);
        
        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 (strncmp(lineData.word[0],"loop", 4) == 0){
        int checkLoopEnd = loopCommand(selectedFile);
        lcd.setAddress(0,3);
        lcd.printf("TEST2   ");
        if (checkLoopEnd == 1)
            return 1;
    }
            
    else if (strncmp(lineData.word[0],"end", 3) == 0){
        if (strncmp(lineData.word[1],"program", 7) == 0)
            return 0;
        else if (strncmp(lineData.word[1],"loop", 4) == 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 < currNumDevices; i++){
            if (strncmp(lineData.word[0], devices[i].name, strlen(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(); 
    }  
    
    return -1;
}


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

int main() {
    
    fullInit(); //Initialize anything that's required to run the code (LCD)
    
        /******************************************************************************/
        /***                 <Get all the Potential Programs>                       ***/
        /******************************************************************************/
        int numTextFiles = 0;
        string tempTextFiles[25]; //Assuming Maximum of 25 txt files will be on the SD Card
        lcd.cls(); //clear the display
        
        vector<string> filenames = readFileNames("/sd");
        numTextFiles = getFileNamesWithoutExt(tempTextFiles, filenames);
        string *textFiles = resize_StringArr(tempTextFiles, numTextFiles); //Resize Array
        
        //delete[] tempTextFiles; //free previous array
            
    
        /******************************************************************************/
        /***                   <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();
        
        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);
            int checkEnd = interpretCommand(selectedFile);   
            
            lcd.setAddress(0,3);
            lcd.printf("TEST3   ");
        
            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