Firmware Test of Tilt Sense using BMI160

Dependencies:   mbed TI_ADS1220 ESP8266

Fork of GeoDynamics by GeoDynamics Hibrid Seismograph

main.cpp

Committer:
firewalk
Date:
2016-10-20
Revision:
5:96fff32333e8
Parent:
4:c79a3c86ab36

File content as of revision 5:96fff32333e8:

//GeoDynamics Seismograph
//Celso B. Varella Neto
//-----------------------------------------------------------------------------
#include "mbed.h"
#include "ESP8266.h"
#include "ADS1220.h"

/*Timer*/
Timer t;

/* defines the axis for acc */
#define ACC_NOOF_AXIS       3
#define GYR_NOOF_AXIS       2

/* bmi160 slave address */
#define BMI160_ADDR         ((0x68)<<1)

/*Value to Transform Rad to Deg*/
#define RAD_DEG           57.29577951

#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

/*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];

/*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};

double acc_result_buffer[ACC_NOOF_AXIS] = {0x5555, 0x5555, 0x5555};
double gyr_result_buffer[GYR_NOOF_AXIS] = {0x5555, 0x5555};

double accel_ang_x, accel_ang_y;
double tiltx, tilty;
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("GEODYNAMICS SEISMOGRAPH - EMBARCADOS CONTEST\n\r");
    pc.printf("Configuring IMU BMI160...\n\r");
    wait_ms(250);
    
    /*Config Freq. I2C Bus*/
    i2c.frequency(20000);
    
    /*Reset BMI160*/
    i2c_reg_buffer[0] = 0x7E;
    i2c_reg_buffer[1] = 0xB6;    
    i2c.write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
    wait_ms(200);
    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 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 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("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("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("GYR Range Configured to 250deg/s\n\r");
    
    wait_ms(2000);
    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) {
        
        /*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);
        
        /*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);
        
        /*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);
        
        /*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);
                
        /*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;
        
        /*Stop Timer*/
        t.stop();
                
        /*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 to find Loop Time*/
        //pc.printf("Tempo Loop %f \r\n",t.read());
        
        /*Reset Timer*/
        t.reset();
        /*Start Timer*/
        t.start();
        
        tiltx_prev = tiltx;
        tilty_prev = 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


         
    }
}

//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");
}