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
Revision 9:5a0c4c6e39c7, committed 2014-09-24
- Comitter:
- mehatfie
- Date:
- Wed Sep 24 22:23:00 2014 +0000
- Parent:
- 8:e9f836163229
- Child:
- 10:e8db892fbc52
- Commit message:
- - System error checking and syntax checking should be completed; --- Compiled code still functions correctly; --- All error checking has not been checked that they indeed error out / not error out and function as planned
Changed in this revision
--- a/Devices/Motor.cpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Devices/Motor.cpp Wed Sep 24 22:23:00 2014 +0000
@@ -1,21 +1,13 @@
#include "Motor.hpp"
-//#include "mbed.h"
-//#include "LocalPinNames.h"
-//#include "BridgeDriver.h"
//Constructor
Motor::Motor(LineData lineData){
- /*
- //Order of Line: Command, Local_Name, VOLTAGE_DRIVER, Channel(1,2,3,4,5,6,7,8)
- if (lineData.numWords != 4){
- //Error Check, incorrect number of parameter, error out
- //return 0;
- }*/
- /*lcd.setAddress(0,3);
- lcd.printf("CHECK Motor Construct");
- wait(2);*/
-
+ //Order of Line: Command, Local_Name, MOTOR, MotorID(A,B,C,D)
+ //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 != 4)
+ this->errorFlag = 1;
+
string channel = lineData.word[3]; //Parameter is a single character, so dereference the point to the word
if ((channel.compare("A") == 0) || (channel.compare("a") == 0))
@@ -26,7 +18,11 @@
this->motor = BridgeDriver::MOTOR_C;
else if ((channel.compare("D") == 0) || (channel.compare("d") == 0))
this->motor = BridgeDriver::MOTOR_D;
-
+
+ //MotorID not known
+ else
+ this->errorFlag = 1;
+
bridges.enablePwm(this->motor, 1);
}
@@ -37,15 +33,8 @@
//A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on]
int Motor::interpret(LineData &lineData){
- /*
- lcd.setAddress(0,2);
- lcd.printf("CHECK Motor 123456");
- lcd.setAddress(0,3);
- lcd.printf("func: %s ", lineData.word[1]);
- wait(2);*/
-
+
//Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,.......
- //char localname[15] = lineData.word[0]; //just for the sake of following the variable easily and understanding
string func = lineData.word[1];
/******************************************************************************/
@@ -53,16 +42,21 @@
/******************************************************************************/
if (func.compare("enableBrake") == 0){
- if (lineData.numWords != 4){
- //Error Check, incorrect number of parameter, error out
- return 0;
+ if (lineData.numWords != 3){
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
//Initialize and Convert Parameters
string enable = lineData.word[2];
int enableValue = 0;
- sscanf(enable.c_str(), "%d", &enableValue);
+ int numValuesFound = sscanf(enable.c_str(), "%d", &enableValue);
+ if (numValuesFound < 1){
+ ErrorOut("Parameter Unknown, enableBrake value can't be converted", lineData.lineNumber);
+ return -1;
+ }
+
bridges.enableBraking(getMotor(), enableValue);
}
@@ -71,9 +65,9 @@
/******************************************************************************/
else if (func.compare("forceBrake") == 0){
- if (lineData.numWords != 3){
- //Error Check, incorrect number of parameter, error out
- return 0;
+ if (lineData.numWords != 2){
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
bridges.forceBrake(getMotor());
@@ -85,15 +79,9 @@
/******************************************************************************/
else if (func.compare("drive") == 0){
- /*lcd.setAddress(0,2);
- lcd.printf("wrd2: %s", lineData.word[1]);
- lcd.setAddress(0,3);
- lcd.printf("TEST2 ");
- wait(2);*/
-
if (lineData.numWords != 4){
- //Error Check, incorrect number of parameter, error out
- return 0;
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
//Initialize Parameters
@@ -105,55 +93,62 @@
int dirValue = 0;
//Convert string to usable values
- //NOTE both atof and atoi functions return 0 if no valid conversion could be performed
- sscanf(speed.c_str(), "%f", &speedValue);
+ 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)
- return 0; //Error Out because a value gives no functionality or is wrong
-
+
+ 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
- return 0; //Error Out since the parameter is incorrect
-
+
+ else{
+ ErrorOut("Direction Value must be C or CC", lineData.lineNumber);
+ return -1;
+ }
bridges.drive(getMotor(), dirValue, speedValue); //Turn on the Motor
-
}
+
+
/******************************************************************************/
/**** <Func: off> ****/
/******************************************************************************/
else if (func.compare("off") == 0){
- /*lcd.setAddress(0,2);
- lcd.printf("wrd2: %s", lineData.word[1]);
- lcd.setAddress(0,3);
- lcd.printf("TEST2 ");
- wait(1);*/
-
if (lineData.numWords != 2){
- //Error Check, incorrect number of parameter, error out
- return 0;
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
- bridges.drive(getMotor(), 0, 0); //Turn off the Motor
+ off();
}
else {
- return 0;
-
- }
+ ErrorOut("Unknown Command for Motor Class", lineData.lineNumber);
+ return -1;
+ }
- 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 Motor::off(void){
+ bridges.drive(getMotor(), 0, 0); //Turn off the Motor
+}
/*
--- a/Devices/Motor.hpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Devices/Motor.hpp Wed Sep 24 22:23:00 2014 +0000
@@ -11,6 +11,7 @@
public:
Motor(LineData);
int interpret(LineData&);
+ int off();
enum BridgeDriver::Motors getMotor();
//void enableBrake();
//int forceBrake();
--- a/Devices/PinIN.cpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Devices/PinIN.cpp Wed Sep 24 22:23:00 2014 +0000
@@ -6,6 +6,10 @@
//Constructor
PinIN::PinIN(LineData lineData){
+ //Order of Line: Command, Local_Name, PIN_IN, pinName, pinMode
+ if (lineData.numWords != 5)
+ this->errorFlag = 1;
+
string _pinName = lineData.word[3]; // Local Pin
string _pinMode = lineData.word[4]; // Pin Mode to Select
@@ -46,7 +50,10 @@
this->pinName = AI4;
else if(_pinName.compare("AI5") == 0)
this->pinName = AI5;
-
+
+ //Pin Name not recognized
+ else
+ this->errorFlag = 1;
if(_pinMode.compare("PU") == 0)
this->pinMode = PullUp;
@@ -57,48 +64,16 @@
else if(_pinMode.compare("OD") == 0)
this->pinMode = OpenDrain;
+ //Pin Mode not recognized
+ else
+ this->errorFlag = 1;
}
-/*
- #define DIO0 P2_2
-#define DIO1 P2_3
-#define DIO2 P2_4
-#define DIO3 P2_5
-#define DIO4 P2_6
-#define DIO5 P2_7
-#define DIO6 P2_8
-#define DIO7 P2_9
-#define DIO8 P1_1
-#define DIO9 P1_4
-#define DIO10 P1_8
-#define DIO11 P1_9
-#define SS1 P0_19
-#define SS2 P0_20
-#define SS3 P0_21
-#define SS4 P0_22
-#define SS_ADC P1_0
-#define AI0 P0_23
-#define AI1 P0_24
-#define AI2 P0_25
-#define AI3 P0_26
-#define AI4 P1_30
-#define AI5 P1_31
-#define KILL P2_11
-#define CAN1_RX P0_0
-#define CAN1_TX P0_1
-#define CAN2_RX P0_4
-#define CAN2_TX P0_5
- */
//A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on]
int PinIN::interpret(LineData &lineData){
- /*
- lcd.setAddress(0,2);
- lcd.printf("CHECK Motor 123456");
- lcd.setAddress(0,3);
- lcd.printf("func: %s ", lineData.word[1]);
- wait(2);*/
-
+
+ //Initialize the Pin with appropriate values
DigitalIn signal(pinName, pinMode);
//Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,.......
@@ -110,15 +85,26 @@
if (func.compare("wait") == 0){
if (lineData.numWords != 3){
- //Error Check, incorrect number of parameter, error out
- return 0;
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
//Initialize and Convert Parameters
string pinValue = lineData.word[2];
int pinValue_Value = 0;
- sscanf(pinValue.c_str(), "%d", &pinValue_Value);
+
+ int numValuesFound = sscanf(pinValue.c_str(), "%d", &pinValue_Value);
+ if (numValuesFound < 1){
+ ErrorOut("Parameter Unknown, pin value can't be converted", lineData.lineNumber);
+ return -1;
+ }
+ if(pinValue_Value < 0 && pinValue_Value > 1){
+ ErrorOut("Pin Value must be either 0 or 1", lineData.lineNumber);
+ return -1;
+ }
+
+ //Wait on the signal to turn to the specified value
while(signal.read() != pinValue_Value);
}
@@ -127,18 +113,28 @@
/*** <Func: val> ***/
/******************************************************************************/
// returns 1 if the check value is equal to the current check value of the Pin
- if (func.compare("val") == 0){
+ else if (func.compare("val") == 0){
if (lineData.numWords != 3){
- //Error Check, incorrect number of parameter, error out
- return 0;
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
//Initialize and Convert Parameters
string checkValue = lineData.word[2];
int checkValue_Value = 0;
- sscanf(checkValue.c_str(), "%d", &checkValue_Value);
+ int numValuesFound = sscanf(checkValue.c_str(), "%d", &checkValue_Value);
+ if (numValuesFound < 1){
+ ErrorOut("Parameter Unknown, pin value can't be converted", lineData.lineNumber);
+ return -1;
+ }
+ if(checkValue_Value < 0 && checkValue_Value > 1){
+ ErrorOut("Pin Value must be either 0 or 1", lineData.lineNumber);
+ return -1;
+ }
+
+ //Return one if value meets the wanted pin value, return 0 if it doesn't
if(signal.read() == checkValue_Value)
return 1;
else
@@ -146,10 +142,13 @@
}
else {
- return 0;
-
+ ErrorOut("Unknown Command for PinIn Class", lineData.lineNumber);
+ return -1;
}
-
- return 0;
+
+ return 0; //Return success as 0 since no condition had to be met
}
+int PinIN::off(void){
+ //Do Nothing as you don't need to turn a Pin off
+}
\ No newline at end of file
--- a/Devices/PinIN.hpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Devices/PinIN.hpp Wed Sep 24 22:23:00 2014 +0000
@@ -12,6 +12,7 @@
public:
PinIN(LineData);
int interpret(LineData&);
+ int off();
};
#endif
\ No newline at end of file
--- a/Devices/VoltageDriver.cpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Devices/VoltageDriver.cpp Wed Sep 24 22:23:00 2014 +0000
@@ -7,15 +7,14 @@
VoltageDriver::VoltageDriver(LineData lineData){
//Order of Line: Command, Local_Name, VOLTAGE_DRIVER, Channel(1,2,3,4,5,6,7,8)
- if (lineData.numWords != 4){
- //Error Check, incorrect number of parameter, error out
- //return 0;
- }
+ if (lineData.numWords != 4)
+ this->errorFlag = 1;
string channelstr = lineData.word[3]; //Parameter is a number
- //int channelValue = 0;
- sscanf(channelstr.c_str(), "%d", &channel);
-
+ int numValuesFound = sscanf(channelstr.c_str(), "%d", &channel);
+ if (numValuesFound < 1)
+ this->errorFlag = 1;
+
//Channel Value between 1 to 8
if (channel >= 1 && channel <= 8){
@@ -38,14 +37,14 @@
break;
}
}
- else{
- //ERROR Out
- //Unacceptable channel, or conversion function failed when converting string to int
- }
+
+ //Channel does not fall into valid selection
+ else
+ this->errorFlag = 1;
}
-int VoltageDriver::getChannel(){
+int VoltageDriver::getChannel(){
return this->channel;
}
@@ -53,8 +52,7 @@
//A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on]
int VoltageDriver::interpret(LineData &lineData){
- //order of line: local_name, function_name, param1, param2, param3,.......
- //string localname = linedata.word[0]; //just for the sake of following the variable easily and understanding
+ //Order of line: local_name, function_name, param1, param2, param3,.......
string func = lineData.word[1];
/******************************************************************************/
@@ -62,9 +60,9 @@
/******************************************************************************/
if (func.compare("forcebrake") == 0){
- if (lineData.numWords != 3){
- //error check, incorrect number of parameter, error out
- return 0;
+ if (lineData.numWords != 2){
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
bridges.forceBrake(channel);
@@ -78,16 +76,11 @@
//order of line: local_name, drive
if (lineData.numWords != 2){
- //error check, incorrect number of parameter, error out
- return 0;
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
- //int state = 2;
bridges.drive(channel, 1); //turn channel on
- /*lcd.setaddress(0,2);
- lcd.printf("test ch: %d, state: %d", channelvalue, state);
- wait(3);*/
-
}
@@ -95,20 +88,27 @@
/**** <func: off> ****/
/******************************************************************************/
else if (func.compare("off") == 0){
- //order of line: local_name, drive, duration
if (lineData.numWords != 2){
- //error check, incorrect number of parameter, error out
- return 0;
+ ErrorOut("Incorrect number of parameters", lineData.lineNumber);
+ return -1;
}
- bridges.drive(getChannel(), 0); //turn channel off
+ off();
}
+
else {
- return 0;
-
- }
+ ErrorOut("Unknown Command for Voltage Driver Class", lineData.lineNumber);
+ return -1;
+ }
- return 1;
-}
\ No newline at end of file
+ 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 VoltageDriver::off(void){
+ bridges.drive(getChannel(), 0); //turn channel off
+}
+
--- a/Devices/VoltageDriver.hpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Devices/VoltageDriver.hpp Wed Sep 24 22:23:00 2014 +0000
@@ -11,6 +11,7 @@
public:
VoltageDriver(LineData);
int interpret(LineData&);
+ int off();
int getChannel();
//void enableBrake();
//int forceBrake();
--- a/Initialization.cpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Initialization.cpp Wed Sep 24 22:23:00 2014 +0000
@@ -66,9 +66,19 @@
wait(.6);
lcd.cls(); //clear the display
lcd.setAddress(0,0);
- lcd.printf("LCD Initialized");
+ lcd.printf("Initializing...");
}
+void ErrorOut(string message, int lineNumber){
+
+ lcd.cls(); //clear the display
+
+ lcd.setAddress(0,0);
+ lcd.printf("Error: %s", message);
+
+ lcd.setAddress(0,3);
+ lcd.printf("Line Number: %d", lineNumber);
+}
/******************************************************************************/
/*** <Parent Device Class Initializations> ***/
@@ -77,4 +87,4 @@
int numDevices = sizeof(DeviceNames)/sizeof(DeviceNames[0]);
int currNumDevices = 0;
-vector<Device*> devices;
\ No newline at end of file
+vector<Device*> devices; //create a vector to hold all of the devices
\ No newline at end of file
--- a/Initialization.hpp Wed Sep 24 01:46:02 2014 +0000
+++ b/Initialization.hpp Wed Sep 24 22:23:00 2014 +0000
@@ -50,7 +50,7 @@
void initLCD(void); //Initialize the LCD
-
+void ErrorOut(string, int); //Outputs error message, line number, and formatting to LCD
/******************************************************************************/
/*** <Line Data Struct Initializations> ***/
@@ -85,9 +85,11 @@
public:
string name;
+ int errorFlag;
enum DeviceType type;
static Device* newDevice(int, string, LineData);
virtual int interpret(LineData&) = 0;
+ virtual int off() = 0;
};
extern vector<Device*> devices; //Initialize array of devices, initially assume 15 devices will be used (will expand as needed)
--- a/TextFile.h Wed Sep 24 01:46:02 2014 +0000
+++ b/TextFile.h Wed Sep 24 22:23:00 2014 +0000
@@ -32,26 +32,22 @@
// read file names into vector of strings
vector<string> readFileNames(char *dir) {
- lcd.setAddress(0,1);
- lcd.printf("TEST1");
-
vector<string> filenames;
DIR *dp;
struct dirent *dirp;
- lcd.setAddress(0,2);
- lcd.printf("TEST2");
-
+
dp = opendir(dir);
- lcd.setAddress(0,3);
- lcd.printf("TEST3");
-
- //read all directory and file names in current directory into filename vector
- while((dirp = readdir(dp)) != NULL) {
- filenames.push_back(string(dirp->d_name));
+ //if no directory was found, don't try and get the fileNames and return an empty vector of 0
+ if (dp != NULL){
+
+ //read all directory and file names in current directory into filename vector
+ while((dirp = readdir(dp)) != NULL) {
+ filenames.push_back(string(dirp->d_name));
+ }
+ closedir(dp);
}
- closedir(dp);
return filenames;
}
@@ -94,47 +90,48 @@
/******************************************************************************/
//
-void getNextLine(FILE *selectedFile, LineData &lineData) {
+int getNextLine(FILE *selectedFile, LineData &lineData) {
lineData.lineAddress = ftell(selectedFile);
+ if (lineData.lineAddress == -1L){
+ ErrorOut("Unable to get address of line, SD Card Removed?", lineData.lineNumber + 1);
+ return -1;
+ }
+
//char *newLine;
//getline(selectedFile, newLine);
char newLine[MAX_LINE_LENGTH];
fgets(newLine, MAX_LINE_LENGTH, selectedFile);
- string tempString(newLine);
- //lineData.fullLine = newLine;
- lineData.lineNumber++;
+ if (newLine == NULL){
+ ErrorOut("Unable to get the next line, SD Card Removed?", lineData.lineNumber + 1);
+ return -1;
+ }
- stringstream newLineStrm(newLine);
- //string tempWord = strtok(cpyLine, " ");
+ lineData.lineNumber++; // new line successfully found, increase lineNumber
+ //pull out each individual word (separated by any white space), and place it in the vector
+ stringstream newLineStrm(newLine);
istream_iterator<string> it(newLineStrm);
istream_iterator<string> end;
vector<string> results(it, end);
+
+ //copy the vector of results into the array of words
copy(results.begin(), results.end(), lineData.word);
lineData.numWords = results.size(); //Record the number of words in the line
- results.erase(results.begin(), results.end());
+ results.erase(results.begin(), results.end()); //remove the results vector from memory
- /*
- int numWords = 0;
- while (tempWord != NULL){
- strcpy(lineData.word[numWords], tempWord); //Record the word in the lineData array
- numWords++; //add the number of words first, since we've already got one word, this helps for the way the while loop works too
- tempWord = strtok(NULL, " ");
- }*/
-
-
-
+ //Update the Current Line Number
lcd.setAddress(0,2);
lcd.printf("Current Line#: %d ", lineData.lineNumber);
+ //Update the cmd/dvc label for the line so that the user has an idea of what's going on
lcd.setAddress(0,3);
- lcd.printf(" "); // Clear the Line using Spaces (Emptyness) - Note one line is 20 Characters
+ lcd.printf(" "); // Clear the Line using Spaces (Emptyness) - Note one line is 20 Characters
lcd.setAddress(0,3);
lcd.printf("cmd/dvc: %s", lineData.word[0]);
--- a/main.cpp Wed Sep 24 01:46:02 2014 +0000
+++ b/main.cpp Wed Sep 24 22:23:00 2014 +0000
@@ -5,6 +5,7 @@
#include "TextLCD.h"
#include "SDFileSystem.h"
#include "Initialization.hpp"
+//#include "mainFunctions.hpp"
#include "TextFile.h"
#include <stdio.h>
#include <string>
@@ -17,26 +18,26 @@
//extern "C" void mbed_reset(); //enable software reset of code
+
+int cyclePrograms(vector<string>, int, int, int);
+void resetLineData(LineData &); //reset and all variables of the Line Data Struct
int interpretCommand(FILE *, LineData &);
+
int loopCommand(FILE *, LineData &);
-/**********************************************************************************************************************************/
-/**********************************************************************************************************************************/
-/*************************** <FUNCTION: resetLineData> **************************/
-/**********************************************************************************************************************************/
-/**********************************************************************************************************************************/
+/******************************************************************************/
+/*** <Function: resetLineData> ***/
+/******************************************************************************/
+
void resetLineData(LineData &lineData){
- //lineData.fullLine.clear();
lineData.lineNumber = 0;
lineData.numWords = 0;
lineData.lineAddress = 0;
}
-
-
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************ <FUNCTION: cyclePrograms> *****************************/
@@ -82,45 +83,39 @@
/**********************************************************************************************************************************/
//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};
+enum ConditionType{xAND, AND, xOR, OR, NONE};
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
+ 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;
+ //Initialize variables
LineData param[15];
- //vector<LineData> param;
vector<ConditionOp> paramCondition;
//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++){
+ //this line reads: Condition, data_for_param1, CONDTITION_OP1, data_for_param2, CONDTITION_OP2, data_for_param3......
+ //Staring index of first data parameter is the 2nd word, therefore 1
+ int i = 1, numParam = 0, paramNumWords = 0;
+ for (i = 1; i < lineData.numWords; i++){
// 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"){
- //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;
+ paramCondition[numParam].op = NONE;
numParam++;
}
@@ -131,7 +126,6 @@
// 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());
@@ -144,26 +138,29 @@
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;
+
+ //send the data parameters in order to get them interpreted by the appropriate device
+ //if the value it's checking for meets the criteria you want, the device should return 1, if it doesn't meet the criteria the device should return 0
int j = 0, k = 0;
for (j = 0; j < numParam; j++){
paramCondition[j].value = interpretCommand(selectedFile, param[j]);
+
+ //error out if the interpretted command returned an error
+ if (paramCondition[j].value == -1)
+ return -1;
}
+
//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;
+ vector<ConditionOp> combinedCondition;
+ ConditionOp tempCombinedCondition;
int first = 1, last = 0;
for (k = 0; k < numParam; k++){
@@ -289,26 +286,32 @@
int conditionSuccess = combinedCondition.back().value; //value is the success(1) or failure(0) of the condition statement
- int checkEnd = 0;
+ int checkEnd = 0, returnValue;
if (!conditionSuccess){
while (checkEnd != 4){
- getNextLine(selectedFile, lineData);
+ returnValue = getNextLine(selectedFile, lineData);
+
+ //if getNextLine returned an error, then error out
+ if (returnValue == -1)
+ return -1;
// check if the first word is an end command (avoids interpreting functions that perform actions)
if (lineData.word[0].compare("end") == 0)
checkEnd = interpretCommand(selectedFile, lineData);
if (checkEnd == 4) // custom return value for this function
- return 0;
+ return 0; //Function operated successfully but doesn't return a value
+ else if (checkEnd == -1) //if interpretCommand returned an error, then error out
+ return -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 1;
+ return 0; //Function operated successfully but doesn't return a value
}
@@ -323,23 +326,32 @@
//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 numValuesFound = sscanf(loopCondition.c_str(), "%d", &loopConditionValue);
+ if (numValuesFound < 1){
+ ErrorOut("Parameter Unknown, loopCondition Value can't be converted", lineData.lineNumber);
+ return -1;
+ }
int loopStartAddress = 0, loopLineNumber = 0, firstLineOfLoop = 1;
lcd.setAddress(0,0);
lcd.printf("Cycle 1 of %d", loopConditionValue);
+ float totalLoopTime = 0;
Timer cycleTimer;
- float totalLoopTime = 0;
cycleTimer.reset();
cycleTimer.start();
- int counter = 1, checkEnd = 0;
+ int counter = 1, checkEnd = 0, returnValue;
while (counter <= loopConditionValue){
- getNextLine(selectedFile, lineData);
+ returnValue = getNextLine(selectedFile, lineData);
+ //if getNextLine returned an error, then return error out
+ if (returnValue == -1)
+ return -1;
+
//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
@@ -367,17 +379,24 @@
lcd.setAddress(0,0);
lcd.printf("Cycle %d of %d", counter, loopConditionValue);
- fseek(selectedFile, loopStartAddress, SEEK_SET);
- lineData.lineNumber = loopLineNumber - 2;
+ int seekFailure = fseek(selectedFile, loopStartAddress, SEEK_SET); //fseek returns 0 on success
+ if (seekFailure){
+ ErrorOut("In Loop Failed to seek line", lineData.lineNumber); //Spaces make it look nice on the LCD
+ return -1;
+ }
+
+ lineData.lineNumber = loopLineNumber - 1;
checkEnd = 0;
//Restart the timer for the next loop
cycleTimer.reset();
cycleTimer.start();
}
+ else if (checkEnd == -1) //if interpretCommand returned an error, then return error out
+ return -1;
}
- return 1;
+ return 0; //Return Success, no value is being sent so don't return 1
}
/**********************************************************************************************************************************/
@@ -396,57 +415,66 @@
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 *************************
+ ErrorOut("No device match found in the system", lineData.lineNumber); //Spaces make it look nice on LCD
+ return -1;
}
//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];
+ devices.back()->name = lineData.word[1];
+
+ //since the constructor cannot return a value, it will trip the error Flag if something is wrong, check that flag, and return error if it has been tripped
+ if (devices.back()->errorFlag == 1){
+ ErrorOut("Error initializing device", lineData.lineNumber);
+ return -1;
+ }
}
}
else if (lineData.word[0].compare("delay") == 0){
string duration = lineData.word[1];
int durationValue = 0;
- sscanf(duration.c_str(), "%d", &durationValue);
+ int numValuesFound = sscanf(duration.c_str(), "%d", &durationValue);
- if (durationValue){
+ if (numValuesFound < 1){
+ ErrorOut("Parameter Unknown, Duration Value can't be converted", lineData.lineNumber);
+ return -1;
+ }
+
+ if (durationValue > 0){
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
+ ErrorOut("Duration value is less than 0", lineData.lineNumber);
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("loop") == 0)
+ return loopCommand(selectedFile, lineData); //Process the loop command and return the value that it returns
- else if (lineData.word[0].compare("condition") == 0){
- int checkLoopEnd = conditionCommand(selectedFile, lineData);
- if (checkLoopEnd == 1)
+ else if (lineData.word[0].compare("condition") == 0)
+ return conditionCommand(selectedFile, lineData); //Process the condition command and return the value that it returns
+
+ //end has custom return value for specific functions, since "end" is a common keyword amongst functions
+ else if (lineData.word[0].compare("end") == 0){
+ if (lineData.word[1].compare("program") == 0)
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 2;
- }
- else if (lineData.word[1].compare("loop") == 0){
+ else if (lineData.word[1].compare("loop") == 0)
return 3;
- }
- else if (lineData.word[1].compare("condition") == 0){
+ else if (lineData.word[1].compare("condition") == 0)
return 4;
+
+ else{
+ ErrorOut("Unknown function ending", lineData.lineNumber);
+ return -1;
}
}
@@ -461,19 +489,16 @@
//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);
+ ErrorOut("No device match found in the system", lineData.lineNumber); //Spaces make it look nice on LCD
+ return -1;
}
//Local Name matches a device, send line to that device in order to process the functionality
- else{
- //addDevice(deviceFound);
- return devices[deviceFound]->interpret(lineData);
- }
+ else
+ return devices[deviceFound]->interpret(lineData); //call the device specific interpret command, and return the value it returns
}
- return -1;
+ return 0; //Return Success, no value is being sent so don't return 1
}
@@ -490,92 +515,119 @@
LineData 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);
-
+ /******************************************************************************/
+ /*** <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");
+
+ //Error check whether the SD Card exists and was able to be accessed.... or if there's no files on the SD Card
+ if (filenames.size() == 0){
+ ErrorOut("No Files Found, or Directory can't be accessed", 0); //Spaces make it look nice on LCD
+ return -1; //End program by returning in the main()
+ }
+
+ numTextFiles = getFileNamesWithoutExt(textFiles, filenames);
- /******************************************************************************/
- /*** <Select the Program txt File> ***/
- /******************************************************************************/
- int fileSelected = 0, selectedFileIndex = 0;
+ //Error check whether the SD Card has any txt files in it's first directory
+ if (numTextFiles == 0){
+ ErrorOut("No Program (.txt) Files Found in first Directory", 0); //Spaces make it look nice on LCD
+ return -1; //End program by returning in the main()
+ }
- 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 = 0;
- lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
+ /******************************************************************************/
+ /*** <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);
- 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());
+ uint8_t lastButState = 0;
+ lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
+
+ selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, -1); //Initialize the first file to the screen
+ while(!fileSelected) {
- /******************************************************************************/
- /*** <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);
+ 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;
}
+ }
+
+ lcd.setCursor(TextLCD::CurOn_BlkOff); //turn blinking cursor off
+
+ 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");
+
+ //Error out of attempt to open the selected file was unsuccessful
+ if(selectedFile == NULL) {
+ ErrorOut("Unable to Open Selected File", 0); //Spaces make it look nice on LCD
+ return -1; //End program by returning in the main()
+ }
+ /******************************************************************************/
+ /*** <Start Running through the Program txt File Lines> ***/
+ /******************************************************************************/
+
while(1){
- resetLineData(lineData);
-
+ resetLineData(lineData); //Reset the values in the struct that holds the Line Data, in preparation for a new line read
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;
+ int endOfFile = 0, error = 0, returnValue, checkEnd;
while (!endOfFile){
-
- getNextLine(selectedFile, lineData);
- int checkEnd = interpretCommand(selectedFile, lineData);
+
+ //Re-initialize variables
+ returnValue = 0;
+ checkEnd = 0;
+
+ returnValue = getNextLine(selectedFile, lineData); //get the next line of data
+
+ //if getNextLine returned an error, then return error in main
+ if (returnValue == -1)
+ error = 1;
+
+ checkEnd = interpretCommand(selectedFile, lineData); //interpret the line data
if (checkEnd == 2)
endOfFile = 1;
+ else if (checkEnd == -1) //if interpretCommand returned an error, then return error in main
+ error = 1;
+
+ //Before erroring out, turn all devices off so that they power down
+ if (error){
+ for(vector<Device*>::iterator it=devices.begin(); it < devices.end(); it++)
+ (*it)->off();
+
+ return -1;
+ }
+
}
-
lcd.cls(); //clear the display
lcd.setAddress(0,0);
lcd.printf("END OF PROGRAM");
@@ -592,127 +644,4 @@
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /***** 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
\ No newline at end of file
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mainFunctions.cpp Wed Sep 24 22:23:00 2014 +0000
@@ -0,0 +1,431 @@
+//#include "mainFunctions.hpp"
+//
+///******************************************************************************/
+///*** <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: resetLineData> ***/
+///******************************************************************************/
+//
+//void resetLineData(LineData &lineData){
+//
+// lineData.lineNumber = 0;
+// lineData.numWords = 0;
+// lineData.lineAddress = 0;
+//}
+//
+///******************************************************************************/
+///*** <Function: interpretCommand> ***/
+///******************************************************************************/
+//
+//int interpretCommand(FILE *selectedFile, LineData &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("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 2;
+// }
+// else if (lineData.word[1].compare("loop") == 0){
+// return 3;
+// }
+// else if (lineData.word[1].compare("condition") == 0){
+// return 4;
+// }
+// }
+//
+// //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);
+// return devices[deviceFound]->interpret(lineData);
+// }
+// }
+//
+// return -1;
+//}
+//
+///******************************************************************************/
+///*** <Function: loopCommand> ***/
+///******************************************************************************/
+//
+//int loopCommand(FILE *selectedFile, LineData &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;
+//
+// lcd.setAddress(0,0);
+// lcd.printf("Cycle 1 of %d", loopConditionValue);
+//
+// Timer cycleTimer;
+// float totalLoopTime = 0;
+// cycleTimer.reset();
+// cycleTimer.start();
+//
+// int counter = 1, checkEnd = 0;
+// while (counter <= loopConditionValue){
+//
+// 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);
+//
+// //Increase the loop counter and go back to the beginning of the loop
+// if (checkEnd == 3){
+//
+// //Output the Avg Cycle Time
+// cycleTimer.stop();
+// totalLoopTime += cycleTimer.read();
+//
+// lcd.setAddress(0,1);
+// lcd.printf("Avg t(sec): %1.3f", (totalLoopTime / counter));
+//
+// //Output Cycle Number
+// counter++;
+// lcd.setAddress(0,0);
+// lcd.printf("Cycle %d of %d", counter, loopConditionValue);
+//
+// fseek(selectedFile, loopStartAddress, SEEK_SET);
+// lineData.lineNumber = loopLineNumber - 2;
+// checkEnd = 0;
+//
+// //Restart the timer for the next loop
+// cycleTimer.reset();
+// cycleTimer.start();
+// }
+// }
+//
+// return 1;
+// }
+//
+///******************************************************************************/
+///*** <Function: conditionCommand> ***/
+///******************************************************************************/
+//
+//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;
+//
+//
+// //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++){
+//
+// // 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"){
+//
+// //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;
+// 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++){
+//
+// if (k == numParam - 1)
+// last = 1;
+//
+// if (!last){
+// if (paramCondition[k].op != xAND && paramCondition[k].op != xOR && paramCondition[k + 1].op != xAND && paramCondition[k + 1].op != xOR){
+// //AND
+// if (paramCondition[k].op == AND){
+// if (!first && prevCondition != xAND && prevCondition != xOR)
+// combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value;
+// else if (first || prevCondition == xAND || prevCondition == xOR){
+// 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;
+// else if (first || prevCondition == xAND || prevCondition == xOR){
+// tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value;
+// combinedCondition.push_back(tempCombinedCondition);
+// first = 0;
+// }
+// prevCondition = OR;
+// }
+// }
+//
+// // first value is something, not exclusive, but next values are exclusive
+// else if (first && (paramCondition[k].op == AND || paramCondition[k].op == OR) && (paramCondition[k + 1].op == xAND || paramCondition[k + 1].op == xOR)){
+// tempCombinedCondition.value = paramCondition[k].value;
+// tempCombinedCondition.op = paramCondition[k].op;
+// combinedCondition.push_back(tempCombinedCondition);
+// prevCondition = paramCondition[k].op;
+// first = 0;
+// }
+//
+// else{
+// //xAND
+// if (paramCondition[k].op == xAND){
+// if (combinedCondition.size() == 0){ // No values so start a new combinedCondition
+// tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value;
+// tempCombinedCondition.op = xAND;
+// combinedCondition.push_back(tempCombinedCondition);
+// prevCondition = xAND;
+// }
+// else{
+// if (combinedCondition.back().op == xAND){ // AND the value to the back most combinedCondition
+// combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value;
+// prevCondition = xAND;
+// }
+// else if (combinedCondition.back().op != xAND){ // Start a new combinedCondition
+// tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value;
+// tempCombinedCondition.op = xAND;
+// combinedCondition.push_back(tempCombinedCondition);
+// prevCondition = xAND;
+// }
+// }
+//
+// }
+//
+// //xOR
+// else if (paramCondition[k].op == xOR){
+// if (combinedCondition.size() == 0){ // No values so start a new combinedCondition
+// tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value;
+// tempCombinedCondition.op = xOR;
+// combinedCondition.push_back(tempCombinedCondition);
+// prevCondition = xOR;
+// }
+// else{
+// if (combinedCondition.back().op == xOR){ // OR the value to the back most combinedCondition
+// combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value;
+// prevCondition = xOR;
+// }
+// else if (combinedCondition.back().op != xOR){ // Start a new combinedCondition
+// tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value;
+// tempCombinedCondition.op = xOR;
+// combinedCondition.push_back(tempCombinedCondition);
+// 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)){
+// 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, yet there is still another value that has not been combined, as it is supposed
+// // to be AND /OR to the exclusive xAND / xOR set
+// else if (last && (prevCondition == xAND || prevCondition == xOR) && (combinedCondition.back().op == AND || combinedCondition.back().op == OR)){
+// 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){
+//
+// while (checkEnd != 4){
+//
+// getNextLine(selectedFile, lineData);
+//
+// // check if the first word is an end command (avoids interpreting functions that perform actions)
+// if (lineData.word[0].compare("end") == 0)
+// checkEnd = interpretCommand(selectedFile, lineData);
+//
+// if (checkEnd == 4) // custom return value for this function
+// return 0;
+// }
+// }
+//
+// // 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 1;
+//}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mainFunctions.hpp Wed Sep 24 22:23:00 2014 +0000
@@ -0,0 +1,37 @@
+//#ifndef MAINFUNCTIONS_HPP
+//#define MAINFUNCTIONS_HPP
+//
+//#include "Initialization.hpp"
+////#include "TextFile.h"
+//
+///******************************************************************************/
+///*** <Function Initializations> ***/
+///******************************************************************************/
+//
+//int cyclePrograms(vector<string>, int, int, int);
+//
+//void resetLineData(LineData &); //reset and all variables of the Line Data Struct
+//
+//int interpretCommand(FILE *, LineData &);
+//
+//int loopCommand(FILE *, LineData &);
+//
+//
+////Create an enum map of the positble conditions
+//enum ConditionType{xAND, AND, xOR, OR, NONE};
+//
+//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 *, LineData &);
+//
+//
+///******************************************************************************/
+///*** <Line Data Struct Initializations> ***/
+///******************************************************************************/
+//
+//
+//
+//#endif
\ No newline at end of file