![](/media/cache/profiles/me.png.50x50_q85.jpg)
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-06-08
- Revision:
- 0:642a7818292a
- Child:
- 1:a147ca4f8fa0
File content as of revision 0:642a7818292a:
/*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 //LocalFileSystem sd("local");// 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 //HMC5883L 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 camara(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); //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; //********************************************* //**********interruobcion 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 Vcondicional=0; //iniciando camara camera=0; led=1; wait(2); camera=1; led=0; wait(1); 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; while(h<0.4){ 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(); tipo=2; RS[12]= guardar(tipo); save_mision(); build_tr2(); 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(); tipo=2; RS[12]= guardar(tipo); build_tr1(); 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=h; float hact=get_altura(); while(hact>=0){ obc.printf("********************sleep mode**************************"); //while(hact!=0.0){ hant=hact; hact=get_altura(); take_tl(); take_mision(); save_tl(); tipo=2; RS[12]= guardar(tipo); save_mision(); hact=hact-hant; obc.printf("diferente de cero alt=%f\n",h); } //******* OFF MODE //camara=1; // apagando camara wait(0.5 ); camera=0; wait(1); camera=1; wait(3); obc.printf("apagando camara\n\r"); led=0; Vcondicional=1; //apagando sensores sc.putc(sos); obc.printf("sos: %d\n",sos); //obc.printf("%d\n",alt); //activar modo reset PWR_EnterSTANDBYMode(); //apagar obc } //********* Funciones void take_tl(void){ int i; IMU[0]=imu[0]=1;// mag.getMx(); IMU[1]=imu[1]=2;// mag.getMy(); IMU[2]=imu[2]=3;// mag.getMz(); uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050); // Read WHO_AM_I register for MPU-6050\ if (whoami == 0x68) // WHO_AM_I should always be 0x68 { 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] = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set imu[4]= (float)accelCount[1]*aRes - accelBias[1]; imu[5]= (float)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]= (float)gyroCount[0]*gRes; // - gyroBias[0]; // get actual gyro value, this depends on scale being set imu[7]= (float)gyroCount[1]*gRes; // - gyroBias[1]; imu[8]= (float)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 temp[0]=temperature*1000; //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);//temperatura en milivoltios ajuatado a 12 bits. sensor_adc[0]=temp3.read_u16();sen_adc[0]=(sensor_adc[0]>>4); sensor_adc[1]=corriente.read_u16();sen_adc[1]=(sensor_adc[1]>>4); sensor_adc[2]=voltaje.read_u16();sen_adc[2]=(sensor_adc[2]>>4); 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){ 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 %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],sensor_adc[0],sensor_adc[1],sensor_adc[2],suv,h); obc.printf("%.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],sensor_adc[0],sensor_adc[1],sensor_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 bar=ceil(P*100); //tomando los 20 bits sin procesar del barometro uint16_t y,z,y4,y3,y2,z4,ah,al; uint32_t par[3];// 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 paquetes de 32 bits par[0]=(bar<<12)|temp[0]; 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,y4,y3,y2,z4,ah,al; uint32_t par;// 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){ /* sc.putc(trama[1]); sc.putc(trama[2]); sc.putc(trama[3]); sc.putc(trama[4]); sc.putc(trama[5]); sc.putc(trama[6]); sc.putc(trama[7]); sc.putc(trama[8]); sc.putc(trama[9]); sc.putc(trama[10]); sc.putc(trama[11]); sc.putc(trama[12]); sc.putc(trama[13]); sc.putc(trama[14]); sc.putc(trama[15]); sc.putc(trama[16]); sc.putc(trama[17]); sc.putc(trama[18]); sc.putc(trama[19]); sc.putc(trama[20]); sc.putc(trama[21]); sc.putc(trama[22]); sc.putc(trama[23]); sc.putc(trama[24]); sc.putc(trama[25]); sc.putc(trama[26]); sc.putc(trama[27]); sc.putc(trama[28]); sc.putc(trama[29]); sc.putc(trama[30]); */ 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"); // obc.printf("%d..................",fp); fscanf(fp,"%d %f %f",&BR,&BMPTemp,&Pi); fclose(fp); //fin de la lectura de datos } //return (BMPTemp, pi); 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+.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); //GRBANDO 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++) { //FILE *fobc=fopen("/sd/condiciones/iniciales.txt","a"); 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 { FILE *pp=fopen(file,"a"); if (pp == NULL) {printf("no se inicion 5...");} fprintf(pp,"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %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],sensor_adc[0],sensor_adc[1],sensor_adc[2],suv,h); //fprintf(pp,"%f %f %f %f %f\r\n",t.read(),BMPTemp,P,h,altura1); //guarda en el sd fclose(pp); return (2); } }