With SD Card
Dependencies: NAVDATA RA8875 SDFileSystem VCODATA mbed
main.cpp
- Committer:
- gstedile
- Date:
- 2017-07-30
- Revision:
- 2:968b38c3ef49
- Parent:
- 1:30b1ca228fc7
File content as of revision 2:968b38c3ef49:
#include <time.h> #include "mbed.h" // v112 #include "RA8875.h" // v102 #include "MyFont18x32.h" #include "BPG_Arial08x08.h" #include "BPG_Arial10x10.h" #include "BPG_Arial20x20.h" #include "BPG_Arial31x32.h" #include "BPG_Arial63x63.h" #include "GPS.h" // Comunicacion con el gps. #include "NAVDATA.h" // Para la clase NAVDATA que maneja los datos de navegación del último período. #include "VCODATA.h" // Para la clase VCODATA que maneja los datos de navegación más recientes parametrizados por velocidad de cada período. #include "SDFileSystem.h" // SD Card #include <sstream> // Para uso de streams #include <string> int err_Store=0; int TESTING=0; // -->1:Habilita test de funcionamiento del almacenamiento de datos. int DEBUG1=0; // -->1:Habilita informacion para debug. int DEBUG2=0; // -->1:Habilita informacion para debug2. int DEBUG_GPS=0; // -->1:Habilita datos para debug de comunicacion con gps. int SIMULATION=1; // -->1: Habilita simulacion cuando no hay datos gps. enum sentido{DWN=0,UP,NO}; enum figura{ZONA=0,SIN_DT,CIRC,FLECHA,ElIP,GAUGE}; const char *sd_dir="/sd/snocc"; // Directorio de almacenamiento de datos. const char *sd_file="/sd/snocc/sdsnocc.csv"; // Archivo csv de almacenamiento de datos. const int V_M=40; //Velocidad Maxima float Counter=0; //Contador de pulsos del sensor de flujo. float LCounter=0; //Consumo en litros int sepx= 105; // Separacion x entre recuadros int sepy= 66; // Separacion x entre recuadros int sizex1=100; // Tamaño cuadro para valores int sizey1=40; int xr1=10; // Posicion de recuadros para exhibir datos int yr1=10; int xr2=xr1+sepx; int yr2=yr1; int xr3=xr1; int yr3=yr1+sepy; int xr4=xr1; int yr4=yr3+sepy; int xr5=xr1; int yr5=yr4+sepy; int xr6=xr2; int yr6=yr5; int signal_x=xr2; // REGION DE SEÑALIZACION int signal_y=yr3; int signal_x_sz=99; int signal_y_sz= 2*sepy-10; NAVDATA NAVIGATION_OBJECT; //Objeto que maneja los datos de navegación del último período. (ANTERIORMENTE LLAMADO NAVIGATION_TABLE, nombre que generaba confusion) VCODATA NAVIGATION_VMATRIX(NAVIGATION_OBJECT, V_M); // Objeto que maneja la matriz de datos de navegación $ VCODATA NAVIGATION_V_SMOOTH_MTRX(NAVIGATION_OBJECT, V_M); // Objeto que maneja la matriz de datos de navegación promediados $ NAVDATA TestNAV; // Objeto para crear matriz default; /// DEBUG? LocalFileSystem local("local"); // Para <PrintScreen> Serial pc(USBTX, USBRX); RA8875 lcd(p5, p6, p7, p8, NC, "lcd"); // MOSI, MISO, SCK, /ChipSelect, /reset, name // Comunicacion con Display SDFileSystem sd(p11, p12, p13, p14, "sd"); // SD CARD: mosi, miso, sclk, cs // Comunicacion con SD card //>>>>>>>>>>>>>>>>>> SECCION TOUCH PANEL <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< extern "C" void mbed_reset(); #define min(a,b) ((a<b)?a:b) #define max(a,b) ((a>b)?a:b) bool Intersect(rect_t rect, point_t p) { if (p.x >= min(rect.p1.x, rect.p2.x) && p.x <= max(rect.p1.x, rect.p2.x) && p.y >= min(rect.p1.y, rect.p2.y) && p.y <= max(rect.p1.y, rect.p2.y)) return true; else return false; } //>>>>>>>>>>>>>>>>>> FIN SECCION TOUCH PANEL <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //Función para la interrupción void trigger() { Counter++; LCounter=Counter/2500; } //##################### GAUGE - CLOCK ################################################################## uint16_t ccenterx=100, ccentery=100; //center x,y of the clock const uint16_t cradius = 110;//radius of the clock const float scosConst = 0.0174532925; float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0, vx = 0, vy = 0; float sdeg = 0, mdeg = 0, hdeg = 0, vdeg=0; uint16_t osx, osy, omx, omy, ohx, ohy,ovx, ovy; uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0; uint32_t targetTime = 0;// for next 1 second timeout uint8_t hh, mm, ss; //containers for current time void drawClockFace() { lcd.fillcircle(ccenterx, ccentery, cradius, Blue); lcd.fillcircle(ccenterx, ccentery, cradius - 4, Black); uint16_t span_angle=180; // Grados de span en el reloj. int j=0, RD=255,GN=255, BL=255; for (int i = 0; i <= span_angle; i += 2) { sx = cos((i - 180) * scosConst); sy = sin((i - 180) * scosConst); x0 = sx * (cradius - 4) + ccenterx; yy0 = sy * (cradius - 4) + ccentery; x1 = sx * (cradius - 40) + ccenterx; yy1 = sy * (cradius - 40) + ccentery; if (i < span_angle/2)j=i; else j=(span_angle-i) ; if (2*j/span_angle>0.9) { RD=0; GN=255; BL=0; } else if (2*j/span_angle<0.75){ RD=255; GN=255*4*(2*j/span_angle)/3; BL=0; } else { RD=255*4*(1-(2*j/span_angle)); GN=255; BL=0; } if (i<10 || i>170) lcd.line(x0, yy0, x1, yy1, RGB(255,0,0)); else if (i<20 || i>160) lcd.line(x0, yy0, x1, yy1,RGB(255,50,0)); else if (i<30 || i>150) lcd.line(x0, yy0, x1, yy1, RGB(255,120,0)); else if (i<40 || i>140) lcd.line(x0, yy0, x1, yy1, RGB(255,200,0)); else if (i<50 || i>130) lcd.line(x0, yy0, x1, yy1, RGB(255,255,0)); else if (i<60 || i>120) lcd.line(x0, yy0, x1, yy1, RGB(200,255,0)); else if (i<70 || i>110) lcd.line(x0, yy0, x1, yy1, RGB(120,255,0)); else if (i<80 || i>100) lcd.line(x0, yy0, x1, yy1, RGB(50,255,0)); else lcd.line(x0, yy0, x1, yy1, RGB(0,255,0)); } for (int i = 0; i <= span_angle; i +=5 ) { // DIBUJO ESCALA 1 //sx = cos((i - 90) * scosConst); sx = cos((i - 180) * scosConst); //sy = sin((i - 90) * scosConst); sy = sin((i - 180) * scosConst); x0 = sx * (cradius - 4) + ccenterx; yy0 = sy * (cradius - 4) + ccentery; x1 = sx * (cradius - 10) + ccenterx; yy1 = sy * (cradius - 10) + ccentery; lcd.line(x0, yy0, x1, yy1, White); } for (int i = 0; i <= span_angle; i +=15 ) { // DIBUJO ESCALA 2 sx = cos((i - 180) * scosConst); sy = sin((i - 180) * scosConst); x0 = sx * (cradius - 4) + ccenterx; yy0 = sy * (cradius - 4) + ccentery; x1 = sx * (cradius - 20) + ccenterx; yy1 = sy * (cradius - 20) + ccentery; lcd.line(x0, yy0, x1, yy1, White); } lcd.SetTextCursor(ccenterx-35, ccentery-25); lcd.SelectUserFont(BPG_Arial20x20); lcd.background(Black); lcd.foreground(RGB(0,0,255)); lcd.printf("SNOCC"); lcd.SetTextCursor(ccenterx-35, ccentery+15); lcd.printf("METER"); lcd.SetTextCursor(ccenterx-18, (ccentery - cradius +20)); lcd.background(RGB(0,255,0)); lcd.foreground(Black); lcd.printf("VCO"); lcd.background(Black); } void setup(void) { lcd.foreground(White); lcd.background(Black); //ccenterx = lcd.width() / 2; //ccentery = lcd.height() / 2; osx = ccenterx; osy = ccentery; omx = ccenterx; omy = ccentery; ohx = ccenterx; ohy = ccentery; } void drawClockGauge(float value, float fullscl ) { // Ej. fullscl 2 => -1 a 1 vdeg=180 * value/fullscl; vx = cos((vdeg - 90) * scosConst); vy = sin((vdeg - 90) * scosConst); lcd.filltriangle(vx * (cradius - 14) + ccenterx + 1, vy * (cradius - 14) + ccentery + 1, (ccenterx + 1)-(vy * (cradius - 14))*0.1, (ccentery + 1)+vx * (cradius - 14)*0.1,(ccenterx + 1)+(vy * (cradius - 14))*0.1, (ccentery + 1)-vx * (cradius - 14)*0.1, RGB(200,255,0), FILL); lcd.line(vx * (cradius - 14) + ccenterx + 1, vy * (cradius - 14) + ccentery + 1, ccenterx + 1, ccentery + 1, Red); lcd.fillcircle(ccenterx + 1, ccentery + 1, 3, Red); } void drawPrintPrfm( int x, int y, float val){// ubicacion x,y, valor lcd.roundrect( x,y,x+82,y+36,6,4, RGB(0,0,255)); lcd.SelectUserFont(BPG_Arial31x32); if (val==0) lcd.SetTextCursor(x+15,y+3); // 100-val=100 ---> print 100 else lcd.SetTextCursor(x+21,y+3); lcd.foreground(RGB(200,255,0)); lcd.background(Black); if ( val<=100) { lcd.printf ("%2.0f \r\n",100-val); // Valor porcentual del complemento lcd.SelectUserFont(BPG_Arial20x20); lcd.SetTextCursor(x+62,y+11); lcd.printf("%%"); } else lcd.printf ("---\r\n"); } void drawPrintTime(uint16_t x, uint16_t y, uint8_t h, uint8_t m, uint8_t s) { lcd.SetTextCursor (x, y); lcd.printf(__DATE__); lcd.SetTextCursor (x, y - 13); if (hh > 12) { if (hh < 22) lcd.printf("0"); lcd.printf ("%d",hh - 12); } else { if (hh < 10) lcd.printf("0"); lcd.printf ("%d",hh); } lcd.printf (":"); if (mm < 10) lcd.printf("0"); lcd.printf ("%d",mm); lcd.printf (":"); if (ss < 10) lcd.printf("0"); lcd.printf ("%d",ss); if (hh > 12) { lcd.printf(" pm"); } else { lcd.printf (" am"); } } void reloj(uint16_t cx,uint16_t cy,sentido sent,float gauge, float fullscale){ // coord x, coord y, valor, fondo de escala; ccenterx = cx; ccentery = cy; osx = ccenterx; osy = ccentery; omx = ccenterx; omy = ccentery; ohx = ccenterx; ohy = ccentery; drawClockFace(); drawClockGauge(gauge, fullscale ); drawPrintPrfm(ccenterx - 40, ccentery +40, abs(gauge*100)); } /* Funcion build_default_Mtrx: Carga los datos (consumo/milla) del vector LAST_NAV_DATA de los objetos NAVDATA de VCODATA para testing.*/ /* Si el parámetro virtual_speed es cero, se completa la matríz con valores default. Sino, se carga solamente un vector NAVDATA con valores default consistentes con los parámetros y se almacena en la matríz cuando la cantidad de períodos a vel constante es alcanzada. Este caso es utilizado para testing.*/ int build_default_Mtrx(VCODATA &Test_Matrix_VCO,NAVDATA &TestNDO, double virtual_speed, double virtual_timestamp){ double virtual_time=0; double virtual_longitude=-58.5797; // Mantiene cte la Longitud. double virtual_latitude=-34.4251; double virtual_counter=0; if (virtual_speed==0){ //virtual_timestamp=0.00000001; // en segundos for (int i=1; i< Test_Matrix_VCO.vel_max; i++){ virtual_speed= i*1.0; if (i<12) virtual_time=5.0*i; // Formato NMEA: hhmmss,ss else { int mnts=int(5*i/60); virtual_time = ((mnts*100) +((5*i)- (mnts*60))); // Formato NMEA: (hh)mmss,ss } TestNDO.LAST_NAV_DATA[cons_interpolated]=-1; // --> -1:Datos iniciales. TestNDO.np_concat=0; // Cantidad de periodos concatenados:-->0: Solo valores de inicio. virtual_latitude+=(virtual_speed*5/3600)/(59.99999981628485);// Tomo delta_t virtual de (virtual_speed*Delta t) y // calculo latitud recorrida en virtual_timestamp @virtual_speed y longitud cte. if (i<10) virtual_counter+=0.6*i*i; // Simulacion de consumo; modificar y probar else if (i<20) virtual_counter+=55; else if(i<30) virtual_counter+=900/i; else virtual_counter+=0.06*i*i; int err_Rot=TestNDO.rotate_data(virtual_longitude, virtual_latitude, virtual_time, virtual_counter, NAVIGATION_VMATRIX.vel_max); virtual_timestamp+=5; // en segundos, 5 segundos de período if(err_Rot==0){ // Si la rotacion fue 100% exitosa if(Test_Matrix_VCO.store_data(TestNDO,1)!=0) return -1; //Notar que no requiere validar velocidad constante para almacenar; almacena todos los periodos bien rotados. } else { if(err_Rot==1) return 1; // Tiempo entre muestras demasiado grande. Períódo no válido. else return 2; // Timestamp no válido. } } } else{ // Rota valores para la velocidad indicada, seteando valores crecientes de consumo para testing TestNDO.np_concat=0; // Cantidad de periodos concatenados:-->0: Solo valores de inicio. float virtual_longitude=-58.5797; // Mantiene cte la Longitud. float virtual_latitude=-34.4251+((virtual_speed*virtual_timestamp)/(59.99999981628485*3600));// Tomo delta_t virtual de (virtual_speed*virtual_timestamp) y calculo // latitud navegada en virtual_timestamp @virtual_speed y longitud cte. virtual_time=virtual_timestamp; //en formato NMEA hhmmss,ss float virtual_counter=0.01*virtual_timestamp*virtual_timestamp; // Simulacion de consumo creciente; modificar y probar int err_Rot=TestNDO.rotate_data(virtual_longitude, virtual_latitude, virtual_time, virtual_counter, NAVIGATION_VMATRIX.vel_max); if(err_Rot==0){ // Si la rotacion fue 100% exitosa if(Test_Matrix_VCO.store_data(TestNDO,2)==-1) return -1; // Notar que requiere 2 períodos a igual velocidad para que se almacene definitivamente. } else { if(err_Rot==1) return 1; // Tiempo entre muestras demasiado grande. Períódo no válido. else return 2; // Timestamp no válido. } } return 0; } /* Funcion print_VCO_curve : Imprime la curva de consumo/milla en funcion de la velocidad a partir del vector de objetos NAV_DATA de la clase VCODATA, con lineas (printline=1) o puntos (=0) Parametros: Objeto VCODATA; Interpolated: 0 -> no imprime valores interpolados o promediados; 1: interpola con puntos, 2: interpola con lineas*/ void print_VCO_curve(VCODATA &Matrix_VCO, int interpolated){ //lcd.puts("ENTRANDO a print_VCO_curve\r\n"); // DEBUG int vcc[2]; float r,s; // Consumo int y,x; int VCO= Matrix_VCO.get_VCO(vcc); int y_offset=250; //Para que imprima de abajo hacia arriba. int y_text_offset=15; //Para cooregir diferencia de impresion entre caracter y linea. int x_offset=30; //Posicionamiento en x int y_i=y_offset; //Punto origen y int x_i=x_offset; //Punto origen x int x_scale=10; // Escala para graficar eje x. int y_scale=90; // Escala para graficar eje y. lcd.background(RGB(255,255,255)); lcd.foreground(Blue); lcd.SelectUserFont(BPG_Arial20x20); lcd.SetTextCursor(0,0); // Pongo cursor en posicion lcd.cls(); lcd.roundrect( 5,20,470,270,10,8, RGB(255,255,0)); // Rectangulo para encuadre de graficos lcd.fillroundrect(10,25,465,264,5,3,Green); lcd.foreground(RGB(255,255,0)); lcd.background(Green); for (int n=0;n<Matrix_VCO.vel_max;n++){ // Recorre x de 0 a vel_max. s = Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_mile_p]; // Consumo por milla del período y=int(y_offset-y_scale*s); // El consumo máximo es alrededor de 2 l/m => Multiplico por y_scale // para que ocupe mas pantalla. x=n*x_scale+x_offset; // para aumentar el span (eje x) switch (interpolated){ case 0: if (Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_interpolated]==0){ //Valores sin interpolar lcd.SetTextCursor(x,y-y_text_offset); lcd.printf("."); } break; case 1: if ((Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_interpolated]==1) || (Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_interpolated]==2))lcd.foreground(Orange); // interpola con puntos de otro color lcd.SetTextCursor(x,y-y_text_offset); // el offset adicional es para corregir la diferencia de ubicacion linea-caracter. lcd.printf("."); lcd.foreground(RGB(255,255,0)); break; case 2: lcd.line(x_i,y_i,x,y); // Imprime linea break; default: lcd.SetTextCursor(x,y-y_text_offset); lcd.printf("."); break; } x_i=x; y_i=y; } x_i=x_offset; y_i=y_offset; lcd.SelectUserFont(BPG_Arial10x10); // Seleccion de tipo y tamaño de letras lcd.background(Green); lcd.foreground(Blue); lcd.SetTextCursor(30,32); lcd.puts("Cons.(l/mn)\r\n"); lcd.SetTextCursor(420,235); lcd.puts("Vel.(kn)\r\n"); lcd.line(x_i,y_i,Matrix_VCO.vel_max*x_scale+x_offset,y_i); // Imprimo eje x. for(int j=10;j<=Matrix_VCO.vel_max;j+=10){ int x=j*x_scale+x_offset; lcd.line(x,y_i,x,y_i-5); lcd.SetTextCursor(x,y_i+5); lcd.printf("%d",j); } lcd.line(x_i,y_i,x_i,40); // Imprimo eje y. for(int k=1;k<=5;k++){ y=y_offset-k*0.5*y_scale; lcd.line(x_i,y,x_i+10,y); lcd.SetTextCursor(x_i-15,y+5); if(y>=0)lcd.printf("%.1f",k*0.5); } if (VCO>0){ r = Matrix_VCO.NAV_DATA[vcc[1]].LAST_NAV_DATA[cons_mile_p]; // Valor de consumo para VMC. s = Matrix_VCO.NAV_DATA[vcc[0]].LAST_NAV_DATA[cons_mile_p]; // Valor de consumo para VCO. y=int(y_offset-y_scale*s); // el consumo máximo es alrededor de 2 l/m. Multiplico por y_scale para que ocupe mas pantalla. x=vcc[0]*x_scale+x_offset; // para aumentar el span (eje x) if (interpolated==2){ lcd.circle(x,y,5); } else{ lcd.SetTextCursor(x,y); lcd.printf("*"); } lcd.SetTextCursor(vcc[0]*x_scale+x_offset+10,y_offset-s*y_scale+20); lcd.printf("%.2lf l/m",s); lcd.SetTextCursor(vcc[0]*x_scale+x_offset+10,y_offset-s*y_scale+10); lcd.printf("VCO: %d kn",vcc[0]); y=int(y_offset-y_scale*r); // el consumo máximo es alrededor de 2 l/m. Multiplico por y_scale para que ocupe mas pantalla. x=vcc[1]*x_scale+x_offset; // para aumentar el span (eje x) if (interpolated==2){ lcd.circle(x,y,5); } else{ lcd.SetTextCursor(x,y); lcd.printf("*"); } lcd.SetTextCursor(vcc[1]*x_scale+x_offset+10,y_offset-r*y_scale-20); lcd.printf("%.2lf l/m",r); lcd.SetTextCursor(vcc[1]*x_scale+x_offset+10,y_offset-r*y_scale-30); lcd.printf("VMC: %d kn",vcc[1]); } else{ lcd.SetTextCursor(120,35); lcd.SelectUserFont(BPG_Arial10x10); // Seleccion de tipo y tamaño de letras lcd.printf("No hay datos suficientes para obtener la VCO"); lcd.printf("%d",VCO);//DEBUG } lcd.foreground(RGB(255,255,0)); lcd.background(Black); } /* Funcion print_VCO_data : Imprime una tabla con los datos de consumo/milla en funcion de la velocidad a partir del vector de objetos NAV_DATA de la clase VCODATA. Parametros: Objeto VCODATA; */ void print_VCO_data(VCODATA &Matrix_VCO){ float cons, vel; lcd.SelectUserFont(BPG_Arial10x10); // Seleccion de tipo y tamaño de letras lcd.background(RGB(255,255,255)); lcd.foreground(Blue); lcd.SetTextCursor(0,0); // Pongo cursor en posicion lcd.cls(); lcd.puts("Velocidad-Consumo\r\n"); for (int n=0;n<83;n++){ // Recorre x de 0 a 83. (Maxima cantidad que entra en una pantalla) cons = Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_mile_p]; // Consumo por milla del período vel= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[speed_p]; // Velocidad del período. lcd.printf("| %d - %lf | %lf |",n,vel,cons); } wait(3); lcd.cls(); for (int n=83;n<Matrix_VCO.vel_max;n++){ // Recorre x de 0 a vel_max. cons = Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_mile_p]; // Consumo por milla del período vel= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[speed_p]; // Velocidad del período. lcd.printf("| %d - %lf | %lf |",n,vel,cons); } //lcd.SelectUserFont(BPG_Arial20x20); // Seleccion de tipo y tamaño de letras } /* Funcion mtrx2sd: Guarda los datos de la matriz en un archivo de texto existente*/ int mtrx2sd(VCODATA &Matrix_VCO, const char *filename){ double lngtd_f,lngtd_i,lttd_f,lttd_i,tm_f,tm_i,dstnc_p,spd_p,cnsmptn_i,cnsmptn_f,cnsmptn_p,cns_ml_p,cns_hr_p,cns_ntrpltd; // Variables de navegacion; FILE *fp1; fp1 = fopen(filename, "w"); //Apertura para escritura if(fp1 == NULL) { return -1; } for (int n=0;n<=Matrix_VCO.vel_max;n++){ lngtd_f= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[longitude_f]; // Longitud y Latitud iniciales y finales. lngtd_i= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[longitude_i]; lttd_f= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[latitude_f]; lttd_i= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[latitude_i]; tm_f= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[time_f]; // El dato (timestamp al final del período en cuestion, en horas) se obtendrá luego proveniente del GPS. tm_i= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[time_i]; // Timestamp al inicio del período en horas. dstnc_p= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[distance_p]; // Distancia recorrida durante este período en millas nauticas. spd_p= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[speed_p]; // Velocidad media del período en nudos. cnsmptn_i= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[consumption_i]; // Consumo en litros al comienzo del período. cnsmptn_f= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[consumption_f]; // Consumo en litros al final del período. cnsmptn_p= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[consumption_p]; // Consumo en litros del período. cns_ml_p= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_mile_p]; // Consumo en litros por milla nautica. cns_hr_p= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_hour_p]; // Consumo en litros por hora. cns_ntrpltd= Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_interpolated]; // Consumo interpolado?: -1-> initial padding fprintf(fp1,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\r\n",lngtd_f,lngtd_i,lttd_f,lttd_i,tm_f,tm_i,dstnc_p,spd_p,cnsmptn_i,cnsmptn_f,cnsmptn_p,cns_ml_p,cns_hr_p,cns_ntrpltd); } return fclose(fp1); } /* Funcion sd2mtrx: Guarda los datos de un archivo de texto existente en la matriz*/ int sd2mtrx(VCODATA &Matrix_VCO, const char *filename){ double lngtd_f,lngtd_i,lttd_f,lttd_i,tm_f,tm_i,dstnc_p,spd_p,cnsmptn_i,cnsmptn_f,cnsmptn_p,cns_ml_p,cns_hr_p,cns_ntrpltd; // Variables de navegacion; FILE *fp1; fp1 = fopen(filename, "r"); //Apertura para escritura if(fp1 == NULL) { return -1; } for (int n=0;n<Matrix_VCO.vel_max;n++){ fscanf(fp1,"%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf;%lf",&lngtd_f,&lngtd_i,<td_f,<td_i,&tm_f,&tm_i,&dstnc_p,&spd_p,&cnsmptn_i,&cnsmptn_f,&cnsmptn_p,&cns_ml_p,&cns_hr_p,&cns_ntrpltd); // Leemos un double y lo guardamos Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[longitude_f]=lngtd_f; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[longitude_i]=lngtd_i; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[latitude_f]=lttd_f; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[latitude_i]=lttd_i; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[time_f]=tm_f; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[time_i]=tm_i; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[distance_p]=dstnc_p; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[speed_p]=spd_p; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[consumption_i]=cnsmptn_i; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[consumption_f]=cnsmptn_f; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[consumption_p]=cnsmptn_p; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_mile_p]=cns_ml_p; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_hour_p]=cns_hr_p; Matrix_VCO.NAV_DATA[n].LAST_NAV_DATA[cons_interpolated]=cns_ntrpltd; } return fclose(fp1); } /* Function print_signal: imprime un simbolo a partir de las coordenadas de un rectangulo: signal=0-> ZONA VCO,1:Sin datos; 2:Circulo; 3:flecha; 4: elipse */ void print_signal(int x1, int y1, int x2, int y2, int R, int G, int B, figura FIG, sentido S, float prfm){ int tx1,tx2,tx3,rx1,rx2,ty1,ty2,ty3,ry1,ry2, delta_ty1,delta_ty2,delta_ty3; uint16_t cex,cey,cer1,cer2; int delta=6; // Redimensiono para ajstar la figura dentro del rectangulo x1+=delta; y1+=delta; x2-=delta; y2-=delta; cex=(x1+x2)/2; cey=(y1+y2)/2; cer2= (y2-y1)/2; cer1= (x2-x1)/2; switch (S){ case 1: { // UP tx1=(x2+x1)/2; //Dimensiones para flecha ty1=y1+4; tx2=x2-2; ty2=(y2+y1)/2; tx3=x1+2; ty3=(y2+y1)/2; delta_ty1=8; delta_ty2=-5; delta_ty3=-5; rx1=(x2+3*x1)/4; ry1=(y2+y1)/2; rx2=(3*x2+x1)/4; ry2=y2-4; } break; case 0: { // DWN tx1=(x2+x1)/2; ty1=y2-4; tx2=x2-2; ty2=(y2+y1)/2; tx3=x1+3; ty3=(y2+y1)/2; delta_ty1=-8; delta_ty2=5; delta_ty3=5; rx1=(x2+3*x1)/4; ry1=y1+4; rx2=(3*x2+x1)/4; ry2=(y2+y1)/2; } break; default: break; } switch (FIG){ case 0: // ZONA VCO // lcd.roundrect( x1-8,y1-8,x2+8,y2+8, 10,8, BrightBlue); //lcd.roundrect( x1-4,y1-4, x2+4,y2+4, 10,8, RGB(153,0,153)); //lcd.foreground(BrightBlue); lcd.SelectUserFont(BPG_Arial10x10); lcd.fillroundrect( x1+3,y1+3, x2-3,y2-3, 5,4, RGB(R,G,B)); lcd.SetTextCursor(x1+14,y1-10+(y2-y1)/5); lcd.background(RGB(R,G,B)); lcd.foreground(White); lcd.printf ("NAVEGANDO"); lcd.SetTextCursor(x1+29,y1-18+(y2-y1)/2-10); //lcd.SetTextCursor(132,140); lcd.SelectUserFont(BPG_Arial20x20); lcd.printf ("EN"); lcd.SetTextCursor(x1+19,y1-18+(y2-y1)*2/3); //lcd.SetTextCursor(135,170); lcd.printf ("ZONA"); lcd.SetTextCursor(x1+24,y1-18+(y2-y1)*9/10); //lcd.SetTextCursor(135,170); lcd.printf ("VCO"); break; case 1: // SIN DATOS //lcd.roundrect( x1-8,y1-8,x2+8,y2+8, 10,8, BrightBlue); //lcd.roundrect( x1-4,y1-4, x2+4,y2+4, 10,8, RGB(153,0,153)); lcd.fillroundrect( x1+3,y1+3, x2-3,y2-3, 5,4, RGB(0,0,0)); // Limpia el rectangulo lcd.foreground(BrightBlue); lcd.SelectUserFont(BPG_Arial10x10); lcd.SetTextCursor(x1+18,y1+38); lcd.printf ("SIN DATOS"); lcd.SetTextCursor(x1+14,y1+68); lcd.printf ("SUFICIENTES\r\n"); break; case 2: // CIRCULO lcd.fillroundrect( x1+3,y1+3, x2-3,y2-3, 5,4, RGB(0,0,0)); //Limpia el rectangulo lcd.circle( cex,cey, cer2+10, BrightBlue); lcd.fillcircle(cex,cey,cer2+5,RGB(R,G,B)); break; case 3: // FLECHA //lcd.roundrect( x1-8,y1-8,x2+8,y2+8, 10,8, BrightBlue); //lcd.roundrect( x1-4,y1-4, x2+4,y2+4, 10,8, RGB(153,0,153)); lcd.fillroundrect( x1+3,y1+3, x2-3,y2-3, 5,4, RGB(0,0,0)); //Limpia el rectangulo lcd.fillroundrect(rx1,ry1, rx2,ry2, 5,3, RGB(R,G,B) ); lcd.filltriangle( tx1,ty1, tx2,ty2, tx3,ty3, RGB(R,G,B)); lcd.SetTextCursor(x1+(x2-x1)/2-3,y1+(y2-y1)/5); lcd.background(BrightGreen); lcd.foreground(Black); lcd.SelectUserFont(BPG_Arial10x10); lcd.printf ("A"); lcd.SetTextCursor(x1+(x2-x1)/3,y1+(y2-y1)/2-10); //lcd.SetTextCursor(132,140); lcd.printf ("ZONA"); lcd.SetTextCursor(x1+(x2-x1)/3+2,y1+(y2-y1)*2/3); //lcd.SetTextCursor(135,170); lcd.printf ("VCO"); break; case 4: // ELIPSE lcd.fillroundrect( x1+3,y1+3, x2-3,y2-3, 5,4, RGB(0,0,0)); //Limpia el rectangulo lcd.ellipse( cex,cey,cer1,cer2, BrightBlue); lcd.fillellipse( cex,cey, cer1-5,cer2-5, RGB(R,G,B)); break; case 5: // RELOJ if (S==UP)reloj(cex,cey,S,prfm-1,2); else reloj(cex,cey,S,1-prfm,2); // coord x, coord y, sentido, valor, fondo de escala; break; default: reloj(cex,cey,S,prfm-1,2); break; } } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FUNCION print_fondo1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< void print_fondo1(uint8_t r, uint8_t g,uint8_t b,uint8_t r1, uint8_t g1,uint8_t b1){ int y_offset=250; //Para que imprima de abajo hacia arriba. int x_offset=30; //Posicionamiento en x lcd.background(RGB(0,0,0)); lcd.foreground(RGB(r1,g1,b1)); lcd.SelectUserFont(BPG_Arial20x20); lcd.SetTextCursor(0,0); // Pongo cursor en posicion lcd.cls(); lcd.roundrect( 2,2,475,270,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de graficos lcd.fillroundrect(7,7,470,264,5,3, RGB(r,g,b)); lcd.foreground(RGB(r1,g1,b1)); lcd.background(RGB(r,g,b)); // Para escribir sobre este fondo } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fin FUNCION print_fondo1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FUNCION print_fondo2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< void print_fondo2(uint8_t r, uint8_t g,uint8_t b,uint8_t r1, uint8_t g1,uint8_t b1){ /* Declaradas int sepx= 105; // Separacion x entre recuadros int sepy= 66; // Separacion x entre recuadros int sizex1=100; // Tamaño cuadro para valores int sizey1=40; int xr1=10; // Posicion de recuadros para exhibir datos int yr1=10; int xr2=xr1+sepx; int yr2=yr1; int xr3=xr1; int yr3=yr1+sepy; int xr4=xr1; int yr4=yr3+sepy; int xr5=xr1; int yr5=yr4+sepy; int xr6=xr1; int yr6=yr5+sepy; */ lcd.background(RGB(0,0,0)); lcd.foreground(RGB(r1,g1,b1)); lcd.SelectUserFont(BPG_Arial20x20); lcd.SetTextCursor(0,0); // Pongo cursor en posicion lcd.roundrect( xr1,yr1,xr1+sizex1,yr1+sepy-8,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de valores //lcd.fillroundrect(xr1+3,yr1+4,xr1+95,yr1+sizey1,8,5, Black); //RGB(r,g,b)); // Rectangulo interior lleno lcd.roundrect(xr1+3,yr1+4,xr1+95,yr1+sizey1,8,5, RGB(r,g,b)); // Vacio lcd.roundrect( xr2,yr2,xr2+sizex1,yr2+sepy-8,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de valores //lcd.fillroundrect(xr2+4,yr2+4,xr2+95,yr2+sizey1,8,5, Black); //RGB(r,g,b)); lcd.roundrect(xr2+4,yr2+4,xr2+95,yr2+sizey1,8,5, RGB(r,g,b)); lcd.roundrect( xr3,yr3,xr3+sizex1,yr3+sepy-8,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de valores //lcd.fillroundrect(xr3+4,yr3+4,xr3+95,yr3+sizey1,8,5, Black); //RGB(r,g,b)); lcd.roundrect(xr3+4,yr3+4,xr3+95,yr3+sizey1,8,5, RGB(r,g,b)); lcd.roundrect( xr4,yr4,xr4+sizex1,yr4+sepy-8,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de valores //lcd.fillroundrect(xr4+4,yr4+4,xr4+95,yr4+sizey1,8,5, Black); //RGB(r,g,b)); lcd.roundrect(xr4+4,yr4+4,xr4+95,yr4+sizey1,8,5, RGB(r,g,b)); lcd.roundrect( xr5,yr5,xr5+sizex1,yr5+sepy-8,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de valores //lcd.fillroundrect(xr5+4,yr5+4,xr5+95,yr5+sizey1,8,5, Black); //RGB(r,g,b)); lcd.roundrect(xr5+4,yr5+4,xr5+95,yr5+sizey1,8,5, RGB(r,g,b)); lcd.roundrect( xr6,yr6,xr6+sizex1,yr6+sepy-8,10,8, RGB(r1,g1,b1)); // Rectangulo para encuadre de valores //lcd.fillroundrect(xr6+4,yr6+4,xr6+95,yr6+sizey1,8,5, Black); //RGB(r,g,b)); lcd.roundrect(xr6+4,yr6+4,xr6+95,yr6+sizey1,8,5, RGB(r,g,b)); lcd.roundrect( signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz+3, 10,8, BrightBlue); //Rectangulo para encuadre de grafico de señalizacion (Flecha) //lcd.roundrect( signal_x+4, signal_y-4, signal_x+signal_x_sz+4,signal_y + signal_y_sz+4, 10,8, RGB(153,0,153)); lcd.foreground(RGB(r1,g1,b1)); //lcd.background(RGB(r,g,b)); // Si se usa lleno, para escribir sobre este fondo lcd.background(Black); // Para rectangulo vacio } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIN FUNCION print_fondo2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FUNCION print_values <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< void print_values(int vel, int vco, int vmc, double cons_m, double cons_h, float lcount){ int offset_x=30, offset_y=8; // Para ubicar los valores dentro de los recuadros del fondo2. print_fondo2(255,255,255,0,0,255); // ya deja el background correcto //lcd.background(Black); // int foregndcolor=RGB(0,255,0); int despx=7,despy=7; lcd.SelectUserFont(BPG_Arial31x32); lcd.SetTextCursor(xr1+offset_x,yr1+offset_y); lcd.fillroundrect(xr1+despx,yr1+despy,xr1+sizex1-despx,yr1+sizey1-3,8,5,Black); lcd.foreground(foregndcolor); lcd.printf("%2d ",vel); lcd.SetTextCursor(xr2+ offset_x,yr2+offset_y); lcd.fillroundrect(xr2+despx,yr2+despy,xr2+sizex1-despx,yr2+sizey1-3,8,5, Black); lcd.foreground(foregndcolor); lcd.printf("%2d",vco); lcd.SetTextCursor(xr3+offset_x,yr3+offset_y); lcd.fillroundrect(xr3+despx,yr3+despy,xr3+sizex1-despx,yr3+sizey1-3,8,5, Black); lcd.foreground(foregndcolor); lcd.printf("%2d", vmc); lcd.SetTextCursor(xr4+offset_x-10,yr4+offset_y); lcd.fillroundrect(xr4+despx,yr4+despy,xr4+sizex1-despx,yr4+sizey1-3,8,5, Black); lcd.foreground(foregndcolor); lcd.printf("%.2lf", cons_m); lcd.SetTextCursor(xr5+offset_x-10,yr5+offset_y); lcd.fillroundrect(xr5+despx,yr5+despy,xr5+sizex1-despx,yr5+sizey1-3,8,5, Black); lcd.foreground(foregndcolor); lcd.printf("%.2lf", cons_h); lcd.SetTextCursor(xr6+offset_x-10,yr6+offset_y); lcd.fillroundrect(xr6+despx,yr6+despy,xr6+sizex1-despx,yr6+sizey1-3,8,5, Black); lcd.foreground(foregndcolor); if (lcount<100)lcd.printf("%.2lf", lcount); else lcd.printf("%.1lf", lcount); lcd.SelectUserFont(BPG_Arial10x10); lcd.background(Black); lcd.foreground(RGB(0,255,0)); lcd.SetTextCursor(xr1+offset_x-12,yr1+sepy-28+offset_y); lcd.printf("VEL.GPS(kt)"); lcd.SetTextCursor(xr2+offset_x-5,yr2+sepy-28+offset_y); lcd.printf("VCO (kt)"); lcd.SetTextCursor(xr3+offset_x-5,yr3+sepy-28+offset_y); lcd.printf("VMC (kt)"); lcd.SetTextCursor(xr4+offset_x-7,yr4+sepy-28+offset_y); lcd.printf("Cons.(L/M)"); lcd.SetTextCursor(xr5+offset_x-5,yr5+sepy-28+offset_y); lcd.printf("Cons(L/H)"); lcd.SetTextCursor(xr6+offset_x-15,yr6+sepy-28+offset_y); lcd.printf("Cons.Ac(L/M)"); } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIN FUNCION print_values <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FUNCION bienvenida <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< void bienvenida(){ // Prueba de gauge print_fondo1(0,0,0,0,0,255); lcd.SelectUserFont(BPG_Arial63x63); lcd.SetTextCursor(135,34); lcd.foreground(RGB(0,255,0)); lcd.puts("SNOCC"); lcd.SelectUserFont(BPG_Arial31x32); lcd.SetTextCursor(20,130); lcd.foreground(RGB(0,255,0)); lcd.puts("S"); lcd.foreground(RGB(255,255,0)); lcd.puts("istema\t"); lcd.foreground(RGB(0,255,0)); lcd.puts(" N"); lcd.foreground(RGB(255,255,0)); lcd.puts("autico de "); lcd.foreground(RGB(0,255,0)); lcd.puts(" O"); lcd.foreground(RGB(255,255,0)); lcd.puts("ptimizacion "); lcd.SetTextCursor(40,200); lcd.foreground(RGB(255,255,0)); lcd.puts("de "); lcd.foreground(RGB(0,255,0)); lcd.puts("C"); lcd.foreground(RGB(255,255,0)); lcd.puts("onsumo "); lcd.puts("de "); lcd.foreground(RGB(0,255,0)); lcd.puts("C"); lcd.foreground(RGB(255,255,0)); lcd.puts("ombustible"); wait(5); lcd.cls(); print_fondo1(0,225,0,0,255,0); lcd.SelectUserFont(BPG_Arial63x63); lcd.background(RGB(0,220,0)); lcd.foreground(RGB(220,255,0)); lcd.SetTextCursor(95,20); lcd.puts("Bienvenido"); lcd.SetTextCursor(220,100); lcd.puts("a"); lcd.SetTextCursor(160,190); lcd.puts("Bordo"); wait(5); lcd.cls(); print_fondo1(0,0,0,0,0,255); print_fondo2(255,255,255,0,0,255); reloj(345,135,UP,-1,2); wait(1); reloj(345,132,UP,1,2); wait(1); reloj(345,132,UP,0,2); wait(3); lcd.cls(); print_fondo1(0,0,0,0,0,255); } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIN FUNCION bienvenida <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FUNCION despedida <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< void despedida(){ lcd.cls(); print_fondo1(0,225,0,0,255,0); lcd.SelectUserFont(BPG_Arial63x63); lcd.background(RGB(0,225,0)); lcd.foreground(RGB(220,255,0)); lcd.SetTextCursor(170,20); lcd.puts("Hasta"); lcd.SetTextCursor(100,100); lcd.puts(" el proximo"); lcd.SetTextCursor(170,180); lcd.puts("viaje..."); wait(2); lcd.background(RGB(0,100,0)); lcd.cls(); lcd.SetTextCursor(112,100); lcd.puts("SNOCC"); wait(2); for (int i=0; i<273;i++){ lcd.foreground(RGB(0,225,0)); lcd.line(0,i,480,i); wait_ms(15); lcd.foreground(RGB(200,200,255)); lcd.line(0,i+2,480,i+2); lcd.foreground(RGB(0,0,200)); lcd.line(0,i,480,i); wait_ms(15); lcd.foreground(RGB(0,0,200)); lcd.line(0,i+2,480,i+2); } lcd.background(RGB(0,0,0)); lcd.cls(); while(1); } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIN FUNCION despedida <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //################################################### MAIN ################################################### int main() { int VCC[2]; // Array de valores crucero críticos. VCC[0]=VCO; VCC[1]=VMC (Velocidad de Máximo Consumo) VCC[0]=-1; VCC[1]=-1; bool menu_flag1=0; // Flags para touch bool menu_flag2=1; bool menu_flag3=0; // 1--> Apagar int R,G,B=0; int R1,G1,B1=0; int err_Mtrx=0; float PRFM=-1; // Performance sentido SENTIDO; // Sentido de la flecha figura FIG; loc_t butt_x1=450; // Posicion boton1 loc_t butt_y1=240; loc_t butt_x2=405; // Posicion boton2 loc_t butt_y2=40; loc_t butt_x3=450; // Posicion boton3 loc_t butt_y3=12; rect_t PrintScreenRectB1 = { butt_x1-20, butt_y1, butt_x1+20, butt_y1+25}; // Rectangulo para encuadrar boton 1. rect_t PrintScreenFillRectB1 = { butt_x1-18, butt_y1+2, butt_x1+18, butt_y1+23 }; // Rectangulo relleno para encuadrar boton 1 rect_t PrintScreenRectB2 = { butt_x2-25, butt_y2, butt_x2+25, butt_y2+25}; // Rectangulo para encuadrar boton 2. rect_t PrintScreenFillRectB2 = { butt_x2-23, butt_y2+2, butt_x2+24, butt_y2+23 }; // Rectangulo relleno para encuadrar boton 2 rect_t PrintScreenRectB3 = { butt_x3-18, butt_y3, butt_x3+18, butt_y3+25}; // Rectangulo para encuadrar boton 3. rect_t PrintScreenFillRectB3 = { butt_x3-16, butt_y3+2, butt_x3+16, butt_y3+23 }; // Rectangulo relleno para encuadrar boton 3. pc.baud(460800); lcd.init(); lcd.TouchPanelCalibrate(); // Esta funcion fue modificada para fijar calibracion. lcd.cls(); lcd.foreground(RGB(255,255,0)); // Seteo del color de las letras. lcd.SelectUserFont(BPG_Arial20x20); // Seleccion de tipo y tamaño de letras GPS gps(p9, p10); // Agrego para comunicacion con el GPS //------------------------------------------------------------------------------------------------------------- // Sensor de flujo: InterruptIn pulse_sensor(p15); // Defino pulse_sensor como una entrada de interrupción en p15 . pulse_sensor.mode(PullUp); // PullUp para esa entrada. //pulse_sensor.rise(&trigger); // Dispara interrupción con flanco ascendente. (Podría tambien ser desecendente--> fall) pulse_sensor.fall(&trigger); //-------------------------------------------------------------------------------------------------------------- lcd.SetTextCursor(0,0); // Posicionamiento de cursor. lcd.puts(">>>>>>>>>>>>>< Proyecto SNOCC ><<<<<<<<<<<<<<\r\n"); if (!sd2mtrx(NAVIGATION_VMATRIX, sd_file)) lcd.puts("Datos leidos de SD card\r\n"); // Cargando matriz desde SD. else{ lcd.puts("Error al leer los datos.\r\n Inicio sin datos historicos.\r\n"); if (TESTING){ err_Mtrx=build_default_Mtrx(NAVIGATION_VMATRIX,TestNAV,0,0); if(err_Mtrx!=0) lcd.printf("Error al crear la Matriz default.%d\r\n",err_Mtrx); // Creando matriz de inicio default. else lcd.printf("Matriz default creada con exito.\r\n"); } if (!mtrx2sd(NAVIGATION_VMATRIX, sd_file)) lcd.printf("Datos default guardados en SD card\r\n"); else { lcd.puts("Error al guardar los datos default.\r\nCreando directorio en SD card...\r\n"); if(!mkdir(sd_dir, 0777)){ // Creando directorio si no existe. lcd.printf("Creado: %s\r\n", sd_dir); lcd.printf("Cargando datos de inicio default en SD card...\r\n"); if (!mtrx2sd(NAVIGATION_VMATRIX, sd_file)) lcd.printf("Datos default guardados en SD card\r\n"); else lcd.puts("Error al guardar los datos default.\r\nNo se podran almacenar los datos.\r\n"); } else lcd.puts("Error al guardar los datos default.\r\nNo se podran almacenar los datos.\r\n"); } } bienvenida(); // Bienvenida float delta=5.0;//DEBUG float virtual_tmstmp=0.0;//DEBUG int prueba=0; // Variable indice para simulacion. ///////////////////////////////////////////////// LOOP INFINITO //////////////////////////////////////////////////// while(1) { lcd.SetTextCursor(0,0); // Pongo cursor en posicion if (DEBUG_GPS)lcd.printf("M0: %s \r\n\r\n", gps.msg); //Imprimo el mensaje crudo proveniente de la uart if(!menu_flag1){ //Boton 1 no presionado if(gps.sample()) { // Si es exitosa la obtencion de datos del gps. lcd.foreground(RGB(0,255,0)); // Seteo del color de las letras. lcd.SelectUserFont(BPG_Arial20x20); // Seleccion de tipo y tamaño de letras lcd.SetTextCursor(0,0); // Cursor en posicion if (!NAVIGATION_OBJECT.rotate_data(gps.longitude, gps.latitude, gps.time, Counter,NAVIGATION_VMATRIX.vel_max )){ NAVIGATION_OBJECT.LAST_NAV_DATA[cons_interpolated]=0; // Dato tipo recolectado err_Store=NAVIGATION_VMATRIX.store_data(NAVIGATION_OBJECT,3); // Luego de rotar los datos en la tabla de navegacion, // la guarda en la matriz segun criterios de la clase VCODATA // Deben registrarse 3 periodos de velocidad quasi constante para // que se almacene definitivamente el dato consolidado de los mismos. int i=int(NAVIGATION_OBJECT.LAST_NAV_DATA[speed_p]); NAVIGATION_V_SMOOTH_MTRX.smooth(4, NAVIGATION_VMATRIX); // Genera matriz de datos filtrados con pasabajos int VCO=NAVIGATION_V_SMOOTH_MTRX.get_VCO(&VCC[0]); // VCO OBTENIDA DE MATRIZ FILTRADA. print_values(NAVIGATION_OBJECT.LAST_NAV_DATA[speed_p], VCC[0],VCC[1], NAVIGATION_OBJECT.LAST_NAV_DATA[cons_mile_p], NAVIGATION_OBJECT.LAST_NAV_DATA[cons_hour_p], LCounter); if (DEBUG1) { lcd.SetTextCursor(0,60); lcd.puts("Rotacion exitosa!-->"); lcd.printf("Error de rotacion:\t %d\r\n",err_Store); // DEBUG lcd.printf("Speed_f_Mtrx(%d):\t %lf kn.\r\n",i, NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[speed_p]); // DEBUG lcd.printf("Speed_f_Last(%d):\t\t %lf km/h.\r\n",i, NAVIGATION_OBJECT.LAST_NAV_DATA[speed_p]*1.852); // DEBUG lcd.printf("Time_f_Mtrx(%d):\t %lf Hours.\r\n",i, NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[time_f]); // DEBUG lcd.printf("Time_f_Last(%d):\t %lf Hours.\r\n",i, NAVIGATION_OBJECT.LAST_NAV_DATA[time_f]); // DEBUG lcd.printf("Dist_p_Mtrx(%d):\t %lf miles.\r\n",i,NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[distance_p]); // DEBUG } NAVIGATION_VMATRIX.interpolate(); // Interpolacion. if (!mtrx2sd(NAVIGATION_VMATRIX, sd_file)) lcd.printf("Datos guardados en SD card\r\n"); // Almacenamiento de datos en SD. else lcd.printf("Error al guardar los datos.\r\n"); //______ _______________________________________________________________________________________________________________ /*int signal_x=100; // REGION DE SEÑALIZACION int signal_y=75; int signal_x_sz=110; int signal_y_sz=120;*/ //PRFM=NAVIGATION_VMATRIX.performance(i); PRFM=NAVIGATION_V_SMOOTH_MTRX.performance(i); // PERFORMANCE OBTENIDA DE MATRIZ FILTRADA. R1=0; // COLOR DEFAULT PARA CIRCULO DE REFERENCIA DE PERFORMANCE (,PRFM) G1=255; B1=0; lcd.foreground(RGB(R1,G1,B1)); /*lcd.SetTextCursor(0,245); lcd.printf("VCO: %d \t\t",VCC[0]); lcd.printf("VMC: %d \r\n",VCC[1]); */ if (PRFM!=-1 && VCC[0]!=-1){ if (PRFM>0.98) { R=0; G=255; B=0; } else { if (PRFM<0.75){ R=255; G=255*4*PRFM/3; B=0; } else { R=255*4*(1-PRFM); G=255; B=0; } } float delta_vel= NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[speed_p]-VCC[0]; // ES IGUAL QUE EN MTRX FILTRADA if (fabs(delta_vel)<2){ FIG=ZONA; } else FIG=FLECHA; if (delta_vel<0) SENTIDO=UP; else SENTIDO=DWN; print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz, 0, 255, 0,FIG,SENTIDO,PRFM); // SI ESTA EN ENTORNO DE VCO--> IMPRIMIR "ZONA VCO". } else { print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz,R,G,B,SIN_DT,NO,PRFM); // SIN DATOS: SOLO RECUADRO PARA TEXTO } // =================================== ZONA PERFORMANCE =================================================================== if (PRFM >= 0) print_signal(305, 85,385,175, R, G, B,GAUGE,SENTIDO,PRFM); else print_signal(305, 85, 385,175, R, G, B,GAUGE,UP, 2.35); lcd.background(Black); lcd.foreground(RGB(0,255,0)); // =================================== FIN ZONA PERFORMANCE =================================================================== //############################## MODULO DE PERIODO NO VALIDADO ######################################################################### } else {lcd.puts("Periodo no valido!\r\n"); wait(1); print_fondo1(0,0,0,0,0,255); print_fondo2(255,255,255,0,0,255); } } else { // No hay datos gps lcd.foreground(RGB(0,255,0)); // Seteo del color de las letras. lcd.SelectUserFont(BPG_Arial20x20); // Seleccion de tipo y tamaño de letras lcd.SetTextCursor(10,10); if (DEBUG1){ if (!mtrx2sd(NAVIGATION_VMATRIX, sd_file)) lcd.printf("Datos default guardados en SD card\r\n"); //DEBUG else lcd.printf("Error al guardar los datos default.\r\n"); //DEBUG lcd.printf("Aun no hay datos gps disponibles. Usando historicos.\r\n"); } NAVIGATION_V_SMOOTH_MTRX.smooth(4, NAVIGATION_VMATRIX); // Genera matriz de datos filtrados con pasabajos int VCO=NAVIGATION_V_SMOOTH_MTRX.get_VCO(&VCC[0]); // VCO OBTENIDA DE MATRIZ FILTRADA. if(!SIMULATION) print_values(-1, VCC[0],VCC[1],-1, NAVIGATION_OBJECT.LAST_NAV_DATA[cons_hour_p], LCounter); //_____________________________________________________________________________________________________________________ // REGION DE SEÑALIZACION if (prueba >= NAVIGATION_VMATRIX.vel_max) prueba=prueba-NAVIGATION_VMATRIX.vel_max; PRFM=NAVIGATION_V_SMOOTH_MTRX.performance(prueba); // PERFORMANCE OBTENIDA DE MATRIZ FILTRADA. float delta_vel= NAVIGATION_VMATRIX.NAV_DATA[prueba].LAST_NAV_DATA[speed_p]-VCC[0]; // Diferencia de velocidad respecto de la vco if (PRFM!=-1 && VCC[0]!=-1){ if (fabs(delta_vel)<2) FIG=ZONA; else FIG=FLECHA; if (delta_vel<0) SENTIDO=UP; else SENTIDO=DWN; print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz, 0, 255, 0,FIG,SENTIDO,PRFM); // SI ESTA EN ENTORNO DE VCO--> IMPRIMIR "ZONA VCO". } else { print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz,R,G,B,SIN_DT,NO,PRFM); // SIN DATOS SUFICIENTES } // =================================== ZONA PERFORMANCE =================================================================== if (PRFM >= 0) print_signal(305, 85,385,175, R, G, B,GAUGE,SENTIDO,PRFM); else print_signal(305, 85, 385,175, R, G, B,GAUGE,UP, 2.35); print_values(NAVIGATION_VMATRIX.NAV_DATA[prueba].LAST_NAV_DATA[speed_p], VCC[0],VCC[1], NAVIGATION_VMATRIX.NAV_DATA[prueba].LAST_NAV_DATA[cons_mile_p], NAVIGATION_VMATRIX.NAV_DATA[prueba].LAST_NAV_DATA[cons_hour_p], LCounter); lcd.background(Black); lcd.foreground(RGB(0,255,0)); lcd.SetTextCursor(223,12); lcd.SelectUserFont(BPG_Arial10x10); //lcd.printf("Speedsim[%d]: %.1f \r\n",prueba,NAVIGATION_VMATRIX.NAV_DATA[prueba].LAST_NAV_DATA[speed_p]); lcd.printf("SIMULACION"); wait_ms(600); lcd.foreground(RGB(255,0,0)); lcd.SetTextCursor(223,12); lcd.SelectUserFont(BPG_Arial10x10); lcd.printf("SIMULACION"); prueba++; // ====================================== FIN ZONA PERFORMANCE =============================================================== //%%%%%%%%%%%%%%%%% ESTA PARTE ES PARA VALIDAR EL FUNCIONAMIENTO DE LA ROTACION Y ALMACENAMIENTO DE DATOS %%%%%%%%%%%%%%%%%%%%% if (TESTING){ //DEBUG float vrtl_speed=12; // pruebo cargar datos para velocidad 12. TestNAV.LAST_NAV_DATA[cons_interpolated]=0; // --> -1:Datos iniciales. 0--> recolectado (setear para testing) err_Mtrx=build_default_Mtrx(NAVIGATION_VMATRIX, TestNAV, vrtl_speed, virtual_tmstmp); if(err_Mtrx!=0){ lcd.printf("Error al cargar datos en la Matriz default.%d..\r\n", err_Mtrx); // DEBUG; ya se crea la matriz en el arranque, si no hay archivo. } else lcd.printf("Datos para virtual_speed= %.1f cargado con exito.\r\n",vrtl_speed); lcd.printf("Virtual_Timestamp=%.2f.\t",virtual_tmstmp);//DEBUG virtual_tmstmp+=delta; // DEBUG Esta en formato NMEA(hhmmss.ss): no son validos los valores de segundos mayores a 59, por lo tanto // cuando se ingrese 100,00 despues de 95,00 se espera que el sistema no valide la ronda pues en ese // formato 100,00 < 95,00 (1m < 95s); seria un valor entrante menor que el anterior. lcd.printf("V_time(h):%lf\r\n",TestNAV.time_NMEA2hours(virtual_tmstmp)); } //%%%%%%%%%%%%% FIN DE LA PARTE PARA PROBAR EL FUNCIONAMIENTO DE LA ROTACION Y ALMACENAMIENTO DE DATOS......DEBUG.%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%% DEBUG2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if (DEBUG2){ int buff_indx=int(NAVIGATION_VMATRIX.NAV_DATA[NAVIGATION_VMATRIX.vel_max].LAST_NAV_DATA[speed_p]+0.5); // DEBUG lcd.printf("Cons_m_p[%d]= %.3f l/ml\t",buff_indx, NAVIGATION_VMATRIX.NAV_DATA[buff_indx].LAST_NAV_DATA[cons_mile_p]); lcd.printf("Dist_p[%d]= %lf ml\r\n",buff_indx, NAVIGATION_VMATRIX.NAV_DATA[buff_indx].LAST_NAV_DATA[distance_p]); lcd.printf("Tiempo_f[%d]= %lf h\t",buff_indx, NAVIGATION_VMATRIX.NAV_DATA[buff_indx].LAST_NAV_DATA[time_f]); lcd.printf("Tiempo_i[%d]= %lf h\r\n",buff_indx, NAVIGATION_VMATRIX.NAV_DATA[buff_indx].LAST_NAV_DATA[time_i]); lcd.printf("Buff_INDX = %d \t", buff_indx); lcd.printf("Speed_p[%d]= %.2f knots\r\n",buff_indx, NAVIGATION_VMATRIX.NAV_DATA[buff_indx].LAST_NAV_DATA[speed_p]); lcd.printf("Per_con[vel_max]= %d \t", NAVIGATION_VMATRIX.NAV_DATA[NAVIGATION_VMATRIX.vel_max].np_concat); lcd.printf("V_buff[%d]= %.2f\t", NAVIGATION_VMATRIX.vel_max,NAVIGATION_VMATRIX.NAV_DATA[NAVIGATION_VMATRIX.vel_max].LAST_NAV_DATA[speed_p]); lcd.printf("TestNAV-time_f = %lf \t", TestNAV.LAST_NAV_DATA[time_f]); lcd.printf("TestNAV-time_i = %lf \r\n", TestNAV.LAST_NAV_DATA[time_i]); lcd.printf("TestNAV-max_per_t = %lf \t", TestNAV.max_period_time); lcd.printf("TestNAV-time_p = %lf \r\n", TestNAV.LAST_NAV_DATA[time_f]-TestNAV.LAST_NAV_DATA[time_i]); lcd.printf("TestNAV-cons_m_p = %lf \t", TestNAV.LAST_NAV_DATA[cons_mile_p]); lcd.printf("TestNAV-cons_h_p = %lf \r\n", TestNAV.LAST_NAV_DATA[cons_hour_p]); //lcd.SelectUserFont(BPG_Arial20x20); // Seleccion de tipo y tamaño de letras } //%%%%%%%%%%%%% FIN DEBUG2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } //===========================TOUCH & ACTIONS =================================================================================================== lcd.fillroundrect(PrintScreenFillRectB1,5,2, RGB(50,100,0)); lcd.roundrect(PrintScreenRectB1, 8,3, RGB(0,0,255)); lcd.fillroundrect(PrintScreenFillRectB3,10,10, RGB(100,0,0)); lcd.roundrect(PrintScreenRectB3, 12,12, RGB(255,0,0)); lcd.foreground(RGB(0,0,255)); lcd.background(RGB(50,100,0)); lcd.SelectUserFont(BPG_Arial10x10); lcd.puts(butt_x1-18, butt_y1+4, "CURVA"); lcd.SelectUserFont(BPG_Arial10x10); lcd.foreground(RGB(255,0,0)); lcd.background(RGB(100,0,0)); lcd.puts(butt_x3-10, butt_y3+10, "OFF"); lcd.background(Black); for (int i=0;i<2000;i++) { // Barrido para el touch point_t p; if (lcd.TouchPanelReadable(&p)) { menu_flag1=Intersect(PrintScreenRectB1, p); // Levanta menu_flag1 menu_flag3=Intersect(PrintScreenRectB3, p); // Levanta menu_flag3 if (menu_flag1){ lcd.foreground(RGB(255,0,0)); lcd.background(RGB(50,255,0)); lcd.puts(butt_x1-18, butt_y1+4, "CURVA"); // Indica boton presionado i=2000; menu_flag2=0; } // Baja menu_flag2 else { if (menu_flag3) despedida(); } } wait_ms(2); } lcd.background(Black); } // Fin if menu_flag1 else { // Boton 1 presionado if(!menu_flag2) { // Boton 2 no presionado //if(build_default_Mtrx(NAVIGATION_VMATRIX)==-1) lcd.printf("Error al crear la Matriz default...\r\n"); // DEBUG Curve NAVIGATION_V_SMOOTH_MTRX.smooth(4, NAVIGATION_VMATRIX); // Genera matriz de datos filtrados con pasabajos print_VCO_curve(NAVIGATION_VMATRIX,0); // Valores recolectados wait(2); print_VCO_curve(NAVIGATION_VMATRIX,1); // Interpolados (puntos) wait(2); print_VCO_curve(NAVIGATION_V_SMOOTH_MTRX,1); // Suavizado (puntos) wait(2); print_VCO_curve(NAVIGATION_VMATRIX,2); // Interpolados (lineas) wait(2); print_VCO_curve(NAVIGATION_V_SMOOTH_MTRX,2); // Suavizados (lineas) lcd.SelectUserFont(BPG_Arial10x10); lcd.fillroundrect(PrintScreenFillRectB2,5,2, BrightBlue); lcd.roundrect(PrintScreenRectB2, 8,5, White); lcd.foreground(RGB(0,255,0)); lcd.background(BrightBlue); for (int j=0;j<2000;j++) { // Barrido para el touch point_t p2; lcd.puts(butt_x2-21, butt_y2 +4, "VOLVER"); //lcd.background(Black); if (lcd.TouchPanelReadable(&p2)) { menu_flag2=Intersect(PrintScreenRectB2, p2); if (menu_flag2) { lcd.foreground(Red); lcd.puts(butt_x2-40, butt_y2 +4, "VOLVER"); menu_flag1=0; // Bajo menu_flag1; j=2000; print_fondo1(0,0,0,0,0,255); //Imprimo fondo de pantalla ppal. print_fondo2(50,50,255,0,0,255); } } } } // Fin if boton2 no presionado } // Fin else (boton 1 presionado) lcd.foreground(RGB(0,255,0)); } //Fin while 1 }