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
main.cpp
00001 00002 #include "mbed.h" 00003 #include "MPU6050.h" 00004 #include "REF_VALUES.h" 00005 #include "CONSTANTS.h" 00006 #include "FUNCTIONS.h" 00007 #include "Timer.h" 00008 #include "MBed_Adafruit_GPS.h" 00009 00010 /** 00011 * Debbuging led 00012 */ 00013 DigitalOut myled(LED1); 00014 00015 /** 00016 * Puerto serial 00017 */ 00018 Serial pc(USBTX, USBRX, BAUD_RATE); 00019 00020 /** 00021 * Puntero hacia el puerto serial utilizado para la comunicacion entre el GPS y el Micro 00022 */ 00023 Serial * gps_Serial; 00024 00025 /** 00026 * Objeto MPU6050 00027 */ 00028 MPU6050 mpu(PF_15, PF_14); 00029 00030 /** 00031 * Threads 00032 */ 00033 Thread sampleAccelero; 00034 Thread printDebug; 00035 Thread sendAccelero; 00036 Thread getCoordinates; 00037 00038 /** 00039 * Mutex 00040 */ 00041 Mutex semaforo; 00042 Mutex globalVar; 00043 00044 /** 00045 * Mailboxes 00046 */ 00047 Mail<acceleration, 1> mail_box; 00048 Mail<acceleration, 1> mail_meass; 00049 00050 /** 00051 * Variables de control 00052 */ 00053 bool earthquakeHappening = false; 00054 bool beenHere = false; 00055 00056 00057 00058 /** 00059 * Handler para la utilizacion del GPS 00060 */ 00061 Adafruit_GPS myGPS(new Serial(PC_12, PD_2)); //object of Adafruit's GPS class 00062 00063 00064 /** 00065 * Imprime los resultados de la medicion del sismo 00066 */ 00067 void print_debug(){ 00068 string tweet; 00069 while(true){ 00070 wait(1); 00071 osEvent evt = mail_meass.get(); 00072 if (evt.status == osEventMail) { 00073 acceleration *mail = (acceleration*)evt.value.p; 00074 if (mail->x == 0 && mail->y == 0){ 00075 mail_meass.free(mail); 00076 continue; 00077 } 00078 tweet = compute_intensity(mail->x, mail->y); 00079 semaforo.lock(); 00080 pc.printf("%s\n\r",tweet); 00081 semaforo.unlock(); 00082 mail_meass.free(mail); 00083 pc.printf("Time: %d:%d:%d.%u\r\n", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); 00084 pc.printf("Date: %d/%d/20%d\r\n", myGPS.day, myGPS.month, myGPS.year); 00085 pc.printf("Location: %f%c, %f%c\r\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); 00086 pc.printf("Altitude: %f\r\n", myGPS.altitude); 00087 00088 } 00089 } 00090 } 00091 00092 00093 /** 00094 * Interpreta la acceleracion sismica del terremoto a una escala de la intensidad del mismo. 00095 */ 00096 string compute_intensity(float xPGA, float yPGA){ 00097 float maxPGA; 00098 00099 xPGA >= yPGA ? maxPGA = xPGA : maxPGA = yPGA; 00100 00101 string result; 00102 00103 if (maxPGA >= moderate.lowBound && maxPGA <= moderate.highBound) 00104 result = "Earthquake detected! \t Mercalli Scale: " + moderate.scale + "\t" + moderate.damage + " Damage"; 00105 00106 else if (maxPGA >= strong.lowBound && maxPGA <= strong.highBound) 00107 result = "Earthquake detected! \t Mercalli Scale: " + strong.scale + "\t" + strong.damage + " Damage"; 00108 00109 else if (maxPGA >= veryStrong.lowBound && maxPGA <= veryStrong.highBound) 00110 result = "Earthquake detected! \t Mercalli Scale: " + veryStrong.scale + "\t" + veryStrong.damage + " Damage"; 00111 00112 else if (maxPGA >= severe.lowBound && maxPGA <= severe.highBound) 00113 result = "Earthquake detected! \t Mercalli Scale: " + severe.scale + "\t" + severe.damage + " Damage"; 00114 00115 else if (maxPGA >= violent.lowBound && maxPGA <= violent.highBound) 00116 result = "Earthquake detected! \t Mercalli Scale: " + violent.scale + "\t" + violent.damage + " Damage"; 00117 00118 else if (maxPGA >= extreme.lowBound && maxPGA <= extreme.highBound) 00119 result = "Earthquake detected! \t Mercalli Scale: " + extreme.scale + "\t" + extreme.damage + " Damage"; 00120 00121 else 00122 result = "No Intensity recognized"; 00123 00124 return result; 00125 } 00126 00127 00128 /** 00129 * Mide la data entregada por el acelerometro 00130 */ 00131 void measure() { 00132 00133 // Ajusta la sensibilidad del sensor 00134 mpu.setAcceleroRange(MPU6050_ACCELERO_RANGE_2G); 00135 00136 // Configura la frecuencia de corte del filtro paso bajo 00137 mpu.setBW(MPU6050_BW_5); 00138 00139 // Test the connection 00140 if (mpu.testConnection()) 00141 pc.printf("MPU6050 test passed \r\n"); 00142 else 00143 pc.printf("MPU6050 test failed \r\n"); 00144 00145 /** 00146 * Array que almacena la data Raw para la acceleracion en X, Y, Z 00147 */ 00148 float acce[3]; 00149 /** 00150 * Aceleracion en X 00151 */ 00152 float xAcc; 00153 /** 00154 * Aceleracion en Y 00155 */ 00156 float yAcc; 00157 00158 00159 while(1) { 00160 // Adecua el muestreo para una frecuencia determinada 00161 wait(SAMPLE_RATE_MEASURE); 00162 00163 // Procesa la data obtenida del sensor de las aceleraciones en X, Y, Z 00164 mpu.getAccelero(acce); 00165 00166 // Aceleracion sismica en XY (g) 00167 xAcc = (float)acce[0] / (GRAVITY_CONSTANT); 00168 yAcc = (float)acce[1] / (GRAVITY_CONSTANT); 00169 00170 acceleration* mailAcc = mail_box.alloc(); 00171 00172 mailAcc->x = abs(xAcc); 00173 mailAcc->y = abs(yAcc); 00174 mail_box.put(mailAcc); 00175 00176 // Revisa la ocurrencia de un sismo 00177 if (abs(xAcc) >= moderate.lowBound || abs(yAcc) >= moderate.lowBound && !beenHere){ 00178 globalVar.lock(); 00179 earthquakeHappening = true; 00180 beenHere = true; 00181 globalVar.unlock(); 00182 } 00183 00184 } 00185 00186 } 00187 00188 void send_meassure(){ 00189 Timer tick; 00190 bool meassuring = false; 00191 acceleration *data; 00192 acceleration maxData; 00193 maxData.x = 0; 00194 maxData.y = 0; 00195 while (true){ 00196 wait_ms(200); 00197 globalVar.lock(); 00198 if (earthquakeHappening) 00199 meassuring = true; 00200 globalVar.unlock(); 00201 while (meassuring){ 00202 wait_ms(50); 00203 osEvent evt = mail_box.get(); 00204 if (evt.status == osEventMail) { 00205 acceleration *mail = (acceleration*)evt.value.p; 00206 data = mail; 00207 mail_box.free(mail); 00208 } 00209 if (data->x >= moderate.lowBound || data->y >= moderate.lowBound ){ 00210 tick.reset(); 00211 if (data->x > maxData.x || data->y > maxData.y){ 00212 maxData = *data; 00213 } 00214 } 00215 else { 00216 tick.start(); 00217 if (tick.read_ms() <= 200) 00218 continue; 00219 tick.stop(); 00220 meassuring = false; 00221 } 00222 } 00223 globalVar.lock(); 00224 beenHere = false; 00225 earthquakeHappening = false; 00226 globalVar.unlock(); 00227 acceleration* mailAcc = mail_meass.alloc(); 00228 mailAcc->x = maxData.x; 00229 mailAcc->y = maxData.y; 00230 mail_meass.put(mailAcc); 00231 maxData.x = 0; 00232 maxData.y = 0; 00233 } 00234 } 00235 00236 /** 00237 * Se encarga de obtener la cordenadas del Thread 00238 */ 00239 void getGPSCoordinates(){ 00240 00241 char c; // when read via Adafruit_GPS::read(), the class returns single character stored here 00242 Timer refresh_Timer; // sets up a timer for use in loop; how often do we print GPS info? 00243 const int refresh_Time = 2000; //refresh time in ms 00244 00245 myGPS.begin(9600); // sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *) 00246 // a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf 00247 00248 myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation 00249 myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); 00250 myGPS.sendCommand(PGCMD_ANTENNA); 00251 00252 refresh_Timer.start(); // starts the clock on the timer 00253 00254 while(true){ 00255 c = myGPS.read(); // queries the GPS 00256 00257 // check if we recieved a new message from GPS, if so, attempt to parse it, 00258 if ( myGPS.newNMEAreceived() ) 00259 if ( !myGPS.parse(myGPS.lastNMEA()) ) 00260 continue; 00261 } 00262 } 00263 00264 00265 int main() 00266 { 00267 sampleAccelero.start(measure); 00268 sendAccelero.start(send_meassure); 00269 printDebug.start(print_debug); 00270 getCoordinates.start(getGPSCoordinates); 00271 }
Generated on Wed Jul 20 2022 18:22:37 by 1.7.2