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
main.cpp
- Committer:
- dudanian
- Date:
- 2014-12-02
- Revision:
- 0:4e6ae21cbd31
- Child:
- 1:c47a2f0816bb
File content as of revision 0:4e6ae21cbd31:
#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); } }