Geolocation through Ethernet
Dependencies: mbed HTTPClient MMA8452Q mbed-rtos 4DGL-uLCD-SE NTPClient SDFileSystem1 EthernetInterface
main.cpp@3:65349fe42061, 2020-12-18 (annotated)
- Committer:
- stephenb
- Date:
- Fri Dec 18 19:36:51 2020 +0000
- Revision:
- 3:65349fe42061
- Parent:
- 1:b0c480b628cd
First Final Version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
stephenb | 0:070ff55a028f | 1 | #include "mbed.h" |
stephenb | 0:070ff55a028f | 2 | #include "NTPClient.h" |
stephenb | 0:070ff55a028f | 3 | #include "EthernetInterface.h" |
stephenb | 0:070ff55a028f | 4 | #include "HTTPClient.h" |
stephenb | 1:b0c480b628cd | 5 | #include "SDFileSystem.h" |
stephenb | 3:65349fe42061 | 6 | #include "MMA8452Q.h" |
stephenb | 3:65349fe42061 | 7 | #include "alarm.h" |
stephenb | 0:070ff55a028f | 8 | |
stephenb | 3:65349fe42061 | 9 | //Set up |
stephenb | 3:65349fe42061 | 10 | SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card |
stephenb | 3:65349fe42061 | 11 | MMA8452Q accel(p28, p27, 0x1D); //Accelerometer |
stephenb | 3:65349fe42061 | 12 | InterruptIn ain1(p16); //Temperature Sensor Interrupt |
stephenb | 3:65349fe42061 | 13 | AnalogIn ain(p15); //Temperature Sensor input |
stephenb | 0:070ff55a028f | 14 | HTTPClient httpClient; |
stephenb | 3:65349fe42061 | 15 | Thread thread; //Temperature check thread |
stephenb | 3:65349fe42061 | 16 | Thread accelerometer; //Accelerometer check thread |
stephenb | 3:65349fe42061 | 17 | Timer Clock; //Timer for timestamps |
stephenb | 3:65349fe42061 | 18 | |
stephenb | 0:070ff55a028f | 19 | |
stephenb | 0:070ff55a028f | 20 | void parse(char buffer[], int *j, char *string); //FUNCTION TO PARSE HTTP GET DATA |
stephenb | 1:b0c480b628cd | 21 | void sdlog(int type, float time, float input0, char input1[], char input2[], char input3[]); //Function to write to the SD card |
stephenb | 0:070ff55a028f | 22 | char httpGetData[200]; //BUFFER TO HOLD DATA FROM HTTP GET REQUEST |
stephenb | 3:65349fe42061 | 23 | int location(); //Function to get the location data |
stephenb | 3:65349fe42061 | 24 | void temperature(); //Outputs the temeprature to LCD and SD card |
stephenb | 3:65349fe42061 | 25 | void tempchange_thread(); //Temperature function to check value exceeds limits |
stephenb | 3:65349fe42061 | 26 | void accel_thread(); //Function to measure the accelerometer |
stephenb | 3:65349fe42061 | 27 | |
stephenb | 0:070ff55a028f | 28 | int main() { |
stephenb | 3:65349fe42061 | 29 | Clock.start(); //Start timer |
stephenb | 3:65349fe42061 | 30 | accel.init(); //initalize accelerometer |
stephenb | 3:65349fe42061 | 31 | thread.start(tempchange_thread); //Start temperature check thread |
stephenb | 3:65349fe42061 | 32 | accelerometer.start(accel_thread); //Start accelerometer thread |
stephenb | 3:65349fe42061 | 33 | ain1.rise(tempchange_thread); |
stephenb | 3:65349fe42061 | 34 | ain1.fall(tempchange_thread); |
stephenb | 3:65349fe42061 | 35 | |
stephenb | 3:65349fe42061 | 36 | |
stephenb | 3:65349fe42061 | 37 | |
stephenb | 0:070ff55a028f | 38 | //Display Settings |
stephenb | 0:070ff55a028f | 39 | uLCD.baudrate(115200); //Baudrate of display |
stephenb | 0:070ff55a028f | 40 | uLCD.cls(); //Clear uLCD screen |
stephenb | 3:65349fe42061 | 41 | uLCD.background_color(BLACK); //Background colour |
stephenb | 3:65349fe42061 | 42 | uLCD.color(WHITE); //Text colour |
stephenb | 3:65349fe42061 | 43 | |
stephenb | 3:65349fe42061 | 44 | |
stephenb | 3:65349fe42061 | 45 | while(true){ //Loop to control timing of temperature and location updates |
stephenb | 3:65349fe42061 | 46 | location(); |
stephenb | 3:65349fe42061 | 47 | for (int k = 0; k < 20; k++){ //Temperature fcn runs every 30 seconds, location fcn runs every 10 minutes |
stephenb | 3:65349fe42061 | 48 | temperature(); |
stephenb | 3:65349fe42061 | 49 | wait(30); //waits 30 seconds before running the fcn again |
stephenb | 3:65349fe42061 | 50 | } |
stephenb | 3:65349fe42061 | 51 | } |
stephenb | 3:65349fe42061 | 52 | } |
stephenb | 3:65349fe42061 | 53 | |
stephenb | 0:070ff55a028f | 54 | |
stephenb | 3:65349fe42061 | 55 | void parse(char buffer[], int *j, char *string) { |
stephenb | 3:65349fe42061 | 56 | //extracts next location string data item from buffer |
stephenb | 3:65349fe42061 | 57 | int i=0; |
stephenb | 3:65349fe42061 | 58 | for (i=0; i<=strlen(buffer); i++) { //TOTAL SIZE OF RETURNED DATA |
stephenb | 3:65349fe42061 | 59 | if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string |
stephenb | 3:65349fe42061 | 60 | //comma is the string field delimiter |
stephenb | 3:65349fe42061 | 61 | string[i]=0; //SETS END OF STRING TO 0 |
stephenb | 3:65349fe42061 | 62 | *j=*j+i+1; //UPDATES to 1 after comma seperated value |
stephenb | 3:65349fe42061 | 63 | break; |
stephenb | 3:65349fe42061 | 64 | } else string[i]=buffer[*j+i]; //Keep adding to the string |
stephenb | 3:65349fe42061 | 65 | } |
stephenb | 3:65349fe42061 | 66 | } |
stephenb | 3:65349fe42061 | 67 | |
stephenb | 3:65349fe42061 | 68 | void sdlog(int type, float time, float input0, char input1[], char input2[], char input3[]){ |
stephenb | 3:65349fe42061 | 69 | FILE *file; |
stephenb | 3:65349fe42061 | 70 | switch (type){ |
stephenb | 3:65349fe42061 | 71 | case 0: |
stephenb | 3:65349fe42061 | 72 | file = fopen("/sd/location.txt", "w"); |
stephenb | 3:65349fe42061 | 73 | fprintf(file, "TIME: %f, Latitude: %s Longitude: %s, City: %s\n\r", time, input1, input2, input3); |
stephenb | 3:65349fe42061 | 74 | fclose(file); |
stephenb | 3:65349fe42061 | 75 | break; |
stephenb | 3:65349fe42061 | 76 | case 1: |
stephenb | 3:65349fe42061 | 77 | file = fopen("/sd/temperature.txt", "w"); |
stephenb | 3:65349fe42061 | 78 | fprintf(file, "TIME: %f, %f degC\n\r", time, input0); |
stephenb | 3:65349fe42061 | 79 | fclose(file); |
stephenb | 3:65349fe42061 | 80 | break; |
stephenb | 3:65349fe42061 | 81 | case 2: |
stephenb | 3:65349fe42061 | 82 | file = fopen("/sd/acceleration.txt", "w"); |
stephenb | 3:65349fe42061 | 83 | fprintf(file, "TIME: %f, WARNING: LOAD EXCEDDED MAXIMUM ALLOWED ANGLE\n\r", time); |
stephenb | 3:65349fe42061 | 84 | fclose(file); |
stephenb | 3:65349fe42061 | 85 | break; |
stephenb | 3:65349fe42061 | 86 | default: |
stephenb | 3:65349fe42061 | 87 | break; |
stephenb | 3:65349fe42061 | 88 | } |
stephenb | 3:65349fe42061 | 89 | } |
stephenb | 3:65349fe42061 | 90 | |
stephenb | 3:65349fe42061 | 91 | int location(){ |
stephenb | 0:070ff55a028f | 92 | eth.init(); //USE DHCP to get local IP address |
stephenb | 0:070ff55a028f | 93 | eth.connect(); //Connect to the network |
stephenb | 0:070ff55a028f | 94 | |
stephenb | 0:070ff55a028f | 95 | char success[10]={0}; //success first |
stephenb | 0:070ff55a028f | 96 | char countryFull[20]={0}; //Full Country Name |
stephenb | 0:070ff55a028f | 97 | char countryAbrv[5]={0}; //Abbreviated Country Name or country Code |
stephenb | 0:070ff55a028f | 98 | char stateAbrv[5]={0}; //Abbreviated State or region code |
stephenb | 0:070ff55a028f | 99 | char stateFull[15]={0}; //Full State Name |
stephenb | 0:070ff55a028f | 100 | char city[15]={0}; //City Name |
stephenb | 0:070ff55a028f | 101 | char zip[6]={0}; //ZIP CODE |
stephenb | 0:070ff55a028f | 102 | char latitude[10]={0}; //latitude |
stephenb | 0:070ff55a028f | 103 | char longitude[10]={0}; //longitude |
stephenb | 0:070ff55a028f | 104 | char timeZone[30]={0}; //timeZone |
stephenb | 0:070ff55a028f | 105 | int j=0; |
stephenb | 0:070ff55a028f | 106 | HTTPResult r = httpClient.get("http://ip-api.com/csv",httpGetData,128); //GET GEOLOCATION DATA (CSV) |
stephenb | 0:070ff55a028f | 107 | |
stephenb | 0:070ff55a028f | 108 | if (r==HTTP_OK) { //IF THE DATA WAS RECIEVED |
stephenb | 0:070ff55a028f | 109 | j=0; |
stephenb | 0:070ff55a028f | 110 | //parse and display each of the API's location information strings on the LCD |
stephenb | 0:070ff55a028f | 111 | parse(httpGetData, &j, success); |
stephenb | 0:070ff55a028f | 112 | parse(httpGetData,&j,countryFull); |
stephenb | 0:070ff55a028f | 113 | parse(httpGetData,&j,countryAbrv); |
stephenb | 0:070ff55a028f | 114 | parse(httpGetData,&j,stateAbrv); |
stephenb | 0:070ff55a028f | 115 | parse(httpGetData,&j,stateFull); |
stephenb | 0:070ff55a028f | 116 | parse(httpGetData,&j,city); |
stephenb | 0:070ff55a028f | 117 | parse(httpGetData,&j,zip); |
stephenb | 0:070ff55a028f | 118 | parse(httpGetData,&j,latitude); |
stephenb | 0:070ff55a028f | 119 | parse(httpGetData,&j,longitude); |
stephenb | 0:070ff55a028f | 120 | parse(httpGetData,&j,timeZone); |
stephenb | 0:070ff55a028f | 121 | } |
stephenb | 0:070ff55a028f | 122 | else { //HTTP GET REQUEST ERRORED |
stephenb | 0:070ff55a028f | 123 | uLCD.cls(); |
stephenb | 0:070ff55a028f | 124 | uLCD.printf("HTTP Error %d", r); |
stephenb | 0:070ff55a028f | 125 | return -1; |
stephenb | 0:070ff55a028f | 126 | } |
stephenb | 3:65349fe42061 | 127 | sdlog(0, Clock.read(), 2, latitude, longitude, city);// Save info to SD card |
stephenb | 3:65349fe42061 | 128 | eth.disconnect(); //DISCONNECT FROM THE NETWORK |
stephenb | 3:65349fe42061 | 129 | //Print Location Information |
stephenb | 0:070ff55a028f | 130 | uLCD.locate(0,0); |
stephenb | 3:65349fe42061 | 131 | uLCD.textbackground_color(BLACK); |
stephenb | 0:070ff55a028f | 132 | uLCD.printf("%s, %s\n",city,countryFull); //Print City and Country |
stephenb | 0:070ff55a028f | 133 | uLCD.printf("LAT:%s\nLONG:%s\n",latitude,longitude); //LATITUDE AND LONGITUDE |
stephenb | 3:65349fe42061 | 134 | return 1; |
stephenb | 3:65349fe42061 | 135 | } |
stephenb | 3:65349fe42061 | 136 | |
stephenb | 3:65349fe42061 | 137 | |
stephenb | 3:65349fe42061 | 138 | |
stephenb | 3:65349fe42061 | 139 | void accel_thread(){ |
stephenb | 3:65349fe42061 | 140 | |
stephenb | 3:65349fe42061 | 141 | float X=accel.readX(); |
stephenb | 3:65349fe42061 | 142 | float Y=accel.readY(); |
stephenb | 3:65349fe42061 | 143 | |
stephenb | 3:65349fe42061 | 144 | while(true){ |
stephenb | 3:65349fe42061 | 145 | if((X <-0.6 && X>=-0.9)||(X >0.6&&X<=0.9)||(Y <-0.6 && Y>=-0.9)||(Y >0.6 && Y<=0.9)){ |
stephenb | 3:65349fe42061 | 146 | uLCD.textbackground_color(RED); |
stephenb | 3:65349fe42061 | 147 | uLCD.locate(0, 5); // setting cursor on LED |
stephenb | 3:65349fe42061 | 148 | uLCD.printf("WARNING"); |
stephenb | 3:65349fe42061 | 149 | uLCD.locate(0,6); |
stephenb | 3:65349fe42061 | 150 | uLCD.printf("CONTAINER UNSTABLE"); |
stephenb | 3:65349fe42061 | 151 | uLCD.locate(0,7); |
stephenb | 3:65349fe42061 | 152 | uLCD.printf("CHECK CONTAINER"); |
stephenb | 3:65349fe42061 | 153 | } |
stephenb | 3:65349fe42061 | 154 | else if ((X<-0.9)||(X>0.9)||(Y<-0.9)||(Y>0.9)){ |
stephenb | 3:65349fe42061 | 155 | soundalarm(); //Sounds alarm |
stephenb | 3:65349fe42061 | 156 | sdlog(2, Clock.read(), 0,0,0,0); //Records tipping to SD card with timestamp |
stephenb | 3:65349fe42061 | 157 | uLCD.textbackground_color(RED); |
stephenb | 3:65349fe42061 | 158 | uLCD.locate(0,5); // Move cursor |
stephenb | 3:65349fe42061 | 159 | uLCD.printf("WARNING"); |
stephenb | 3:65349fe42061 | 160 | uLCD.locate(0,6); |
stephenb | 3:65349fe42061 | 161 | uLCD.printf("CONTAINER INVERTED"); |
stephenb | 3:65349fe42061 | 162 | uLCD.locate(0,7); |
stephenb | 3:65349fe42061 | 163 | uLCD.textbackground_color(BLUE); |
stephenb | 3:65349fe42061 | 164 | uLCD.printf("Press to clear"); |
stephenb | 3:65349fe42061 | 165 | } |
stephenb | 3:65349fe42061 | 166 | else{ |
stephenb | 3:65349fe42061 | 167 | uLCD.textbackground_color(BLACK); |
stephenb | 3:65349fe42061 | 168 | uLCD.locate(0,5); // setting cursor on LED |
stephenb | 3:65349fe42061 | 169 | uLCD.printf("--------------"); |
stephenb | 3:65349fe42061 | 170 | uLCD.locate(0,6); |
stephenb | 3:65349fe42061 | 171 | uLCD.printf("Container Stable"); |
stephenb | 3:65349fe42061 | 172 | uLCD.locate(0,7); |
stephenb | 3:65349fe42061 | 173 | uLCD.printf("--------------"); |
stephenb | 3:65349fe42061 | 174 | } |
stephenb | 3:65349fe42061 | 175 | } |
stephenb | 3:65349fe42061 | 176 | } |
stephenb | 3:65349fe42061 | 177 | |
stephenb | 1:b0c480b628cd | 178 | |
stephenb | 3:65349fe42061 | 179 | void tempchange_thread(){ //Constantly checking if temperature goes above 20C |
stephenb | 3:65349fe42061 | 180 | |
stephenb | 3:65349fe42061 | 181 | float tempnotright; |
stephenb | 3:65349fe42061 | 182 | float change; |
stephenb | 3:65349fe42061 | 183 | change = ain1.read() * 3.3; |
stephenb | 3:65349fe42061 | 184 | tempnotright = (change - 0.5) * 100.0; |
stephenb | 3:65349fe42061 | 185 | |
stephenb | 3:65349fe42061 | 186 | if (tempnotright > 20) { |
stephenb | 3:65349fe42061 | 187 | uLCD.locate(0,9); |
stephenb | 3:65349fe42061 | 188 | uLCD.textbackground_color(BLACK); |
stephenb | 3:65349fe42061 | 189 | uLCD.printf("%fs: %f C", Clock.read(), tempnotright); |
stephenb | 3:65349fe42061 | 190 | uLCD.locate(0,10); |
stephenb | 3:65349fe42061 | 191 | uLCD.textbackground_color(RED); |
stephenb | 3:65349fe42061 | 192 | uLCD.printf("CORRECTION NEEDED!"); |
stephenb | 3:65349fe42061 | 193 | soundalarm(); |
stephenb | 3:65349fe42061 | 194 | sdlog(1, Clock.read(), tempnotright,0,0,0); |
stephenb | 3:65349fe42061 | 195 | } |
stephenb | 3:65349fe42061 | 196 | Thread:: wait(5); |
stephenb | 0:070ff55a028f | 197 | } |
stephenb | 1:b0c480b628cd | 198 | |
stephenb | 3:65349fe42061 | 199 | |
stephenb | 3:65349fe42061 | 200 | void temperature(){ //Sort LCD |
stephenb | 3:65349fe42061 | 201 | float voltage_in; |
stephenb | 3:65349fe42061 | 202 | float degrees_c; |
stephenb | 3:65349fe42061 | 203 | int i; |
stephenb | 3:65349fe42061 | 204 | for(i = 0; i < 1000; i++) { |
stephenb | 3:65349fe42061 | 205 | voltage_in = ain * 3.3; |
stephenb | 3:65349fe42061 | 206 | degrees_c = (voltage_in - 0.5) * 100.0; |
stephenb | 3:65349fe42061 | 207 | uLCD.locate(0,9); |
stephenb | 3:65349fe42061 | 208 | uLCD.textbackground_color(BLACK); |
stephenb | 3:65349fe42061 | 209 | uLCD.printf("%fs: %f C", Clock.read(), degrees_c); |
stephenb | 3:65349fe42061 | 210 | |
stephenb | 3:65349fe42061 | 211 | if(degrees_c <= 20){ //Correct Temp Range |
stephenb | 3:65349fe42061 | 212 | sdlog(1, Clock.read(), degrees_c,0,0,0); |
stephenb | 3:65349fe42061 | 213 | uLCD.locate(0,10); |
stephenb | 3:65349fe42061 | 214 | uLCD.textbackground_color(GREEN); |
stephenb | 3:65349fe42061 | 215 | uLCD.printf("Correct Temperature"); |
stephenb | 3:65349fe42061 | 216 | |
stephenb | 3:65349fe42061 | 217 | } |
stephenb | 3:65349fe42061 | 218 | else{ //Incorrect Temp Range |
stephenb | 3:65349fe42061 | 219 | soundalarm(); |
stephenb | 3:65349fe42061 | 220 | sdlog(1, Clock.read(), degrees_c,0,0,0); |
stephenb | 3:65349fe42061 | 221 | uLCD.textbackground_color(RED); |
stephenb | 3:65349fe42061 | 222 | uLCD.locate(0,10); |
stephenb | 3:65349fe42061 | 223 | uLCD.printf("CORRECTION NEEDED!"); |
stephenb | 3:65349fe42061 | 224 | } |
stephenb | 3:65349fe42061 | 225 | } |
stephenb | 3:65349fe42061 | 226 | } |