Mbed Clock application using an NTP connection to get internet time and a terminal interface to send commands
Dependencies: 4DGL-uLCD-SE EthernetInterface NTPClient mbed-rtos mbed SDFileSystem wavfile
Diff: main.cpp
- Revision:
- 0:4e6ae21cbd31
- Child:
- 1:c47a2f0816bb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Dec 02 17:22:43 2014 +0000 @@ -0,0 +1,176 @@ +#include "mbed.h" +#include "rtos.h" +#include "EthernetInterface.h" +#include "uLCD_4DGL.h" +#include "Clock.h" +#include <string> +#include <sstream> +#include <vector> + +uLCD_4DGL uLCD(p28,p27,p30); +Serial pc(USBTX, USBRX); +Mutex cMutex; +Mutex sMutex; +Clock clk; +EthernetInterface eth; + +/** + * Function to get a command from the virtual serial connection. + * Will prompt the serial port for a command and read a command + * into a buffer and convert that buffer to a string object. This + * function should only be used while testing without a connection. + */ +string getCommand() { + char buffer[100]; + char next = 0; + int i = 0; + sMutex.lock(); + pc.printf("Enter a command: \n\r"); + sMutex.unlock(); + do { + sMutex.lock(); + if (pc.readable()) { + next = pc.getc(); + buffer[i++] = next; + } + sMutex.unlock(); + Thread::wait(0.1); + } while (next != '\r'); + + buffer[i] = '\0'; + sMutex.lock(); + pc.printf("Command entered: %s\n\r", buffer); + sMutex.unlock(); + return string(buffer); +} + +/** + * Function to take a string command and break it into tokens of words/numbers. + * These tokens will be added to the vector given as an argument and can then be + * parsed to execute a command. + */ +vector<string>& splitCommand(const string &command, vector<string> &tokens) { + string buf; + stringstream ss(command); + + while (ss >> buf) + tokens.push_back(buf); + + return tokens; +} + +/** + * Function to actually parse and execute a given command. If the command is not + * supported, an error function will be called to give feedback. + */ +void parseCommand(const vector<string> &tokens) { + sMutex.lock(); + pc.printf("number of tokens: %d\n\r", tokens.size()); + sMutex.unlock(); + + if (tokens.size() < 2) { + // error message + return; + } + + string operation = tokens[0]; + string destination = tokens[1]; + + if (operation == "set") { + if (destination == "time") { + int hour = atoi(tokens[2].c_str()); + int minute = atoi(tokens[3].c_str()); + int period = tokens.at(4) == "am" ? AM : PM; + cMutex.lock(); + clk.setTime(hour, minute, period); + cMutex.unlock(); + } else if (destination == "alarm") { + int hours = atoi(tokens[2].c_str()); + int minutes = atoi(tokens[3].c_str()); + } else if (destination == "timezone") { + int timezone = atoi(tokens[2].c_str()); + cMutex.lock(); + clk.setTimezone(timezone); + cMutex.unlock(); + } else { + //return error message + } + } else if (operation == "sync") { + if (destination == "time") { + + cMutex.lock(); + if (clk.syncTime() == 0) { + sMutex.lock(); + pc.printf("Set time successfully\r\n"); + } else { + sMutex.lock(); + pc.printf("Error\r\n"); + } + sMutex.unlock(); + cMutex.unlock(); + } + // return error message + } +} + +/** + * Thread which updates the clock on the lcd while the main thread is waiting for + * or executing a command. + */ +void lcdUpdateThread(void const *args) { + time_t time; + struct tm *timeinfo; + char buffer[20]; + + // set initial time + cMutex.lock(); + clk.syncTime(); + clk.setTimezone(-5); + cMutex.unlock(); + + // set lcd format + sMutex.lock(); + uLCD.text_width(2); + uLCD.text_height(2); + uLCD.color(BLUE); + sMutex.unlock(); + + while (1) { + cMutex.lock(); + time = clk.getTime(); + cMutex.unlock(); + + timeinfo = localtime(&time); + strftime(buffer, 20, "%I:%M:%S %p", timeinfo); + + sMutex.lock(); + uLCD.locate(0,3); + uLCD.printf("%s", buffer); + sMutex.unlock(); + Thread::wait(0.25); + } +} + +/** + * main function which loops getting a command, parsing that command, and executing + * that command. It also starts a thread which updates the clock separate from the + * command execution. + */ +int main() { + vector<string> tokens; + + eth.init(); + eth.connect(); + wait(5); // I don't know why you have to wait... + + pc.printf("%s\n\r", eth.getIPAddress()); + + Thread updateThread(lcdUpdateThread); + + while (1) { + tokens.clear(); + string command = getCommand(); + splitCommand(command, tokens); + parseCommand(tokens); + } +}