Firmware Test of Tilt Sense using BMI160

Dependencies:   mbed TI_ADS1220 ESP8266

Fork of GeoDynamics by GeoDynamics Hibrid Seismograph

Files at this revision

API Documentation at this revision

Comitter:
firewalk
Date:
Thu Oct 20 04:27:46 2016 +0000
Parent:
4:c79a3c86ab36
Commit message:
Complete Firmware of Geodynamic Seismograph

Changed in this revision

ADS1220.lib Show annotated file Show diff for this revision Revisions of this file
ESP8266.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADS1220.lib	Thu Oct 20 04:27:46 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/firewalk/code/TI_ADS1220/#34692a3d25f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266.lib	Thu Oct 20 04:27:46 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/quevedo/code/ESP8266/#77388e8f0697
--- 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");
+}