Luka Danilovic
/
ELEC351_10497267_SUBMISSION
ELEC351 SUBMISSION - Same as on the DLE
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(ð); /* 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 */ }