Final MEMBITT Code

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed

Fork of reminder_main by Senior Design

main.cpp

Committer:
deronmai
Date:
2016-12-06
Revision:
5:69da174d0f56
Parent:
4:ae6216936ddf
Child:
6:ce8d4456e28b

File content as of revision 5:69da174d0f56:

#include "mbed.h"
#include <string>
#include <vector>
#include "utils.h"
#include "SDFileSystem.h"
#include "uLCD_4DGL.h"
DigitalOut myled(LED1);


InterruptIn pb1(p21);
InterruptIn pb2(p22);

uLCD_4DGL uLCD(p28,p27,p29);
SDFileSystem sd(p5, p6, p7, p8, "sd");
//PinDetect pb1(p21); // receive new schedule
Serial pc(USBTX, USBRX); // tx, rx .... for testing purposes (remove later)
//Serial blue(p13, p14, 9600);
Serial easyVR(p13,p14);
void pb1_hit_interrupt (void);
void pb2_hit_interrupt (void);


// Global vars
time_t ct_time;
struct tm * timeinfo;
schedule myschedule;

// Function declares
void clock_main(struct reminder *current_reminder);
int estimate_time(struct reminder current_reminder);
void write_schedule_sd(char *buffer, int size);
void speak(int num);
void synthesis(reminder x);
void synTimes(reminder x);
int schedule_read();
void writetest();
void packdata(int send); // if send == 1 send data to pc
//void pb1_hit_callback (void);
void receive_schedule();

int main()
{
    // in real project, we will set the time via the internet
    //uLCD.printf("Hello world\n");
    // localtime(
    pb1.mode(PullUp);
    // Delay for initial pullup to take effect
    wait(.01);
    // Attach the address of the interrupt handler routine for pushbutton
    pb1.fall(&pb1_hit_interrupt);
    pb2.mode(PullUp);
    wait(.01);
    pb2.fall(&pb2_hit_interrupt);

    srand (time(NULL)); // initialize random numbers
    /*
    int i = 0;
    while(1)
    {

        uLCD.printf("%i",i);
        wait(1);
    }*/
    /*
    reminder test_reminder;
    // test_reminder.tm_time.tm_sec = 0;
    test_reminder.tm_time.tm_min = 36;
    test_reminder.tm_time.tm_hour = 11;
    for (int i = 0; i < 7; i++) {
        if (i == 1 || i == 3 || i == 4 || i == 5) test_reminder.reminder_days[i] = 1; // set MWHF
        else test_reminder.reminder_days[i] = 0;
    }*/
    // test_reminder.tm_time.tm_mday = 1; // day of the month
    // test_reminder.tm_time.tm_mon = 0; // months since January
    // test_reminder.tm_time.tm_year = 0; // years since 1970
    //myschedule.addReminder(test_reminder);
    uLCD.printf("waiting to receive schedule\n");
    receive_schedule();
    int current_time = schedule_read();
    //uLCD.printf("current time set to: %i", current_time);

    set_time(current_time-18000);  // Set RTC time to Wed, 28 Oct 2009 14:24:30
    // subtract 5*60*60 for eastern time
    time_t clock;
    time_t seconds = time(NULL);
    uLCD.printf("Time as a basic string = %s", ctime(&seconds));
    //packdata(1);
    wait(1);

    int flag = 0;

    //Day currentDay = Wednesday;
    uLCD.printf("current day is %i\n",timeinfo->tm_wday);
    int time_diff;
    while(1) {
        for (int i = 0; i < myschedule.getSize(); i++) {
            timeinfo = localtime (&clock); // ct_time not set right now
            time(&clock);
            pc.printf("Time as a basic string = %s\n\r", ctime(&clock));
            reminder tmpReminder = myschedule.getCurrentReminder();
            // CHANGE TO POTENTAILLY NOT INCREMENTING CURRENT REMINDER?
            flag = 0;
            while (!flag) {
                if (tmpReminder.reminder_days[timeinfo->tm_wday] != 1) {
                    // pc.printf("%i\n\r", myschedule.reminder_list[i].reminder_days[currentDay]);
                    i++; // current reminder not set to go off today; go to next reminder
                    tmpReminder = myschedule.nextReminder();
                }
                // may need to check if the current reminder is not last one, otherwise out of bounds ERROR
                else {
                    time_diff = estimate_time(tmpReminder);
                    //uLCD.locate(0,0);
                    uLCD.printf("time_diff is %i\n\r", time_diff);
                    if (time_diff < 0) {
                        i++;
                        tmpReminder = myschedule.nextReminder();
                    } else flag = 1;
                    // sleep(sleep_time); // try and sleep here
                    // wait(sleep_time); // replace this wait function with a smart sleep to save power and then poll after that
                }
                //wait(1);
            }
            uLCD.printf("%s\n", tmpReminder.notification);
            if (tmpReminder.notification == "App") {
                uLCD.printf("checking app\n");
                //if (timeinfo->tm_min == tmpReminder.min && timeinfo->tm_hour == tmpReminder.hour - 1) {
                //if (tmpReminder.hour - timeinfo->tm_hour <= 1) {
                if (time_diff <= 60) {

                    myled = true;
                    synthesis(tmpReminder);
                    uLCD.printf("moving to next reminder\n");
                    myschedule.nextReminder();
                    uLCD.printf("moved to next reminder\n");
                    flag = 0;
                }
            } else {
                if (timeinfo->tm_min == tmpReminder.min && timeinfo->tm_hour == tmpReminder.hour) {
                    myled = true;
                    synthesis(tmpReminder);
                    uLCD.printf("moving to next reminder\n");
                    myschedule.nextReminder();
                    uLCD.printf("moved to next reminder\n");
                    flag = 0;
                }
            }
            wait(1);
        }
        uLCD.printf("All reminders done for the day\n");
        while(1) {}
    }
}

