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);
/******************************************************************************/