1

Dependencies:   mbed SDFileSystem ds3231

main.cpp

Committer:
sixto94
Date:
2019-01-08
Revision:
0:8b72e62543ea

File content as of revision 0:8b72e62543ea:

/******************************************************** 
 * Real Time Clock
 * By Mollie Coleman - University of Bath, 2018
 *  
 * This code uses a pre-defined library created
 * by Justin Jordan which has specified functions
 * that can be used to set the time and access it
 *
 * Hardware:
 *     1. mbed LPC1768
 *     2. DS3231MPMB1 Peripheral Module
 *     3. CR1025 Battery
 *     4. 4x Jumper Cables
 *
 * Connectivity: (RTC --> mbed)
 *     J1-3 SCL --> P27
 *     J1-4 SDA --> P28
 *     J1-5 GND --> GND
 *     J1-6 VCC --> VOUT
 *
 * References: 
 *     1. https://os.mbed.com/components/DS3231/
 *     2. https://os.mbed.com/users/techstep/code
 *               /DS3231/file/1607610a4ee9/DS3231.cpp/
 *     3. https://os.mbed.com/handbook/Timer
 ********************************************************/

/*********************************** 
 * Importing of the required libs  *
 ***********************************/
#include "ds3231.h"
#include "iostream"
#include "SDFileSystem.h"
#include "string"
#include "sstream"
#include "inttypes.h"
#include "stdio.h"
#define ESC 0x1B
#define PRIx16 "hx"

/************************************ 
 * Defining the ports that the RTC  *
 * and SD reader is attatched to.   *
 ************************************/
Ds3231 rtc(p28, p27);
SDFileSystem sd (p5, p6, p7, p8, "sd");

/************************************
 * Creating a timer variable to be  * 
 * used to deal with the time taken *
 * to save the data                 *
 ************************************/
Timer t;

/************************************
 * This can be updated for more     *
 * variables, or change the type to *
 * suit the needs. These are the    *
 * variables to be stored in on the *
 * SD card in a .txt file           * 
 ************************************/
float temperature = 0.0;
float uvData = 0.0;
float LUXData = 0.0;
char buffer[12];
    
/********************************************************
 * settingCalTimeVal Funtion
 *
 * Parameters:
 *     1. ds3231_time_t rtc_time
 *     2. ds3231_calendar_t rtc_calendar
 *
 * This funtion is only used when the time 
 * needs to be set for the first time. Once
 * done, this is no longer required as the 
 * time and date is stored and the RTC keeps 
 * it up to date. 
 *
 * The data is stored in a tempoary variable,
 * temp. A pointer is used and assigned the 
 * reference point for that specific piece 
 * of data.The vale of temp is then stored 
 * at that location in memory. 
 *
 * Once all the assigning and storing of data 
 * is complete, the time and data are set and 
 * stored indefinitely.
 *
 * rtc.set_time() <- Function defined in ds3231.cpp
 * rtc.set_calendar() <- Function defined in ds3231.cpp
 *     If the time/date cannot be set, the function will
 *     return 1, where the code is then terminated.
 *
 * (If the time needs to be updated, the numbers in the 
 *  below can be altered accordingly)
 ********************************************************/
void settingCalTimeVal(ds3231_time_t rtc_time, ds3231_calendar_t rtc_calendar)
{
    uint32_t temp;
    uint32_t* mem;
    bool* mem2;
    
    temp = 17;
    mem = &rtc_time.hours;
    *mem = temp;
    
    temp = 30;
    mem = &rtc_time.minutes;
    *mem = temp;
    
    temp = 30;
    mem = &rtc_time.seconds;
    *mem = temp;
    
    temp = 0;
    mem2 = &rtc_time.mode;
    *mem2 = temp;
    
    temp = 2;
    mem = &rtc_calendar.day;
    *mem = temp;
    
    temp = 06;
    mem = &rtc_calendar.date;
    *mem = temp;
    
    temp = 11;
    mem = &rtc_calendar.month;
    *mem = temp;
    
    temp = 18;
    mem = &rtc_calendar.year;
    *mem = temp;
    
    //Setting the time/date and storing it       
    if(rtc.set_time(rtc_time) || rtc.set_calendar(rtc_calendar))
    {
        printf("uh oh");
        exit(0); //terminates the program
    }
}