int estimate_time(struct reminder current_reminder)
{
    // estimates the remaining time until the next reminder so program can sleep till then to save battery
    //uLCD.printf("current hour: %i note hour %i\n\r", timeinfo->tm_hour, current_reminder.hour);
    int estimated_time = (60*current_reminder.hour) - (60*timeinfo->tm_hour) +
                         (current_reminder.min - timeinfo->tm_min);
    // convert hours to min, find estimated time before reminder plus 1 hour (60 min)

    return estimated_time;


    //if (current_reminder.reminder_days[currentDay] == 1) //

}

// use pushbutton to do this
void receive_schedule()
{
    pc.baud(9600);
    char buff[1000];
    int i = 0;
    bool flag = false;
    while(!flag) {
        buff[i] = pc.getc();
        uLCD.printf("%c", buff[i]);
        //blue.putc(buff[i]);
        flag = buff[i] == '^';
        if (flag) uLCD.printf("flag detected");
        i++;
    }
    write_schedule_sd(buff, i);
}

void write_schedule_sd(char *buffer, int size)
{
    mkdir("/sd/mydir", 0777);
    FILE *fp = fopen("/sd/mydir/schedule.txt", "w");
    if(fp == NULL) {
        error("Could not open file for write\n");
    }
    fprintf(fp, buffer);
    fclose(fp);
}

