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 0:22618cf06f45, committed 2014-09-16
- Comitter:
- mehatfie
- Date:
- Tue Sep 16 15:28:59 2014 +0000
- Child:
- 1:5731f31f96be
- Commit message:
- - Initial Commit; - Code is a mess (in mid transition of general code architecture); - Functionality work to drive motors in both direction and turn off; - Delay functionality working; - Able to read a program from a txt file and perform functionality
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BridgeDriver.lib Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/jason701802/code/BridgeDriver/#397718f9300a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Device.cpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,15 @@ +/*#include "Device.hpp" +#include "Motor.hpp" +#include "VoltageDriver.hpp" + +Device* Device::newDevice(int deviceFound){ + + if(MOTOR) + return new Motor(); + else if(VOLTAGE_DRIVER) + return new VoltageDriver(); + +} + + */ + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Device.hpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,73 @@ +#ifndef DEVICE_HPP +#define DEVICE_HPP + +#include "Initialization.hpp" +#include "mbed.h" +#include "LocalPinNames.h" +#include "BridgeDriver.h" +#include "DeviceClasses.h" +//#include "Motor.hpp" +//#include "VoltageDriver.hpp" + +enum DeviceType{MOTOR, VOLTAGE_DRIVER}; +static const enum DeviceType Device_Map[] = {MOTOR, VOLTAGE_DRIVER}; +const char *DeviceNames[] = {"MOTOR", "VOLTAGE_DRIVER"}; +extern int numDevices = sizeof(DeviceNames)/sizeof(DeviceNames[0]); +extern int currNumDevices = 0; + +/* +class Device{ + + public: + char name[100]; + static Device* newDevice(int); + int interpret(); +}; + +extern Device devices[15]; //Initialize array of devices, initially assume 15 devices will be used (will expand as needed) + +void addDevice(int deviceFound){ + + //devices[currNumDevices] = Device::newDevice(deviceFound); + currNumDevices++; +} + */ + + + + +struct DeviceData { + DeviceType type; + char name[MAX_LINE_LENGTH]; + union { + Voltage_Driver VOLTAGE_DRIVER; + Motor MOTOR; + }; +}; + +extern struct DeviceData devices[15]; //Initialize array of devices, initially assume 15 devices will be used (will expand as needed) + +void relayLine(DeviceData device){ + switch(device.type){ + case MOTOR: device.MOTOR.interpret(); break; + case VOLTAGE_DRIVER: device.VOLTAGE_DRIVER.interpret(); break; + } +} + +void addDevice(int deviceFound){ + + //Save the device type + switch (Device_Map[deviceFound]){ + case MOTOR: devices[currNumDevices].type = MOTOR; break; + case VOLTAGE_DRIVER: devices[currNumDevices].type = VOLTAGE_DRIVER; break; + } + + strcpy(devices[currNumDevices].name, lineData.word[1]); //Save the Local Name of the Device, the second word in a device adding line is the Local_Name + relayLine(devices[currNumDevices]); //Give the command to the appropraite class in order to initialize itself based on the line + currNumDevices++; //Increment the total number of devices created +} + + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DeviceClasses.h Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,394 @@ +/*#include "mbed.h" +#include "LocalPinNames.h" +#include "TextLCD.h" +#include "BridgeDriver.h" +*/ +#include "Device.hpp" + + +/**********************************************************************************************************************************/ +/**********************************************************************************************************************************/ +/*************************** <CLASS: Voltage_Driver> ****************************/ +/**********************************************************************************************************************************/ +/**********************************************************************************************************************************/ + +class Voltage_Driver{ + + public : + //uint8_t ch123; //Channel value this device is set to + int ch; + int test; + + int interpret(); + int forceBrake(); + //int forceFloat(); + float drive(); + + //Voltage_Driver(); + void setChannel(int channel){ + Voltage_Driver::ch = channel; + } + + int getChannel(){ + return Voltage_Driver::ch; + } +}; + +//Voltage_Driver::Voltage_Driver(void){ +//} + +//A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on] +int Voltage_Driver::interpret(){ + /* + lcd.cls(); //clear the display + lcd.setAddress(0,3); + lcd.printf("Test2 "); + lcd.setAddress(0,1); + lcd.printf("wrd1: %s", lineData.word[0]); + lcd.setAddress(0,2); + lcd.printf("wrd2: %s", lineData.word[1]); + wait(3); +*/ + + + char *firstWord = lineData.word[0]; //get the first word in the line +/* + lcd.setAddress(0,2); + lcd.printf("fW: %s", firstWord); + lcd.setAddress(0,3); + lcd.printf("ch: %d", ch); + wait(3);*/ + + //Initialize the class and device + if (strncmp(firstWord,"device", 6) == 0){ + //Order of Line: Command, Local_Name, VOLTAGE_DRIVER, Channel(1,2,3,4,5,6,7,8) + + test = 10; + + if (lineData.numWords != 4){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + char *channel = lineData.word[3]; //Parameter is a number + int channelValue = atoi(channel); + + //Channel Value between 1 to 8 + if (channelValue >= 1 && channelValue <= 8){ + + setChannel(channelValue); + //ch = channelValue; + + lcd.setAddress(0,2); + lcd.printf("fW: %s", firstWord); + //lcd.setAddress(0,3); + //lcd.printf("ch: %d", getChannel()); + lcd.setAddress(0,3); + lcd.printf("test: %d", test); + //lcd.setAddress(0,3); + //lcd.printf("chString: %s", chString); + wait(2); + + switch (channelValue){ + case 1: + case 2: + bridges.enablePwm(BridgeDriver::MOTOR_A, 0); + break; + case 3: + case 4: + bridges.enablePwm(BridgeDriver::MOTOR_B, 0); + break; + case 5: + case 6: + bridges.enablePwm(BridgeDriver::MOTOR_C, 0); + break; + case 7: + case 8: + bridges.enablePwm(BridgeDriver::MOTOR_D, 0); + break; + } + /* lcd.setAddress(0,2); + lcd.printf("AchannelVal: %d", channelValue); + lcd.setAddress(0,3); + lcd.printf("Ach: %d", ch); + wait(3);*/ + + } + else{ + //ERROR Out + //Unacceptable channel, or conversion function failed when converting string to int + } + } + + //if the first word is not "device" it means that it's trying to perform a function to a specific Motor + else{ + + + + //Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,....... + char *localname = lineData.word[0]; //just for the sake of following the variable easily and understanding + char *func = lineData.word[1]; + + /******************************************************************************/ + /*** <Func: forceBrake> ***/ + /******************************************************************************/ + if (strncmp(func,"forceBrake", 10) == 0){ + + if (lineData.numWords != 3){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + bridges.forceBrake(ch); + } + + + /******************************************************************************/ + /*** <Func: drive> ***/ + /******************************************************************************/ + else if (strncmp(func,"drive", 5) == 0){ + //Order of Line: Local_Name, drive + + lcd.setAddress(0,0); + lcd.printf("lclN: %s ", localname); + lcd.setAddress(0,2); + lcd.printf("func: %s ", func); + //lcd.setAddress(0,3); + //lcd.printf("3ch: %d ", getChannel()); + lcd.setAddress(0,3); + lcd.printf("test: %d", test); + //lcd.setAddress(0,3); + //lcd.printf("chString: %s ", chString); + wait(3); + + if (lineData.numWords != 2){ + //Error Check, incorrect number of parameter, error out + return 0; + } + /* + int State = 2; + int channelValue = atoi(chString); + State = bridges.drive(channelValue, 1); //Turn channel on + lcd.setAddress(0,2); + lcd.printf("TEST ch: %d, State: %d", channelValue, State); + wait(3);*/ + + } + + + /******************************************************************************/ + /**** <Func: off> ****/ + /******************************************************************************/ + else if (strncmp(func,"drive", 5) == 0){ + //Order of Line: Local_Name, drive, duration + + if (lineData.numWords != 2){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + bridges.drive(getChannel(), 0); //Turn channel off + } + + else { + return 0; + + } + } + /* + lcd.setAddress(0,3); + lcd.printf("ENDch: %d ", getChannel()); + wait(3);*/ + + return 1; +} + + + +/**********************************************************************************************************************************/ +/**********************************************************************************************************************************/ +/******************************** <CLASS: Motor> ********************************/ +/**********************************************************************************************************************************/ +/**********************************************************************************************************************************/ + +class Motor{ + + enum BridgeDriver::Motors motor; + + public : + int interpret(); + void enableBrake(); + int forceBrake(); + //int forceFloat(); + float drive(); + + + void setMotor(BridgeDriver::Motors selectedMotor){ + motor = selectedMotor; + } + + enum BridgeDriver::Motors getMotor(){ + return motor; + } + +}; + +//A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on] +int Motor::interpret(){ + /* + lcd.cls(); //clear the display + lcd.setAddress(0,3); + lcd.printf("Test2 "); + lcd.setAddress(0,1); + lcd.printf("wrd1: %s", lineData.word[0]); + lcd.setAddress(0,2); + lcd.printf("wrd2: %s", lineData.word[1]); + wait(3); +*/ + + char *firstWord = lineData.word[0]; //splits the str based on a space delimeter + + if (strncmp(firstWord,"device", 6) == 0){ + //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; + } + + char channel = *lineData.word[3]; //Parameter is a single character, so dereference the point to the word + + switch (channel){ + case 'A': + case 'a': + setMotor(BridgeDriver::MOTOR_A); + break; + case 'B': + case 'b': + setMotor(BridgeDriver::MOTOR_B); + break; + case 'C': + case 'c': + setMotor(BridgeDriver::MOTOR_C); + break; + case 'D': + case 'd': + setMotor(BridgeDriver::MOTOR_D); + break; + } + } + + //if the first word is not "device" it means that it's trying to perform a function to a specific Motor + else{ + //Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,....... + char *localname = lineData.word[0]; //just for the sake of following the variable easily and understanding + char *func = lineData.word[1]; + + /******************************************************************************/ + /*** <Func: enableBrake> ***/ + /******************************************************************************/ + if (strncmp(func,"enableBrake", 11) == 0){ + + if (lineData.numWords != 4){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + //Initialize and Convert Parameters + char *enable = lineData.word[2]; + int enableValue = atoi(enable); + + bridges.enableBraking(getMotor(), enableValue); + } + + /******************************************************************************/ + /*** <Func: forceBrake> ***/ + /******************************************************************************/ + else if (strncmp(func,"forceBrake", 10) == 0){ + + if (lineData.numWords != 3){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + bridges.forceBrake(getMotor()); + } + + + /******************************************************************************/ + /*** <Func: drive> ***/ + /******************************************************************************/ + else if (strncmp(func,"drive", 5) == 0){ + + if (lineData.numWords != 4){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + //Initialize Parameters + char *speed = lineData.word[2]; + char *dir = lineData.word[3]; + + //Initialize Convertion Variables if needed + float speedValue; + int dirValue = 0; + + //Convert string to usable values + //NOTE both atof and atoi functions return 0 if no valid conversion could be performed + speedValue = atof(speed) / 100; + + if (speedValue <= 0) + return 0; //Error Out because a value gives no functionality or is wrong + + if (strncmp(dir,"CC", 2) == 0 || strncmp(dir,"cc", 2) == 0) + dirValue = -1; //Turn Clockwise + else if (strncmp(dir,"C", 1) == 0 || strncmp(dir,"c", 1) == 0) + dirValue = 1; //Turn CounterClockwise + else + return 0; //Error Out since the parameter is incorrect + + bridges.drive(getMotor(), dirValue, speedValue); //Turn on the Motor + } + /******************************************************************************/ + /**** <Func: off> ****/ + /******************************************************************************/ + else if (strncmp(func,"off", 3) == 0){ + + if (lineData.numWords != 2){ + //Error Check, incorrect number of parameter, error out + return 0; + } + + bridges.drive(getMotor(), 0, 0); //Turn off the Motor + } + + else { + return 0; + + } + } + + return 1; +} + + + + + + + + + + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FrontPanelButtons.lib Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/jason701802/code/FrontPanelButtons/#b2844843297f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Initialization.hpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,53 @@ +#ifndef INITIALIZATION_HPP +#define INITIALIZATION_HPP + +#include "mbed.h" +#include "LocalPinNames.h" +#include "BridgeDriver.h" +#include "FrontPanelButtons.h" +#include "TextLCD.h" +#include "SDFileSystem.h" + +//Initializations +Timer timer; // general purpose timer +I2C i2c( P0_10, P0_11 ); // I2C bus (SDA, SCL) +BridgeDriver bridges(&i2c, 1); // Bridge +TextLCD_I2C lcd( &i2c, MCP23008_SA0, TextLCD::LCD20x4 ); // LCD +SDFileSystem sd(P0_18, P0_17, P0_15, P0_16, "sd"); // the pinout on the mbed LPC1768 + +DigitalIn killSw(KILL); + +extern const int MAX_LINE_LENGTH = 100; + +void initLCD(void); + +void fullInit() { + + killSw.mode(PullUp); + initLCD(); +} + +void initLCD(void) { + + i2c.frequency(1000000); + lcd.setBacklight(TextLCD::LightOn); + wait(.6); + lcd.cls(); //clear the display + lcd.setAddress(0,0); + lcd.printf("LCD Initialized"); +} + + +struct Line{ + + char *fullLine; //full line, starting from the beginning + char *currPartLine; //current line, meaning that it only knows whatever has not been used in the line + int lineNumber; //current line number in the program txt file that is running + char word[15][MAX_LINE_LENGTH]; //array of words from the line of text, assuming no more than 15 words will be in any given line + //in this initialization there are 15 string (pointers) of size MAX_LINE_LENGTH each + int numWords; //Number of words in the given line +}; + +extern struct Line lineData; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LocalPinNames.h Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,36 @@ +#ifndef LOCALPINNAMES_H + +#define LOCALPINNAMES_H + + /* local name, resouce name */ +#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 + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP23017.lib Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/wim/code/MCP23017/#5696b886a895
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Motor.cpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,181 @@ +//#include "Motor.hpp" +//#include "mbed.h" +//#include "LocalPinNames.h" +//#include "BridgeDriver.h" +// +////Constructor +//Motor::Motor(){ +// /* +// //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; +// }*/ +// +// char channel = *lineData.word[3]; //Parameter is a single character, so dereference the point to the word +// +// switch (channel){ +// case 'A': +// case 'a': +// this->motor = BridgeDriver::MOTOR_A; +// break; +// case 'B': +// case 'b': +// this->motor = BridgeDriver::MOTOR_B; +// break; +// case 'C': +// case 'c': +// this->motor = BridgeDriver::MOTOR_C; +// break; +// case 'D': +// case 'd': +// this->motor = BridgeDriver::MOTOR_D; +// break; +// } +//} +// +// +//enum BridgeDriver::Motors Motor::getMotor(){ +// return this->motor; +//} +// +////A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on] +//int Motor::interpret(){ +// +// +// //Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,....... +// char *localname = lineData.word[0]; //just for the sake of following the variable easily and understanding +// char *func = lineData.word[1]; +// +// /******************************************************************************/ +// /*** <Func: enableBrake> ***/ +// /******************************************************************************/ +// if (strncmp(func,"enableBrake", 11) == 0){ +// +// if (lineData.numWords != 4){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// //Initialize and Convert Parameters +// char *enable = lineData.word[2]; +// int enableValue = atoi(enable); +// +// bridges.enableBraking(getMotor(), enableValue); +// } +// +// /******************************************************************************/ +// /*** <Func: forceBrake> ***/ +// /******************************************************************************/ +// else if (strncmp(func,"forceBrake", 10) == 0){ +// +// if (lineData.numWords != 3){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// bridges.forceBrake(getMotor()); +// } +// +// +// /******************************************************************************/ +// /*** <Func: drive> ***/ +// /******************************************************************************/ +// +// +// /******************************************************************************/ +// /**** <Func: off> ****/ +// /******************************************************************************/ +// else if (strncmp(func,"off", 3) == 0){ +// +// if (lineData.numWords != 2){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// bridges.drive(getMotor(), 0, 0); //Turn off the Motor +// } +// +// else { +// return 0; +// +// } +// +// +// return 1; +//} +// +// +// +// +// +// +// +///* +//int Motor::enableBrake(){ +// +// if (lineData.numWords != 4){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// //Initialize and Convert Parameters +// char *enable = lineData.word[2]; +// int enableValue = atoi(enable); +// +// //If the atoi returned anything besides 0, it worked properly +// if (enableValue) +// bridges.enableBraking(getMotor(), enableValue); +// else{ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// return 1; +//} +// +//int Motor::forceBrake(){ +// +// if (lineData.numWords != 3){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// bridges.forceBrake(getMotor()); +//} +// +//int Motor::drive(){ +// +// if (lineData.numWords != 4){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// //Initialize Parameters +// char *speed = lineData.word[2]; +// char *dir = lineData.word[3]; +// +// //Initialize Convertion Variables if needed +// float speedValue; +// int dirValue = 0; +// +// //Convert string to usable values +// //NOTE both atof and atoi functions return 0 if no valid conversion could be performed +// speedValue = atof(speed) / 100; +// +// if (speedValue <= 0) +// return 0; //Error Out because a value gives no functionality or is wrong +// +// if (strncmp(dir,"CC", 2) == 0 || strncmp(dir,"cc", 2) == 0) +// dirValue = -1; //Turn Clockwise +// else if (strncmp(dir,"C", 1) == 0 || strncmp(dir,"c", 1) == 0) +// dirValue = 1; //Turn CounterClockwise +// else +// return 0; //Error Out since the parameter is incorrect +// +// bridges.drive(getMotor(), dirValue, speedValue); //Turn on the Motor +//} +//*/ +// +// +// \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Motor.hpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,21 @@ +//#ifndef MOTOR_HPP +//#define MOTOR_HPP +// +//#include "Device.hpp" +// +//class Motor: public Device{ +// +// private: +// enum BridgeDriver::Motors motor; +// +// public: +// Motor(); +// int interpret(); +// enum BridgeDriver::Motors getMotor(); +// //void enableBrake(); +// //int forceBrake(); +// //int forceFloat(); +// //float drive(); +//}; +// +//#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/SDFileSystem/#7b35d1709458
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextFile.h Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,119 @@ +#include "mbed.h" +#include "TextLCD.h" +#include "SDFileSystem.h" +#include <stdio.h> +#include <string> +#include <stdlib.h> +#include <vector> +using std::string; + + +//vector<string> filenames; //filenames are stored in a vector string + +vector<string> readFileNames(char *); +int getFileNamesWithoutExt(string[], vector<string> &); +string getPreviousLine(istream &); + + + +/******************************************************************************/ +/*** <readFileNames> ***/ +/******************************************************************************/ +// read file names into vector of strings +vector<string> readFileNames(char *dir) { + + vector<string> filenames; + DIR *dp; + struct dirent *dirp; + dp = opendir(dir); + //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); + return filenames; +} + + + +/******************************************************************************/ +/*** <getFileNamesWithoutExt> ***/ +/******************************************************************************/ + // save filename strings to array from vector using an iterator +int getFileNamesWithoutExt(string fileNames[], vector<string> &filenames) { + + //Cycle through all files listed in the directoy (strings in the vector list) + int n = 0; + for(vector<string>::iterator it=filenames.begin(); it < filenames.end(); it++) + { + //Convert the Vector found String to a char for use in the strtok function + char temp[50]; + if((*it).size() < 100) + strcpy(temp, (*it).c_str()); + + // Retrieve the fileName and fileExtension by splitting the string + char *fileName; + char *fileExtension; + fileName = strtok(temp, "."); + fileExtension = strtok(NULL, "."); + + // if the file is a .txt file, then save it to the array + if (strncmp(fileExtension,"txt", 3) == 0) { + fileNames[n] = fileName; + n++; + } + } + + return n; //Return the number of txt files that were found in the directory +} + +/******************************************************************************/ +/*** <getNextLine> ***/ +/******************************************************************************/ +// + +void getNextLine(FILE *selectedFile) { + + char newLine[MAX_LINE_LENGTH]; + fgets(newLine, MAX_LINE_LENGTH, selectedFile); + + lineData.fullLine = newLine; + lineData.lineNumber++; + + //Create a copy of the line, so that we don't effect the full line when we're extracting the words + char cpyLine[MAX_LINE_LENGTH]; + strcpy(cpyLine, newLine); + + char *tempWord; + int numWords = 0; + tempWord = strtok(cpyLine, " "); + 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, " "); + } + + lineData.numWords = numWords; //Record the number of words in the line + + lcd.setAddress(0,1); + lcd.printf("Current Line#: %d", lineData.lineNumber); + /* + lcd.cls(); //clear the display + lcd.setAddress(0,0); + lcd.printf("wrd1: %s", lineData.word[0]); + lcd.setAddress(0,1); + lcd.printf("wrd2: %s", lineData.word[1]); + lcd.setAddress(0,2); + lcd.printf("wrd3: %s", lineData.word[2]); + lcd.setAddress(0,3); + lcd.printf("wrd4: %s", lineData.word[3]); + wait(5);*/ +} + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/jason701802/code/TextLCD/#1c0232c55749
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VoltageDriver.cpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,107 @@ +//#include "VoltageDriver.hpp" +//#include "mbed.h" +//#include "LocalPinNames.h" +//#include "BridgeDriver.h" +// +////Constructor +//VoltageDriver::VoltageDriver(){ +// +// //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; +// } +// +// char *channel = lineData.word[3]; //Parameter is a number +// int channelValue = atoi(channel); +// +// //Channel Value between 1 to 8 +// if (channelValue >= 1 && channelValue <= 8){ +// +// switch (channelValue){ +// case 1: +// case 2: +// bridges.enablePwm(BridgeDriver::MOTOR_A, 0); +// break; +// case 3: +// case 4: +// bridges.enablePwm(BridgeDriver::MOTOR_B, 0); +// break; +// case 5: +// case 6: +// bridges.enablePwm(BridgeDriver::MOTOR_C, 0); +// break; +// case 7: +// case 8: +// bridges.enablePwm(BridgeDriver::MOTOR_D, 0); +// break; +// } +// } +// else{ +// //ERROR Out +// //Unacceptable channel, or conversion function failed when converting string to int +// } +//} +// +// +//int VoltageDriver::getChannel(){ +// return this->channel; +//} +// +// +////A line consists of [ __(Local_Name)__ __(function)__ __(parameter1)__ __(parameter2)__ __(parameter3)__ ... and so on] +//int VoltageDriver::interpret(){ +// +// //Order of Line: Local_Name, Function_Name, Param1, Param2, Param3,....... +// char *func = lineData.word[1]; +// +// /******************************************************************************/ +// /*** <Func: forceBrake> ***/ +// /******************************************************************************/ +// if (strncmp(func,"forceBrake", 10) == 0){ +// +// if (lineData.numWords != 3){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// bridges.forceBrake(this->channel); +// } +// +// +// /******************************************************************************/ +// /*** <Func: drive> ***/ +// /******************************************************************************/ +// else if (strncmp(func,"drive", 5) == 0){ +// //Order of Line: Local_Name, drive +// +// if (lineData.numWords != 2){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// bridges.drive(this->channel, 1); //Turn channel on +// +// } +// +// +// /******************************************************************************/ +// /**** <Func: off> ****/ +// /******************************************************************************/ +// else if (strncmp(func,"drive", 5) == 0){ +// //Order of Line: Local_Name, drive, duration +// +// if (lineData.numWords != 2){ +// //Error Check, incorrect number of parameter, error out +// return 0; +// } +// +// bridges.drive(getChannel(), 0); //Turn channel off +// } +// +// else { +// return 0; +// } +// +// return 1; +//} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VoltageDriver.hpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,21 @@ +//#ifndef VOLTAGEDRIVER_HPP +//#define VOLTAGEDRIVER_HPP +// +//#include "Device.hpp" +// +//class VoltageDriver: public Device{ +// +// private: +// int channel; +// +// public: +// VoltageDriver(); +// int interpret(); +// int getChannel(); +// //void enableBrake(); +// //int forceBrake(); +// //int forceFloat(); +// //float drive(); +//}; +// +//#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,401 @@ + +#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 <iostream> +#include <fstream> +#include <vector> +using std::string; + +//const int MAX_LINE_LENGTH = 100; +struct Line lineData; +//Device devices[15]; +DeviceData devices[15]; + +//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 +*/ + +void resetLineData(){ + + lineData.fullLine = NULL; + lineData.lineNumber = 0; + lineData.numWords = 0; +} + +FrontPanelButtons buttons(&i2c); + + +/* + Make LOOP function + - All you need to do is remember (val = ftell(fp)) the beginning of the line you're currently reading. + - If it turns out to be a LOOP call, then you simply send that remembered value to the LOOP function, and it will continue to LOOP back to that position until the condition is met. + + + func LOOP (FILE *fp, int loopStart){ + + string conditions; + fseek(fp, loopStart, SEEK_SET); + fgets(conditions, MAX_LINE_LENGTH, fp); + + int numCycles = interpretLoopCondtions(); + + int i = 0; + int checkEndLoop = 0; + while (i < numCycles) { + + checkEndLoop = interpretLine(fp); //if end Loop return ____ (1?), return 0 on success + if (checkEndLoop) //if it's not the end of the loop, the counter will not increase and we'll just interpret the next line + i++; + } + } //loop conditions met, return to main code + + + */ + + + +int cyclePrograms(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 +} + + +string* resize_StringArr(string oldArr[], int newSize) { + + string newArr[newSize]; + memcpy(newArr, oldArr, newSize * sizeof(string)); + + return newArr; +} + + +int main() { + + fullInit(); //Initialize anything that's required to run the code (LCD) + + /******************************************************************************/ + /*** <Get all the Potential Programs> ***/ + /******************************************************************************/ + int numTextFiles = 0; + string tempTextFiles[25]; //Assuming Maximum of 25 txt files will be on the SD Card + lcd.cls(); //clear the display + + vector<string> filenames = readFileNames("/sd"); + numTextFiles = getFileNamesWithoutExt(tempTextFiles, filenames); + string *textFiles = resize_StringArr(tempTextFiles, numTextFiles); //Resize Array + + //delete [] tempTextFiles; //free previous array + + + /******************************************************************************/ + /*** <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(); + + 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); + + if (strncmp(lineData.word[0],"device", 6) == 0){ + + int i = 0, deviceFound = -1; + for (i = 0; i < numDevices; i++) + if (strncmp(lineData.word[2], DeviceNames[i], strlen(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 + addDevice(deviceFound); + } + + else if (strncmp(lineData.word[0],"delay", 5) == 0){ + char *duration = lineData.word[1]; + int durationValue = atoi(duration); + + 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 + } + } + + else if (strncmp(lineData.word[0],"loop", 4) == 0){ + //Do something for looping + } + + else if (strncmp(lineData.word[0],"end", 3) == 0){ + if (strncmp(lineData.word[1],"program", 7) == 0) + endOfFile = 1; + } + + //not a keyword so check if it's a localName for a device + else{ + + int i = 0, deviceFound = -1; + for (i = 0; i < currNumDevices; i++){ + if (strncmp(lineData.word[0], devices[i].name, strlen(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(); + } + } + + + 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 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Sep 16 15:28:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9327015d4013 \ No newline at end of file