ELEC351 SUBMISSION - Same as on the DLE

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "main.hpp" // Contains other HPP files and function prototypes (WITH INCLUSION SAFEGUARDS)
00002 
00003 
00004 //**********************************SETUP*************************************//
00005 C_sensorData sensorData;                    // Initialise samplingMaster
00006 C_DT  Date_Time;                            // Initialise loggingMaster
00007 circularBuffer buffer;                      // Initialise recordsMaster
00008 TextLCD LCD(D9, D8, D7, D6, D4, D2);        // Initialise LCD driver
00009 SDBlockDevice sd(PB_5, D12, D13, D10);      // Initialise SD card driver
00010 Thread wdtThread(osPriorityNormal);         // Crate thread for WDT
00011 Thread samplingThread (osPriorityRealtime); // Create thread for sampling
00012 Thread puttyThread (osPriorityNormal);      // Create thread for PuTTY
00013 Thread displayThread (osPriorityNormal);    // Create thread for LCD
00014 Thread htmlThread (osPriorityNormal, OS_STACK_SIZE*2);  // Create thread for HTML
00015 Thread sdcardThread (osPriorityNormal,OS_STACK_SIZE*2); // Create thread for sd card
00016 Ticker samplingTick;                        // Create ticker for sampling
00017 TDS_record  tempRec;                        // Create temporary storage (GLOBAL)
00018 EthernetInterface eth;                      // Create eth interface (GLOBAL)
00019 float interval;                             // Create sampling interval (GLOBAL)
00020 bool wdtFlag;                               // Create wdt flag (GLOBAL)
00021 bool state;                                 // Create sampling state (GLOBAL)
00022 DigitalIn button(USER_BUTTON);              // Create D_in for blue button
00023 DigitalOut greenLED(PB_11);                 // Create D_out for green LED
00024 DigitalOut sdSatusLED(PE_15);               // Create D_out for white LED
00025 
00026 
00027 //********************************FUNCTIONS***********************************//
00028 
00029 void samplingISR()                          // Sampling interupt
00030 {
00031     samplingThread.signal_set(GET_SAMPLE);  // Signal thread to sample
00032 }
00033 
00034 
00035 void samplingFunction()                     // Reads sensors and time
00036 {
00037     while(true) {
00038 
00039         Thread::signal_wait(GET_SAMPLE);         // Wait on signal
00040         if (state == 1) {                            // If sampling on
00041             tempRec.record_Data = sensorData.read(); // Aquire sensors
00042             tempRec.record_DT = Date_Time.getDT();   // Aquire date and time
00043             buffer.write(tempRec);                   // Record sample
00044             Thread::signal_clr(GET_SAMPLE);          // Clear signal
00045             
00046             // Branch out when sampling is finished
00047             displayThread.signal_set(DISP_SAMPLE);   // Signal thread to display sample
00048             htmlThread.signal_set(HTML_SAMPLE);      // Signal thread to update webpage
00049             sdcardThread.signal_set(SD_SAMPLE);      // Signal thread to write to sd card
00050         }
00051 
00052         // WDT flag set
00053         wdtFlag = 1;
00054         
00055     }
00056 }
00057 
00058 
00059 void wdtFunction()          /* Simplest Watch Dog Timer that resets the system
00060                             if the sampling thread does not set a flag every
00061                             sampling interval                                 */
00062 {
00063     while(true) {                           // Always perform check
00064         Thread::wait(interval*1000+5);      // Block (For lower plwer consumption) until ready to read
00065         if (wdtFlag == 0) {                 // If flag not set
00066             NVIC_SystemReset();;            // Reset chip
00067         } else {                            // else
00068             wdtFlag =0;                     // clear flag and loop
00069         }
00070     }
00071 }
00072 
00073 void displayFunction()                     // Displays sample to LCD & PuTTY
00074 {
00075     while(true) {
00076         Thread::signal_wait(DISP_SAMPLE);  // Wait on signal
00077             buffer.read(0);                    // Read last record and diplay
00078             LCD.cls();                         // Clear LCD
00079             LCD.printf("Temp Press Light%.1f  %4.0f %.3f", tempRec.record_Data.temp, tempRec.record_Data.pres, tempRec.record_Data.ligt);
00080         Thread::signal_clr(DISP_SAMPLE);   // Clear signal
00081     }
00082 }
00083 
00084 
00085 void sdFunction()                           // Writes data to sd card
00086 {
00087     Thread::wait(10);                       // Powerup time
00088     greenLED = 1;                           // Turn off at the start
00089     FILE* fp;                               // File pointer
00090     int batchCount;                         // Record grouping counter
00091     batchCount = 0;                         // Reset
00092 
00093     if ( sd.init() == 0) {                  // Check for initialisation
00094         FATFileSystem fs("sd", &sd);        // Create file system
00095 
00096         fp = fopen("/sd/records.txt","a");  // Open file for write
00097 
00098         if (fp != NULL) {                   // Check for sucess
00099 
00100             sdSatusLED = 0;                 // Turn on status LED (white)
00101 
00102             while(button ==0) {             // If dismounting
00103 
00104                 batchCount++;
00105                 Thread::signal_wait(SD_SAMPLE);  // Wait on signal
00106 
00107                 TDS_record sdRec = tempRec; // Copy for safe storage
00108 
00109                 // Write to file
00110                 fprintf(fp, "\r Record number: %d \n\r", buffer.recNum()-1);
00111                 fprintf(fp, " Date: %d.%d.%d \n\r", sdRec.record_DT.day, sdRec.record_DT.mnt, sdRec.record_DT.yr);
00112                 fprintf(fp, " Time: %d:%d:%d \n\r", sdRec.record_DT.hr, sdRec.record_DT.min, sdRec.record_DT.sec);
00113                 fprintf(fp, " Temperature = %1.2f  \n\r", sdRec.record_Data.temp);
00114                 fprintf(fp, " Pressure    = %4.0f  \n\r", sdRec.record_Data.pres);
00115                 fprintf(fp, " Light Level = %1.3f  \n\r", sdRec.record_Data.ligt);
00116                 fprintf(fp, " \n\r \n\n");
00117 
00118                 if (batchCount == 10) {                 // Save in batches of 10
00119                     batchCount =0;                      // Reset counter
00120                     fclose(fp);                         // Save & Close file
00121                     fp = fopen("/sd/records.txt","a");  // Open file for write
00122                 }
00123 
00124 
00125                 Thread::signal_clr(SD_SAMPLE);          // Clear signal
00126 
00127             }
00128 
00129             sdSatusLED = 1;              // Turn off status LED (white)
00130             fclose(fp);                  // Save & Close file
00131             sd.deinit();                 // Uninitialise sd card
00132             for (int i=0; i <5; i++) {   // Do 5 times
00133                 greenLED = 0;
00134                 wait(0.25);              // Flash LED at 4Hz
00135                 greenLED = 1;
00136                 wait(0.25);
00137 
00138             }
00139         }
00140     }
00141 }
00142 
00143 
00144 
00145 
00146 void htmlFunction() /* Creates and updates webpage. The code for setting up the
00147 ethernet conection & server is from our lab tasks:
00148 "https://os.mbed.com/teams/University-of-Plymouth-Stage-2-and-3/code/Task671-mbedos-FZ429-TCP-dynamic/file/76bd6f78cabc/main.cpp/" */
00149 {
00150     TDS_record htmlRec;      /* Temporary storage that can be overwritten only
00151     when webpage is refreshed                                                 */
00152 
00153     // Config ethernet connection
00154     eth.set_network(IP, NETMASK, GATEWAY);
00155     eth.connect();
00156 
00157     TCPServer srv;           //TCP IP Server
00158     TCPSocket clt_sock;      //Socket for communication
00159     SocketAddress clt_addr;  //Address of incoming connection
00160 
00161     /* Open the server on ethernet stack */
00162     srv.open(&eth);
00163 
00164     /* Bind the HTTP port (TCP 80) to the server */
00165     srv.bind(eth.get_ip_address(), 80);
00166 
00167     /* Can handle 5 simultaneous connections */
00168     srv.listen(5);
00169 
00170     while(true) {
00171 
00172         using namespace std;
00173         //Block and wait on an incoming connection
00174         srv.accept(&clt_sock, &clt_addr);
00175 
00176         htmlRec = tempRec;      // Copy to safe storage for generating the html
00177 
00178         // Strings to store record parameters
00179         // Record number
00180         char Num[32];
00181         // Date
00182         char Date[32];
00183         // Time
00184         char Time[32];
00185         // Sensor data
00186         char Temp[32];
00187         char Pres[32];
00188         char Ligt[32];
00189 
00190 
00191         //Convert to a C String
00192         // Record number
00193         sprintf(Num, " <h1> Record Number: %d </h1> \n\r", buffer.recNum());
00194         // Date
00195         sprintf(Date, "<p> Date: %d.%d.%d </p> \n\r", htmlRec.record_DT.day, htmlRec.record_DT.mnt, htmlRec.record_DT.yr);
00196         // Time
00197         sprintf(Time, "<p> Time: %d:%d:%d </p> \n\n\r", htmlRec.record_DT.hr, htmlRec.record_DT.min, htmlRec.record_DT.sec);
00198         // Sensor Data
00199         sprintf(Temp, "<p> Temperature = %1.2f </p> \n\r", htmlRec.record_Data.temp);
00200         sprintf(Pres, "<p> Pressure    = %4.0f </p> \n\r", htmlRec.record_Data.pres);
00201         sprintf(Ligt, "<p> Light Level = %1.3f </p> \n\r", htmlRec.record_Data.ligt);
00202 
00203         //Uses a C++ string to make it easier to concatenate
00204         string webpage;
00205 
00206         //Build the C++ string webpage
00207         webpage = HTTP_HEADER;          // Header
00208         webpage += Num;                 // Record number
00209         webpage += Date;                // Record date
00210         webpage += Time;                // Record time
00211         webpage += Temp;                // Record temperature
00212         webpage += Pres;                // Record preassure
00213         webpage += Ligt;                // Record light level
00214         webpage += HTTP_FOOTER;         // Webpage
00215 
00216         //Send static HTML webpage (as a C string)
00217         clt_sock.send(webpage.c_str(), webpage.size()+8);
00218 
00219     }
00220 }
00221 
00222 
00223 void changeSamplingT(float interval)
00224 {
00225     if (interval < (float)0.2) {
00226         interval = 0.2;                    // Max sampling interval 5Hz
00227     }
00228     samplingTick.detach();
00229     samplingTick.attach(&samplingISR, interval); //Dettach and Re-atttach ISR to ticker
00230 }
00231 
00232 
00233 //**********************************MAIN**************************************//
00234 int main()
00235 {
00236     state = 1;                             // Turn on sampling
00237     sdSatusLED = 1;                        // Turn sd card status LED off
00238     interval = 15;                          // Default sampling interval
00239     samplingTick.attach(&samplingISR, interval);  // Attach ISR
00240     wdtThread.start(wdtFunction);           // Start WTD thread
00241     samplingThread.start(samplingFunction); // Start sampling thread
00242     displayThread.start(displayFunction);   // Start display thread
00243     htmlThread.start(htmlFunction);         // Start HTML thread
00244     sdcardThread.start(sdFunction);         // Start sd card thread
00245     Date_Time.setD(10, 10, 2018);           // Set date to submission deadline
00246     Date_Time.setT(10, 00, 00);             // Set time to submission deadline
00247     LCD.printf("Hello, Waiting  on first sample"); // Show signs of life on LCD
00248 
00249 
00250     /*=========================== DEMO CODE ==================================*/
00251 //    interval=1;                 // Set new interval to 1 sec
00252 //    changeSamplingT(interval);  // Change the interval
00253 //    Thread::wait(3000);         // Wait for 3 sample intervals
00254 //    state = 0;                  // Turn off sampling
00255 //    buffer.del(1);              // Delete record number 1
00256 //    buffer.read(1);             // Read record number 1
00257 //    Thread::wait(3000);         // Wait so user can see
00258 //    buffer.delAll();            // Delete all records
00259 //    Thread::wait(3000);         // Wait so user can see
00260 //    buffer.readAll();           // Read all records
00261     /*======================= END OF DEMO CODE ===============================*/
00262 
00263     Thread::wait(osWaitForever);            /* Scheduler put thread to sleep
00264                                             untill interupt to sample occurs but
00265                                             function remains in scope         */
00266 }
00267