int schedule_read()
{
    char time_read[1];
    int set_time = 0;;
    //uLCD.locate(0,0);
    //uLCD.printf("reading schedule\r\n");
    FILE *fp = fopen("/sd/mydir/schedule.txt", "r");
    if(fp == NULL) {
        error("Could not open file to read\n");
    }

    // get time
    fread(time_read,1,1,fp);
    if (time_read[0] != '[') {
        uLCD.locate(0,0);
        uLCD.printf("[ not found, instead found %s\r\n",time_read[0]);
        error("Time in incorrect format, expected [, got %s\n",time_read[0]);
    }
    while (time_read[0] != ']') {
        fread(time_read,1,1,fp);
        if (time_read[0] != ']') set_time = (set_time*10)+(time_read[0] - '0');
    }

    //set_time(set_time);




    //uLCD.locate(0,0);
    //uLCD.printf("opened successfully\r\n");
    char reminder_size[1];
    int header = 1;
    int reminder_count = 0;
    //fgets(reminder_size, sizeof(reminder_size), fp);
    fread(reminder_size,1,1,fp);
    if (reminder_size[0] != '{') {
        uLCD.locate(0,0);
        uLCD.printf("{ not found, instead found %s\r\n",reminder_size[0]);
        error("Schedule in incorrect format, expected {, got %s\n",reminder_size[0]);
    }
    while (header) {
        char test[1];
        //fgets(reminder_size, sizeof(reminder_size), fp);
        fread(test,1,1,fp);
        if (test[0] == '|') header = 0;
        else {
            //uLCD.printf("%s %i",reminder_size[0], (int)reminder_size[0]);
            uLCD.printf("%c",test[0]);
            //wait(4);
            reminder_count = (reminder_count*10)+(test[0] - '0');
        }
    }
    uLCD.cls();
    //uLCD.locate(0,0);
    //uLCD.printf("parsing schedule reminder count is %i\r\n", reminder_count);
    //wait(5);
    reminder tmp;

    char buf[REMINDER_SIZE];
    //int days;
    for (int i = 0; i < reminder_count; i++) {
        //fgets(buf, sizeof(buf), fp);
        fread(buf,sizeof(buf),1,fp);
        uLCD.cls();
        uLCD.locate(0,0);
        uLCD.printf("buf is %s\r\n",buf);
        wait(.1);
        char *pch;
        pch = strtok (buf,"+");
        tmp.notification = pch;
        uLCD.printf("%s\n", pch);
        wait(.1);
        pch = strtok (NULL,"+");
        //uLCD.printf("%s\n", pch);
        if (strlen(pch) == 1) tmp.hour = (int) (pch[0] - '0');
        else tmp.hour = (int) ((pch[0] - '0') * 10 + (pch[1] - '0'));
        //if (tmp.hour > 24
        uLCD.printf("%i\n", tmp.hour);
        //wait(1);
        pch = strtok (NULL,"+");
        if (strlen(pch) == 1) tmp.min = (int) (pch[0] - '0');
        else tmp.min = (int) ((pch[0] - '0') * 10 + (pch[1] - '0'));
        uLCD.printf("%i\n", tmp.min);
        wait(.1);
        pch = strtok (NULL,"+");
        for (int i = 0; i < 7; i++) {
            tmp.reminder_days[i] = (int) pch[i] - '0';
            //days = days/10;
            uLCD.printf("%i\n", tmp.reminder_days[i]);
            //wait(.1);
        }

        //add to the (schedule) vector here
        myschedule.addReminder(tmp);
        wait(5);
    }
    fclose(fp);
    uLCD.cls();
    uLCD.printf("returned time here");

    return set_time;
}
/*
void clock_main(struct reminder *current_reminder) {

}
*/

void packdata(int send)
{

    dateTime testdt;
    testdt.month = 1;
    testdt.day = 2;
    testdt.year = 2009;
    myschedule.updateRecord(testdt, 1);
    myschedule.updateRecord(testdt, 0);

    int rem_num = 0; // number of reminders
    char con[2];
    string record_str = "";
    string part;
    int data_entries;
    record tmpr;
    dateTime tmpd;
    uLCD.printf("test start\r\n");
    for (int i = 0; i < myschedule.getSize(); i++) {
        uLCD.printf("schedule entries exist\r\n");
        data_entries = myschedule.getNumRecords(i);
        if (data_entries) { // more than 1 data entry
            rem_num++;
            char de[2];
            sprintf(con, "%d", i);
            sprintf(de, "%d", data_entries);
            record_str += "|r" + (string)con + "(" + (string)de + ")";
            tmpr = myschedule.getRecord(i);
            for (int j = 0; j < data_entries; j++) {
                tmpd = tmpr.date[j];
                char tmpmon[2], tmpday[2], tmpyear[2];
                sprintf(tmpmon, "%d", tmpd.month);
                sprintf(tmpday, "%d", tmpd.day);
                sprintf(tmpyear, "%d", tmpd.year);
                part = "[";
                if (tmpd.month < 10) part += "0";
                part += (string) tmpmon + "-";
                if (tmpd.day < 10) part += "0";
                part += (string)tmpday + "-" + (string)tmpyear + "]";
                char tmpval[1];
                sprintf(tmpval, "%d", tmpr.data[j]);
                part += tmpval;
                uLCD.printf("%s\r\n", part.c_str());
                //part = "[" + tmpd.month + "-" + tmpd.day + "-" + tmpd.year + "]";
                record_str += part;
            }
        }
    }
    char remnum[2];
    sprintf(remnum, "%d", rem_num);
    record_str = "{" + (string)remnum + record_str + "}";
    uLCD.printf("%s\r\n", record_str.c_str());
    uLCD.printf("starting data record write\r\n");


    // save data to buffer
    const char *buffer = record_str.c_str();
    mkdir("/sd/mydir", 0777);
    FILE *fp = fopen("/sd/mydir/data.txt", "w");
    if(fp == NULL) {
        error("Could not open file for write\n");
    }
    fprintf(fp, buffer);
    fclose(fp);

    // if send is 1, send to desktop
    if (send) {
        pc.printf("%s", buffer);
    }

}


