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-09
Revision:
6:23c3adb0470d
Parent:
3:b711df1f40cb

File content as of revision 6:23c3adb0470d:

#include "mbed.h"
#include "rtos.h"
#include "EthernetInterface.h"
#include "uLCD_4DGL.h"
#include "SDFileSystem.h"
#include "Clock.h"
#include "Recorder.h"
#include "Speaker.h"
#include <string>

//#define SERVER_IP "143.215.120.157"
#define SERVER_IP "143.215.119.135"
#define SERVER_PORT 13000
#define REC_NAME "/sd/rec.wav"
#define PLAY_NAME "/sd/play.wav"

#define BUF_SIZE 8192

// Big Components
uLCD_4DGL uLCD(p28,p27,p30);
Serial pc(USBTX, USBRX);
Serial easyVR(p13, p14);
SDFileSystem sdc(p5, p6, p7, p8, "sd");
EthernetInterface eth;
TCPSocketConnection server;
Clock clk;

// Small Components
Speaker speaker(p21);
DigitalOut sleepLED(LED4);
Mutex cMutex;
Mutex sMutex;
char buf[BUF_SIZE];
// float array for recorder (they share the buffer)
float *buffer = (float*)buf; 

// Help with noise
AnalogIn pin15(p15);
AnalogIn pin16(p16);
AnalogIn pin17(p17);
AnalogIn pin19(p19);

void aThread(void const *args) {
    while (1) {
        Thread::signal_wait(0x1, osWaitForever);
        for (int i = 0; i < 5; i++) {
            speaker.playNote(969.0, 0.5, 0.1);
            Thread::wait(1000);
        }
    }
}

void execute(char *command) {
    char buffer[12];
    int hour, minute, period, zone;
    sscanf(command, "%s %d %d %d %d", buffer, &hour, &minute, &period, &zone);
    string operation(buffer);
    
    if (operation == "setTime") {
        cMutex.lock();
        clk.setTime(hour, minute, period);
        cMutex.unlock();
    } else if (operation == "setTimezone") {
        cMutex.lock();
        clk.setTimezone(zone);
        cMutex.unlock();
    } else if (operation == "setAlarm") {
        cMutex.lock();
        clk.setAlarm(hour, minute, period);
        cMutex.unlock(); 
    } else if (operation == "setTimer") {
        cMutex.lock();
        clk.setTimer(hour, minute);
        cMutex.unlock(); 
    } else if (operation == "deleteAlarm") {
        cMutex.lock();
        clk.deleteAlarm();
        cMutex.unlock(); 
    } else if (operation == "syncNow") {
        cMutex.lock();            
        if (clk.syncTime() != 0) {
            printf("  ERROR: failed to sync time\n\n\r");
        }
        cMutex.unlock();
    } else if (operation == "noCommand") {
        printf("  ERROR: speech not recognized\n\n\r");
    } else {
        printf("  ERROR: not a valid command\n\n\r");
    }
}


/**
 * 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();
        bool alarmSet = clk.alarmSet();
        cMutex.unlock();
        
        timeinfo = localtime(&time);
        strftime(buffer, 20, "%I:%M:%S        %p", timeinfo);
        
        sMutex.lock();
        uLCD.locate(0,3);
        uLCD.printf("%s", buffer);
        if (alarmSet)
            uLCD.printf("ALARM SET");
        else
            uLCD.printf("         ");
        sMutex.unlock();
        Thread::wait(200);
    }
}

void init() {
    printf("\r\n\n--Starting MbedClock--\n\r");
    
    eth.init();
    printf(" * Initialized Ethernet\n\r");
    
    eth.connect();
    printf(" * Connected using DHCP\n\r");
    wait(5);
    printf(" * Using IP: %s\n\r", eth.getIPAddress());
    
    easyVR.putc('b');
    easyVR.getc();
    printf(" * Initialized EasyVR\n\r");

    
}

void waitForTrigger() {
    // set EasyVR to 2 claps
    sMutex.lock();
    easyVR.putc('s');
    easyVR.putc('A' + 1);
    sMutex.unlock();
    wait(0.2);
    
    // Clear buffer and wait for awake
    printf("Waiting for trigger...");
    sMutex.lock();
    while (easyVR.readable())
        easyVR.getc();
    sMutex.unlock();
    sleepLED = 1;
    while(!easyVR.readable()) {
        wait(0.2);
    }
    sleepLED = 0;
    printf("trigger received!\n\r");
}

void waitForTrigger2() {
    char rchar = 0;
    sleepLED = 1;
    printf("Waiting for trigger...");
    while (rchar!='A') {
        wait(.001);
        sMutex.lock();
        easyVR.putc('d');
// a small delay is needed when sending EasyVR several characters
        wait(.001);
        easyVR.putc('A');
        sMutex.unlock();
        while (!easyVR.readable()) {
            wait(0.2);
        }
        sMutex.lock();
        rchar=easyVR.getc();
        sMutex.unlock();
        // word recognized
        if (rchar=='r') {
            wait(.001);
            sMutex.lock();
            easyVR.putc(' ');
            rchar=easyVR.getc();
            sMutex.unlock();
        // error
        } else if (rchar=='e') {
            wait(.001);
            sMutex.lock();
            easyVR.putc(' ');
            rchar=easyVR.getc();
            easyVR.putc(' ');
            rchar=easyVR.getc();
            sMutex.unlock();
        }
    }
    sleepLED = 0;
    printf("trigger received!\n\r");
}

void sendFile() {
    printf("  Sending \"%s\"...", REC_NAME);
    FILE *fp = fopen(REC_NAME, "rb");

    int sum = 0;
    while (sum < 110296)
    {
        int i = fread(buf, 1, BUF_SIZE, fp);
        server.send(buf, i);
        sum += i;
    }
    printf("sent\n\r");
    fclose(fp);
    
    int n = server.receive(buf, BUF_SIZE);
    buf[n] = '\0';
    printf("  Received \"%s\"\n\n\r", buf);
}

int main() {
    init();
    //RtosTimer alarmTimer(aThread, osTimerOnce, NULL);

    
    Thread alarmThread(aThread);
    Thread updateThread(lcdUpdateThread);
    printf(" * Started LCD and Alarm Threads\n\n\r");
    
    cMutex.lock();
    clk.setAlarmThread(&alarmThread);
    cMutex.unlock();
    while(1) {
        waitForTrigger();

        printf("  Recording audio file...");
        rec(REC_NAME, 5);
        printf("complete\n\r");
        //wait(0.1);
        //play(FILE_NAME);
        
        if (!server.connect(SERVER_IP, SERVER_PORT)) {
            printf("  Connected to %s\n\r", SERVER_IP);
            sendFile();
            execute(buf);
            server.close();
        } else {
            printf("  Unable to connect to %s\n\n\r", SERVER_IP);
        }
    }
}