Firmware Test of Tilt Sense using BMI160

Dependencies:   mbed TI_ADS1220 ESP8266

Fork of GeoDynamics by GeoDynamics Hibrid Seismograph

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //GeoDynamics Seismograph
00002 //Celso B. Varella Neto
00003 //-----------------------------------------------------------------------------
00004 #include "mbed.h"
00005 #include "ESP8266.h"
00006 #include "ADS1220.h"
00007 
00008 /*Timer*/
00009 Timer t;
00010 
00011 /* defines the axis for acc */
00012 #define ACC_NOOF_AXIS       3
00013 #define GYR_NOOF_AXIS       2
00014 
00015 /* bmi160 slave address */
00016 #define BMI160_ADDR         ((0x68)<<1)
00017 
00018 /*Value to Transform Rad to Deg*/
00019 #define RAD_DEG           57.29577951
00020 
00021 #define PGA 1                 // Programmable Gain = 1
00022 #define VREFE 5.0                // External reference of 5.00V
00023 #define VFSR VREFE/PGA
00024 #define FSR (((long int)1<<23))
00025 #define LSB_Size (VFSR/FSR)
00026 
00027 #define IP "184.106.153.149" // thingspeak.com IP Address
00028 
00029 /*Serial-USB LPCXpresso4337*/ 
00030 Serial pc(USBTX, USBRX); // tx, rx
00031 
00032 /*I2C pin connected to BMI160*/
00033 I2C i2c(P2_3, P2_4);
00034 
00035 /*Serial pin connected to ESP8266*/
00036 ESP8266 wifi(P2_10, P2_11, 115200); // baud rate for wifi
00037 char snd[255],rcv[1000];
00038 
00039 /*SPI pin connected to ADS120*/
00040 ADS1220 ads1220_com(D11, D12, D13);
00041 DigitalIn DRDY(D9);
00042 
00043 
00044 
00045 /* variable to store IMU BMI160 samples and manipulate */
00046 int16_t acc_sample_buffer[ACC_NOOF_AXIS] = {0x5555, 0x5555, 0x5555};
00047 int16_t gyr_sample_buffer[GYR_NOOF_AXIS] = {0x5555, 0x5555};
00048 
00049 double acc_result_buffer[ACC_NOOF_AXIS] = {0x5555, 0x5555, 0x5555};
00050 double gyr_result_buffer[GYR_NOOF_AXIS] = {0x5555, 0x5555};
00051 
00052 double accel_ang_x, accel_ang_y;
00053 double tiltx, tilty;
00054 double tiltx_prev, tilty_prev;
00055 
00056 char i2c_reg_buffer[2] = {0};
00057 
00058 /*variables to store ADS1220 samples and manipulate*/
00059 void showvolt(float volts);
00060 signed long t1Data, t2Data;
00061 float Vout, volt, ch1[2000], ch2[2000];
00062 char AIN1 = 57, AIN2 = 56;
00063 int chn, i;
00064 
00065 /*Functions*/
00066 float code2volt(float c); //Convert ADC numeric 24bit to Volts
00067 int find_maximum(float a[]); //Find Largest Value in Array
00068 void wifi_send(void); //Send data to ThingSpeak using WIFI ESP8266
00069  
00070 int main() {
00071 
00072     pc.printf("GEODYNAMICS SEISMOGRAPH - EMBARCADOS CONTEST\n\r");
00073     pc.printf("Configuring IMU BMI160...\n\r");
00074     wait_ms(250);
00075     
00076     /*Config Freq. I2C Bus*/
00077     i2c.frequency(20000);
00078     
00079     /*Reset BMI160*/
00080     i2c_reg_buffer[0] = 0x7E;
00081     i2c_reg_buffer[1] = 0xB6;    
00082     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
00083     wait_ms(200);
00084     pc.printf("BMI160 Reseted\n\r");
00085     
00086     /*Habilita o Acelerometro*/
00087     i2c_reg_buffer[0] = 0x7E;
00088     i2c_reg_buffer[1] = 0x11; //PMU Normal   
00089     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
00090     pc.printf("Acc Enable\n\r");
00091     
00092     /*Habilita o Giroscopio*/
00093     i2c_reg_buffer[0] = 0x7E;
00094     i2c_reg_buffer[1] = 0x15;  //PMU Normal 
00095     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
00096     pc.printf("Gyr Enable\n\r");
00097     
00098     /*Config o Data Rate ACC em 1600Hz*/
00099     i2c_reg_buffer[0] = 0x40;
00100     i2c_reg_buffer[1] = 0x2C;    
00101     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
00102     pc.printf("ACC Data Rate Configured to 1600Hz\n\r");
00103     
00104     /*Config o Data Rate GYR em 1600Hz*/
00105     i2c_reg_buffer[0] = 0x42;
00106     i2c_reg_buffer[1] = 0x2C;    
00107     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
00108     pc.printf("GYR Data Rate Configured to 1600Hz\n\r");
00109     
00110     /*Config o Range GYR em 250º/s*/
00111     i2c_reg_buffer[0] = 0x43;
00112     i2c_reg_buffer[1] = 0x03;    
00113     i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
00114     pc.printf("GYR Range Configured to 250deg/s\n\r");
00115     
00116     wait_ms(2000);
00117     pc.printf("BMI160 Configured\n\r");
00118     
00119     pc.printf("ADS1220 Initializing\n\r");
00120     ads1220_com.Config();
00121     //Configure ADS1220 to Single Shot, Turbo Mode & 2000sps
00122     pc.printf("ADS1220 Configured and Initialized\n\r");
00123     
00124     pc.printf("Configuring ESP8266\n\r");
00125     pc.printf("SET mode to AP\r\n");
00126     wifi.SetMode(1);    // set ESP mode to 1
00127     wifi.RcvReply(rcv, 1000);    //receive a response from ESP
00128     pc.printf("%s",rcv);    //Print the response onscreen
00129     pc.printf("Conneting to AP\r\n");
00130     wifi.Join("cbv", "26141916");     // Your wifi username & Password 
00131     wifi.RcvReply(rcv, 1000);    //receive a response from ESP
00132     pc.printf("%s", rcv);    //Print the response onscreen
00133     wait(8);  //waits for response from ESP
00134     pc.printf("Getting IP\r\n");    //get IP addresss from the connected AP
00135     wifi.GetIP(rcv);    //receive an IP address from the AP
00136     pc.printf("%s", rcv);    
00137     wait(5); // Delay 5 sec to give the pir time to get snapshut of the surrounding
00138     pc.printf("ESP8266 Configured\r\n");
00139     
00140     wait(2);
00141     
00142     t.start();
00143         
00144     while(1) {
00145         
00146         /*Read Register from Accelerometer*/
00147         i2c_reg_buffer[0] = 0x12;
00148         i2c.write(BMI160_ADDR, i2c_reg_buffer, 1, true);
00149         i2c.read(BMI160_ADDR, (char *)&acc_sample_buffer, sizeof(acc_sample_buffer), false);
00150         
00151         /*Read Register from Gyroscope*/
00152         i2c_reg_buffer[0] = 0x0C;
00153         i2c.write(BMI160_ADDR, i2c_reg_buffer, 1, true);
00154         i2c.read(BMI160_ADDR, (char *)&gyr_sample_buffer, sizeof(gyr_sample_buffer), false);
00155         
00156         /*Adjust Raw Data from Accelerometer to G Units*/  
00157         acc_result_buffer[0] = (acc_sample_buffer[0]/16384.0);
00158         acc_result_buffer[1] = (acc_sample_buffer[1]/16384.0);
00159         acc_result_buffer[2] = (acc_sample_buffer[2]/16384.0);
00160         
00161         /*Adjust Raw Data from Gyroscope to deg/s Units */ 
00162         gyr_result_buffer[0] = (gyr_sample_buffer[0]/131.2);
00163         gyr_result_buffer[1] = (gyr_sample_buffer[1]/131.2);
00164                 
00165         /*Compute Dip Angle from Accelerometer Data*/
00166         accel_ang_x=atan(acc_result_buffer[0]/sqrt(pow(acc_result_buffer[1],2) + pow(acc_result_buffer[2],2)))*RAD_DEG;
00167         accel_ang_y=atan(acc_result_buffer[1]/sqrt(pow(acc_result_buffer[0],2) + pow(acc_result_buffer[2],2)))*RAD_DEG;
00168         
00169         /*Stop Timer*/
00170         t.stop();
00171                 
00172         /*Compute Rotation Angle from Gyroscope and Fusion Data using Complementary Filter*/
00173         tiltx = (0.0280*(tiltx_prev+(gyr_result_buffer[0]*t.read())))+(0.9719*(accel_ang_x));
00174         tilty = (0.0280*(tilty_prev+(gyr_result_buffer[1]*t.read())))+(0.9719*(accel_ang_y));
00175         
00176         /*Debug to find Loop Time*/
00177         //pc.printf("Tempo Loop %f \r\n",t.read());
00178         
00179         /*Reset Timer*/
00180         t.reset();
00181         /*Start Timer*/
00182         t.start();
00183         
00184         tiltx_prev = tiltx;
00185         tilty_prev = tilty;
00186         
00187         i = 0;
00188        while(i != 2000) { 
00189         //Read Analog Data
00190         ads1220_com.set_MUX(AIN1); //Configure to Sample Channel 1
00191         ads1220_com.SendStartCommand(); //Start Aquisition
00192         while (DRDY != 0){} // Wait data on Buffer
00193         t1Data = ads1220_com.ReadData(); //Read Data Sampled on Channel 1
00194                         
00195         ads1220_com.set_MUX(AIN2); //Configure to Sample Channel 2
00196         ads1220_com.SendStartCommand(); //Start Aquisition
00197         while (DRDY != 0){} // Wait data on Buffer
00198         t2Data = ads1220_com.ReadData(); //Read Data Sampled on Channel 2
00199         
00200         
00201         ch1[i] = code2volt(t1Data); //Convert ADC Ch1 data to Volts
00202         ch2[i] = code2volt(t2Data); //Convert ADC Ch2 data to Volts
00203         
00204         i = i + 1;                              
00205         }
00206         /*Send Sensors Data to Serial*/
00207         pc.printf("%.3f, %.3f\n\r",tiltx, tilty);
00208         pc.printf("%4.3f, %4.3f\n\r",ch1[find_maximum(ch1)], ch2[find_maximum(ch2)]);
00209         pc.printf("Sending WiFi information\n\r");
00210         wifi_send(); //Send Sensors Data to ThingSpeak using ESP8266
00211 
00212 
00213          
00214     }
00215 }
00216 
00217 //Function to Convert ADC Data Read
00218 float code2volt(float c)
00219 {
00220     float Vout = 0;
00221     Vout = (float)(c*LSB_Size*1000);    //In  mV
00222     return Vout;
00223 }
00224 
00225 //Function Return Largest Element on Array
00226 int find_maximum(float a[]) {
00227     int c, index;
00228     float max;
00229     max = a[0];
00230     index = 0;
00231  
00232   for (c = 1; c < 2000; c++) {
00233     if (a[c] > max) {
00234        index = c;
00235        max = a[c];
00236     }
00237   }
00238   return index;
00239 }
00240 
00241 //SEND DATA TO THINGSPEAK VIA ESP8266   
00242 void wifi_send(void){
00243    
00244     strcpy(snd,"AT+CIPMODE=0");//Setting WiFi into MultiChannel mode
00245     wifi.SendCMD(snd);
00246     //pc.printf(snd);
00247     wifi.RcvReply(rcv, 3000);
00248     //pc.printf("%s", rcv);
00249   
00250   //WIFI updates the Status to Thingspeak servers//
00251     strcpy(snd,"AT+CIPMUX=1");//Setting WiFi into MultiChannel mode
00252     wifi.SendCMD(snd);
00253     //pc.printf(snd);
00254     wifi.RcvReply(rcv, 3000);
00255     //pc.printf("%s", rcv);
00256   
00257   
00258   sprintf(snd,"AT+CIPSTART=4,\"TCP\",\"%s\",80",IP); //Initiate connection with THINGSPEAK server 
00259   wifi.SendCMD(snd);
00260   //pc.printf(snd);
00261   wifi.RcvReply(rcv, 3000);
00262   //pc.printf("%s", rcv);
00263  
00264   strcpy(snd,"AT+CIPSEND=4,99");    //Send Number of open connections,Characters to send 
00265   wifi.SendCMD(snd);
00266   //pc.printf(snd);
00267   wifi.RcvReply(rcv, 3000);
00268   //pc.printf("%s", rcv);
00269   
00270     
00271   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
00272   //pc.printf("String length %3d\r\n",strlen(snd));
00273   //pc.printf("%s",snd);
00274   wifi.SendCMD(snd);
00275   wifi.RcvReply(rcv, 3000);
00276   //pc.printf("%s", rcv);
00277   
00278   
00279   //wifi.SendCMD("AT+CIPCLOSE"); //Close the connection to server
00280   //wifi.RcvReply(rcv, 3000);
00281   //pc.printf("%s", rcv);
00282   pc.printf("Data Sent \r\n");
00283 }