Firmware Test of Tilt Sense using BMI160
Dependencies: mbed TI_ADS1220 ESP8266
Fork of GeoDynamics by
Diff: main.cpp
- 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"); +}