GroupZ - 05012018 1511
main.cpp
- Committer:
- mslade
- Date:
- 2018-01-09
- Revision:
- 1:84581acd1333
- Parent:
- 0:1c898341428b
File content as of revision 1:84581acd1333:
#include "mbed.h" #include "lcdClass.h" #include "math.h" #include "SDBlockDevice.h" #include "FATFileSystem.h" #include "EthernetInterface.h" #include "TCPServer.h" #include "TCPSocket.h" #include "BMP280.h" #include <string> #include <iostream> #define HTTP_STATUS_LINE "HTTP/1.0 200 OK" #define HTTP_HEADER_FIELDS "Content-Type: text/html; charset=utf-8" #define HTTP_RESPONSE HTTP_STATUS_LINE "\r\n" \ HTTP_HEADER_FIELDS "\r\n" \ "\r\n" \ HTTP_MESSAGE_BODY "\r\n" #define IP "10.0.0.10" #define NETMASK "255.0.0.0" #define GATEWAY "10.0.0.1" //********************Variables and Initialisations****************************************// Serial myserial(USBTX,USBRX); lcdClass mylcd(D9,D8,D7,D6,D5,D4); DigitalOut leds(D11); InterruptIn SWi1(D1); InterruptIn SWi2(D0); InterruptIn SWi3(D2); AnalogIn ldrin(A0); int SW1 = 0; int SW2 = 0; int SW3 = 0; int record = 0; int serialmode = 0; int pcinput = 0; int lcdmode = 2; int datemode = 1; int y = 2015; int mon = 1; int d = 1; int h = 0; int minu = 0; Thread thread1, thread2, thread3, thread4, thread5, thread6; int serialcheck = 0; int samplerate = 1000; Semaphore mysem(10); char ldrString[10]; char tempString[10]; char presString[10]; BMP280 BMP(D14, D15); string database[5][120]; bool togPress = false; bool debugmode = false; bool data120 = false; bool switchactive = false; struct tm T; bool mainset = false; int SetDateTime(int year, int month, int day, int hour, int min); bool Pressed, Pressed1, yearPress, monPress, dayPress, hourPress, minPress = false; InterruptIn onBoardSwitch(USER_BUTTON); bool EditTimeParam = false; int TimeParam = 0; char Row1[32]; char Row2[32]; SDBlockDevice sd(PB_5, D12, D13, D10); FATFileSystem fs("sd", &sd); //set up SD void serialmenu(); void ratelimiter(); void clockz(); void showrecord(); //******************Variables and Initialisations*****************************************// void sensors(void const *name) { //This function is used to sample the sensors, control the serial menu and update the 2D array while(true) { mysem.wait(); Thread::wait(samplerate); //Set thread wait to the samplerate (default 1000ms) if (debugmode) {leds = 1;} //Turn on white LED time_t timer = time(NULL); //Set time to 0 strftime(Row1, 32, "%H:%M:%S", localtime(&timer));//Format Time as string strftime(Row2, 32, "%d/%m/%Y", localtime(&timer)); //Format Date as string float ldr = floor(ldrin*30000)/100; //Set ldr to ldr value to 2 decimal points float temp = BMP.getTemperature(); //Set temp to the BMP temperature float presh = BMP.getPressure() ; //Set presh to the BMP pressure sprintf(ldrString , "%2.2f", ldr); //Format ldr as string sprintf(tempString, "%2.2f", temp); //Format temp as string sprintf(presString, "%3.2f", presh); //Format pressure as string //Case statment for mode set by serial //0: Main, 1: live data, 2: show data, 3: delete data, 4: set samplerate, 5: set Time/date, 6: toggle debug, 7: show IP if (serialmode == 0 && mainset == false) {serialmenu(); mainset = true;} if (serialmode == 1 && mainset == false) {mainset = true; myserial.printf("ldr=%s temp=%s pres=%s \r\n", ldrString, tempString, presString); } if (serialmode == 2 && mainset == false) {showrecord(); mainset = true; } if (serialmode == 3 && mainset == false) {mainset = true; myserial.printf("Deleted all temp sensor data \r\n"); memset(database,0,sizeof(database));} if (serialmode == 4 && mainset == false) {ratelimiter(); mainset = true;} if (serialmode == 5 && mainset == false) {mainset = true; myserial.printf("Set Time/Date \r\n");} if (serialmode == 6 && mainset == false) {mainset = true; debugmode = !debugmode; if (debugmode) {myserial.printf("Debug on \r\n");} else {myserial.printf("Debug off \r\n");} } if (serialmode == 7 && mainset == false) {mainset = true; myserial.printf("IP: %s \r\n", IP);} //Update 2D array with data database[0][record] = ldrString; //Column 1: ldr data database[1][record] = tempString; //Column 2: temp data database[2][record] = presString; //Column 3: pressure data database[3][record] = Row1; database[4][record] = Row2; if (debugmode) {leds = 0;} //Turn off white led if (record > 119) {record = 0; data120 = true; } else { record += 1;} //Increment record counter mysem.release(); //Release thread. } } void showrecord(){ //This function is used to display the last 120 data entries on serial //Don't display the data until there is 120 data entries. if (data120 == false) {myserial.printf("Not enough records. Please wait %d seconds. \r\n", 120-record); serialmode = 0; mainset = false;} else { for(int i=record; i < 120; i++) { //Displays all the recent values from current record to 120 (FIFO buffer) string response; response = "Time:" ; response += database[3][i]; //Add time response += " Date:"; response += database[4][i]; //Add date response += " LDR:" ; response += database[0][i]; //Add LDR value response += " Temp:"; response += database[1][i]; //Add Temp value response += " Pres:"; response += database[2][i]; //Add pressure value response += "\r\n"; //Line return myserial.printf(response.c_str()); //Display Time, LDR, Temp, Press } for(int i = 0; i < record; i++){ //displays all the recent values from 0 to record (FIFO buffer) string response; response = "Time:" ; response += database[3][i]; //Add time response += " Date:"; response += database[4][i]; //Add date response += " LDR:" ; response += database[0][i]; //Add LDR value response += " Temp:"; response += database[1][i]; //Add Temp value response += " Pres:"; response += database[2][i]; //Add pressure value response += "\r\n"; //Line return myserial.printf(response.c_str()); //Display Time, LDR, Temp, Press } } } } void LCDupdate (void const *name){ //The purpose of this function is to update the LCD screen while (true) { mysem.wait(); Thread::wait(50); //Wait 50ms if (SW3 == 1) { if (togPress == false) { if (lcdmode == 2) {lcdmode = 1;} else {lcdmode += 1;} togPress = true; mylcd.cls(); } } else { togPress = false;} //Toggle mode if (lcdmode == 1) { clockz(); } //Display time if (lcdmode == 2) { //Display live sensor data mylcd.locate(9,1); mylcd.printf("L:%s ", ldrString); //Display LDR value mylcd.locate(0,1); mylcd.printf("T:%s ", tempString); //Display temp value mylcd.locate(4,0); mylcd.printf("P:%s ", presString); //Display pressure value } mysem.release(); //Release thread } } void enet(void const *name) //The purpose of this function is to set up and transmit data via ethernet { EthernetInterface eth; //Configure an ethernet connection eth.set_network(IP, NETMASK, GATEWAY); //Configure network eth.connect(); //Connect ethernet TCPServer srv; //Socket for communication SocketAddress clt_addr; //Address of incoming connection srv.open(ð); // Open the server on ethernet stack srv.bind(eth.get_ip_address(), 80); // Bind the HTTP port (TCP 80) to the server srv.listen(5); // Can handle 5 simultaneous connections while (true) { mysem.wait(); using namespace std; TCPSocket clt_sock; srv.accept(&clt_sock, &clt_addr); //This code sends the HTML website to the computer. string response; response = "<html> \r\n "; response += "<meta http-equiv=\"refresh\" content=\"1; url=http://10.0.0.10\">"; response += "\r\n <h1 style=\"color:black; font-size: 200%; position: fixed; top:17.5%; left:38%;\"> "; response += Row1; response += "</h1> \r\n <h1 style=\"color:black; font-size: 200%; position: fixed; top:17.5%; left:55.5%;\">"; response += Row2; response += "</h1> \r\n <h1 style=\"color:black; font-size: 400%; position: fixed; top:30%; left:46%;\">"; response += tempString; response += "</h1> \r\n <h1 style=\"color:black; font-size: 400%; position: fixed; top:51%; left:46%;\">"; response += ldrString; response += "</h1> \r\n <h1 style=\"color:black; font-size: 400%; position: fixed; top:72%; left:46%;\">"; response += presString; response += "</h1> \r\n <body style=\"background-image:url(https://image.ibb.co/nyTj9w/pic2.png); background-size: 100% 100%;\"></body> "; response += "\r\n </html>"; clt_sock.send(response.c_str(), response.size()+1); Thread::wait(samplerate); //Thread wait 10ms mysem.release(); //Release thread } } void serialin(void const *name){ //The purpose of this function is to handle the serial communication while (true) { mysem.wait(); Thread::wait(1000); //Thread wait 1000ms myserial.scanf("%d", &serialcheck); //Wait for command from serial if (serialmode != 5 && serialcheck == 9) {serialmode = 0; mainset = false;} //if command is 9 return to main menu else if (serialmode == 0) {serialmode = serialcheck; mainset = false; myserial.printf("press 9 to return to main menu\r\n");} else if (serialmode == 4) { //if the mode is set samplerate: if (serialcheck == 1) {samplerate = 100; } //Set samplerate to 0.1s if (serialcheck == 2) {samplerate = 1000;} //Set samplerate to 1s if (serialcheck == 3) {samplerate = 5000;} //Set samplerate to 5s if (serialcheck == 4) {samplerate = 10000;} //Set samplerate to 10s if (serialcheck == 5) {samplerate = 15000;} //Set samplerate to 15s if (serialcheck == 6) {samplerate = 30000;} //Set samplerate to 30s if (serialcheck == 7) {samplerate = 60000;} //Set samplerate to 60s if (serialcheck < 8 && serialcheck > 0) {myserial.printf("Sample rate set to %dms \r\n", samplerate); serialmode = 0; mainset = false;} } if (serialmode == 5) { //if the mode is set date/time if (mainset == false) {datemode = 1; mainset = true; } if (datemode == 1) { myserial.printf(" Set year: "); datemode++;} //set year else if (datemode == 2) { myserial.printf("%d \r\n Set month: ",serialcheck); y = serialcheck; datemode++;} //set month else if (datemode == 3) { myserial.printf("%d \r\n Set day: ",serialcheck); mon = serialcheck; datemode++;} //set day else if (datemode == 4) { myserial.printf("%d \r\n Set hour: ",serialcheck); d = serialcheck; datemode++;} //set hour else if (datemode == 5) { myserial.printf("%d \r\n Set minute: ", serialcheck); h = serialcheck; datemode++;} //set minute else {myserial.printf("%d \r\nDate set to: %d/%d/%d %d:%d \r\n", serialcheck,d, mon, y, h, serialcheck); minu = serialcheck; serialmode = 0;set_time(SetDateTime(y, mon, d, h, minu)); mainset = false;} } mysem.release(); } } void interrupts(void const *name){ //The purpose of this function is to wait for Interrupt-In's while (true) { mysem.wait(); Thread::wait(40); //Thread wait 40ms SW1 = SWi1; //Set SW1 SW2 = SWi2; //Set SW2 SW3 = SWi3; //Set SW3 mysem.release(); //Release thread } } void SDcard(void const *name){ while (true) { mysem.wait(); Thread::wait(samplerate); FILE* fp = fopen("/sd/test.txt","a"); //edit test.txt file string response; response = Row1; response += ","; //Add time response += Row2; response += ","; //Add date response += ldrString; response += ","; //Add ldr value response += tempString; response += ","; //Add temp value response += presString; response += "\r\n"; //Add pressure value fprintf(fp, response.c_str()); //Print response if (onBoardSwitch == 1) { //if switch is pressed start eject switchactive = true; } if (switchactive == true) { sd.deinit(); //eject SD } fclose(fp); //Close test.txt mysem.release(); } } int SetDateTime(int year, int month, int day, int hour, int min) { //The purpose of this function is to set the date and time T.tm_year = year - 1900; //Set year T.tm_mon = month - 1; //Set month T.tm_mday = day; //Set day T.tm_hour = hour; //Set hour T.tm_min = minu; //Set minute T.tm_sec = 0; //Set second return (mktime(&T)); } void clockz() { //The purpose of this function is to set the time on the LCD if ((SW1 == 1) && (SW2 == 1)) { //If both buttons pressed if (Pressed == false) { //if first time: EditTimeParam = not EditTimeParam; //Toggle mode if (EditTimeParam == false) { set_time(SetDateTime(y, mon, d, h, minu)); } //Set Datetime mylcd.cls(); //Clear LCD screen Pressed = true; } } else{ Pressed = false; } if (EditTimeParam == true) { if (SW1 == 1) { //if switch is pressed if (Pressed1 == false) { TimeParam++; //increment TimeParam for switch case mylcd.cls(); //Clear LCD screen Pressed1 = true; if (TimeParam > 4) {TimeParam = 0;} } } else { Pressed1 = false; } switch (TimeParam) { case 0: //Year if (SW2 == 1) { if (yearPress == false) { y++; yearPress = true; } } else { yearPress = false; } //Increment year if (y > 2030) { y = 2015; mylcd.cls(); } //If upper limit hit, reset to lower limit mylcd.locate(0, 0); mylcd.printf("Year: %d\n", y); //Display year break; case 1: //Month if (SW2 == 1) { if (monPress == false) { mon++; monPress = true; } } else { monPress = false; } //Increment month if (mon > 12) { mon = 1; mylcd.cls(); } //if upper limit hit, reset to lower limit mylcd.locate(0, 0); mylcd.printf("Month: %d\n", mon); //Display month break; case 2: //Day if (SW2 == 1) { if (dayPress == false) { d++; dayPress = true; } } else { dayPress = false; } //Increment day if ((mon == (4 || 6 || 9 || 11)) && (d > 30)) { d = 1; mylcd.cls(); } else if ((mon == 2) && (d > 28)) { d = 0; mylcd.cls(); } else if (d > 31) { d = 0; mylcd.cls(); } mylcd.locate(0, 0); mylcd.printf("Day: %d\n", d); //Display day break; case 3: //Hour if (SW2 == 1) { if (hourPress == false) { h++; hourPress = true; } } else { hourPress = false; } //Increment hour if (h > 23) { h = 0; mylcd.cls(); } //if upper limit hit, reset to lower limit mylcd.locate(0, 0); mylcd.printf("Hour: %d\n", h); //Display hour break; case 4: //Minute if (SW2 == 1) { if (minPress == false) { minu++; minPress = true; } } else { minPress = false; } //Increment minute if (minu > 59) { minu = 0; mylcd.cls(); } //if upper limit hit, reset to lower limit mylcd.locate(0, 0); mylcd.printf("Minute: %d\n", minu); //Display minute break; } } else { mylcd.locate(0, 0); mylcd.printf("%s", Row1); //Print Time on LCD, row 1 mylcd.locate(0, 1); mylcd.printf("%s", Row2); //Print Date on LCD, row 2 } } void serialmenu() { //The purpose of this function is to print the serial menu myserial.printf("Welcome to Group Z ELEC351 Coursework. Press 9 to start. \r\n"); myserial.printf("Please select (type in the number) an option: \r\n"); myserial.printf("1. Show live sensor data \r\n"); myserial.printf("2. Show old sensor data \r\n"); myserial.printf("3. delete all sensor data \r\n"); myserial.printf("4. Select sampling rate \r\n"); myserial.printf("5. Set time/date \r\n"); myserial.printf("6. Toggle debug \r\n"); myserial.printf("7. Show IP address \r\n"); } void ratelimiter() { //The purpose of this function is to print the samplerate options to the serial myserial.printf("Please select (type in the number) a sample rate: \r\n"); myserial.printf("1. 0.1s \r\n"); myserial.printf("2. 1s \r\n"); myserial.printf("3. 5s \r\n"); myserial.printf("4. 10s \r\n"); myserial.printf("5. 15s \r\n"); myserial.printf("6. 30s \r\n"); myserial.printf("7. 60s \r\n"); } int main(){ //The purpose of this function is to be the main code to run the threads. myserial.baud(115200); //Set serial speed to 115200 mylcd.cls(); //Clear LCD thread1.start(callback(enet, (void *) "Thread1\r\n")); // Start Ethernet thread thread2.start(callback(sensors, (void *) "Thread2\r\n")); // Start sensors thread thread3.start(callback(serialin,(void *) "Thread3\r\n")); // Start Serialin thread thread4.start(callback(interrupts,(void *) "Thread4\r\n")); // Start interrupts thread thread5.start(callback(LCDupdate,(void *) "Thread5\r\n")); // Start LCDupdate thread thread6.start(callback(SDcard,(void *) "Thread6\r\n")); // Start SDcard thread set_time(SetDateTime(y, mon, d, h, minu)); //Set DateTime }