void writetest()
{
    uLCD.printf("starting test\r\n");
    char *buffer = "hello1";
    mkdir("/sd/mydir", 0777);
    FILE *fp = fopen("/sd/mydir/data.txt", "w");
    if(fp == NULL) {
        error("Could not open file for write\n");
    }
    fprintf(fp, buffer);
    fclose(fp);
    uLCD.printf("first opened\r\n");
    char *buffer2 = "good2";
    FILE *fq = fopen("/sd/mydir/data.txt", "w");
    if(fq == NULL) {
        error("Could not open file for write\n");
    }
    fprintf(fq, buffer2);
    fclose(fq);
    uLCD.printf("second opened\r\n");


    char open[10];
    FILE *fw = fopen("/sd/mydir/data.txt", "r");
    if(fw == NULL) {
        error("Could not open file to read\n");
    }
    fread(open,sizeof(open),8,fw);
    uLCD.printf("%s", open);
    uLCD.printf("should have printed\r\n");

}

// Function to play a sound file on speaker
void speak(int num)
{

    // Send Play Sound command
    easyVR.putc('w');
    // small delay is needed between characters
    wait(.002);
    // Sound table index
    easyVR.putc('A' + num/32);
    wait(.002);
    easyVR.putc('A' + num%32);
    wait(.002);
    // max volume
    easyVR.putc('P');
    // Wait for response of 'o' as playback ends
    while (easyVR.getc()!='o') {}
    wait(.25);
}

void synthesis(reminder x)
{
    uLCD.printf("speaking syn\n");
    if(x.notification == "App") {
        speak(synWords[3]);
        wait(0.001);
        synTimes(x);
    } else {
        //reminder
        int asking = 1;
        int result;
        int repeat = 0;
        int response = 0;
        while (asking) {
            speak(synWords[2]);
            wait(0.001);
            //ask if they've taken their medication
            speak(synWords[6]);
            wait(0.001);
            //intake and process yes/no response
            easyVR.putc('d');
            wait(.001);
            easyVR.putc('B');
            clock_t endwait;
            endwait = clock() + 60 * CLOCKS_PER_SEC ;
            while (easyVR.readable()!=0 && clock() < endwait) {}
            if (clock() < endwait) {
                response = 1;
                //asking = 0;
            } else {
                repeat++;
                if (repeat > 2) {
                    result = -1;
                    asking = 0;
                }
            }
            if (response) {
                char rchar=easyVR.getc();
                pc.putc(rchar);
                if (rchar == 'r') {
                    easyVR.putc(' ');
                    rchar = easyVR.getc();
                    //for a yes response
                    if (rchar=='A' || rchar=='C' || rchar=='E' || rchar=='G' || rchar == 'I' || rchar == 'K') {
                        uLCD.printf("yes");
                        //yes++;
                        //response++;
                        result = 1;
                    } else if (rchar == 'B' || rchar=='D' || rchar=='F' || rchar=='H' || rchar=='J' || rchar=='K') {
                        uLCD.printf("no");
                        result = 0;
                        //no++;
                        //response++;
                    }
                    asking = 0;
                    uLCD.printf("asking = 0\n");

                } else if (rchar == 'e') {
                    uLCD.printf("error");
                    result = -1;
                    repeat++;
                    if (repeat > 2) {
                        result = -1;
                        asking = 0;
                        // try again
                    }
                } else uLCD.printf("%c ",rchar);
            }
        }

        uLCD.printf("done\n");
        dateTime dt_record;
        dt_record.month = timeinfo->tm_mday;
        dt_record.day = timeinfo->tm_mon+1; // days since january (0-11) so add 1
        dt_record.year = timeinfo->tm_year + 1990; // years since 1990
        myschedule.updateRecord(dt_record, result);
        // do error checking for no response
        //thank the user
        speak(synWords[7]);
    }

    myled = 0;
    wait(0.001);

}