/*
 * Converts the input into a type String
 */
template <typename T>
std::string to_string(T value)
{
    std::ostringstream os;
    os << value ;
    return os.str() ;
}

/***********************************************************
 * Main Function
 * 
 * Calls the function that sets the time it it is needed, 
 * else it is commented out and the time is retrieved. 
 *
 * rtc.get_time() <- Function defined in ds3231.cpp
 * rtc.get_calendar() <- Function defined in ds3231.cpp
 *     These are called if the time has already been
 *     set and we do not want to over-write what has
 *     been stored in the memory.
 *
 * When the mbed is disconencted, it will continue to  
 * run and update the time. This means, when re-attatched
 * the time is what it should be, not the last time it was
 * when it was switched off.  
 ************************************************************/
int main(void)
{
    time_t epoch_time;

    /* default, use bit masks in ds3231.h for desired operation */
    ds3231_cntl_stat_t rtc_control_status = {0,0}; 
    ds3231_time_t rtc_time;
    ds3231_calendar_t rtc_calendar;
    rtc.set_cntl_stat_reg(rtc_control_status);
    
    /* Uncomment if you want to set the time */
    //settingCalTimeVal(rtc_time, rtc_calendar);
    
    rtc.get_time(&rtc_time);
    rtc.get_calendar(&rtc_calendar);    
    //std::string CalendarResult = to_string((uint16_t)dates);
    //printf("Cal: %lu", (unsigned long)dates);
    
    /* 
     * This if statement checks to see if there is a directory already made on the
     * sd card and if there is not, then it will create the wanted directory. This
     * means that any SD card that is plugged in will have this directory created 
     * automatically. 
     */
    DIR* dir = opendir("/sd/data");
    if(dir)
    {
        printf("The directory already exits");  
    }
    else
    {
        mkdir("/sd/data", 0777);
        printf("The directory has been created on the SD card");
    }
    
    /*
     * This section deals with the setting of the file name to be the date. This
     * is also where the data is stored into the file, in a specific format. 
     */
    epoch_time = rtc.get_epoch();
    strftime(buffer, 32, "%I:%M:%S", localtime(&epoch_time));
    
    struct tm tm = *localtime(&epoch_time);
    double date  = tm.tm_mday;
    double month = tm.tm_mon + 1;
    double year  = tm.tm_year + 1900;
    std::string dateS = to_string(date);
    std::string monthS = to_string(month);
    std::string yearS = to_string(year);
    
    //Setting the filename to be the date in the format date-month-year
    std::string fileNameS = "/sd/data/" + dateS + "-" + monthS + "-" + yearS + ".txt";
    const char *fileNameC = fileNameS.c_str();
    FILE *out_file = fopen(fileNameC, "w");
    
    if(out_file == NULL)
    {
        error("Could not open file for write\n");
    }
    
    fseek(out_file, 0, SEEK_END); // goto end of file
    if(ftell(out_file) == 0)
    {
        fprintf(out_file, "-----------------------------------------------\r\n|   Time   | Temperature | UV Data | LUX Data |\r\n-----------------------------------------------\r\n");
    }
    
    if(temperature != 0 && uvData != 0 && LUXData != 0)
    {
        fseek(out_file, 0, SEEK_END);
        epoch_time = rtc.get_epoch();
        strftime(buffer, 32, "%I:%M:%S %p\n", localtime(&epoch_time));
        
        fprintf(out_file, "|    %s    |    %f    | UV Data | LUX Data |\r\n-----------------------------------------------\r\n", buffer, temperature);
    }
    printf("Finished writing to the file");
    fclose(out_file);
}