ELEC351 SUBMISSION - Same as on the DLE

/media/uploads/Luka_Danilovic/elec_315_prototype_assembly.jpg

main/main.cpp

Committer:
Luka_Danilovic
Date:
2018-01-10
Revision:
0:c66224a27cf8

File content as of revision 0:c66224a27cf8:

#include "main.hpp" // Contains other HPP files and function prototypes (WITH INCLUSION SAFEGUARDS)


//**********************************SETUP*************************************//
C_sensorData sensorData;                    // Initialise samplingMaster
C_DT  Date_Time;                            // Initialise loggingMaster
circularBuffer buffer;                      // Initialise recordsMaster
TextLCD LCD(D9, D8, D7, D6, D4, D2);        // Initialise LCD driver
SDBlockDevice sd(PB_5, D12, D13, D10);      // Initialise SD card driver
Thread wdtThread(osPriorityNormal);         // Crate thread for WDT
Thread samplingThread (osPriorityRealtime); // Create thread for sampling
Thread puttyThread (osPriorityNormal);      // Create thread for PuTTY
Thread displayThread (osPriorityNormal);    // Create thread for LCD
Thread htmlThread (osPriorityNormal, OS_STACK_SIZE*2);  // Create thread for HTML
Thread sdcardThread (osPriorityNormal,OS_STACK_SIZE*2); // Create thread for sd card
Ticker samplingTick;                        // Create ticker for sampling
TDS_record  tempRec;                        // Create temporary storage (GLOBAL)
EthernetInterface eth;                      // Create eth interface (GLOBAL)
float interval;                             // Create sampling interval (GLOBAL)
bool wdtFlag;                               // Create wdt flag (GLOBAL)
bool state;                                 // Create sampling state (GLOBAL)
DigitalIn button(USER_BUTTON);              // Create D_in for blue button
DigitalOut greenLED(PB_11);                 // Create D_out for green LED
DigitalOut sdSatusLED(PE_15);               // Create D_out for white LED


//********************************FUNCTIONS***********************************//

void samplingISR()                          // Sampling interupt
{
    samplingThread.signal_set(GET_SAMPLE);  // Signal thread to sample
}


void samplingFunction()                     // Reads sensors and time
{
    while(true) {

        Thread::signal_wait(GET_SAMPLE);         // Wait on signal
        if (state == 1) {                            // If sampling on
            tempRec.record_Data = sensorData.read(); // Aquire sensors
            tempRec.record_DT = Date_Time.getDT();   // Aquire date and time
            buffer.write(tempRec);                   // Record sample
            Thread::signal_clr(GET_SAMPLE);          // Clear signal
            
            // Branch out when sampling is finished
            displayThread.signal_set(DISP_SAMPLE);   // Signal thread to display sample
            htmlThread.signal_set(HTML_SAMPLE);      // Signal thread to update webpage
            sdcardThread.signal_set(SD_SAMPLE);      // Signal thread to write to sd card
        }

        // WDT flag set
        wdtFlag = 1;
        
    }
}


void wdtFunction()          /* Simplest Watch Dog Timer that resets the system
                            if the sampling thread does not set a flag every
                            sampling interval                                 */
{
    while(true) {                           // Always perform check
        Thread::wait(interval*1000+5);      // Block (For lower plwer consumption) until ready to read
        if (wdtFlag == 0) {                 // If flag not set
            NVIC_SystemReset();;            // Reset chip
        } else {                            // else
            wdtFlag =0;                     // clear flag and loop
        }
    }
}

void displayFunction()                     // Displays sample to LCD & PuTTY
{
    while(true) {
        Thread::signal_wait(DISP_SAMPLE);  // Wait on signal
            buffer.read(0);                    // Read last record and diplay
            LCD.cls();                         // Clear LCD
            LCD.printf("Temp Press Light%.1f  %4.0f %.3f", tempRec.record_Data.temp, tempRec.record_Data.pres, tempRec.record_Data.ligt);
        Thread::signal_clr(DISP_SAMPLE);   // Clear signal
    }
}


void sdFunction()                           // Writes data to sd card
{
    Thread::wait(10);                       // Powerup time
    greenLED = 1;                           // Turn off at the start
    FILE* fp;                               // File pointer
    int batchCount;                         // Record grouping counter
    batchCount = 0;                         // Reset

    if ( sd.init() == 0) {                  // Check for initialisation
        FATFileSystem fs("sd", &sd);        // Create file system

        fp = fopen("/sd/records.txt","a");  // Open file for write

        if (fp != NULL) {                   // Check for sucess

            sdSatusLED = 0;                 // Turn on status LED (white)

            while(button ==0) {             // If dismounting

                batchCount++;
                Thread::signal_wait(SD_SAMPLE);  // Wait on signal

                TDS_record sdRec = tempRec; // Copy for safe storage

                // Write to file
                fprintf(fp, "\r Record number: %d \n\r", buffer.recNum()-1);
                fprintf(fp, " Date: %d.%d.%d \n\r", sdRec.record_DT.day, sdRec.record_DT.mnt, sdRec.record_DT.yr);
                fprintf(fp, " Time: %d:%d:%d \n\r", sdRec.record_DT.hr, sdRec.record_DT.min, sdRec.record_DT.sec);
                fprintf(fp, " Temperature = %1.2f  \n\r", sdRec.record_Data.temp);
                fprintf(fp, " Pressure    = %4.0f  \n\r", sdRec.record_Data.pres);
                fprintf(fp, " Light Level = %1.3f  \n\r", sdRec.record_Data.ligt);
                fprintf(fp, " \n\r \n\n");

                if (batchCount == 10) {                 // Save in batches of 10
                    batchCount =0;                      // Reset counter
                    fclose(fp);                         // Save & Close file
                    fp = fopen("/sd/records.txt","a");  // Open file for write
                }


                Thread::signal_clr(SD_SAMPLE);          // Clear signal

            }

            sdSatusLED = 1;              // Turn off status LED (white)
            fclose(fp);                  // Save & Close file
            sd.deinit();                 // Uninitialise sd card
            for (int i=0; i <5; i++) {   // Do 5 times
                greenLED = 0;
                wait(0.25);              // Flash LED at 4Hz
                greenLED = 1;
                wait(0.25);

            }
        }
    }
}




