Component Test's Software to work with "Universal Controller Box" - Software is an interpreter or "compiler" for programs to be done with a .txt file and read off of the SD Card
Dependencies: BridgeDriver FrontPanelButtons MCP23017 SDFileSystem TextLCD mbed
main.cpp
- Committer:
- mehatfie
- Date:
- 2014-09-19
- Revision:
- 3:078e9a1e8be3
- Parent:
- 2:3e7baa3e3fec
- Child:
- 4:86d0d04cc055
File content as of revision 3:078e9a1e8be3:
#include "mbed.h"
#include "LocalPinNames.h"
#include "BridgeDriver.h"
#include "FrontPanelButtons.h"
#include "TextLCD.h"
#include "SDFileSystem.h"
#include "Initialization.hpp"
//#include "DeviceClasses.h"
//#include "Device.hpp"
#include "Motor.hpp"
#include "VoltageDriver.hpp"
#include "TextFile.h"
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <vector>
using std::string;
//const int MAX_LINE_LENGTH = 100;
//struct Line lineData;
//DeviceData devices[15];
FrontPanelButtons buttons(&i2c);
//extern "C" void mbed_reset(); //enable software reset of code
/*
http://stackoverflow.com/questions/3081289/how-to-read-a-line-from-a-text-file-in-c-c
http://stackoverflow.com/questions/12475915/rewind-stream-pointer-to-the-line-back
recurrsive
*/
int interpretCommand(FILE *, Line &);
int loopCommand(FILE *, Line &);
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/*************************** <FUNCTION: resetLineData> **************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
void resetLineData(Line &lineData){
//lineData.fullLine.clear();
lineData.lineNumber = 0;
lineData.numWords = 0;
lineData.lineAddress = 0;
}
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************ <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: resize_StringArr> ************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
string* resize_StringArr(string oldArr[], int newSize) {
string newArr[newSize];
memcpy(newArr, oldArr, newSize * sizeof(string));
return newArr;
}
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************** <FUNCTION: loopCommand> *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
int loopCommand(FILE *selectedFile, Line &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;
int counter = 0, checkEnd = 0;
while (counter < loopConditionValue){
getNextLine(selectedFile, lineData);
checkEnd = interpretCommand(selectedFile, lineData);
if (firstLineOfLoop){
loopStartAddress = lineData.lineAddress; //Save the Line Address
loopLineNumber = lineData.lineNumber; //Save the Line Number
firstLineOfLoop = 0;
}
//Increase the loop counter and go back to the beginning of the loop
if (checkEnd == 1){
counter++;
lcd.setAddress(0,2);
lcd.printf("Loop Cycle %d of %d", counter, loopConditionValue);
fseek(selectedFile, loopStartAddress, SEEK_SET);
lineData.lineNumber = loopLineNumber - 2;
}
}
return 1;
}
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************* <FUNCTION: interpretCommand> *************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
int interpretCommand(FILE *selectedFile, Line &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]))
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("end") == 0){
if (lineData.word[1].compare("program") == 0){
return 0;
}
else if (lineData.word[1].compare("loop") == 0){
return 1;
}
}
//not a keyword so check if it's a localName for a device
else{
int i = 0, deviceFound = -1;
for (i = 0; i < 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);
devices[deviceFound]->interpret(lineData);
}
}
return -1;
}
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/****************************** <FUNCTION: main> ********************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
int main() {
fullInit(); //Initialize anything that's required to run the code (LCD)
struct Line 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);
/******************************************************************************/
/*** <Select the Program txt File> ***/
/******************************************************************************/
int fileSelected = 0, selectedFileIndex = 0;
lcd.cls(); //clear the display
lcd.setAddress(0,1);
lcd.printf("Select Your Program");
lcd.setAddress(0,2);
lcd.printf("Num Programs = %d", numTextFiles);
uint8_t lastButState;
lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, -1); //Initialize the first file to the screen
while(!fileSelected) {
uint8_t curButState = buttons.readBus();
if(curButState != lastButState){
lastButState = curButState;
if(buttons.readRight())
selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 1);
else if(buttons.readLeft())
selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 0);
else if(buttons.readSel())
fileSelected = 1;
}
}
char selectedFileName[50];
strcpy(selectedFileName, textFiles[selectedFileIndex].c_str());
/******************************************************************************/
/*** <Open the Program txt File> ***/
/******************************************************************************/
//Create the string of the full directory and path to the program txt file
char selectedFileFullName[100] = "/sd/"; //Assuming that no directory and file name will be longer than 100 characters
strcat(selectedFileFullName, selectedFileName);
strcat(selectedFileFullName, ".txt");
FILE *selectedFile = fopen(selectedFileFullName, "r");
lcd.cls(); //clear the display
if(selectedFile == NULL) {
lcd.setAddress(0,0);
lcd.printf("Invalid");
wait(10);
}
while(1){
resetLineData(lineData);
lcd.cls(); //clear the display
lcd.setAddress(0,0);
lcd.printf("Program: %s", selectedFileName);
/******************************************************************************/
/*** <Start Running through the Program txt File Lines> ***/
/******************************************************************************/
int endOfFile = 0;
while (!endOfFile){
getNextLine(selectedFile, lineData);
int checkEnd = interpretCommand(selectedFile, lineData);
if (checkEnd == 0)
endOfFile = 1;
}
lcd.cls(); //clear the display
lcd.setAddress(0,0);
lcd.printf("END OF PROGRAM");
lcd.setAddress(0,2);
lcd.printf("To Restart...");
lcd.setAddress(0,3);
lcd.printf("Press BACK");
while(!buttons.readBack());
lcd.setAddress(0,1);
//rewind(selectedFile);
}
}
/***** Cycle through txt lines and remember last lines ******/
/*
int running = 0, selectedFile = 0;
int locCount = 0, tempSpot = 0;
int loc[4];
char line[32];
uint8_t lastButState;
while(1){
lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
while(!running) {
uint8_t curButState = buttons.readBus();
if(curButState != lastButState){
switch(lastButState = curButState){
case 0x1F: //right
loc[locCount] = ftell(fp);
if (locCount >= 3)
locCount = 0;
else
locCount++;
//tempSpot = ftell(fp);
fgets(line, 32, fp);
lcd.setAddress(0,1);
lcd.printf("L: %s", line);
wait(0.2);
break;
case 0x2F: //left
if (locCount == 0) {
locCount = 3;
fseek(fp, loc[locCount], SEEK_SET);
}
else {
fseek(fp, loc[locCount - 1], SEEK_SET);
locCount--;
}
fgets(line, 32, fp);
lcd.setAddress(0,1);
lcd.printf("L: %s", line);
wait(0.2);
break;
}
}
}
}
*/
/******* Select the Program txt File ***********/
/*
int numTextFiles = 0;
string tempTextFiles[25]; //Assuming Maximum of 25 txt files will be on the SD Card
lcd.cls(); //clear the display
readFileNames("/sd");
numTextFiles = getFileNamesWithoutExt(tempTextFiles);
string *textFiles = resize_StringArr(tempTextFiles, numTextFiles); //Resize Array
//delete [] tempTextFiles; //free previous array
int running = 0, selectedFile = 0;
lcd.cls(); //clear the display
lcd.setAddress(0,1);
lcd.printf("Select Your Program");
lcd.setAddress(0,2);
lcd.printf("Num Programs = %d", numTextFiles);
uint8_t lastButState;
while(1){
lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
while(!running) {
uint8_t curButState = buttons.readBus();
if(curButState != lastButState){
switch(lastButState = curButState){
case 0x1F: //right
selectedFile = cyclePrograms(textFiles, numTextFiles, selectedFile, 1);
break;
case 0x2F: //left
selectedFile = cyclePrograms(textFiles, numTextFiles, selectedFile, 0);
break;
}
}
}
}
*/
/*float speed = 0.5;
while(1){
bridges.drive(1, -1*speed);
wait(2);
bridges.drive(1, speed);
wait(2);
}*/
//BridgeDriver::MOTOR_A