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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }