Firmware Test of Tilt Sense using BMI160

Dependencies:   mbed TI_ADS1220 ESP8266

Fork of GeoDynamics by GeoDynamics Hibrid Seismograph

Revision:
5:96fff32333e8
Parent:
4:c79a3c86ab36
--- a/main.cpp	Thu Sep 22 22:39:40 2016 +0000
+++ b/main.cpp	Thu Oct 20 04:27:46 2016 +0000
@@ -1,4 +1,9 @@
+//GeoDynamics Seismograph
+//Celso B. Varella Neto
+//-----------------------------------------------------------------------------
 #include "mbed.h"
+#include "ESP8266.h"
+#include "ADS1220.h"
 
 /*Timer*/
 Timer t;
@@ -10,17 +15,34 @@
 /* bmi160 slave address */
 #define BMI160_ADDR         ((0x68)<<1)
 
-/*Valor para Transformar de Radiano para Graus*/
+/*Value to Transform Rad to Deg*/
 #define RAD_DEG           57.29577951
 
-/*Comunicacao LPCXpresso4337*/ 
+#define PGA 1                 // Programmable Gain = 1
+#define VREFE 5.0                // External reference of 5.00V
+#define VFSR VREFE/PGA
+#define FSR (((long int)1<<23))
+#define LSB_Size (VFSR/FSR)
+
+#define IP "184.106.153.149" // thingspeak.com IP Address
+
+/*Serial-USB LPCXpresso4337*/ 
 Serial pc(USBTX, USBRX); // tx, rx
 
-/*Comunicacao I2C*/
+/*I2C pin connected to BMI160*/
 I2C i2c(P2_3, P2_4);
 
+/*Serial pin connected to ESP8266*/
+ESP8266 wifi(P2_10, P2_11, 115200); // baud rate for wifi
+char snd[255],rcv[1000];
 
-/* buffer to store acc samples */
+/*SPI pin connected to ADS120*/
+ADS1220 ads1220_com(D11, D12, D13);
+DigitalIn DRDY(D9);
+
+
+
+/* variable to store IMU BMI160 samples and manipulate */
 int16_t acc_sample_buffer[ACC_NOOF_AXIS] = {0x5555, 0x5555, 0x5555};
 int16_t gyr_sample_buffer[GYR_NOOF_AXIS] = {0x5555, 0x5555};
 
@@ -32,10 +54,23 @@
 double tiltx_prev, tilty_prev;
 
 char i2c_reg_buffer[2] = {0};
