![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Component Test's Software to work with "Universal Controller Box" - Software is an interpreter or "compiler" for programs to be done with a .txt file and read off of the SD Card
Dependencies: BridgeDriver FrontPanelButtons MCP23017 SDFileSystem TextLCD mbed
main.cpp@10:e8db892fbc52, 2014-09-24 (annotated)
- Committer:
- mehatfie
- Date:
- Wed Sep 24 22:54:36 2014 +0000
- Revision:
- 10:e8db892fbc52
- Parent:
- 9:5a0c4c6e39c7
- Child:
- 11:bc9cd2869f95
- Dummy Mode implemented with code functioning after compile; --- goes through all of the code, but doesn't actually turn anything on or run any physical functionality, it simple performs syntax checking on the entire programming, and resets and runs
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mehatfie | 0:22618cf06f45 | 1 | #include "mbed.h" |
mehatfie | 0:22618cf06f45 | 2 | #include "LocalPinNames.h" |
mehatfie | 0:22618cf06f45 | 3 | #include "BridgeDriver.h" |
mehatfie | 0:22618cf06f45 | 4 | #include "FrontPanelButtons.h" |
mehatfie | 0:22618cf06f45 | 5 | #include "TextLCD.h" |
mehatfie | 0:22618cf06f45 | 6 | #include "SDFileSystem.h" |
mehatfie | 0:22618cf06f45 | 7 | #include "Initialization.hpp" |
mehatfie | 9:5a0c4c6e39c7 | 8 | //#include "mainFunctions.hpp" |
mehatfie | 0:22618cf06f45 | 9 | #include "TextFile.h" |
mehatfie | 0:22618cf06f45 | 10 | #include <stdio.h> |
mehatfie | 0:22618cf06f45 | 11 | #include <string> |
mehatfie | 0:22618cf06f45 | 12 | #include <stdlib.h> |
mehatfie | 0:22618cf06f45 | 13 | #include <fstream> |
mehatfie | 0:22618cf06f45 | 14 | #include <vector> |
mehatfie | 0:22618cf06f45 | 15 | using std::string; |
mehatfie | 0:22618cf06f45 | 16 | |
mehatfie | 1:5731f31f96be | 17 | FrontPanelButtons buttons(&i2c); |
mehatfie | 1:5731f31f96be | 18 | |
mehatfie | 0:22618cf06f45 | 19 | //extern "C" void mbed_reset(); //enable software reset of code |
mehatfie | 0:22618cf06f45 | 20 | |
mehatfie | 9:5a0c4c6e39c7 | 21 | |
mehatfie | 9:5a0c4c6e39c7 | 22 | int cyclePrograms(vector<string>, int, int, int); |
mehatfie | 1:5731f31f96be | 23 | |
mehatfie | 9:5a0c4c6e39c7 | 24 | void resetLineData(LineData &); //reset and all variables of the Line Data Struct |
mehatfie | 1:5731f31f96be | 25 | |
mehatfie | 5:e36e0538a903 | 26 | int interpretCommand(FILE *, LineData &); |
mehatfie | 9:5a0c4c6e39c7 | 27 | |
mehatfie | 5:e36e0538a903 | 28 | int loopCommand(FILE *, LineData &); |
mehatfie | 1:5731f31f96be | 29 | |
mehatfie | 9:5a0c4c6e39c7 | 30 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 31 | /*** <Function: resetLineData> ***/ |
mehatfie | 9:5a0c4c6e39c7 | 32 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 33 | |
mehatfie | 5:e36e0538a903 | 34 | void resetLineData(LineData &lineData){ |
mehatfie | 0:22618cf06f45 | 35 | |
mehatfie | 0:22618cf06f45 | 36 | lineData.lineNumber = 0; |
mehatfie | 0:22618cf06f45 | 37 | lineData.numWords = 0; |
mehatfie | 2:3e7baa3e3fec | 38 | lineData.lineAddress = 0; |
mehatfie | 0:22618cf06f45 | 39 | } |
mehatfie | 0:22618cf06f45 | 40 | |
mehatfie | 1:5731f31f96be | 41 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 42 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 43 | /************************ <FUNCTION: cyclePrograms> *****************************/ |
mehatfie | 1:5731f31f96be | 44 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 45 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 46 | |
mehatfie | 2:3e7baa3e3fec | 47 | int cyclePrograms(vector<string> files, int SIZE, int currIndex, int direction){ |
mehatfie | 0:22618cf06f45 | 48 | |
mehatfie | 0:22618cf06f45 | 49 | int nextIndex = 0; |
mehatfie | 0:22618cf06f45 | 50 | switch(direction){ |
mehatfie | 0:22618cf06f45 | 51 | case 0: //Cycle Back one File |
mehatfie | 0:22618cf06f45 | 52 | if ((currIndex - 1) < 0) |
mehatfie | 0:22618cf06f45 | 53 | nextIndex = SIZE - 1; |
mehatfie | 0:22618cf06f45 | 54 | else |
mehatfie | 0:22618cf06f45 | 55 | nextIndex = currIndex - 1; |
mehatfie | 0:22618cf06f45 | 56 | break; |
mehatfie | 0:22618cf06f45 | 57 | case 1: //Cycle Forward one File |
mehatfie | 0:22618cf06f45 | 58 | if ((currIndex + 1) >= SIZE) |
mehatfie | 0:22618cf06f45 | 59 | nextIndex = 0; |
mehatfie | 0:22618cf06f45 | 60 | else |
mehatfie | 0:22618cf06f45 | 61 | nextIndex = currIndex + 1; |
mehatfie | 0:22618cf06f45 | 62 | break; |
mehatfie | 0:22618cf06f45 | 63 | case -1: //set the selectedFile to the currIndex (used for initialization) |
mehatfie | 0:22618cf06f45 | 64 | nextIndex = currIndex; |
mehatfie | 0:22618cf06f45 | 65 | break; |
mehatfie | 0:22618cf06f45 | 66 | } |
mehatfie | 0:22618cf06f45 | 67 | |
mehatfie | 0:22618cf06f45 | 68 | //Output file on Display |
mehatfie | 0:22618cf06f45 | 69 | lcd.setAddress(0,3); |
mehatfie | 0:22618cf06f45 | 70 | lcd.printf(" "); // Clear the Line using Spaces (Emptyness) - Note one line is 20 Characters |
mehatfie | 0:22618cf06f45 | 71 | wait(.2); |
mehatfie | 0:22618cf06f45 | 72 | lcd.setAddress(0,3); |
mehatfie | 4:86d0d04cc055 | 73 | lcd.printf("%s", files[nextIndex]); |
mehatfie | 0:22618cf06f45 | 74 | |
mehatfie | 0:22618cf06f45 | 75 | return nextIndex; // Return the file index in the Array |
mehatfie | 0:22618cf06f45 | 76 | } |
mehatfie | 0:22618cf06f45 | 77 | |
mehatfie | 0:22618cf06f45 | 78 | |
mehatfie | 5:e36e0538a903 | 79 | /**********************************************************************************************************************************/ |
mehatfie | 5:e36e0538a903 | 80 | /**********************************************************************************************************************************/ |
mehatfie | 5:e36e0538a903 | 81 | /************************** <FUNCTION: conditionCommand> *****************************/ |
mehatfie | 5:e36e0538a903 | 82 | /**********************************************************************************************************************************/ |
mehatfie | 5:e36e0538a903 | 83 | /**********************************************************************************************************************************/ |
mehatfie | 5:e36e0538a903 | 84 | |
mehatfie | 5:e36e0538a903 | 85 | //Create an enum map of the positble conditions |
mehatfie | 9:5a0c4c6e39c7 | 86 | enum ConditionType{xAND, AND, xOR, OR, NONE}; |
mehatfie | 5:e36e0538a903 | 87 | |
mehatfie | 5:e36e0538a903 | 88 | struct ConditionOp{ |
mehatfie | 5:e36e0538a903 | 89 | |
mehatfie | 5:e36e0538a903 | 90 | int value; //returned value of the interpret function: 1 = meets criteria, 0 = criteria not met, -1 = failed to interpret |
mehatfie | 9:5a0c4c6e39c7 | 91 | 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 |
mehatfie | 5:e36e0538a903 | 92 | }; |
mehatfie | 5:e36e0538a903 | 93 | |
mehatfie | 5:e36e0538a903 | 94 | int conditionCommand(FILE *selectedFile, LineData &lineData){ |
mehatfie | 10:e8db892fbc52 | 95 | |
mehatfie | 9:5a0c4c6e39c7 | 96 | //Initialize variables |
mehatfie | 5:e36e0538a903 | 97 | LineData param[15]; |
mehatfie | 5:e36e0538a903 | 98 | vector<ConditionOp> paramCondition; |
mehatfie | 5:e36e0538a903 | 99 | |
mehatfie | 5:e36e0538a903 | 100 | |
mehatfie | 5:e36e0538a903 | 101 | //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 |
mehatfie | 9:5a0c4c6e39c7 | 102 | //this line reads: Condition, data_for_param1, CONDTITION_OP1, data_for_param2, CONDTITION_OP2, data_for_param3...... |
mehatfie | 9:5a0c4c6e39c7 | 103 | //Staring index of first data parameter is the 2nd word, therefore 1 |
mehatfie | 9:5a0c4c6e39c7 | 104 | int i = 1, numParam = 0, paramNumWords = 0; |
mehatfie | 9:5a0c4c6e39c7 | 105 | for (i = 1; i < lineData.numWords; i++){ |
mehatfie | 6:d1594fd2ec5a | 106 | |
mehatfie | 5:e36e0538a903 | 107 | // if the word is not an AND or an OR, it must mean it's for the specific function |
mehatfie | 5:e36e0538a903 | 108 | // set the current parameter's next word to be equal to the current word we're checking |
mehatfie | 5:e36e0538a903 | 109 | // increase number of words that the parameter has |
mehatfie | 5:e36e0538a903 | 110 | if (lineData.word[i] != "AND" && lineData.word[i] != "xAND" && lineData.word[i] != "OR" && lineData.word[i] != "xOR"){ |
mehatfie | 6:d1594fd2ec5a | 111 | |
mehatfie | 5:e36e0538a903 | 112 | param[numParam].word[paramNumWords] = lineData.word[i]; |
mehatfie | 5:e36e0538a903 | 113 | paramNumWords++; |
mehatfie | 5:e36e0538a903 | 114 | |
mehatfie | 5:e36e0538a903 | 115 | //if this is the last word in the line.... |
mehatfie | 5:e36e0538a903 | 116 | if(i == (lineData.numWords - 1)){ |
mehatfie | 5:e36e0538a903 | 117 | param[numParam].numWords = paramNumWords; |
mehatfie | 9:5a0c4c6e39c7 | 118 | paramCondition[numParam].op = NONE; |
mehatfie | 5:e36e0538a903 | 119 | numParam++; |
mehatfie | 5:e36e0538a903 | 120 | } |
mehatfie | 5:e36e0538a903 | 121 | |
mehatfie | 5:e36e0538a903 | 122 | } |
mehatfie | 5:e36e0538a903 | 123 | |
mehatfie | 5:e36e0538a903 | 124 | // if the word is an AND or an OR, it must mean the last function has been completely identified |
mehatfie | 5:e36e0538a903 | 125 | // set the parameters number of Words value to the calculated value |
mehatfie | 5:e36e0538a903 | 126 | // increase the number of Parameters (the current parameter function we're filling) |
mehatfie | 5:e36e0538a903 | 127 | 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){ |
mehatfie | 5:e36e0538a903 | 128 | |
mehatfie | 5:e36e0538a903 | 129 | param[numParam].numWords = paramNumWords; |
mehatfie | 5:e36e0538a903 | 130 | |
mehatfie | 5:e36e0538a903 | 131 | paramCondition.push_back(ConditionOp()); |
mehatfie | 5:e36e0538a903 | 132 | if (lineData.word[i].compare("AND") == 0) |
mehatfie | 5:e36e0538a903 | 133 | paramCondition[numParam].op = AND; |
mehatfie | 5:e36e0538a903 | 134 | else if (lineData.word[i].compare("xAND") == 0) |
mehatfie | 5:e36e0538a903 | 135 | paramCondition[numParam].op = xAND; |
mehatfie | 5:e36e0538a903 | 136 | else if (lineData.word[i].compare("OR") == 0) |
mehatfie | 5:e36e0538a903 | 137 | paramCondition[numParam].op = OR; |
mehatfie | 5:e36e0538a903 | 138 | else if (lineData.word[i].compare("xOR") == 0) |
mehatfie | 5:e36e0538a903 | 139 | paramCondition[numParam].op = xOR; |
mehatfie | 5:e36e0538a903 | 140 | |
mehatfie | 5:e36e0538a903 | 141 | numParam++; // increase the index of param |
mehatfie | 5:e36e0538a903 | 142 | paramNumWords = 0; // reset the number of words |
mehatfie | 5:e36e0538a903 | 143 | } |
mehatfie | 5:e36e0538a903 | 144 | } |
mehatfie | 5:e36e0538a903 | 145 | |
mehatfie | 9:5a0c4c6e39c7 | 146 | |
mehatfie | 9:5a0c4c6e39c7 | 147 | //send the data parameters in order to get them interpreted by the appropriate device |
mehatfie | 9:5a0c4c6e39c7 | 148 | //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 |
mehatfie | 6:d1594fd2ec5a | 149 | int j = 0, k = 0; |
mehatfie | 5:e36e0538a903 | 150 | for (j = 0; j < numParam; j++){ |
mehatfie | 5:e36e0538a903 | 151 | paramCondition[j].value = interpretCommand(selectedFile, param[j]); |
mehatfie | 9:5a0c4c6e39c7 | 152 | |
mehatfie | 9:5a0c4c6e39c7 | 153 | //error out if the interpretted command returned an error |
mehatfie | 9:5a0c4c6e39c7 | 154 | if (paramCondition[j].value == -1) |
mehatfie | 9:5a0c4c6e39c7 | 155 | return -1; |
mehatfie | 5:e36e0538a903 | 156 | } |
mehatfie | 5:e36e0538a903 | 157 | |
mehatfie | 9:5a0c4c6e39c7 | 158 | |
mehatfie | 5:e36e0538a903 | 159 | //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) |
mehatfie | 5:e36e0538a903 | 160 | //this should make the xAND's / xOR's into a single member of the combinedCondition vector |
mehatfie | 5:e36e0538a903 | 161 | enum ConditionType prevCondition = NONE; |
mehatfie | 9:5a0c4c6e39c7 | 162 | vector<ConditionOp> combinedCondition; |
mehatfie | 9:5a0c4c6e39c7 | 163 | ConditionOp tempCombinedCondition; |
mehatfie | 5:e36e0538a903 | 164 | int first = 1, last = 0; |
mehatfie | 5:e36e0538a903 | 165 | for (k = 0; k < numParam; k++){ |
mehatfie | 6:d1594fd2ec5a | 166 | |
mehatfie | 5:e36e0538a903 | 167 | if (k == numParam - 1) |
mehatfie | 5:e36e0538a903 | 168 | last = 1; |
mehatfie | 5:e36e0538a903 | 169 | |
mehatfie | 8:e9f836163229 | 170 | if (!last){ |
mehatfie | 5:e36e0538a903 | 171 | if (paramCondition[k].op != xAND && paramCondition[k].op != xOR && paramCondition[k + 1].op != xAND && paramCondition[k + 1].op != xOR){ |
mehatfie | 5:e36e0538a903 | 172 | //AND |
mehatfie | 5:e36e0538a903 | 173 | if (paramCondition[k].op == AND){ |
mehatfie | 8:e9f836163229 | 174 | if (!first && prevCondition != xAND && prevCondition != xOR) |
mehatfie | 5:e36e0538a903 | 175 | combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value; |
mehatfie | 5:e36e0538a903 | 176 | else if (first || prevCondition == xAND || prevCondition == xOR){ |
mehatfie | 5:e36e0538a903 | 177 | tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; |
mehatfie | 5:e36e0538a903 | 178 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 5:e36e0538a903 | 179 | first = 0; |
mehatfie | 5:e36e0538a903 | 180 | } |
mehatfie | 5:e36e0538a903 | 181 | prevCondition = AND; |
mehatfie | 5:e36e0538a903 | 182 | } |
mehatfie | 5:e36e0538a903 | 183 | |
mehatfie | 5:e36e0538a903 | 184 | //OR |
mehatfie | 5:e36e0538a903 | 185 | else if (paramCondition[k].op == OR){ |
mehatfie | 8:e9f836163229 | 186 | if (!first && prevCondition != xAND && prevCondition != xOR) |
mehatfie | 5:e36e0538a903 | 187 | combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value; |
mehatfie | 6:d1594fd2ec5a | 188 | else if (first || prevCondition == xAND || prevCondition == xOR){ |
mehatfie | 5:e36e0538a903 | 189 | tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; |
mehatfie | 5:e36e0538a903 | 190 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 5:e36e0538a903 | 191 | first = 0; |
mehatfie | 5:e36e0538a903 | 192 | } |
mehatfie | 5:e36e0538a903 | 193 | prevCondition = OR; |
mehatfie | 5:e36e0538a903 | 194 | } |
mehatfie | 5:e36e0538a903 | 195 | } |
mehatfie | 5:e36e0538a903 | 196 | |
mehatfie | 6:d1594fd2ec5a | 197 | // first value is something, not exclusive, but next values are exclusive |
mehatfie | 6:d1594fd2ec5a | 198 | else if (first && (paramCondition[k].op == AND || paramCondition[k].op == OR) && (paramCondition[k + 1].op == xAND || paramCondition[k + 1].op == xOR)){ |
mehatfie | 6:d1594fd2ec5a | 199 | tempCombinedCondition.value = paramCondition[k].value; |
mehatfie | 6:d1594fd2ec5a | 200 | tempCombinedCondition.op = paramCondition[k].op; |
mehatfie | 6:d1594fd2ec5a | 201 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 6:d1594fd2ec5a | 202 | prevCondition = paramCondition[k].op; |
mehatfie | 6:d1594fd2ec5a | 203 | first = 0; |
mehatfie | 6:d1594fd2ec5a | 204 | } |
mehatfie | 6:d1594fd2ec5a | 205 | |
mehatfie | 5:e36e0538a903 | 206 | else{ |
mehatfie | 5:e36e0538a903 | 207 | //xAND |
mehatfie | 8:e9f836163229 | 208 | if (paramCondition[k].op == xAND){ |
mehatfie | 8:e9f836163229 | 209 | if (combinedCondition.size() == 0){ // No values so start a new combinedCondition |
mehatfie | 8:e9f836163229 | 210 | tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; |
mehatfie | 8:e9f836163229 | 211 | tempCombinedCondition.op = xAND; |
mehatfie | 8:e9f836163229 | 212 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 8:e9f836163229 | 213 | prevCondition = xAND; |
mehatfie | 8:e9f836163229 | 214 | } |
mehatfie | 8:e9f836163229 | 215 | else{ |
mehatfie | 8:e9f836163229 | 216 | if (combinedCondition.back().op == xAND){ // AND the value to the back most combinedCondition |
mehatfie | 8:e9f836163229 | 217 | combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value; |
mehatfie | 8:e9f836163229 | 218 | prevCondition = xAND; |
mehatfie | 8:e9f836163229 | 219 | } |
mehatfie | 8:e9f836163229 | 220 | else if (combinedCondition.back().op != xAND){ // Start a new combinedCondition |
mehatfie | 8:e9f836163229 | 221 | tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; |
mehatfie | 8:e9f836163229 | 222 | tempCombinedCondition.op = xAND; |
mehatfie | 8:e9f836163229 | 223 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 8:e9f836163229 | 224 | prevCondition = xAND; |
mehatfie | 8:e9f836163229 | 225 | } |
mehatfie | 8:e9f836163229 | 226 | } |
mehatfie | 8:e9f836163229 | 227 | |
mehatfie | 5:e36e0538a903 | 228 | } |
mehatfie | 5:e36e0538a903 | 229 | |
mehatfie | 5:e36e0538a903 | 230 | //xOR |
mehatfie | 8:e9f836163229 | 231 | else if (paramCondition[k].op == xOR){ |
mehatfie | 8:e9f836163229 | 232 | if (combinedCondition.size() == 0){ // No values so start a new combinedCondition |
mehatfie | 8:e9f836163229 | 233 | tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; |
mehatfie | 8:e9f836163229 | 234 | tempCombinedCondition.op = xOR; |
mehatfie | 8:e9f836163229 | 235 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 8:e9f836163229 | 236 | prevCondition = xOR; |
mehatfie | 8:e9f836163229 | 237 | } |
mehatfie | 8:e9f836163229 | 238 | else{ |
mehatfie | 8:e9f836163229 | 239 | if (combinedCondition.back().op == xOR){ // OR the value to the back most combinedCondition |
mehatfie | 8:e9f836163229 | 240 | combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value; |
mehatfie | 8:e9f836163229 | 241 | prevCondition = xOR; |
mehatfie | 8:e9f836163229 | 242 | } |
mehatfie | 8:e9f836163229 | 243 | else if (combinedCondition.back().op != xOR){ // Start a new combinedCondition |
mehatfie | 8:e9f836163229 | 244 | tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; |
mehatfie | 8:e9f836163229 | 245 | tempCombinedCondition.op = xOR; |
mehatfie | 8:e9f836163229 | 246 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 8:e9f836163229 | 247 | prevCondition = xOR; |
mehatfie | 8:e9f836163229 | 248 | } |
mehatfie | 8:e9f836163229 | 249 | } |
mehatfie | 8:e9f836163229 | 250 | |
mehatfie | 5:e36e0538a903 | 251 | } |
mehatfie | 5:e36e0538a903 | 252 | |
mehatfie | 5:e36e0538a903 | 253 | // 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 |
mehatfie | 5:e36e0538a903 | 254 | // operator of this exclusive xAND / xOR set |
mehatfie | 5:e36e0538a903 | 255 | if ((paramCondition[k + 1].op == AND || paramCondition[k + 1].op == OR) && (prevCondition == xAND || prevCondition == xOR)){ |
mehatfie | 5:e36e0538a903 | 256 | combinedCondition.back().op = paramCondition[k + 1].op; |
mehatfie | 5:e36e0538a903 | 257 | k++; |
mehatfie | 5:e36e0538a903 | 258 | } |
mehatfie | 5:e36e0538a903 | 259 | |
mehatfie | 5:e36e0538a903 | 260 | } |
mehatfie | 5:e36e0538a903 | 261 | } |
mehatfie | 6:d1594fd2ec5a | 262 | |
mehatfie | 6:d1594fd2ec5a | 263 | |
mehatfie | 8:e9f836163229 | 264 | // the last value was not included in any combination, since directly before the last value was an xAND / xOR set that |
mehatfie | 8:e9f836163229 | 265 | // 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 |
mehatfie | 8:e9f836163229 | 266 | // to be AND /OR to the exclusive xAND / xOR set |
mehatfie | 8:e9f836163229 | 267 | else if (last && (prevCondition == xAND || prevCondition == xOR) && (combinedCondition.back().op == AND || combinedCondition.back().op == OR)){ |
mehatfie | 5:e36e0538a903 | 268 | tempCombinedCondition.value = paramCondition[k].value; |
mehatfie | 5:e36e0538a903 | 269 | tempCombinedCondition.op = NONE; |
mehatfie | 5:e36e0538a903 | 270 | combinedCondition.push_back(tempCombinedCondition); |
mehatfie | 5:e36e0538a903 | 271 | } |
mehatfie | 5:e36e0538a903 | 272 | |
mehatfie | 5:e36e0538a903 | 273 | //reset the tempCombinedCondition variable |
mehatfie | 5:e36e0538a903 | 274 | tempCombinedCondition = ConditionOp(); |
mehatfie | 5:e36e0538a903 | 275 | } |
mehatfie | 5:e36e0538a903 | 276 | |
mehatfie | 6:d1594fd2ec5a | 277 | |
mehatfie | 5:e36e0538a903 | 278 | // run through all values in the combined Condition vector, AND'ing / OR'ing as appropriate |
mehatfie | 5:e36e0538a903 | 279 | // in the end, the last value in the array should be the final condition of the Condition statement... whether it was successful or failed |
mehatfie | 5:e36e0538a903 | 280 | for (i = 0; i < (combinedCondition.size() - 1); i++){ |
mehatfie | 5:e36e0538a903 | 281 | if (combinedCondition[i].op == AND) |
mehatfie | 5:e36e0538a903 | 282 | combinedCondition[i + 1].value = combinedCondition[i].value && combinedCondition[i + 1].value; |
mehatfie | 5:e36e0538a903 | 283 | else if (combinedCondition[i].op == OR) |
mehatfie | 5:e36e0538a903 | 284 | combinedCondition[i + 1].value = combinedCondition[i].value || combinedCondition[i + 1].value; |
mehatfie | 5:e36e0538a903 | 285 | } |
mehatfie | 10:e8db892fbc52 | 286 | |
mehatfie | 10:e8db892fbc52 | 287 | |
mehatfie | 10:e8db892fbc52 | 288 | //All syntax checking done by this point, if Dummy then return success in order to check the code within the Condition |
mehatfie | 10:e8db892fbc52 | 289 | if (DummyMode) |
mehatfie | 10:e8db892fbc52 | 290 | return 0; //Function operated successfully but doesn't return a value |
mehatfie | 10:e8db892fbc52 | 291 | |
mehatfie | 10:e8db892fbc52 | 292 | |
mehatfie | 5:e36e0538a903 | 293 | int conditionSuccess = combinedCondition.back().value; //value is the success(1) or failure(0) of the condition statement |
mehatfie | 5:e36e0538a903 | 294 | |
mehatfie | 9:5a0c4c6e39c7 | 295 | int checkEnd = 0, returnValue; |
mehatfie | 5:e36e0538a903 | 296 | if (!conditionSuccess){ |
mehatfie | 6:d1594fd2ec5a | 297 | |
mehatfie | 5:e36e0538a903 | 298 | while (checkEnd != 4){ |
mehatfie | 5:e36e0538a903 | 299 | |
mehatfie | 9:5a0c4c6e39c7 | 300 | returnValue = getNextLine(selectedFile, lineData); |
mehatfie | 9:5a0c4c6e39c7 | 301 | |
mehatfie | 9:5a0c4c6e39c7 | 302 | //if getNextLine returned an error, then error out |
mehatfie | 9:5a0c4c6e39c7 | 303 | if (returnValue == -1) |
mehatfie | 9:5a0c4c6e39c7 | 304 | return -1; |
mehatfie | 6:d1594fd2ec5a | 305 | |
mehatfie | 6:d1594fd2ec5a | 306 | // check if the first word is an end command (avoids interpreting functions that perform actions) |
mehatfie | 5:e36e0538a903 | 307 | if (lineData.word[0].compare("end") == 0) |
mehatfie | 5:e36e0538a903 | 308 | checkEnd = interpretCommand(selectedFile, lineData); |
mehatfie | 5:e36e0538a903 | 309 | |
mehatfie | 5:e36e0538a903 | 310 | if (checkEnd == 4) // custom return value for this function |
mehatfie | 9:5a0c4c6e39c7 | 311 | return 0; //Function operated successfully but doesn't return a value |
mehatfie | 9:5a0c4c6e39c7 | 312 | else if (checkEnd == -1) //if interpretCommand returned an error, then error out |
mehatfie | 9:5a0c4c6e39c7 | 313 | return -1; |
mehatfie | 5:e36e0538a903 | 314 | } |
mehatfie | 5:e36e0538a903 | 315 | } |
mehatfie | 5:e36e0538a903 | 316 | |
mehatfie | 5:e36e0538a903 | 317 | // Return success as the function either met the condition and will continue from the next line, or |
mehatfie | 5:e36e0538a903 | 318 | // failed to meet the condition and ran through the lines inside the condition until "end condition" was found, therefore |
mehatfie | 5:e36e0538a903 | 319 | // the program will proceed from the line after the "end condition" line |
mehatfie | 9:5a0c4c6e39c7 | 320 | return 0; //Function operated successfully but doesn't return a value |
mehatfie | 5:e36e0538a903 | 321 | } |
mehatfie | 6:d1594fd2ec5a | 322 | |
mehatfie | 0:22618cf06f45 | 323 | |
mehatfie | 1:5731f31f96be | 324 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 325 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 326 | /************************** <FUNCTION: loopCommand> *****************************/ |
mehatfie | 1:5731f31f96be | 327 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 328 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 329 | |
mehatfie | 5:e36e0538a903 | 330 | int loopCommand(FILE *selectedFile, LineData &lineData){ |
mehatfie | 1:5731f31f96be | 331 | |
mehatfie | 2:3e7baa3e3fec | 332 | //Get the Condition value for number of times to loop |
mehatfie | 2:3e7baa3e3fec | 333 | string loopCondition = lineData.word[1]; |
mehatfie | 2:3e7baa3e3fec | 334 | int loopConditionValue = 0; |
mehatfie | 9:5a0c4c6e39c7 | 335 | |
mehatfie | 9:5a0c4c6e39c7 | 336 | int numValuesFound = sscanf(loopCondition.c_str(), "%d", &loopConditionValue); |
mehatfie | 9:5a0c4c6e39c7 | 337 | if (numValuesFound < 1){ |
mehatfie | 9:5a0c4c6e39c7 | 338 | ErrorOut("Parameter Unknown, loopCondition Value can't be converted", lineData.lineNumber); |
mehatfie | 9:5a0c4c6e39c7 | 339 | return -1; |
mehatfie | 9:5a0c4c6e39c7 | 340 | } |
mehatfie | 1:5731f31f96be | 341 | |
mehatfie | 2:3e7baa3e3fec | 342 | int loopStartAddress = 0, loopLineNumber = 0, firstLineOfLoop = 1; |
mehatfie | 6:d1594fd2ec5a | 343 | |
mehatfie | 6:d1594fd2ec5a | 344 | lcd.setAddress(0,0); |
mehatfie | 6:d1594fd2ec5a | 345 | lcd.printf("Cycle 1 of %d", loopConditionValue); |
mehatfie | 1:5731f31f96be | 346 | |
mehatfie | 9:5a0c4c6e39c7 | 347 | float totalLoopTime = 0; |
mehatfie | 6:d1594fd2ec5a | 348 | Timer cycleTimer; |
mehatfie | 6:d1594fd2ec5a | 349 | cycleTimer.reset(); |
mehatfie | 6:d1594fd2ec5a | 350 | cycleTimer.start(); |
mehatfie | 6:d1594fd2ec5a | 351 | |
mehatfie | 9:5a0c4c6e39c7 | 352 | int counter = 1, checkEnd = 0, returnValue; |
mehatfie | 6:d1594fd2ec5a | 353 | while (counter <= loopConditionValue){ |
mehatfie | 5:e36e0538a903 | 354 | |
mehatfie | 9:5a0c4c6e39c7 | 355 | returnValue = getNextLine(selectedFile, lineData); |
mehatfie | 5:e36e0538a903 | 356 | |
mehatfie | 9:5a0c4c6e39c7 | 357 | //if getNextLine returned an error, then return error out |
mehatfie | 9:5a0c4c6e39c7 | 358 | if (returnValue == -1) |
mehatfie | 9:5a0c4c6e39c7 | 359 | return -1; |
mehatfie | 9:5a0c4c6e39c7 | 360 | |
mehatfie | 5:e36e0538a903 | 361 | //Must get the address before entering the interpret command |
mehatfie | 5:e36e0538a903 | 362 | // if a Condition command is immediately after, and the condition fails, then |
mehatfie | 5:e36e0538a903 | 363 | // the interpret command will return the line at the "end condition" line, and therefore |
mehatfie | 5:e36e0538a903 | 364 | // set the loop's first line to be the "end condition" line, if interpretCommand is called BEFORE setting the first loop line address |
mehatfie | 1:5731f31f96be | 365 | if (firstLineOfLoop){ |
mehatfie | 1:5731f31f96be | 366 | loopStartAddress = lineData.lineAddress; //Save the Line Address |
mehatfie | 1:5731f31f96be | 367 | loopLineNumber = lineData.lineNumber; //Save the Line Number |
mehatfie | 1:5731f31f96be | 368 | firstLineOfLoop = 0; |
mehatfie | 1:5731f31f96be | 369 | } |
mehatfie | 5:e36e0538a903 | 370 | |
mehatfie | 5:e36e0538a903 | 371 | checkEnd = interpretCommand(selectedFile, lineData); |
mehatfie | 6:d1594fd2ec5a | 372 | |
mehatfie | 1:5731f31f96be | 373 | //Increase the loop counter and go back to the beginning of the loop |
mehatfie | 5:e36e0538a903 | 374 | if (checkEnd == 3){ |
mehatfie | 6:d1594fd2ec5a | 375 | |
mehatfie | 10:e8db892fbc52 | 376 | //All syntax checking done by this point, if Dummy then return success in order to check the code, no need to loop again |
mehatfie | 10:e8db892fbc52 | 377 | if (DummyMode) |
mehatfie | 10:e8db892fbc52 | 378 | return 0; //Function operated successfully but doesn't return a value |
mehatfie | 10:e8db892fbc52 | 379 | |
mehatfie | 6:d1594fd2ec5a | 380 | //Output the Avg Cycle Time |
mehatfie | 6:d1594fd2ec5a | 381 | cycleTimer.stop(); |
mehatfie | 6:d1594fd2ec5a | 382 | totalLoopTime += cycleTimer.read(); |
mehatfie | 2:3e7baa3e3fec | 383 | |
mehatfie | 6:d1594fd2ec5a | 384 | lcd.setAddress(0,1); |
mehatfie | 6:d1594fd2ec5a | 385 | lcd.printf("Avg t(sec): %1.3f", (totalLoopTime / counter)); |
mehatfie | 6:d1594fd2ec5a | 386 | |
mehatfie | 6:d1594fd2ec5a | 387 | //Output Cycle Number |
mehatfie | 6:d1594fd2ec5a | 388 | counter++; |
mehatfie | 6:d1594fd2ec5a | 389 | lcd.setAddress(0,0); |
mehatfie | 6:d1594fd2ec5a | 390 | lcd.printf("Cycle %d of %d", counter, loopConditionValue); |
mehatfie | 2:3e7baa3e3fec | 391 | |
mehatfie | 9:5a0c4c6e39c7 | 392 | int seekFailure = fseek(selectedFile, loopStartAddress, SEEK_SET); //fseek returns 0 on success |
mehatfie | 9:5a0c4c6e39c7 | 393 | if (seekFailure){ |
mehatfie | 9:5a0c4c6e39c7 | 394 | ErrorOut("In Loop Failed to seek line", lineData.lineNumber); //Spaces make it look nice on the LCD |
mehatfie | 9:5a0c4c6e39c7 | 395 | return -1; |
mehatfie | 9:5a0c4c6e39c7 | 396 | } |
mehatfie | 9:5a0c4c6e39c7 | 397 | |
mehatfie | 9:5a0c4c6e39c7 | 398 | lineData.lineNumber = loopLineNumber - 1; |
mehatfie | 5:e36e0538a903 | 399 | checkEnd = 0; |
mehatfie | 6:d1594fd2ec5a | 400 | |
mehatfie | 6:d1594fd2ec5a | 401 | //Restart the timer for the next loop |
mehatfie | 6:d1594fd2ec5a | 402 | cycleTimer.reset(); |
mehatfie | 6:d1594fd2ec5a | 403 | cycleTimer.start(); |
mehatfie | 1:5731f31f96be | 404 | } |
mehatfie | 9:5a0c4c6e39c7 | 405 | else if (checkEnd == -1) //if interpretCommand returned an error, then return error out |
mehatfie | 9:5a0c4c6e39c7 | 406 | return -1; |
mehatfie | 1:5731f31f96be | 407 | } |
mehatfie | 2:3e7baa3e3fec | 408 | |
mehatfie | 9:5a0c4c6e39c7 | 409 | return 0; //Return Success, no value is being sent so don't return 1 |
mehatfie | 1:5731f31f96be | 410 | } |
mehatfie | 1:5731f31f96be | 411 | |
mehatfie | 1:5731f31f96be | 412 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 413 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 414 | /************************* <FUNCTION: interpretCommand> *************************/ |
mehatfie | 1:5731f31f96be | 415 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 416 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 417 | |
mehatfie | 5:e36e0538a903 | 418 | int interpretCommand(FILE *selectedFile, LineData &lineData){ |
mehatfie | 2:3e7baa3e3fec | 419 | |
mehatfie | 2:3e7baa3e3fec | 420 | if (lineData.word[0].compare("device") == 0){ |
mehatfie | 2:3e7baa3e3fec | 421 | |
mehatfie | 1:5731f31f96be | 422 | int i = 0, deviceFound = -1; |
mehatfie | 2:3e7baa3e3fec | 423 | for (i = 0; i < numDevices; i++){ |
mehatfie | 4:86d0d04cc055 | 424 | if (lineData.word[2].compare(DeviceNames[i]) == 0){ |
mehatfie | 1:5731f31f96be | 425 | deviceFound = i; |
mehatfie | 4:86d0d04cc055 | 426 | } |
mehatfie | 2:3e7baa3e3fec | 427 | } |
mehatfie | 9:5a0c4c6e39c7 | 428 | |
mehatfie | 1:5731f31f96be | 429 | //if the device type does not match any known type, error out |
mehatfie | 1:5731f31f96be | 430 | if (deviceFound == -1){ |
mehatfie | 9:5a0c4c6e39c7 | 431 | ErrorOut("No device match found in the system", lineData.lineNumber); //Spaces make it look nice on LCD |
mehatfie | 9:5a0c4c6e39c7 | 432 | return -1; |
mehatfie | 1:5731f31f96be | 433 | } |
mehatfie | 1:5731f31f96be | 434 | |
mehatfie | 1:5731f31f96be | 435 | //Add device to the array of devices and initialize it |
mehatfie | 2:3e7baa3e3fec | 436 | else{ |
mehatfie | 2:3e7baa3e3fec | 437 | devices.push_back(Device::newDevice(deviceFound, lineData.word[1], lineData)); |
mehatfie | 9:5a0c4c6e39c7 | 438 | devices.back()->name = lineData.word[1]; |
mehatfie | 9:5a0c4c6e39c7 | 439 | |
mehatfie | 9:5a0c4c6e39c7 | 440 | //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 |
mehatfie | 9:5a0c4c6e39c7 | 441 | if (devices.back()->errorFlag == 1){ |
mehatfie | 9:5a0c4c6e39c7 | 442 | ErrorOut("Error initializing device", lineData.lineNumber); |
mehatfie | 9:5a0c4c6e39c7 | 443 | return -1; |
mehatfie | 9:5a0c4c6e39c7 | 444 | } |
mehatfie | 2:3e7baa3e3fec | 445 | } |
mehatfie | 1:5731f31f96be | 446 | } |
mehatfie | 1:5731f31f96be | 447 | |
mehatfie | 2:3e7baa3e3fec | 448 | else if (lineData.word[0].compare("delay") == 0){ |
mehatfie | 10:e8db892fbc52 | 449 | |
mehatfie | 10:e8db892fbc52 | 450 | //All syntax checking done by this point, if Dummy then return success in order to check the code, no need wait for a delay |
mehatfie | 10:e8db892fbc52 | 451 | if (DummyMode) |
mehatfie | 10:e8db892fbc52 | 452 | return 0; //Function operated successfully but doesn't return a value |
mehatfie | 10:e8db892fbc52 | 453 | |
mehatfie | 2:3e7baa3e3fec | 454 | string duration = lineData.word[1]; |
mehatfie | 2:3e7baa3e3fec | 455 | int durationValue = 0; |
mehatfie | 9:5a0c4c6e39c7 | 456 | int numValuesFound = sscanf(duration.c_str(), "%d", &durationValue); |
mehatfie | 1:5731f31f96be | 457 | |
mehatfie | 9:5a0c4c6e39c7 | 458 | if (numValuesFound < 1){ |
mehatfie | 9:5a0c4c6e39c7 | 459 | ErrorOut("Parameter Unknown, Duration Value can't be converted", lineData.lineNumber); |
mehatfie | 9:5a0c4c6e39c7 | 460 | return -1; |
mehatfie | 9:5a0c4c6e39c7 | 461 | } |
mehatfie | 9:5a0c4c6e39c7 | 462 | |
mehatfie | 9:5a0c4c6e39c7 | 463 | if (durationValue > 0){ |
mehatfie | 1:5731f31f96be | 464 | timer.reset(); |
mehatfie | 1:5731f31f96be | 465 | timer.start(); |
mehatfie | 1:5731f31f96be | 466 | while (timer.read_ms() < durationValue); //Do Nothing while the timer has not reached the duration |
mehatfie | 1:5731f31f96be | 467 | timer.stop(); //Stop the Timer |
mehatfie | 1:5731f31f96be | 468 | } |
mehatfie | 1:5731f31f96be | 469 | else{ |
mehatfie | 9:5a0c4c6e39c7 | 470 | ErrorOut("Duration value is less than 0", lineData.lineNumber); |
mehatfie | 1:5731f31f96be | 471 | return -1; |
mehatfie | 1:5731f31f96be | 472 | } |
mehatfie | 1:5731f31f96be | 473 | } |
mehatfie | 1:5731f31f96be | 474 | |
mehatfie | 9:5a0c4c6e39c7 | 475 | else if (lineData.word[0].compare("loop") == 0) |
mehatfie | 9:5a0c4c6e39c7 | 476 | return loopCommand(selectedFile, lineData); //Process the loop command and return the value that it returns |
mehatfie | 5:e36e0538a903 | 477 | |
mehatfie | 9:5a0c4c6e39c7 | 478 | else if (lineData.word[0].compare("condition") == 0) |
mehatfie | 9:5a0c4c6e39c7 | 479 | return conditionCommand(selectedFile, lineData); //Process the condition command and return the value that it returns |
mehatfie | 9:5a0c4c6e39c7 | 480 | |
mehatfie | 9:5a0c4c6e39c7 | 481 | //end has custom return value for specific functions, since "end" is a common keyword amongst functions |
mehatfie | 9:5a0c4c6e39c7 | 482 | else if (lineData.word[0].compare("end") == 0){ |
mehatfie | 9:5a0c4c6e39c7 | 483 | if (lineData.word[1].compare("program") == 0) |
mehatfie | 5:e36e0538a903 | 484 | return 2; |
mehatfie | 9:5a0c4c6e39c7 | 485 | else if (lineData.word[1].compare("loop") == 0) |
mehatfie | 5:e36e0538a903 | 486 | return 3; |
mehatfie | 9:5a0c4c6e39c7 | 487 | else if (lineData.word[1].compare("condition") == 0) |
mehatfie | 5:e36e0538a903 | 488 | return 4; |
mehatfie | 9:5a0c4c6e39c7 | 489 | |
mehatfie | 9:5a0c4c6e39c7 | 490 | else{ |
mehatfie | 9:5a0c4c6e39c7 | 491 | ErrorOut("Unknown function ending", lineData.lineNumber); |
mehatfie | 9:5a0c4c6e39c7 | 492 | return -1; |
mehatfie | 2:3e7baa3e3fec | 493 | } |
mehatfie | 1:5731f31f96be | 494 | } |
mehatfie | 1:5731f31f96be | 495 | |
mehatfie | 1:5731f31f96be | 496 | //not a keyword so check if it's a localName for a device |
mehatfie | 1:5731f31f96be | 497 | else{ |
mehatfie | 1:5731f31f96be | 498 | |
mehatfie | 1:5731f31f96be | 499 | int i = 0, deviceFound = -1; |
mehatfie | 2:3e7baa3e3fec | 500 | for (i = 0; i < devices.size(); i++){ |
mehatfie | 2:3e7baa3e3fec | 501 | if (lineData.word[0].compare(devices[i]->name) == 0) |
mehatfie | 1:5731f31f96be | 502 | deviceFound = i; |
mehatfie | 1:5731f31f96be | 503 | } |
mehatfie | 1:5731f31f96be | 504 | |
mehatfie | 1:5731f31f96be | 505 | //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 |
mehatfie | 1:5731f31f96be | 506 | if (deviceFound == -1){ |
mehatfie | 9:5a0c4c6e39c7 | 507 | ErrorOut("No device match found in the system", lineData.lineNumber); //Spaces make it look nice on LCD |
mehatfie | 9:5a0c4c6e39c7 | 508 | return -1; |
mehatfie | 1:5731f31f96be | 509 | } |
mehatfie | 1:5731f31f96be | 510 | |
mehatfie | 1:5731f31f96be | 511 | //Local Name matches a device, send line to that device in order to process the functionality |
mehatfie | 9:5a0c4c6e39c7 | 512 | else |
mehatfie | 9:5a0c4c6e39c7 | 513 | return devices[deviceFound]->interpret(lineData); //call the device specific interpret command, and return the value it returns |
mehatfie | 1:5731f31f96be | 514 | } |
mehatfie | 1:5731f31f96be | 515 | |
mehatfie | 9:5a0c4c6e39c7 | 516 | return 0; //Return Success, no value is being sent so don't return 1 |
mehatfie | 1:5731f31f96be | 517 | } |
mehatfie | 1:5731f31f96be | 518 | |
mehatfie | 1:5731f31f96be | 519 | |
mehatfie | 1:5731f31f96be | 520 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 521 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 522 | /****************************** <FUNCTION: main> ********************************/ |
mehatfie | 1:5731f31f96be | 523 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 524 | /**********************************************************************************************************************************/ |
mehatfie | 1:5731f31f96be | 525 | |
mehatfie | 0:22618cf06f45 | 526 | int main() { |
mehatfie | 0:22618cf06f45 | 527 | |
mehatfie | 0:22618cf06f45 | 528 | fullInit(); //Initialize anything that's required to run the code (LCD) |
mehatfie | 0:22618cf06f45 | 529 | |
mehatfie | 6:d1594fd2ec5a | 530 | LineData lineData; |
mehatfie | 2:3e7baa3e3fec | 531 | resetLineData(lineData); |
mehatfie | 2:3e7baa3e3fec | 532 | |
mehatfie | 9:5a0c4c6e39c7 | 533 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 534 | /*** <Get all the Potential Programs> ***/ |
mehatfie | 9:5a0c4c6e39c7 | 535 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 536 | int numTextFiles = 0; |
mehatfie | 9:5a0c4c6e39c7 | 537 | vector<string> textFiles; //Assuming Maximum of 25 txt files will be on the SD Card |
mehatfie | 9:5a0c4c6e39c7 | 538 | vector<string> filenames = readFileNames("/sd"); |
mehatfie | 9:5a0c4c6e39c7 | 539 | |
mehatfie | 9:5a0c4c6e39c7 | 540 | //Error check whether the SD Card exists and was able to be accessed.... or if there's no files on the SD Card |
mehatfie | 9:5a0c4c6e39c7 | 541 | if (filenames.size() == 0){ |
mehatfie | 9:5a0c4c6e39c7 | 542 | ErrorOut("No Files Found, or Directory can't be accessed", 0); //Spaces make it look nice on LCD |
mehatfie | 9:5a0c4c6e39c7 | 543 | return -1; //End program by returning in the main() |
mehatfie | 9:5a0c4c6e39c7 | 544 | } |
mehatfie | 9:5a0c4c6e39c7 | 545 | |
mehatfie | 9:5a0c4c6e39c7 | 546 | numTextFiles = getFileNamesWithoutExt(textFiles, filenames); |
mehatfie | 0:22618cf06f45 | 547 | |
mehatfie | 9:5a0c4c6e39c7 | 548 | //Error check whether the SD Card has any txt files in it's first directory |
mehatfie | 9:5a0c4c6e39c7 | 549 | if (numTextFiles == 0){ |
mehatfie | 9:5a0c4c6e39c7 | 550 | ErrorOut("No Program (.txt) Files Found in first Directory", 0); //Spaces make it look nice on LCD |
mehatfie | 9:5a0c4c6e39c7 | 551 | return -1; //End program by returning in the main() |
mehatfie | 9:5a0c4c6e39c7 | 552 | } |
mehatfie | 0:22618cf06f45 | 553 | |
mehatfie | 9:5a0c4c6e39c7 | 554 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 555 | /*** <Select the Program txt File> ***/ |
mehatfie | 9:5a0c4c6e39c7 | 556 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 557 | int fileSelected = 0, selectedFileIndex = 0; |
mehatfie | 9:5a0c4c6e39c7 | 558 | |
mehatfie | 9:5a0c4c6e39c7 | 559 | lcd.cls(); //clear the display |
mehatfie | 9:5a0c4c6e39c7 | 560 | lcd.setAddress(0,1); |
mehatfie | 9:5a0c4c6e39c7 | 561 | lcd.printf("Select Your Program"); |
mehatfie | 9:5a0c4c6e39c7 | 562 | lcd.setAddress(0,2); |
mehatfie | 9:5a0c4c6e39c7 | 563 | lcd.printf("Num Programs = %d", numTextFiles); |
mehatfie | 2:3e7baa3e3fec | 564 | |
mehatfie | 9:5a0c4c6e39c7 | 565 | uint8_t lastButState = 0; |
mehatfie | 9:5a0c4c6e39c7 | 566 | lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on |
mehatfie | 9:5a0c4c6e39c7 | 567 | |
mehatfie | 9:5a0c4c6e39c7 | 568 | selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, -1); //Initialize the first file to the screen |
mehatfie | 9:5a0c4c6e39c7 | 569 | while(!fileSelected) { |
mehatfie | 0:22618cf06f45 | 570 | |
mehatfie | 9:5a0c4c6e39c7 | 571 | uint8_t curButState = buttons.readBus(); |
mehatfie | 9:5a0c4c6e39c7 | 572 | if(curButState != lastButState){ |
mehatfie | 9:5a0c4c6e39c7 | 573 | lastButState = curButState; |
mehatfie | 9:5a0c4c6e39c7 | 574 | if(buttons.readRight()) |
mehatfie | 9:5a0c4c6e39c7 | 575 | selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 1); |
mehatfie | 9:5a0c4c6e39c7 | 576 | else if(buttons.readLeft()) |
mehatfie | 9:5a0c4c6e39c7 | 577 | selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 0); |
mehatfie | 9:5a0c4c6e39c7 | 578 | else if(buttons.readSel()) |
mehatfie | 9:5a0c4c6e39c7 | 579 | fileSelected = 1; |
mehatfie | 0:22618cf06f45 | 580 | } |
mehatfie | 9:5a0c4c6e39c7 | 581 | } |
mehatfie | 9:5a0c4c6e39c7 | 582 | |
mehatfie | 9:5a0c4c6e39c7 | 583 | lcd.setCursor(TextLCD::CurOn_BlkOff); //turn blinking cursor off |
mehatfie | 9:5a0c4c6e39c7 | 584 | |
mehatfie | 9:5a0c4c6e39c7 | 585 | char selectedFileName[50]; |
mehatfie | 9:5a0c4c6e39c7 | 586 | strcpy(selectedFileName, textFiles[selectedFileIndex].c_str()); |
mehatfie | 9:5a0c4c6e39c7 | 587 | |
mehatfie | 9:5a0c4c6e39c7 | 588 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 589 | /*** <Open the Program txt File> ***/ |
mehatfie | 9:5a0c4c6e39c7 | 590 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 591 | |
mehatfie | 9:5a0c4c6e39c7 | 592 | //Create the string of the full directory and path to the program txt file |
mehatfie | 9:5a0c4c6e39c7 | 593 | char selectedFileFullName[100] = "/sd/"; //Assuming that no directory and file name will be longer than 100 characters |
mehatfie | 9:5a0c4c6e39c7 | 594 | strcat(selectedFileFullName, selectedFileName); |
mehatfie | 9:5a0c4c6e39c7 | 595 | strcat(selectedFileFullName, ".txt"); |
mehatfie | 9:5a0c4c6e39c7 | 596 | |
mehatfie | 9:5a0c4c6e39c7 | 597 | FILE *selectedFile = fopen(selectedFileFullName, "r"); |
mehatfie | 9:5a0c4c6e39c7 | 598 | |
mehatfie | 9:5a0c4c6e39c7 | 599 | //Error out of attempt to open the selected file was unsuccessful |
mehatfie | 9:5a0c4c6e39c7 | 600 | if(selectedFile == NULL) { |
mehatfie | 9:5a0c4c6e39c7 | 601 | ErrorOut("Unable to Open Selected File", 0); //Spaces make it look nice on LCD |
mehatfie | 9:5a0c4c6e39c7 | 602 | return -1; //End program by returning in the main() |
mehatfie | 9:5a0c4c6e39c7 | 603 | } |
mehatfie | 0:22618cf06f45 | 604 | |
mehatfie | 0:22618cf06f45 | 605 | |
mehatfie | 9:5a0c4c6e39c7 | 606 | /******************************************************************************/ |
mehatfie | 9:5a0c4c6e39c7 | 607 | /*** <Start Running through the Program txt File Lines> ***/ |
mehatfie | 9:5a0c4c6e39c7 | 608 | /******************************************************************************/ |
mehatfie | 10:e8db892fbc52 | 609 | |
mehatfie | 10:e8db892fbc52 | 610 | resetLineData(lineData); //Reset the values in the struct that holds the File / Line Data |
mehatfie | 10:e8db892fbc52 | 611 | lcd.cls(); //clear the display |
mehatfie | 0:22618cf06f45 | 612 | |
mehatfie | 10:e8db892fbc52 | 613 | int endOfFile = 0, error = 0, returnValue, checkEnd; |
mehatfie | 10:e8db892fbc52 | 614 | DummyMode = 1; //set Dummy Mode equal to 1 to simulate the first run through of the code |
mehatfie | 10:e8db892fbc52 | 615 | while (!endOfFile){ |
mehatfie | 0:22618cf06f45 | 616 | |
mehatfie | 10:e8db892fbc52 | 617 | //Re-initialize variables |
mehatfie | 10:e8db892fbc52 | 618 | returnValue = 0; |
mehatfie | 10:e8db892fbc52 | 619 | checkEnd = 0; |
mehatfie | 10:e8db892fbc52 | 620 | |
mehatfie | 10:e8db892fbc52 | 621 | returnValue = getNextLine(selectedFile, lineData); //get the next line of data |
mehatfie | 10:e8db892fbc52 | 622 | |
mehatfie | 10:e8db892fbc52 | 623 | //if getNextLine returned an error, then return error in main |
mehatfie | 10:e8db892fbc52 | 624 | if (returnValue == -1) |
mehatfie | 10:e8db892fbc52 | 625 | error = 1; |
mehatfie | 9:5a0c4c6e39c7 | 626 | |
mehatfie | 10:e8db892fbc52 | 627 | checkEnd = interpretCommand(selectedFile, lineData); //interpret the line data |
mehatfie | 9:5a0c4c6e39c7 | 628 | |
mehatfie | 10:e8db892fbc52 | 629 | if (checkEnd == 2) |
mehatfie | 10:e8db892fbc52 | 630 | endOfFile = 1; |
mehatfie | 10:e8db892fbc52 | 631 | else if (checkEnd == -1) //if interpretCommand returned an error, then return error in main |
mehatfie | 10:e8db892fbc52 | 632 | error = 1; |
mehatfie | 10:e8db892fbc52 | 633 | |
mehatfie | 10:e8db892fbc52 | 634 | //Before erroring out, turn all devices off so that they power down |
mehatfie | 10:e8db892fbc52 | 635 | if (error){ |
mehatfie | 10:e8db892fbc52 | 636 | if (!DummyMode){ //if it is Dummy Mode, then no functionality has actually been turned on, so no need to shut anything off |
mehatfie | 9:5a0c4c6e39c7 | 637 | for(vector<Device*>::iterator it=devices.begin(); it < devices.end(); it++) |
mehatfie | 9:5a0c4c6e39c7 | 638 | (*it)->off(); |
mehatfie | 9:5a0c4c6e39c7 | 639 | } |
mehatfie | 10:e8db892fbc52 | 640 | |
mehatfie | 10:e8db892fbc52 | 641 | return -1; |
mehatfie | 10:e8db892fbc52 | 642 | } |
mehatfie | 10:e8db892fbc52 | 643 | |
mehatfie | 10:e8db892fbc52 | 644 | //Dummy Mode will be turned on for the first run through, set it to 0 after the first run through, |
mehatfie | 10:e8db892fbc52 | 645 | //as the syntax will be checked without erroring, and therefore it is possible to try and run the .txt file |
mehatfie | 10:e8db892fbc52 | 646 | //Seek back to beginning of file |
mehatfie | 10:e8db892fbc52 | 647 | if (DummyMode){ |
mehatfie | 10:e8db892fbc52 | 648 | DummyMode = 0; |
mehatfie | 10:e8db892fbc52 | 649 | rewind(selectedFile); //seek to the beginning of the file |
mehatfie | 10:e8db892fbc52 | 650 | resetLineData(lineData); //Reset the values in the struct that holds the File / Line Data |
mehatfie | 0:22618cf06f45 | 651 | } |
mehatfie | 0:22618cf06f45 | 652 | } |
mehatfie | 10:e8db892fbc52 | 653 | |
mehatfie | 10:e8db892fbc52 | 654 | lcd.cls(); //clear the display |
mehatfie | 10:e8db892fbc52 | 655 | lcd.setAddress(0,0); |
mehatfie | 10:e8db892fbc52 | 656 | lcd.printf("END OF PROGRAM"); |
mehatfie | 10:e8db892fbc52 | 657 | lcd.setAddress(0,2); |
mehatfie | 10:e8db892fbc52 | 658 | lcd.printf("To Restart..."); |
mehatfie | 10:e8db892fbc52 | 659 | lcd.setAddress(0,3); |
mehatfie | 10:e8db892fbc52 | 660 | lcd.printf("Press BACK"); |
mehatfie | 10:e8db892fbc52 | 661 | |
mehatfie | 10:e8db892fbc52 | 662 | while(!buttons.readBack()); |
mehatfie | 10:e8db892fbc52 | 663 | |
mehatfie | 10:e8db892fbc52 | 664 | lcd.setAddress(0,1); |
mehatfie | 10:e8db892fbc52 | 665 | //rewind(selectedFile); |
mehatfie | 0:22618cf06f45 | 666 | |
mehatfie | 2:3e7baa3e3fec | 667 | } |
mehatfie | 2:3e7baa3e3fec | 668 | |
mehatfie | 9:5a0c4c6e39c7 | 669 |