void synTimes(reminder x)
{
    uLCD.printf("speaking time\n");
    // schedule.reminder_list....
    // x is selected reminder
    //two switch case statements: one for if the second number is a 5, one if it's a 0
    int ampm = 0;
    int hour = x.hour;
    if(x.hour > 12) {
        hour = x.hour % 12;
        ampm = 24;
    } else
        ampm = 22;

    // need to add speaking hours?
    speak(synTime[hour-1]);
    wait(0.002);

    int minutes[2];
    minutes[0] = x.min/10;
    minutes[1] = x.min%10;

    switch(minutes[0]) {
        case 0:
            if (minutes[1] == 0) {
                // say "OH"
                // speak(synWords[1]);
                // wait(0.002);
                // say "o'clock"
                speak(synWords[0]);
                wait(0.002);
            }
            else {
                // say "OH"
                speak(synWords[1]);
                wait(0.002);
            }
            break;
        case 1:
            if (minutes[1] == 0) {
                speak(synTime[10-1]);
                wait(0.002);
            } else {
                //say "fifteen"
                speak(synTime[13-1]);
                wait(0.002);
            }
            break;
        case 2:
            //say "twenty"
            speak(synTime[17-1]);
            wait(0.002);
            break;
        case 3:
            //say "thirty"
            speak(synTime[16-1]);
            wait(0.002);
            break;
        case 4:
            //say "forty"
            speak(synTime[15-1]);
            wait(0.002);
            break;
        case 5:
            //say "fifty"
            speak(synTime[14-1]);
            wait(0.002);
            break;
    }
    if (minutes[0] != 1) {
        if (minutes[1] == 5) {
            //say "5"
            speak(synTime[5-1]);
            wait(0.002);
        }
    }
    speak(ampm);
    uLCD.printf("done speaking\n");
}
/*
void pb1_hit_callback (void) {
    uLCD.printf("push button pressed - receive schedule\n");
    receive_schedule();
}*/

void pb1_hit_interrupt (void)
{
    uLCD.printf("push button 1 pressed - send schedule\n");
    //receive_schedule();
    packdata(1);
}

void pb2_hit_interrupt (void)
{
    uLCD.printf("push button 2 pressed - cognitive game\n");
}


void cognitivegame()
{
    /*
    vector<string> wordset1;
    vector<string> wordset2;
    vector<string> wordset3;
    vector<string> wordset4;
    vector<string> wordset5;
    */
    int correct = 0;
    int timesplayed;
    uLCD.printf("Speak: Your recall wordset will now play\n");
    // speak(recall game)
    wait(3);

    int wordset = rand() % 5; // pick random wordset between 1 and 5

    uLCD.printf("Playing wordset %i\n", wordset);
    switch(wordset) {
        case 0: {
            //speak(wordset1);
            break;
        }
        case 1: {
            //speak(wordset2);
            break;
        }
        case 2: {
            //speak(wordset3);
            break;
        }
        case 3: {
            //speak(wordset4);
            break;
        }
        case 4: {
            //speak(wordset5);
            break;
        }
    }
    
    uLCD.printf("Was _____ the first word in the set?\n");
    uLCD.printf("Was _____ the last word in the set?\n");
}