Senses an earthquake with MPU6050 and gets time, coordenates and other details of the event with an Adafruit GPS. All the info is sent to an HTTP server
Dependencies: MPU6050 mbed-http MBed_Adafruit-GPS-Library
source/main.cpp
- Committer:
- Alvaro13
- Date:
- 2019-08-01
- Revision:
- 37:fcb5efa391d5
- Parent:
- 36:32a0a71555f0
- Child:
- 38:0813e461b835
File content as of revision 37:fcb5efa391d5:
#include "mbed.h" #include "MPU6050.h" #include "REF_VALUES.h" #include "CONSTANTS.h" #include "FUNCTIONS.h" #include "Timer.h" #include "MBed_Adafruit_GPS.h" #include "http_request.h" #include "network-helper.h" #include "mbed_mem_trace.h" /** * Debbuging led */ DigitalOut myled(LED1); /** * Puerto serial */ Serial pc(USBTX, USBRX, BAUD_RATE); /** * Puntero hacia el puerto serial utilizado para la comunicacion entre el GPS y el Micro */ Serial * gps_Serial; /** * Objeto MPU6050 */ MPU6050 mpu(PF_15, PF_14); /** * Threads */ Thread sampleAccelero; Thread printDebug; Thread sendAccelero; Thread getCoordinates; /** * Mutex */ Mutex semaforo; Mutex globalVar; /** * Mailboxes */ Mail<acceleration, 1> mail_box; Mail<acceleration, 1> mail_meass; /** * Variables de control */ bool earthquakeHappening = false; bool beenHere = false; /** * Handler para la utilizacion del GPS */ Adafruit_GPS myGPS(new Serial(PC_12, PD_2)); //object of Adafruit's GPS class /** * Codigo para el HTTP post */ void dump_response(HttpResponse* res) { printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str()); printf("Headers:\n"); for (size_t ix = 0; ix < res->get_headers_length(); ix++) { printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str()); } printf("\nBody (%d bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str()); } /** * Imprime los resultados de la medicion del sismo */ void print_debug(){ string tweet; NetworkInterface* network = connect_to_default_network_interface(); if (!network) { printf("Cannot connect to the network, see serial output\n"); return ; } // Create a TCP socket printf("\n----- Setting up TCP connection -----\n"); TCPSocket* socket = new TCPSocket(); nsapi_error_t open_result = socket->open(network); if (open_result != 0) { printf("Opening TCPSocket failed... %d\n", open_result); return ; } nsapi_error_t connect_result = socket->connect("10.60.16.220", 80); if (connect_result != 0) { printf("Connecting over TCPSocket failed... %d\n", connect_result); return ; } printf("Connected over TCP to httpbin.org:80\n"); char timeChar[20]; //string para la hora char dateChar[20]; //string para la fecha char locationChar[20]; //string para las coordenadas char altitudeChar[20]; //string para la altura char tweetChar[30]; //string para el tweet while(true){ wait(1); osEvent evt = mail_meass.get(); if (evt.status == osEventMail) { acceleration *mail = (acceleration*)evt.value.p; if (mail->x == 0 && mail->y == 0){ mail_meass.free(mail); continue; } tweet = compute_intensity(mail->x, mail->y); semaforo.lock(); pc.printf("%s\n\r",tweet); semaforo.unlock(); mail_meass.free(mail); strcpy(tweetChar, tweet.c_str()); sprintf(timeChar,"%d:%d:%d.%u\r\n", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); sprintf(dateChar,"%d/%d/20%d\r\n", myGPS.day, myGPS.month, myGPS.year); sprintf(locationChar,"%f%c, %f%c\r\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); sprintf(altitudeChar,"%f\r\n", myGPS.altitude); // POST request to http server HttpRequest* post_req = new HttpRequest(socket, HTTP_POST, "http://10.60.16.200"); post_req->set_header("Content-Type", "application/json"); // Formando el JSON de salida en la variable body char body[90]; strcpy (body,"{\"Message\":\""); strcat (body, tweetChar); strcat (body, "\", "); strcat (body,"\"Time\":\""); strcat (body, timeChar); strcat (body, "\", "); strcat (body,"\"Date\":\""); strcat (body, dateChar); strcat (body, "\", "); strcat (body,"\"Location\":\""); strcat (body, locationChar); strcat (body, "\", "); strcat (body,"\"Altitude\":\""); strcat (body, altitudeChar); strcat (body, "\""); strcat (body, "}"); pc.printf("%s\n\r",body); HttpResponse* post_res = post_req->send(body, strlen(body)); if (!post_res) { printf("HttpRequest failed (error code %d)\n", post_req->get_error()); return ; } printf("\n----- HTTP POST response -----\n"); dump_response(post_res); delete post_req; } } } /** * Interpreta la acceleracion sismica del terremoto a una escala de la intensidad del mismo. */ string compute_intensity(float xPGA, float yPGA){ float maxPGA; xPGA >= yPGA ? maxPGA = xPGA : maxPGA = yPGA; string result; if (maxPGA >= moderate.lowBound && maxPGA <= moderate.highBound) result = "Earthquake detected! \t Mercalli Scale: " + moderate.scale + "\t" + moderate.damage + " Damage"; else if (maxPGA >= strong.lowBound && maxPGA <= strong.highBound) result = "Earthquake detected! \t Mercalli Scale: " + strong.scale + "\t" + strong.damage + " Damage"; else if (maxPGA >= veryStrong.lowBound && maxPGA <= veryStrong.highBound) result = "Earthquake detected! \t Mercalli Scale: " + veryStrong.scale + "\t" + veryStrong.damage + " Damage"; else if (maxPGA >= severe.lowBound && maxPGA <= severe.highBound) result = "Earthquake detected! \t Mercalli Scale: " + severe.scale + "\t" + severe.damage + " Damage"; else if (maxPGA >= violent.lowBound && maxPGA <= violent.highBound) result = "Earthquake detected! \t Mercalli Scale: " + violent.scale + "\t" + violent.damage + " Damage"; else if (maxPGA >= extreme.lowBound && maxPGA <= extreme.highBound) result = "Earthquake detected! \t Mercalli Scale: " + extreme.scale + "\t" + extreme.damage + " Damage"; else result = "No Intensity recognized"; return result; } /** * Mide la data entregada por el acelerometro */ void measure() { // Ajusta la sensibilidad del sensor mpu.setAcceleroRange(MPU6050_ACCELERO_RANGE_2G); // Configura la frecuencia de corte del filtro paso bajo mpu.setBW(MPU6050_BW_5); // Test the connection if (mpu.testConnection()) pc.printf("MPU6050 test passed \r\n"); else pc.printf("MPU6050 test failed \r\n"); /** * Array que almacena la data Raw para la acceleracion en X, Y, Z */ float acce[3]; /** * Aceleracion en X */ float xAcc; /** * Aceleracion en Y */ float yAcc; while(1) { // Adecua el muestreo para una frecuencia determinada wait(SAMPLE_RATE_MEASURE); // Procesa la data obtenida del sensor de las aceleraciones en X, Y, Z mpu.getAccelero(acce); // Aceleracion sismica en XY (g) xAcc = (float)acce[0] / (GRAVITY_CONSTANT); yAcc = (float)acce[1] / (GRAVITY_CONSTANT); acceleration* mailAcc = mail_box.alloc(); mailAcc->x = abs(xAcc); mailAcc->y = abs(yAcc); mail_box.put(mailAcc); // Revisa la ocurrencia de un sismo if (abs(xAcc) >= moderate.lowBound || abs(yAcc) >= moderate.lowBound && !beenHere){ globalVar.lock(); earthquakeHappening = true; beenHere = true; globalVar.unlock(); } } } void send_meassure(){ Timer tick; bool meassuring = false; acceleration *data; acceleration maxData; maxData.x = 0; maxData.y = 0; while (true){ wait_ms(200); globalVar.lock(); if (earthquakeHappening) meassuring = true; globalVar.unlock(); while (meassuring){ wait_ms(50); osEvent evt = mail_box.get(); if (evt.status == osEventMail) { acceleration *mail = (acceleration*)evt.value.p; data = mail; mail_box.free(mail); } if (data->x >= moderate.lowBound || data->y >= moderate.lowBound ){ tick.reset(); if (data->x > maxData.x || data->y > maxData.y){ maxData = *data; } } else { tick.start(); if (tick.read_ms() <= 200) continue; tick.stop(); meassuring = false; } } globalVar.lock(); beenHere = false; earthquakeHappening = false; globalVar.unlock(); acceleration* mailAcc = mail_meass.alloc(); mailAcc->x = maxData.x; mailAcc->y = maxData.y; mail_meass.put(mailAcc); maxData.x = 0; maxData.y = 0; } } /** * Se encarga de obtener la cordenadas del Thread */ void getGPSCoordinates(){ char c; // when read via Adafruit_GPS::read(), the class returns single character stored here Timer refresh_Timer; // sets up a timer for use in loop; how often do we print GPS info? const int refresh_Time = 2000; //refresh time in ms myGPS.begin(9600); // sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *) // a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); myGPS.sendCommand(PGCMD_ANTENNA); refresh_Timer.start(); // starts the clock on the timer while(true){ c = myGPS.read(); // queries the GPS // check if we recieved a new message from GPS, if so, attempt to parse it, if ( myGPS.newNMEAreceived() ) if ( !myGPS.parse(myGPS.lastNMEA()) ) continue; } } int main() { sampleAccelero.start(measure); sendAccelero.start(send_meassure); printDebug.start(print_debug); getCoordinates.start(getGPSCoordinates); }