+
+/*variables to store ADS1220 samples and manipulate*/
+void showvolt(float volts);
+signed long t1Data, t2Data;
+float Vout, volt, ch1[2000], ch2[2000];
+char AIN1 = 57, AIN2 = 56;
+int chn, i;
+
+/*Functions*/
+float code2volt(float c); //Convert ADC numeric 24bit to Volts
+int find_maximum(float a[]); //Find Largest Value in Array
+void wifi_send(void); //Send data to ThingSpeak using WIFI ESP8266
  
 int main() {
-    pc.printf("Teste BMI160\n\r");
-    pc.printf("Configurando BMI160...\n\r");
+
+    pc.printf("GEODYNAMICS SEISMOGRAPH - EMBARCADOS CONTEST\n\r");
+    pc.printf("Configuring IMU BMI160...\n\r");
     wait_ms(250);
     
     /*Config Freq. I2C Bus*/
@@ -46,90 +81,203 @@
     i2c_reg_buffer[1] = 0xB6;    
     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
     wait_ms(200);
-    pc.printf("BMI160 Resetado\n\r");
+    pc.printf("BMI160 Reseted\n\r");
     
     /*Habilita o Acelerometro*/
     i2c_reg_buffer[0] = 0x7E;
     i2c_reg_buffer[1] = 0x11; //PMU Normal   
     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
-    pc.printf("Acc Habilitado\n\r");
+    pc.printf("Acc Enable\n\r");
     
     /*Habilita o Giroscopio*/
     i2c_reg_buffer[0] = 0x7E;
     i2c_reg_buffer[1] = 0x15;  //PMU Normal 
     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
-    pc.printf("Gyr Habilitado\n\r");
+    pc.printf("Gyr Enable\n\r");
     
     /*Config o Data Rate ACC em 1600Hz*/
     i2c_reg_buffer[0] = 0x40;
     i2c_reg_buffer[1] = 0x2C;    
     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
-    pc.printf("Data Rate ACC Selecionado a 1600Hz\n\r");
+    pc.printf("ACC Data Rate Configured to 1600Hz\n\r");
     
     /*Config o Data Rate GYR em 1600Hz*/
     i2c_reg_buffer[0] = 0x42;
     i2c_reg_buffer[1] = 0x2C;    
     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
-    pc.printf("Data Rate GYR Selecionado a 1600Hz\n\r");
+    pc.printf("GYR Data Rate Configured to 1600Hz\n\r");
     
     /*Config o Range GYR em 250º/s*/
     i2c_reg_buffer[0] = 0x43;
     i2c_reg_buffer[1] = 0x03;    
     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
-    pc.printf("Range GYR Selecionado a 250deg/s\n\r");
+    pc.printf("GYR Range Configured to 250deg/s\n\r");
     
     wait_ms(2000);
-    pc.printf("BMI160 Configurado\n\r");
+    pc.printf("BMI160 Configured\n\r");
+    
+    pc.printf("ADS1220 Initializing\n\r");
+    ads1220_com.Config();
+    //Configure ADS1220 to Single Shot, Turbo Mode & 2000sps
+    pc.printf("ADS1220 Configured and Initialized\n\r");
     
+    pc.printf("Configuring ESP8266\n\r");
+    pc.printf("SET mode to AP\r\n");
+    wifi.SetMode(1);    // set ESP mode to 1
+    wifi.RcvReply(rcv, 1000);    //receive a response from ESP
+    pc.printf("%s",rcv);    //Print the response onscreen
+    pc.printf("Conneting to AP\r\n");
+    wifi.Join("cbv", "26141916");     // Your wifi username & Password 
+    wifi.RcvReply(rcv, 1000);    //receive a response from ESP
+    pc.printf("%s", rcv);    //Print the response onscreen
+    wait(8);  //waits for response from ESP
+    pc.printf("Getting IP\r\n");    //get IP addresss from the connected AP
+    wifi.GetIP(rcv);    //receive an IP address from the AP
+    pc.printf("%s", rcv);    
+    wait(5); // Delay 5 sec to give the pir time to get snapshut of the surrounding
+    pc.printf("ESP8266 Configured\r\n");
+    
+    wait(2);
+    
+    t.start();
         
     while(1) {
         
-        /*Le os Registradores do Acelerometro*/
+        /*Read Register from Accelerometer*/
         i2c_reg_buffer[0] = 0x12;
         i2c.write(BMI160_ADDR, i2c_reg_buffer, 1, true);
         i2c.read(BMI160_ADDR, (char *)&acc_sample_buffer, sizeof(acc_sample_buffer), false);
         
-        /*Le os Registradores do Giroscopio*/
+        /*Read Register from Gyroscope*/
         i2c_reg_buffer[0] = 0x0C;
         i2c.write(BMI160_ADDR, i2c_reg_buffer, 1, true);
         i2c.read(BMI160_ADDR, (char *)&gyr_sample_buffer, sizeof(gyr_sample_buffer), false);
         
-        /*Ajusta dados brutos Acelerometro em unidades de g */
+        /*Adjust Raw Data from Accelerometer to G Units*/  
         acc_result_buffer[0] = (acc_sample_buffer[0]/16384.0);
         acc_result_buffer[1] = (acc_sample_buffer[1]/16384.0);
         acc_result_buffer[2] = (acc_sample_buffer[2]/16384.0);
         
-        /*Ajusta dados Brutos do Giroscopio em unidades de deg/s */
+        /*Adjust Raw Data from Gyroscope to deg/s Units */ 
         gyr_result_buffer[0] = (gyr_sample_buffer[0]/131.2);
         gyr_result_buffer[1] = (gyr_sample_buffer[1]/131.2);
                 
-        /*Calcula os Angulos de Inclinacao com valor do Acelerometro*/
+        /*Compute Dip Angle from Accelerometer Data*/
         accel_ang_x=atan(acc_result_buffer[0]/sqrt(pow(acc_result_buffer[1],2) + pow(acc_result_buffer[2],2)))*RAD_DEG;
         accel_ang_y=atan(acc_result_buffer[1]/sqrt(pow(acc_result_buffer[0],2) + pow(acc_result_buffer[2],2)))*RAD_DEG;
         
-        /*Para o Timer*/
+        /*Stop Timer*/
         t.stop();
                 
-        /*Calcula os Angulos de Rotacao com valor do Giroscopio e aplica filtro complementar realizando a fusao*/
-        tiltx = (0.965*(tiltx_prev+(gyr_result_buffer[0]*t.read())))+(0.035*(accel_ang_x));
-        tilty = (0.965*(tilty_prev+(gyr_result_buffer[1]*t.read())))+(0.035*(accel_ang_y));
+        /*Compute Rotation Angle from Gyroscope and Fusion Data using Complementary Filter*/
+        tiltx = (0.0280*(tiltx_prev+(gyr_result_buffer[0]*t.read())))+(0.9719*(accel_ang_x));
+        tilty = (0.0280*(tilty_prev+(gyr_result_buffer[1]*t.read())))+(0.9719*(accel_ang_y));
         
-        /*Debug para encontrar o tempo do loop*/
-        //pc.printf("%f",t.read());
+        /*Debug to find Loop Time*/
+        //pc.printf("Tempo Loop %f \r\n",t.read());
         
-        /*Reseta o Timer*/
+        /*Reset Timer*/
         t.reset();
-        /*Inicia o Timer*/
+        /*Start Timer*/
         t.start();
         
         tiltx_prev = tiltx;
-        tilty_prev = tilty;                                 
+        tilty_prev = tilty;
         
-        /*Imprime os dados ACC pre-formatados*/
-        pc.printf("%.3f,%.3f\n\r",tiltx, tilty);
+        i = 0;
+       while(i != 2000) { 
+        //Read Analog Data
+        ads1220_com.set_MUX(AIN1); //Configure to Sample Channel 1
+        ads1220_com.SendStartCommand(); //Start Aquisition
+        while (DRDY != 0){} // Wait data on Buffer
+        t1Data = ads1220_com.ReadData(); //Read Data Sampled on Channel 1
+                        
+        ads1220_com.set_MUX(AIN2); //Configure to Sample Channel 2
+        ads1220_com.SendStartCommand(); //Start Aquisition
+        while (DRDY != 0){} // Wait data on Buffer
+        t2Data = ads1220_com.ReadData(); //Read Data Sampled on Channel 2
+        
+        
+        ch1[i] = code2volt(t1Data); //Convert ADC Ch1 data to Volts
+        ch2[i] = code2volt(t2Data); //Convert ADC Ch2 data to Volts
+        
+        i = i + 1;                              
+        }
+        /*Send Sensors Data to Serial*/
+        pc.printf("%.3f, %.3f\n\r",tiltx, tilty);
+        pc.printf("%4.3f, %4.3f\n\r",ch1[find_maximum(ch1)], ch2[find_maximum(ch2)]);
+        pc.printf("Sending WiFi information\n\r");
+        wifi_send(); //Send Sensors Data to ThingSpeak using ESP8266
 
 
          
-        wait_ms(1);
     }
 }
