Luka Danilovic
/
ELEC351_10497267_SUBMISSION
ELEC351 SUBMISSION - Same as on the DLE
Diff: main/main.cpp
- Revision:
- 0:c66224a27cf8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/main.cpp Wed Jan 10 09:49:43 2018 +0000 @@ -0,0 +1,267 @@ +#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 */ +} +