void htmlFunction() /* Creates and updates webpage. The code for setting up the
ethernet conection & server is from our lab tasks:
"https://os.mbed.com/teams/University-of-Plymouth-Stage-2-and-3/code/Task671-mbedos-FZ429-TCP-dynamic/file/76bd6f78cabc/main.cpp/" */
{
    TDS_record htmlRec;      /* Temporary storage that can be overwritten only
    when webpage is refreshed                                                 */

    // Config ethernet connection
    eth.set_network(IP, NETMASK, GATEWAY);
    eth.connect();

    TCPServer srv;           //TCP IP Server
    TCPSocket clt_sock;      //Socket for communication
    SocketAddress clt_addr;  //Address of incoming connection

    /* Open the server on ethernet stack */
    srv.open(&eth);

    /* Bind the HTTP port (TCP 80) to the server */
    srv.bind(eth.get_ip_address(), 80);

    /* Can handle 5 simultaneous connections */
    srv.listen(5);

    while(true) {

        using namespace std;
        //Block and wait on an incoming connection
        srv.accept(&clt_sock, &clt_addr);

        htmlRec = tempRec;      // Copy to safe storage for generating the html

        // Strings to store record parameters
        // Record number
        char Num[32];
        // Date
        char Date[32];
        // Time
        char Time[32];
        // Sensor data
        char Temp[32];
        char Pres[32];
        char Ligt[32];


        //Convert to a C String
        // Record number
        sprintf(Num, " <h1> Record Number: %d </h1> \n\r", buffer.recNum());
        // Date
        sprintf(Date, "<p> Date: %d.%d.%d </p> \n\r", htmlRec.record_DT.day, htmlRec.record_DT.mnt, htmlRec.record_DT.yr);
        // Time
        sprintf(Time, "<p> Time: %d:%d:%d </p> \n\n\r", htmlRec.record_DT.hr, htmlRec.record_DT.min, htmlRec.record_DT.sec);
        // Sensor Data
        sprintf(Temp, "<p> Temperature = %1.2f </p> \n\r", htmlRec.record_Data.temp);
        sprintf(Pres, "<p> Pressure    = %4.0f </p> \n\r", htmlRec.record_Data.pres);
        sprintf(Ligt, "<p> Light Level = %1.3f </p> \n\r", htmlRec.record_Data.ligt);

        //Uses a C++ string to make it easier to concatenate
        string webpage;

        //Build the C++ string webpage
        webpage = HTTP_HEADER;          // Header
        webpage += Num;                 // Record number
        webpage += Date;                // Record date
        webpage += Time;                // Record time
        webpage += Temp;                // Record temperature
        webpage += Pres;                // Record preassure
        webpage += Ligt;                // Record light level
        webpage += HTTP_FOOTER;         // Webpage

        //Send static HTML webpage (as a C string)
        clt_sock.send(webpage.c_str(), webpage.size()+8);

    }
}


void changeSamplingT(float interval)
{
    if (interval < (float)0.2) {
        interval = 0.2;                    // Max sampling interval 5Hz
    }
    samplingTick.detach();
    samplingTick.attach(&samplingISR, interval); //Dettach and Re-atttach ISR to ticker
}


//**********************************MAIN**************************************//
int main()
{
    state = 1;                             // Turn on sampling
    sdSatusLED = 1;                        // Turn sd card status LED off
    interval = 15;                          // Default sampling interval
    samplingTick.attach(&samplingISR, interval);  // Attach ISR
    wdtThread.start(wdtFunction);           // Start WTD thread
    samplingThread.start(samplingFunction); // Start sampling thread
    displayThread.start(displayFunction);   // Start display thread
    htmlThread.start(htmlFunction);         // Start HTML thread
    sdcardThread.start(sdFunction);         // Start sd card thread
    Date_Time.setD(10, 10, 2018);           // Set date to submission deadline
    Date_Time.setT(10, 00, 00);             // Set time to submission deadline
    LCD.printf("Hello, Waiting  on first sample"); // Show signs of life on LCD


    /*=========================== DEMO CODE ==================================*/
//    interval=1;                 // Set new interval to 1 sec
//    changeSamplingT(interval);  // Change the interval
//    Thread::wait(3000);         // Wait for 3 sample intervals
//    state = 0;                  // Turn off sampling
//    buffer.del(1);              // Delete record number 1
//    buffer.read(1);             // Read record number 1
//    Thread::wait(3000);         // Wait so user can see
//    buffer.delAll();            // Delete all records
//    Thread::wait(3000);         // Wait so user can see
//    buffer.readAll();           // Read all records
    /*======================= END OF DEMO CODE ===============================*/

    Thread::wait(osWaitForever);            /* Scheduler put thread to sleep
                                            untill interupt to sample occurs but
                                            function remains in scope         */
}