GroupZ - 05012018 1511
Diff: main.cpp
- Revision:
- 1:84581acd1333
- Parent:
- 0:1c898341428b
--- a/main.cpp Fri Jan 05 15:10:50 2018 +0000 +++ b/main.cpp Tue Jan 09 14:53:07 2018 +0000 @@ -1,6 +1,8 @@ #include "mbed.h" -#include "TextLCD.h" +#include "lcdClass.h" #include "math.h" +#include "SDBlockDevice.h" +#include "FATFileSystem.h" #include "EthernetInterface.h" #include "TCPServer.h" #include "TCPSocket.h" @@ -17,98 +19,309 @@ #define IP "10.0.0.10" #define NETMASK "255.0.0.0" #define GATEWAY "10.0.0.1" - - -BMP280 BMP(D14, D15); -Serial myserial(USBTX,USBRX); -TextLCD mylcd(D9,D8,D7,D6,D5,D4); -BusOut leds(D11,D12); -DigitalIn toggle(D2); -bool pressed = false; -int counter = 0; -AnalogIn ldrin(A0); -Thread thread; -Thread thread2; -Semaphore mysem(10); -char buffer[10]; -char buffer2[10]; -char buffer3[10]; -void enet(void const *name); +//********************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*****************************************// -int main(){ - myserial.baud(115200); - mylcd.cls(); - thread.start(callback(enet, (void *) "Thread\r\n")); - while(true) { +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(); - leds = 1; - float ldr = floor(ldrin*30000)/100; - float temp = BMP.getTemperature(); - float pressure = BMP.getPressure() ; - //if (counter > 7) {counter = 0;} - //leds = counter; - //if (toggle == false) {if (pressed == false) {counter++; pressed = true;} } else {pressed = false;} - //int x = floor(ldr*8); - //leds = counter; - sprintf(buffer , "%2.2f", ldr); - sprintf(buffer2, "%2.2f", temp); - sprintf(buffer3, "%3.2f", pressure); - mylcd.locate(9,1); mylcd.printf("L:%s ", buffer ); - mylcd.locate(0,1); mylcd.printf("T:%s ", buffer2); - mylcd.locate(4,0); mylcd.printf("P:%s ", buffer3); - myserial.printf("ldr=%s temp=%s pres=%s \r\n", buffer, buffer2, buffer3); + 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 - Thread::wait(1000); - leds = 0; - mysem.release(); + //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 { - //Configure an ethernet connection - EthernetInterface eth; - eth.set_network(IP, NETMASK, GATEWAY); - eth.connect(); - printf("The target IP address is '%s'\n", eth.get_ip_address()); - - //Now setup a web server - 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); - + 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: 400%; position: fixed; top:11%; left:37%;\"> "; - response += "16:34"; + 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 += "31/12/2017"; + response += Row2; response += "</h1> \r\n <h1 style=\"color:black; font-size: 400%; position: fixed; top:30%; left:46%;\">"; - response += buffer; + response += tempString; response += "</h1> \r\n <h1 style=\"color:black; font-size: 400%; position: fixed; top:51%; left:46%;\">"; - response += buffer2; + response += ldrString; response += "</h1> \r\n <h1 style=\"color:black; font-size: 400%; position: fixed; top:72%; left:46%;\">"; - response += buffer3; + 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(10); + 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 } \ No newline at end of file