+
+//Function to Convert ADC Data Read
+float code2volt(float c)
+{
+    float Vout = 0;
+    Vout = (float)(c*LSB_Size*1000);    //In  mV
+    return Vout;
+}
+
+//Function Return Largest Element on Array
+int find_maximum(float a[]) {
+    int c, index;
+    float max;
+    max = a[0];
+    index = 0;
+ 
+  for (c = 1; c < 2000; c++) {
+    if (a[c] > max) {
+       index = c;
+       max = a[c];
+    }
+  }
+  return index;
+}
+
+//SEND DATA TO THINGSPEAK VIA ESP8266   
+void wifi_send(void){
+   
+    strcpy(snd,"AT+CIPMODE=0");//Setting WiFi into MultiChannel mode
+    wifi.SendCMD(snd);
+    //pc.printf(snd);
+    wifi.RcvReply(rcv, 3000);
+    //pc.printf("%s", rcv);
+  
+  //WIFI updates the Status to Thingspeak servers//
+    strcpy(snd,"AT+CIPMUX=1");//Setting WiFi into MultiChannel mode
+    wifi.SendCMD(snd);
+    //pc.printf(snd);
+    wifi.RcvReply(rcv, 3000);
+    //pc.printf("%s", rcv);
+  
+  
+  sprintf(snd,"AT+CIPSTART=4,\"TCP\",\"%s\",80",IP); //Initiate connection with THINGSPEAK server 
+  wifi.SendCMD(snd);
+  //pc.printf(snd);
+  wifi.RcvReply(rcv, 3000);
+  //pc.printf("%s", rcv);
+ 
+  strcpy(snd,"AT+CIPSEND=4,99");    //Send Number of open connections,Characters to send 
+  wifi.SendCMD(snd);
+  //pc.printf(snd);
+  wifi.RcvReply(rcv, 3000);
+  //pc.printf("%s", rcv);
+  
+    
+  sprintf(snd,"GET /update?key=WHZBPNRREAXDKYII&field1=%2.2f&field2=%2.2f&field3=%4.2f&field4=%4.2f\r\n",tiltx, tilty, ch1[find_maximum(ch1)], ch2[find_maximum(ch2)]); //Post values to thingspeak
+  //pc.printf("String length %3d\r\n",strlen(snd));
+  //pc.printf("%s",snd);
+  wifi.SendCMD(snd);
+  wifi.RcvReply(rcv, 3000);
+  //pc.printf("%s", rcv);
+  
+  
+  //wifi.SendCMD("AT+CIPCLOSE"); //Close the connection to server
+  //wifi.RcvReply(rcv, 3000);
+  //pc.printf("%s", rcv);
+  pc.printf("Data Sent \r\n");
+}