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
Diff: main.cpp
- Revision:
- 5:e36e0538a903
- Parent:
- 4:86d0d04cc055
- Child:
- 6:d1594fd2ec5a
--- a/main.cpp Fri Sep 19 01:54:00 2014 +0000 +++ b/main.cpp Tue Sep 23 18:24:19 2014 +0000 @@ -6,11 +6,6 @@ #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> @@ -19,33 +14,21 @@ #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 &); +int interpretCommand(FILE *, LineData &); +int loopCommand(FILE *, LineData &); /**********************************************************************************************************************************/ /**********************************************************************************************************************************/ /*************************** <FUNCTION: resetLineData> **************************/ /**********************************************************************************************************************************/ /**********************************************************************************************************************************/ -void resetLineData(Line &lineData){ +void resetLineData(LineData &lineData){ //lineData.fullLine.clear(); lineData.lineNumber = 0; @@ -93,6 +76,344 @@ } +/**********************************************************************************************************************************/ +/**********************************************************************************************************************************/ +/************************** <FUNCTION: conditionCommand> *****************************/ +/**********************************************************************************************************************************/ +/**********************************************************************************************************************************/ + +//Create an enum map of the positble conditions +enum ConditionType{xAND, AND, xOR, OR, NONE}; +//static const enum ConditionType Condition_Map[] = {xAND, AND, xOR, OR}; + +struct ConditionOp{ + + int value; //returned value of the interpret function: 1 = meets criteria, 0 = criteria not met, -1 = failed to interpret + ConditionType op; //operator that follows the given parameter: x val 2 AND y val 3, if this ConditionOp is for x, then the value will be AND +}; + +int conditionCommand(FILE *selectedFile, LineData &lineData){ + + //Get the number of condition parameters + string numConditionVals = lineData.word[1]; + int numConditionValues = 0; + sscanf(numConditionVals.c_str(), "%d", &numConditionValues); + + //LineData tempLineData; + LineData param[15]; + //vector<LineData> param; + vector<ConditionOp> paramCondition; + +/* + int val1, val2, val3, val4; + LineData temp; + temp.numWords = 3; + temp.word[1] = "val"; + temp.word[2] = "1"; + while (true){ + + temp.word[0] = "pin1"; + val1 = interpretCommand(selectedFile, temp); + + temp.word[0] = "pin2"; + val2 = interpretCommand(selectedFile, temp); + + temp.word[0] = "pin3"; + val3 = interpretCommand(selectedFile, temp); + + temp.word[0] = "pin4"; + val4 = interpretCommand(selectedFile, temp); + + lcd.cls(); //clear the display + lcd.setAddress(0,0); + lcd.printf("Pin1: %d", val1); + lcd.setAddress(0,1); + lcd.printf("Pin2: %d", val2); + lcd.setAddress(0,2); + lcd.printf("Pin3: %d", val3); + lcd.setAddress(0,3); + lcd.printf("Pin4: %d", val4); + wait(0.2); + }*/ + + //Fill the param Vector with Line structs of each individual device, this way we can send the Line struct to the appropriate interpret function without modification within the function itself + int i = 2, numParam = 0, paramNumWords = 0; + for (i = 2; i < lineData.numWords; i++){ + + lcd.setAddress(0,3); + lcd.printf("Test2"); + + /*lcd.setAddress(0,2); + lcd.printf("i: %d, nW-1: %d ", i, (lineData.numWords - 1)); + wait(2);*/ + + // if the word is not an AND or an OR, it must mean it's for the specific function + // set the current parameter's next word to be equal to the current word we're checking + // increase number of words that the parameter has + if (lineData.word[i] != "AND" && lineData.word[i] != "xAND" && lineData.word[i] != "OR" && lineData.word[i] != "xOR"){ +// lcd.setAddress(0,3); +// lcd.printf("%dlD[%d]: %s", numParam, i, lineData.word[i]); +// wait(2); + //tempLineData.word[paramNumWords] = lineData.word[i]; + param[numParam].word[paramNumWords] = lineData.word[i]; + paramNumWords++; + + //if this is the last word in the line.... + if(i == (lineData.numWords - 1)){ + param[numParam].numWords = paramNumWords; + paramCondition[numParam].op = NONE; + numParam++; + } + + } + + // if the word is an AND or an OR, it must mean the last function has been completely identified + // set the parameters number of Words value to the calculated value + // increase the number of Parameters (the current parameter function we're filling) + else if (lineData.word[i].compare("AND") == 0 || lineData.word[i].compare("xAND") == 0 || lineData.word[i].compare("OR") == 0 || lineData.word[i].compare("xOR") == 0){ + + //tempLineData.numWords = paramNumWords; + param[numParam].numWords = paramNumWords; + + paramCondition.push_back(ConditionOp()); + if (lineData.word[i].compare("AND") == 0) + paramCondition[numParam].op = AND; + else if (lineData.word[i].compare("xAND") == 0) + paramCondition[numParam].op = xAND; + else if (lineData.word[i].compare("OR") == 0) + paramCondition[numParam].op = OR; + else if (lineData.word[i].compare("xOR") == 0) + paramCondition[numParam].op = xOR; + + //param.push_back(LineData()); + //param[numParam] = tempLineData; + //param.push_back(tempLineData); //add it to the vector list of parameters + //tempLineData = LineData(); //reset + numParam++; // increase the index of param + paramNumWords = 0; // reset the number of words + } + } + + + vector<ConditionOp> combinedCondition; + ConditionOp tempCombinedCondition; + int j = 0, k = 0, returnValue = -1; + for (j = 0; j < numParam; j++){ + paramCondition[j].value = interpretCommand(selectedFile, param[j]); + } + + //create the combined Condition vector (take care of this xAND and xOR statements and combine them into one so that the whole vector is just AND's and OR's) + //this should make the xAND's / xOR's into a single member of the combinedCondition vector + enum ConditionType prevCondition = NONE; + int first = 1, last = 0; + for (k = 0; k < numParam; k++){ +/* +lcd.setAddress(0,3); + lcd.printf("k: %d ", k); + wait(1);*/ + + if (k == numParam - 1) + last = 1; + + if (!last && (prevCondition != AND || prevCondition != OR)){ + if (paramCondition[k].op != xAND && paramCondition[k].op != xOR && paramCondition[k + 1].op != xAND && paramCondition[k + 1].op != xOR){ + + /* lcd.setAddress(0,3); + lcd.printf("Test 0.1 "); + wait(1);*/ + + //AND + if (paramCondition[k].op == AND){ + if (!first && prevCondition != xAND && prevCondition != xOR){ + /* lcd.setAddress(0,3); + lcd.printf("Test 1.6 "); + wait(1);*/ + combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value; + } + else if (first || prevCondition == xAND || prevCondition == xOR){ + /* lcd.setAddress(0,3); + lcd.printf("Test 1.5 "); + wait(1);*/ + tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; + combinedCondition.push_back(tempCombinedCondition); + first = 0; + } + prevCondition = AND; + } + + //OR + else if (paramCondition[k].op == OR){ + if (!first && prevCondition != xAND && prevCondition != xOR){ + combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value; + /*lcd.setAddress(0,3); + lcd.printf("Test 1.1 "); + wait(1);*/ + }else if (first || prevCondition == xAND || prevCondition == xOR){ + /* lcd.setAddress(0,3); + lcd.printf("Test 1.2 "); + wait(1);*/ + tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; + combinedCondition.push_back(tempCombinedCondition); + first = 0; + } + prevCondition = OR; + } + } + + else{ + /*lcd.setAddress(0,3); + lcd.printf("Test 0.2 "); + wait(1);*/ + //xAND + if (paramCondition[k].op == xAND && prevCondition == xAND){ + /*lcd.setAddress(0,3); + lcd.printf("Test 2 "); + wait(1);*/ + combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value; + prevCondition = xAND; + } + else if (paramCondition[k].op == xAND && prevCondition != xAND){ + /*lcd.setAddress(0,3); + lcd.printf("Test 1 "); + wait(1);*/ + tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; + combinedCondition.push_back(tempCombinedCondition); + prevCondition = xAND; + } + /*else if (paramCondition[k].op != xAND && prevCondition == xAND){ + combinedCondition.back().op = paramCondition[k].op; + prevCondition = xAND; + }*/ + + //xOR + else if (paramCondition[k].op == xOR && prevCondition == xOR){ + /*lcd.setAddress(0,3); + lcd.printf("Test 1.3 "); + wait(1);*/ + combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value; + prevCondition = xOR; + } + else if (paramCondition[k].op == xOR && prevCondition != xOR){ + /* lcd.setAddress(0,3); + lcd.printf("Test 1.4 "); + wait(1);*/ + tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; + combinedCondition.push_back(tempCombinedCondition); + prevCondition = xOR; + } + /*else if (paramCondition[k].op != xOR && prevCondition == xOR){ + combinedCondition.back().op = paramCondition[k].op; + prevCondition = xOR; + }*/ + + // Since the k + 1 value is included in the xAND or xOR exclusively, skip checking that value, and add the appropriate AND / OR as the + // operator of this exclusive xAND / xOR set + if ((paramCondition[k + 1].op == AND || paramCondition[k + 1].op == OR) && (prevCondition == xAND || prevCondition == xOR)){ + /*lcd.setAddress(0,3); + lcd.printf("Test 3 "); + wait(1);*/ + combinedCondition.back().op = paramCondition[k + 1].op; + k++; + } + + } + } + + //the last value was not included in any combination, since directly before the last value was an xAND / xOR set that + // included the very last AND / OR as the set's operator + else{ + /*lcd.setAddress(0,3); + lcd.printf("Test 5 "); + wait(1);*/ + tempCombinedCondition.value = paramCondition[k].value; + tempCombinedCondition.op = NONE; + combinedCondition.push_back(tempCombinedCondition); + } + + //reset the tempCombinedCondition variable + tempCombinedCondition = ConditionOp(); + } + + // run through all values in the combined Condition vector, AND'ing / OR'ing as appropriate + // in the end, the last value in the array should be the final condition of the Condition statement... whether it was successful or failed + for (i = 0; i < (combinedCondition.size() - 1); i++){ + if (combinedCondition[i].op == AND) + combinedCondition[i + 1].value = combinedCondition[i].value && combinedCondition[i + 1].value; + else if (combinedCondition[i].op == OR) + combinedCondition[i + 1].value = combinedCondition[i].value || combinedCondition[i + 1].value; + } + + int conditionSuccess = combinedCondition.back().value; //value is the success(1) or failure(0) of the condition statement + + + + int checkEnd = 0; + if (!conditionSuccess){ + lcd.setAddress(0,3); + lcd.printf("CONDITION FAILURE"); + wait(1); + while (checkEnd != 4){ + + getNextLine(selectedFile, lineData); + if (lineData.word[0].compare("end") == 0) + checkEnd = interpretCommand(selectedFile, lineData); + + if (checkEnd == 4) // custom return value for this function + return 0; + } + } + + lcd.setAddress(0,3); + lcd.printf("CONDITION SUCCESS"); + wait(1); + int returnValue2 = 1; + // Return success as the function either met the condition and will continue from the next line, or + // failed to meet the condition and ran through the lines inside the condition until "end condition" was found, therefore + // the program will proceed from the line after the "end condition" line + return returnValue2; +} + /* + for (k = 0; k < numParam; k++){ + if (paramCondition[k].op == AND){ + if (paramCondition[k + 1].op != xAND && paramCondition[k + 1].op != xOR) + tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; + else + tempCombinedCondition.value = paramCondition[k].value; + + tempCombinedCondition.op = AND; + combinedCondition.push_back(tempCombinedCondition); + prevCondition = AND; + } + + else if (paramCondition[k].op == OR){ + if (paramCondition[k + 1].op != xAND && paramCondition[k + 1].op != xOR) + tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; + else + tempCombinedCondition.value = paramCondition[k].value; + + tempCombinedCondition.op = OR; + combinedCondition.push_back(tempCombinedCondition); + prevCondition = OR; + } + + else if (paramCondition[k].op == xAND){ + if (prevCondition == xAND) // if previous one was also xAND, that means we already have a vector member for this (this last member) + combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value; + else{ // if the prevCondition was not xAND, then we need to add a new member to the vector + tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; + combinedCondition.push_back(tempCombinedCondition); + } + prevCondition = xAND; + } + else if (paramCondition[k].op == xOR){ + tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; + prevCondition = xOR; + } + } + + + return 1;*/ + /**********************************************************************************************************************************/ /**********************************************************************************************************************************/ @@ -100,7 +421,7 @@ /**********************************************************************************************************************************/ /**********************************************************************************************************************************/ -int loopCommand(FILE *selectedFile, Line &lineData){ +int loopCommand(FILE *selectedFile, LineData &lineData){ //Get the Condition value for number of times to loop string loopCondition = lineData.word[1]; @@ -112,17 +433,35 @@ int counter = 0, checkEnd = 0; while (counter < loopConditionValue){ - getNextLine(selectedFile, lineData); - checkEnd = interpretCommand(selectedFile, lineData); - + /*lcd.setAddress(0,3); + lcd.printf("BcheckEnd: %d ", checkEnd); + wait(1);*/ + + getNextLine(selectedFile, lineData); + + //Must get the address before entering the interpret command + // if a Condition command is immediately after, and the condition fails, then + // the interpret command will return the line at the "end condition" line, and therefore + // set the loop's first line to be the "end condition" line, if interpretCommand is called BEFORE setting the first loop line address if (firstLineOfLoop){ loopStartAddress = lineData.lineAddress; //Save the Line Address loopLineNumber = lineData.lineNumber; //Save the Line Number firstLineOfLoop = 0; } + + checkEnd = interpretCommand(selectedFile, lineData); + + /*lcd.setAddress(0,3); + lcd.printf("AcheckEnd: %d ", checkEnd); + wait(1);*/ + + /* + lcd.setAddress(0,3); + lcd.printf("checkEnd: %d ", checkEnd); + wait(2);*/ //Increase the loop counter and go back to the beginning of the loop - if (checkEnd == 1){ + if (checkEnd == 3){ counter++; lcd.setAddress(0,2); @@ -130,6 +469,7 @@ fseek(selectedFile, loopStartAddress, SEEK_SET); lineData.lineNumber = loopLineNumber - 2; + checkEnd = 0; } } @@ -142,7 +482,7 @@ /**********************************************************************************************************************************/ /**********************************************************************************************************************************/ -int interpretCommand(FILE *selectedFile, Line &lineData){ +int interpretCommand(FILE *selectedFile, LineData &lineData){ if (lineData.word[0].compare("device") == 0){ @@ -187,13 +527,22 @@ if (checkLoopEnd == 1) return 1; } - + + else if (lineData.word[0].compare("condition") == 0){ + int checkLoopEnd = conditionCommand(selectedFile, lineData); + if (checkLoopEnd == 1) + return 2; + } + // end with custom return value for specific function else if (lineData.word[0].compare("end") == 0){ if (lineData.word[1].compare("program") == 0){ - return 0; + return 2; } else if (lineData.word[1].compare("loop") == 0){ - return 1; + return 3; + } + else if (lineData.word[1].compare("condition") == 0){ + return 4; } } @@ -216,7 +565,7 @@ //Local Name matches a device, send line to that device in order to process the functionality else{ //addDevice(deviceFound); - devices[deviceFound]->interpret(lineData); + return devices[deviceFound]->interpret(lineData); } } @@ -234,7 +583,7 @@ fullInit(); //Initialize anything that's required to run the code (LCD) - struct Line lineData; + struct LineData lineData; resetLineData(lineData); /******************************************************************************/