this program is designed for the CHITISAT's OBC, and is a prototype for the flight plan vs altitude
Dependencies: ADS1015 BMP280 SDFileSystem SENSOR mbed
main.cpp
- Committer:
- FannyCalle
- Date:
- 2018-08-17
- Revision:
- 5:05fd6249c21b
- Parent:
- 4:c2bdc2bced76
File content as of revision 5:05fd6249c21b:
/*Programa principal del computador a bordo del cubesat "CHITISAT" */ //*********************************************************************** #include "mbed.h" #include "Adafruit_ADS1015.h" #include "SDFileSystem.h" #include "BMP280.h" #include "MPU6050.h" //#include "HMC5883L.h" #include "SENSOR.h" //***** declaracion de puertos SDFileSystem sd(PA_12, PA_6, PA_1, PB_0 , "sd");// puerto SPI para el Storage Serial sc(PB_6, PB_7,9600); //puerto para el sistema de comunicacioness //I2C i2c(PB_4,PA_7); // puerto i2c BMP280 bmp(i2c,0xEC); //Default address = 0x76 Adafruit_ADS1115 ads(&i2c); // adc de 16 bits Serial obc(USBTX,USBRX); // puerto virtual del obc SENSOR uv(PB_4,PA_7); //sensor de rayos ultra violeta SENSOR mag(PB_4,PA_7); // magnetometro AnalogIn temp2(PA_5); //sensor de temperatura externa AnalogIn voltaje(PA_4); //sensor analogico de voltaje AnalogIn corriente(PA_3); // sensor analogico de corriente AnalogIn temp3(ADC_TEMP); //sensor de temperatura del arm DigitalOut Vcondicional(PA_8); //encendido de los sensores(logica negada) DigitalOut camera(PB_5); DigitalOut led(PB_3); MPU6050 mpu6050; Timer t; //***** declaracionde funciones void take_tl(void); void take_mision(void); void save_tl(void); void save_mision(void); void build_tr1(void); void build_tr2(void); void send_tr(void); float procesing_h(void); int condiciones_iniciales(void); void filtro_pasa_bajos(void); float get_altura(void); int guardar(int); void prog_camara(void); //declaracion de constntes #define enc 0xA0 //'160' #define stby 0xA1 //'161' #define sos 0xEE //'238' #define com 0xC0 //'192' #define nak 0xC1 //193 #define tc 0xC2 //194 #define data1 0xD1 #define data2 0xD2 #define data3 0xD3 //********************* #define estado = '0xf'; //aun no se para que lo usare //********************* //declaracion de variables globales //************************* uint8_t trama[31]; uint16_t IMU[9]; // magenotometro*3, acelerometro*3, giroscopio*3 float imu[9]; // magenotometro*3, acelerometro*3, giroscopio*3 uint32_t bar; float press=0; uint16_t tem[2],temp[2]; //temperatura interna i externa del cubesast tomadas por i2c uint16_t sen_adc[4]; // sensor temperatura de la placa, sensor de corriente, voltaje, ultravioleta uint16_t sensor_adc[4]; // para la toma de datos analogicos uint16_t suv; uint16_t senfis[4]; //sensor de los fisicos volatile uint8_t menc=nak; // mensaje manipulado por comunicaciones //********************************************* //nuevos valores de datos, aun por revisar char file[]="/sd/prueba1/drop0.txt"; char dato[]="/sd/condiciones/iniciales0.txt"; float BMPTemp = 0; //float altura1,altura0,h; float P, Pi, Pa; float Pp[100]; int BR=0; //bandera de reset float RS[16]; //registro de sensores int ND ; float h,altura1; float P0; float dif; //********************************************* //**********interrupcion activada por el rx de sistema de comunicaciones(sc) void callback(){ uint8_t menr=sc.getc(); if(menr==nak || menr==tc ||menr==com){ //condicional para solo reconocer 3 comandos que puede llegar del sc menc=menr; //si llegara otra cosa no cambiaria menc y no habria conflicto en los loops } obc.printf("resep: %d",menc);// borrar esto } //**********principal int main() { t.reset(); t.start(); //******* inicio obc.printf("iniciando sensores:\n"); //encenciendo sensores //wait(2); Vcondicional=0; //iniciando camara prog_camara(); obc.printf("iniciando camara\n\r"); //******* condiciones iniciales obc.printf("iniciando sistema"); mkdir("/sd/prueba1", 0777); // //LEER LA BANDERA DE STADO DEL SISTEMA BR FILE *fp=fopen("/sd/condiciones/ci.txt","r"); if(fp==NULL){printf("no se pudo acceder al sd 1.."); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset();} fscanf(fp,"%d",&BR); ///*************************************8revisar fclose(fp); int tipo=condiciones_iniciales(); RS[10]= guardar(tipo); P0=Pi; dif=0; float h=get_altura(); tipo=2; RS[11]= guardar(tipo); led=1; //iniciando sistema de comunicaciones for(int i=0;i<=10;i++){ sc.putc(enc); led=!led; obc.printf("encendido: %d\n",enc); wait(0.3); } //******* FULL MODE sc.attach(&callback); //prueba*********** //int alt=50; //int altura=10; //***************** //float x=0.5; float hmin=0.5; float hsil; hsil=hmin-0.1; while(h<hsil){ obc.printf("subiendo en silencio radial altura=%f\n\r",h); h=get_altura(); led=!led; } led=1;wait_ms(20);led=0; while(h>=hmin){ //while(alt>=5){ if (menc==com){ while(menc!=nak && h>=hmin){ if(menc==tc){ while(menc==tc && h>=hmin){//si no hay mensaje nuevo se mantiene en MM hasta que llegue unno take_tl(); take_mision(); h=get_altura(); save_tl(); build_tr2(); tipo=3; RS[12]= guardar(tipo); save_mision(); send_tr(); obc.printf("altura minima con tc1 %f\n",h); } } else{ while(menc==com && h>=hmin){//si no hay mensaje nuevo se mantiene en STM hasta que llegue unno take_tl(); h=get_altura(); save_tl(); build_tr1(); tipo=3; RS[12]= guardar(tipo); send_tr(); obc.printf("altura minima con tc %f\n",h); } } } } else{ while (menc==nak && h>=hmin){// si no hay mensaje nuevo se mantiene en SIM hasta que llegue unno h=get_altura(); take_tl(); take_mision(); save_tl(); tipo=2; RS[12]= guardar(tipo); save_mision(); obc.printf("alt=%f\n",h); } } obc.printf("______________________NORMAL MODE______________________"); } //******* SLEEP MODE for(int i=0;i<=5;i++){ sc.putc(stby); obc.printf("standby: %d",stby); } float hant; hant=h;//altura1; //h=get_altura(); float hact=get_altura();//altura1; float dif; dif=hant-hact; obc.printf("altan=%f altac=%f dif=%f\n",hant,hact,dif); while(dif!=0){ obc.printf("********************sleep mode**************************"); //while(hact!=0.0){ hant=hact; //h=get_altura(); hact=get_altura();//altura1; take_tl(); take_mision(); save_tl(); tipo=2; RS[12]= guardar(tipo); save_mision(); dif=hant-hact; obc.printf("diferente de cero\n altan=%f altac=%f dif=%f\n",hant,hact,dif); led=!led; } //******* OFF MODE //camara=1; // apagando camara prog_camara(); obc.printf("apagando camara\n\r"); led=0; Vcondicional=1; //apagando sensores sc.putc(sos); for(int i=0;i<=9;i++) { obc.printf("sos: %d\n",sos); } //obc.printf("%d\n",alt); //activar modo reset HAL_PWR_EnterSTANDBYMode (); //apagar obc } //********* Funciones void take_tl(void){ int i; IMU[0]=imu[0]= mag.getMx(); IMU[1]=imu[1]= mag.getMy(); IMU[2]=imu[2]= mag.getMz(); mpu6050.MPU6050SelfTest(SelfTest); // Start by performing self test and reporting values if(SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f && SelfTest[5] < 1.0f) { mpu6050.resetMPU6050(); // Reset registers to default in preparation for device calibration mpu6050.calibrateMPU6050(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers mpu6050.initMPU6050(); } if(mpu6050.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01) { // check if data ready interrupt mpu6050.readAccelData(accelCount); // Read the x/y/z adc values mpu6050.getAres(); // Now we'll calculate the accleration value into actual g's imu[3]= accelCount[0];//*aRes - accelBias[0]; // get actual g value, this depends on scale being set imu[4]= accelCount[1];//*aRes - accelBias[1]; imu[5]= accelCount[2];//*aRes - accelBias[2]; mpu6050.readGyroData(gyroCount); // Read the x/y/z adc values mpu6050.getGres(); // Calculate the gyro value into actual degrees per second imu[6]= gyroCount[0];//*gRes; // - gyroBias[0]; // get actual gyro value, this depends on scale being set imu[7]= gyroCount[1];//*gRes; // - gyroBias[1]; imu[8]= gyroCount[2];//*gRes; // - gyroBias[2]; float temobcount = mpu6050.readTempData(); // Read the x/y/z adc values temperature = (temobcount) / 340. + 36.53; // Temperature in degrees Centigrade } for(i=3;i<=8;i++){ //imu.read(); IMU[i]=imu[i];//*10;//para la toma de datos //obc.printf("%d\n",IMU[i]); } press=bmp.getPressure(); //temperatura tomada del imu int tempera=temperature*100; int offsetadc=60; //CORRECCION DE LOS DATOS TOMADOS DEL ADC, EL ERROR ES PRODUCIDO POR VREF. //tempera=ceil(tempera); temp[0]=tempera; //temperatura en milivoltios ajuatado a 12 bits. //float tempe1=temp2.read(); //obteniendo la temperatura en voltaje temp[1]= temp2.read_u16();temp[1]=(temp[1]>>4)+offsetadc;//temperatura en milivoltios ajuatado a 12 bits. sensor_adc[0]=temp3.read_u16();sen_adc[0]=(sensor_adc[0]>>4)+offsetadc; sensor_adc[1]=corriente.read_u16();sen_adc[1]=(sensor_adc[1]>>4)+offsetadc; sensor_adc[2]=voltaje.read_u16();sen_adc[2]=(sensor_adc[2]>>4)+offsetadc; suv=uv.getUV(); //sensor_adc[3]=temp2.read();//uv.read();sen_adc[3]=sensor_adc[3]/0.0008789062; obc.printf("tomando telemetria\n"); } void take_mision(void){ int h1, h2, tiempo; h1=altura1*10; h2=h*10; tiempo=t.read(); tiempo=tiempo*100; senfis[0]=h1; senfis[1]=h2; senfis[2]=tiempo; obc.printf("tiempo=%d",senfis[2]); /* ads.setGain(GAIN_TWOTHIRDS); for(int i=0;i<=3;i++){ senfis[i]= ads.readADC_SingleEnded(i); */ // obc.printf("\n senfis%d:%d 0x%.4x\n",i,senfis[i],senfis[i]); //} obc.printf("tomando mision\n"); } void save_tl(void){ mkdir("/sd/cubesat2p",0777); FILE *fp=fopen("/sd/cubesat2p/trama1.txt","a"); if(fp == NULL){ obc.printf("no se puede abrir sd \n"); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset(); } fprintf(fp,"%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %d %d %d %d %d %f\r\n",imu[0],imu[1],imu[2],imu[3],imu[4],imu[5],imu[6],imu[7],imu[8],press,temperature,temp[1],sen_adc[0],sen_adc[1],sen_adc[2],suv,h); obc.printf("%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %d %d %d %d %d %f\r\n",imu[0],imu[1],imu[2],imu[3],imu[4],imu[5],imu[6],imu[7],imu[8],press,temperature,temp[1],sen_adc[0],sen_adc[1],sen_adc[2],suv,h); fclose(fp); obc.printf("guardando telemetria\n"); } void save_mision(void){ mkdir("/sd/cubesat2p",0777); FILE *fp=fopen("/sd/cubesat2p/trama2.txt","a"); if(fp == NULL){ obc.printf("no se puede abrir sd \n"); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset(); } fprintf(fp,"%d %d %d %d\r\n",senfis[0],senfis[1],senfis[2],senfis[3]); fclose(fp); obc.printf("guardando mision\n"); } void build_tr1(void){ //construir trama de datos 1 int barometro; barometro=ceil(P*100); //tomando los 20 bits sin procesar del barometro bar=barometro; // obc.printf("p=%f barometro= %d bar= %d temp0= %d \n\r",P,barometro,bar,temp[0]); // wait(1); uint16_t y,z,y2,z4,ah,al; uint32_t par[3];// para los tres pares de datos de 32 bits uint32_t y4,y3; uint32_t AH,AL; y=4080; z=15; y4=0xff000000; y3=0x00ff0000; y2=0x0000ff00; z4=0x000000ff; //completando a paquetes de 32 bits par[0]=(bar<<12)|temp[0]; //obc.printf("par 0=%d",par[0]); //wait(1); ah=sen_adc[1]&y; al=sen_adc[1]&z; ah=(ah>>4); par[1]=(temp[1]<<20)|(sen_adc[0]<<8)|ah; uint8_t est=15; par[2]=(al<<28)|(sen_adc[2]<<16)|suv; //asignando 8 bits a cada espacio de la trama for(int i=0;i<=8;i++){ AH=0;AL=0; AH=IMU[i]&y2;AH=(AH>>8); AL=IMU[i]&z4; trama[i*2+1]=AH; trama[i*2+2]=AL; } for(int i=0;i<=2;i++){ AH=0;AL=0; AH=par[i]&y4;AH=(AH>>24); AL=par[i]&y3;AL=(AL>>16); trama[i*4+19]=AH; trama[i*4+20]=AL; AH=0;AL=0; AH=par[i]&y2;AH=(AH>>8); AL=par[i]&z4; trama[i*4+21]=AH; trama[i*4+22]=AL; } trama[0]=data1;//cabecera de la trama de datos 1 //publicando por el puerto serial. la trama de datos for(int i=0;i<=30;i++){ obc.printf("%d\n",trama[i]); } obc.printf("construyendo trama 1\n"); } void build_tr2(void){// construir trama de datos 2 bar=ceil(P*100); //tomando los 20 bits sin procesar del barometro uint16_t y,z,y2,z4,ah,al; uint32_t par,y4,y3;// para los tres pares de datos de 32 bits uint32_t AH,AL; y=4080; z=15; y4=0xff000000; y3=0x00ff0000; y2=0x0000ff00; z4=0x000000ff; //completando a 32 bits par=(bar<<12)|sen_adc[1]; for(int i=0;i<=8;i++){ AH=0;AL=0; AH=IMU[i]&y2;AH=(AH>>8); AL=IMU[i]&z4; trama[i*2+1]=AH; trama[i*2+2]=AL; } //asignando 8 bits a cada espacio de la trama2 AH=0;AL=0; AH=par&y4;AH=(AH>>24); AL=par&y3;AL=(AL>>16); trama[19]=AH; trama[20]=AL; AH=0;AL=0; AH=par&y2;AH=(AH>>8); AL=par&z4; trama[21]=AH; trama[22]=AL; for(int i=0;i<=3;i++){ AH=0;AL=0; AH=senfis[i]&y2;AH=(AH>>8); AL=senfis[i]&z4; trama[i*2+23]=AH; trama[i*2+24]=AL; } trama[0]=data2; //cabecera de la trama de datos 2 //publicando la trama de datos 2 en el puerto virtual for(int i=0;i<=30;i++){ // obc.printf("%d\n",trama[i]); } obc.printf("construyendo trama 2 mision\n"); } void send_tr(void){ for(int i=0;i<=30;i++){ sc.putc(trama[i]); } led=!led; obc.printf("enviando trama\n"); } int condiciones_iniciales() { float Ps=0;//variable auxiliar en la que se acumula la suma de los datos de presion para poder hallar la media if(BR==0) { // recuperar datos iniciales //************************************************************ //TOMAR LOS 100 DATOS CADA .05 SEGUNDOS, PARA DETERMINAR LA PRESION INICIAL for (int i=0;i<100;i++) { BMPTemp=bmp.getTemperature(); // generando t_fine PARA LA TEMPERATURA DE ESCALAMIENTP Pp[i]= bmp.getPressure(); // pi es la condicion inical para la presion Ps=Ps+Pp[i]; led=!led; obc.printf("%.2f\n",Pp[i]); wait(0.05); } //LA MEDIA DE TODOS LOS DATOS NOS DA LA PRESION REAL Pi=Ps/100; //presion real } else { // leer las condiciones iniciales del archivo ci,txt FILE *fp=fopen("/sd/condiciones/ci.txt","r"); fscanf(fp,"%d %f %f",&BR,&BMPTemp,&Pi); fclose(fp); //fin de la lectura de datos } return 1; } void filtro_pasa_bajos() { float wc,ts,es,e; //************************ //constantes para el filtro pasabajos wc=0.1*3.1416*2; // frecuencia de corte para el filtro ts=0.22; // tiempo de muestreo es=-wc*ts; // e=2.71828; // constante e //************************************************************ //FILTRO PASABAJOS //************************************************************ BMPTemp = (bmp.getTemperature()); //CALIBRANDO TEMPERATURA Pa = bmp.getPressure(); //PRESION ANTERIOR P=(1-pow(e,es))*Pa+Pi*pow(e,es); //filtro pasabajos } float get_altura() { float base,ex, cons, dif; float altura0; cons=(273+BMPTemp)/0.0065; ex=0.1903; // constante obtenida de (Ro*L)/(g*M) //************************ // condiciones iniciales para hallar la altura del sistema // la ecuacion utilizada para determinar la altura es la formula barometrica // con las constantes descritas en http://wikipedia/barometric altitud //************************************************************ //TOMANDO LA ALTURA //************************************************************ filtro_pasa_bajos(); base=P/P0; altura1=cons*(1-pow(base,ex)); //ecuacion barometrica //************************************************************ //ESCALANDO LA ALTURA A MEDIO METRO //************************************************************ altura0=floor(altura1); //RECONDEO AL MENOR dif=altura1-altura0; //SACANDO LA PARTE DECIMAL dif=dif*10; //CONVIRTIENDOLO A ENTERO dif=floor(dif); //REDONDEANDO AL MENOR if (altura1 >= 0){ //VER SI ES NEGATIVO O POSITIVO if(dif>=5){ h=altura0+0.5; //SI ES POSITIVO Y MAYOR A 5 LA PARTE DECIMAL, ANIADE .5 AL LA PARTE ENTERA } else{ h=altura0; //SI ES MENOR A 5 LA PARTE DECIMAL Y POSITIVO, SOLO TOMA LA PARTE ENTERA } } else{ if(dif<=5){ //SI ES NEGATIVO Y MENOR A 5 LA PARTE DECIMAL, LE SUMA .5 A LA PARTE ENTERA h=altura0+.5; } else{h=ceil(altura1); // SI EN NEGATIVO Y MAYOR A 5 LA PATE DECIMAL, REDONDEA AL MAYOR } } //************************************************************ //FIN DEL REDONDEO //************************************************************ obc.printf("%.2f %.2f\n",altura1, h); //guarda en el sd //IMPRIME EN PANTALL Pi=P; return (h); } int guardar(int tipo) { int i; //si es de tipo 1, entonces son condicones iniciales if (tipo==1) { if(BR==0) { //CREACION Y APERTURA DEL ULTIMO DOCUMENTO CREADO //lectura del numero del ultimo documento creado. FILE *dp=fopen("/sd/carpetas/numero.txt","r"); if(dp==NULL){printf("no se pudo acceder al sd 2..."); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset();} fscanf(dp,"%d",&ND); fclose(dp); ND=ND+1; // creando la carpeta y guardando los datos iniciales en la carpeta de datos de prueba FILE *dp1=fopen("/sd/carpetas/numero.txt","w"); if(dp1==NULL){printf("no se pudo acceder al sd 3..."); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset();} fprintf(dp1,"%d",ND); fclose(dp1); //GRaBANDO LAS CONDICIONES INICIALES EN EL DOCUMENTO CI FILE *fp=fopen("/sd/condiciones/ci.txt","w"); if(fp==NULL){printf("no s epudo acceder al sd 4..."); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset();} fprintf(fp,"%d %f %f \r\n", BR,BMPTemp,Pi); fclose(fp); // creando la carpeta y guardando los datos iniciales en la carpeta condiciones iniciales dato[25]=ND+48; printf(dato,".txt"); printf("\n"); FILE *fobc=fopen(dato,"a"); for (i=0;i<100;i++) { fprintf(fobc,"%.2f \r\n",Pp[i]); wait(0.01); } fclose(fobc); //fin de la cracion del documento y guardado de datos /////GUARDANDO EL PRIMER DATO EN EL NUEVO DOCUMENTO CREADO file[16]=ND+48; //ajuste a ascii printf(file,".txt"); printf("\n"); FILE *pp=fopen(file,"w"); if(pp==NULL) { printf("no s epudo acceder al sd..5"); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset(); } fprintf(pp,"%f %f %f inicio\r\n",t.read(),BMPTemp,Pi); fclose(pp); led=1; //wait(1); } else{BR=0; } //GRABANDO LAS CONDICIONES INICIALES EN EL DOCUMENTO CI FILE *fp=fopen("/sd/condiciones/ci.txt","w"); if(fp==NULL){printf("no s epudo acceder al sd 6..."); BR=1;// abbrir documento de condiciones iniciles y cambiar Br para doocumentar el resetprogramado NVIC_SystemReset();} fprintf(fp,"%d %f %f \r\n", BR,BMPTemp,Pi); fclose(fp); //fin de la escrituta de datos de datos //lectura del numero del ultimo documento creado. FILE *dp=fopen("/sd/carpetas/numero.txt","r"); fscanf(dp,"%d",&ND); fclose(dp); //fin de la lectura de dato FILE *pp=fopen(file,"w"); fprintf(pp,"recuperacion del sistema satisfactoriamente\r\n"); fclose(pp); return (1); } else { if(tipo==2) { FILE *pp=fopen(file,"a"); if (pp == NULL) {printf("no se inicion 5...");} fprintf(pp,"%f %d %d %d %d %d %d %d %d %d %f %f %d %d %d %d %d %d %f\r\n",t.read(),imu[0],imu[1],imu[2],imu[3],imu[4],imu[5],imu[6],imu[7],imu[8],press,temperature,temp[1],sen_adc[0],sen_adc[1],sen_adc[2],suv,h); fclose(pp); return (2); } else { FILE *pp=fopen(file,"a"); if (pp == NULL) {printf("no se inicion 5...");} fprintf(pp,"%f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %f %f\r\n",t.read(),trama[0],trama[1],trama[2],trama[3],trama[4],trama[5],trama[6],trama[7],trama[8], trama[9],trama[10],trama[11],trama[12],trama[13],trama[14],trama[15],trama[16],trama[17],trama[18], trama[19],trama[20],trama[21],trama[22],trama[23],trama[24],trama[25],trama[26],trama[27],trama[28], trama[29], trama[30], h, altura1); fclose(pp); return (2); } } } void prog_camara(void) { led=0; camera=1; wait(1); camera=0; led=1; wait(2); camera=1; }