Guillermo Stedile / Mbed 2 deprecated SNOCC_V2

Dependencies:   NAVDATA RA8875 SDFileSystem VCODATA mbed

main.cpp

Committer:
gstedile
Date:
2017-06-23
Revision:
1:30b1ca228fc7
Parent:
0:e40cf759ba9a
Child:
2:968b38c3ef49

File content as of revision 1:30b1ca228fc7:


#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=1;                                       // -->1:Habilita informacion para debug.
int DEBUG2=1;                                       // -->1:Habilita informacion para debug2.
int DEBUG_GPS=0;                                   // -->1:Habilita datos para debug de comunicacion con gps.
enum sentido{DWN=0,UP,NO};
enum figura{ZONA=0,SIN_DT,CIRC,FLECHA,ElIP};
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=54;                                  //Velocidad Maxima
float Counter=0;                                    //Contador de pulsos del sensor de flujo.
float LCounter=0;                                   //Consumo en litros

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, "tft");              // 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;
}
int GetScreenCapture(void)
{
    char fqfn[50];
    int i = 0;
    pc.printf("Screen Capture... ");
    for (i=1; i< 100; i++) {
        snprintf(fqfn, sizeof(fqfn), "/local/Screen%02d.bmp", i);
        FILE * fh = fopen(fqfn, "rb");
        if (!fh) {
            lcd.PrintScreen(0,0,480,272,fqfn);
            pc.printf(" as /local/Screen%02d.bmp\r\n", i);
            return i;
        } else {
            fclose(fh);     
        }
    }
    return 0;
}
//>>>>>>>>>>>>>>>>>>  FIN SECCION TOUCH PANEL <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

 //Función para la interrupción
  
    void trigger() {                           
         Counter++;
         LCounter=Counter/2500;
         }
         
         
 /* 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 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=8;                  // 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.puts(">>>>>>>>>>>>>< Proyecto SNOCC ><<<<<<<<<<<<<<\r\n");
        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/m)\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){
            s = Matrix_VCO.NAV_DATA[VCO].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=VCO*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(VCO*x_scale+x_offset+10,y_offset-s*y_scale+20);
            lcd.printf("%lf l/m",s);              
            lcd.SetTextCursor(VCO*x_scale+x_offset+10,y_offset-s*y_scale+40);
            lcd.printf("VCO: %d kn",VCO);  

        }
        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) {
            //error("Could not open file for write\n");
            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) {
            //error("Could not open file for read\n");
            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,&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);                 // 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);   
        }
           
/* 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;
}


/* 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){
    int tx1,tx2,tx3,rx1,rx2,ty1,ty2,ty3,ry1,ry2, delta_ty1,delta_ty2,delta_ty3; 
    int cex,cey,cer1,cer2;
    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;
            ty1=y1;
            tx2=x2;
            ty2=(y2+y1)/2;
            tx3=x1;
            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;
        }
            break;
        case 0: {         // DWN
            tx1=(x2+x1)/2;
            ty1=y2;
            tx2=x2;
            ty2=(y2+y1)/2;
            tx3=x1;
            ty3=(y2+y1)/2;
            delta_ty1=-8;
            delta_ty2=5;
            delta_ty3=5;
            rx1=(x2+3*x1)/4;
            ry1=y1;
            rx2=(3*x2+x1)/4;
            ry2=(y2+y1)/2;
        }
        break;
        default:
        break;
    }
    switch (FIG){
            case 0:
                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.fillroundrect( x1+2,y1+2, x2-2,y2-2, 5,4,    RGB(R,G,B));
                lcd.SetTextCursor(x1+10,y1+(y2-y1)/5);
                lcd.background(BrightGreen);
                lcd.foreground(White);
                lcd.printf ("NAVEGANDO");
                lcd.SetTextCursor(x1+55,y1+(y2-y1)/2-10);
                //lcd.SetTextCursor(132,140);
                lcd.printf ("EN");
                lcd.SetTextCursor(x1+15,y1+(y2-y1)*2/3);
                //lcd.SetTextCursor(135,170);  
                lcd.printf ("ZONA VCO");          
            break;
            case 1:
                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.SetTextCursor(x1+10,y1+28);
                lcd.printf ("SIN DATOS");
                lcd.SetTextCursor(x1+1,y1+48);
                lcd.printf ("SUFICIENTES\r\n");                  
            break;
            case 2:   
                lcd.circle(       cex,cey,  cer2+10, BrightBlue);
                lcd.fillcircle(   cex,cey,cer2+5,RGB(R,G,B));
                
            break;
            case 3: 
                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(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-9,y1+(y2-y1)/5);
                lcd.background(BrightGreen);
                lcd.foreground(Black);
                lcd.printf ("A");
                lcd.SetTextCursor(x1+(x2-x1)/3-6,y1+(y2-y1)/2-10);
                //lcd.SetTextCursor(132,140);
                lcd.printf ("ZONA");
                lcd.SetTextCursor(x1+(x2-x1)/3-3,y1+(y2-y1)*2/3);
                //lcd.SetTextCursor(135,170);
                lcd.printf ("VCO");  
            break;
            case 4:
                lcd.ellipse(      cex,cey,  cer1,cer2, BrightBlue);
                lcd.fillellipse(  cex,cey, cer1-5,cer2-5, RGB(R,G,B));
            default:  
                lcd.circle(       cex,cey,  cer2+10, Blue);
                lcd.fillcircle(   cex,cey,cer2+5,RGB(R,G,B));     
            break;    
  
        }       
          
            
//      lcd.printf("printing 3 x 2 = %d", 3*2);
//     lcd.circle(       cex,cey,  cer2+10,               Blue);
//     lcd.fillcircle(   cex,cey,cer2+5,               Cyan);
///     lcd.ellipse(      440,75,  35,20,            BrightBlue);
///     lcd.fillellipse(  440,75,  25,10,            Blue);
//     lcd.triangle(     tx1,ty1,tx2,ty2,tx3,ty3, Blue);
//    lcd.filltriangle( tx1,ty1+delta_ty1, tx2-5,ty2+delta_ty2, tx3+5,ty3+delta_ty3, RGB(R,G,B));

///     lcd.rect(         400,130, 475,155,          Brown);
///     lcd.fillrect(     405,135, 470,150,          Pink);

//     lcd.fillroundrect(x1-4,y1-4, x2+4,y2+4,  5,3,Blue); 
//     lcd.roundrect( rx1,ry1,rx2,ry2, 10,8,    Blue);
//     lcd.fillroundrect(rx1+5,ry1+5, rx2-5,ry2-5,  5,3,   RGB(R,G,B) );

}


//###################-----------  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;
    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;       // 
    pc.baud(460800);                                           
    pc.printf("\r\nRA8875 Soft Fonts - Build " __DATE__ " " __TIME__ "\r\n");
    lcd.init();
    lcd.TouchPanelCalibrate();   // Funcion modificada para fijar calibracion.
    lcd.cls();
    rect_t PrintScreenRect = { 425-65, 20, 425+65, 60};     // Rectangulo para encuadrar boton.
    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");
        }
    }    
    wait(3);
         
       float delta=5.0;//DEBUG
       float virtual_tmstmp=0.0;//DEBUG 
       
    int   prueba=0;  // BORRAR ESTO. ES SOLO PARA PROBAR <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
       
// --------------------------------  LOOP INFINITO  ------------------------------------
    while(1) {
            
        lcd.SetTextCursor(0,0);             // Pongo cursor en posicion
        lcd.puts(">>>>>>>>>>>>>< Proyecto SNOCC ><<<<<<<<<<<<<<\r\n");
        if (DEBUG_GPS) lcd.printf("M0: %s \r\n\r\n", gps.msg);  //Imprimo el mensaje crudo proveniente de la uart
         
        if(gps.sample()) {                                      // Si es exitosa la obtencion de datos del gps.                        
            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
            lcd.SetTextCursor(0,0);                             // Cursor en posicion
            lcd.puts(">>>>>>>>>>>>>< Proyecto SNOCC ><<<<<<<<<<<<<<\r\n");
            
            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,2); // Luego de rotar los datos en la tabla de navegacion, 
                                                                    // la guarda en la matriz segun criterios de la clase VCODATA
                    
                int i=int(NAVIGATION_OBJECT.LAST_NAV_DATA[speed_p]);   
                //int VCO=NAVIGATION_VMATRIX.get_VCO(&VCC[0]);
                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 (DEBUG1) {    
                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
                }
                lcd.printf("Posicion: Long(%d):\t   %lf    ; Lat:     %lf\r\n",i,NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[longitude_f],NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[latitude_f]);   // DEBUG
                lcd.printf("FlujoVCOmtrx(%d):\t     %lf Litros/Hora\r\n",i, NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[cons_hour_p]);                  // DEBUG
                lcd.printf("FlujoVCOmtrx(%d):\t     %lf Litros/Milla\r\n",i, NAVIGATION_VMATRIX.NAV_DATA[i].LAST_NAV_DATA[cons_mile_p]);                 // DEBUG
                lcd.printf("Cons. Acumulado:\t      %lf l\r\n", LCounter);
                lcd.printf("VCO:\t                  %d knots\r\n", VCO); 
                
                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=80;   // REGION DE SEÑALIZACION
                int signal_y=60;
                int signal_x_sz=120;
                int signal_y_sz=150;
                
                //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 (VERDE)
                G1=255;
                B1=0;
                lcd.foreground(RGB(R1,G1,B1));
                lcd.SetTextCursor(200,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;  
                        signal_x=60;   // REGION DE SEÑALIZACION
                        signal_y=80;
                        signal_x_sz=150;
                        signal_y_sz=120;
                    }    
                    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);  //  SI ESTA EN ENTORNO DE VCO-->  IMPRIMIR "ZONA VCO". 
                
                }
                else {
                    int signal_x=80;   //CAMBIO ZONA DE SEÑALIZACION (PARA TEXTO "SIN DATOS..")
                    int signal_y=85;
                    signal_y_sz=100;    
                    signal_x_sz=130;
                    R1=190;
                    G1=190;
                    B1=190;
                    print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz,R,G,B,SIN_DT,NO);   // SIN DATOS: SOLO RECUADRO PARA TEXTO
    
                } 
                signal_x=265;            // ZONA PERFORMANCE
                signal_y=85;
                signal_x_sz=90;
                signal_y_sz=90;             
                print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz, R1, G1, B1,CIRC,NO);     // CIRCULO VERDE
                
                if (PRFM >= 0){
                    if (SENTIDO==DWN) {
                        print_signal(signal_x+5, (signal_y+5)-(signal_y_sz*(1-PRFM)), signal_x+signal_x_sz-5, (signal_y+signal_y_sz-5)-(signal_y_sz*(1-PRFM)), R, G, B,CIRC,NO);
                        lcd.SetTextCursor(signal_x+20,(signal_y+5)-(signal_y_sz*(1-PRFM))+ 25);                
                        lcd.foreground(RGB(0,0,0));
                        lcd.background(RGB(R,G,B));
                        lcd.SelectUserFont(BPG_Arial31x32);
                        lcd.printf ("%.2f\r\n",PRFM);
                    }    
                    else {
                        print_signal(signal_x+5, (signal_y+5)+(signal_y_sz*(1-PRFM)), signal_x+signal_x_sz-5, (signal_y+signal_y_sz-5)+(signal_y_sz*(1-PRFM)), R, G, B,CIRC,NO);
                        lcd.SetTextCursor(signal_x+20,(signal_y+5)+(signal_y_sz*(1-PRFM))+ 25);
                        lcd.foreground(RGB(0,0,0));
                        lcd.background(RGB(R,G,B));
                        lcd.SelectUserFont(BPG_Arial31x32);
                        lcd.printf ("%.2f\r\n",PRFM);       
                    }
                }    
                lcd.background(Black);
                lcd.foreground(RGB(0,255,0));
                lcd.SetTextCursor(20,245);
                lcd.SelectUserFont(BPG_Arial20x20);
                lcd.printf("VEL: %.1f \r\n",NAVIGATION_OBJECT.LAST_NAV_DATA[speed_p]);    // VELOCIDAD ACTUAL.

//____________________________________________________________________________________________________________________________________________________________              
            }
            else lcd.puts("Periodo no valido!\r\n");  
           
        } 
        else {    // No hay datos gps
            lcd.background(Black);
            lcd.cls();
            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);                     // Posicionamiento de cursor.
            lcd.puts(">>>>>>>>>>>>>< Proyecto SNOCC ><<<<<<<<<<<<<<\r\n");
            lcd.SetTextCursor(0,20);    
            
            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");

            //lcd.printf("Timetick %lf h\r\n", NAVIGATION_OBJECT.LAST_NAV_DATA[time_f]); 
            
            //_____________________________________________________________________________________________________________________
            int signal_x=80;   // REGION DE SEÑALIZACION
            int signal_y=60;
            int signal_x_sz=120;
            int signal_y_sz=150;
            
            if (prueba >= NAVIGATION_VMATRIX.vel_max) prueba=prueba-NAVIGATION_VMATRIX.vel_max;
            PRFM=NAVIGATION_VMATRIX.performance(prueba);
            R1=0;       // COLOR DEFAULT PARA CIRCULO DE REFERENCIA DE PERFORMANCE (VERDE)
            G1=255;
            B1=0;
            lcd.foreground(RGB(R1,G1,B1));
            //lcd.printf("Indice: %d \r\n",prueba);
            //lcd.printf("Perf.: %f \r\n",PRFM);
            lcd.SetTextCursor(200,245);
            lcd.printf("VCO: %d \t\t",NAVIGATION_VMATRIX.get_VCO(&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[prueba].LAST_NAV_DATA[speed_p]-VCC[0];
                
                //float delta_vel=int(NAVIGATION_OBJECT.LAST_NAV_DATA[speed_p])-VCC[0];
                
                if (fabs(delta_vel)<2){
                    FIG=ZONA;  
                    signal_x=60;   // REGION DE SEÑALIZACION
                    signal_y=80;
                    signal_x_sz=150;
                    signal_y_sz=120;
                }    
                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);  //  SI ESTA EN ENTORNO DE VCO-->  IMPRIMIR "ZONA VCO". 
            
            /*
            lcd.SetTextCursor(signal_x+signal_x_sz/2-6,signal_y+signal_y_sz/4);
            lcd.background(RGB(0,255,0));
            lcd.foreground(RGB(0,0,255));
            lcd.printf ("A");
            lcd.SetTextCursor(signal_x+signal_x_sz/3-3,signal_y+signal_y_sz/2-10);
            //lcd.SetTextCursor(132,140);
            lcd.printf ("ZONA");
            lcd.SetTextCursor(signal_x+signal_x_sz/3,signal_y+2*signal_y_sz/3);
            //lcd.SetTextCursor(135,170);
            lcd.printf ("VCO");  
            */
          
            
            //lcd.printf("Delta_v: %.0f \r\n",delta_vel);
            }
            else {
                int signal_x=80;   //CAMBIO ZONA DE SEÑALIZACION (PARA TEXTO "SIN DATOS..")
                int signal_y=85;
                signal_y_sz=100;    
                signal_x_sz=130;
                R1=190;
                G1=190;
                B1=190;
                print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz,R,G,B,SIN_DT,NO);   // SIN DATOS: SOLO RECUADRO PARA TEXTO

            } 
            signal_x=265;            // ZONA PERFORMANCE
            signal_y=85;
            signal_x_sz=90;
            signal_y_sz=90;             
            print_signal(signal_x, signal_y, signal_x + signal_x_sz,signal_y + signal_y_sz, R1, G1, B1,CIRC,NO);     // CIRCULO VERDE
            
            if (SENTIDO==DWN){
                print_signal(signal_x+5, (signal_y+5)-(signal_y_sz*(1-PRFM)), signal_x+signal_x_sz-5, (signal_y+signal_y_sz-5)-(signal_y_sz*(1-PRFM)), R, G, B,CIRC,NO);
                lcd.SetTextCursor(signal_x+20,(signal_y+5)-(signal_y_sz*(1-PRFM))+ 25);                
                lcd.foreground(RGB(0,0,0));
                lcd.background(RGB(R,G,B));
                lcd.SelectUserFont(BPG_Arial31x32);
                if (PRFM >= 0) lcd.printf ("%.2f\r\n",PRFM);
            }    
            else {
                print_signal(signal_x+5, (signal_y+5)+(signal_y_sz*(1-PRFM)), signal_x+signal_x_sz-5, (signal_y+signal_y_sz-5)+(signal_y_sz*(1-PRFM)), R, G, B,CIRC,NO);
                lcd.SetTextCursor(signal_x+20,(signal_y+5)+(signal_y_sz*(1-PRFM))+ 25);
                lcd.foreground(RGB(0,0,0));
                lcd.background(RGB(R,G,B));
                lcd.SelectUserFont(BPG_Arial31x32);
                lcd.printf ("%.2f\r\n",PRFM);       
            }
            lcd.background(Black);
            lcd.foreground(RGB(0,255,0));
            lcd.SetTextCursor(20,235);
            lcd.printf("Flujo Acum: %.1f \r\n",LCounter);
            lcd.SetTextCursor(20,245);
            lcd.SelectUserFont(BPG_Arial20x20);
            lcd.printf("Speed_p: %.1f \r\n",NAVIGATION_VMATRIX.NAV_DATA[prueba].LAST_NAV_DATA[speed_p]);
            prueba++;
            //______________________________________________________________________________________________________________________
            
            if (TESTING){      //DEBUG

           // ESTA PARTE ES PARA PROBAR EL FUNCIONAMIENTO DE LA ROTACION Y ALMACENAMIENTO DE DATOS......DEBUG.
            //lcd.SelectUserFont(BPG_Arial10x10);         // Seleccion de tipo y tamaño de letras
            
            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.
            
            }
            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 DEBUG
             }
                         
            for (int i=0;i<200;i++) {                 // Barrido para el touch
            point_t p;
            lcd.fillroundrect(PrintScreenRect,5,2, Green);
            lcd.roundrect(PrintScreenRect, 5,2, BrightBlue);
            lcd.foreground(BrightBlue);
            lcd.background(Green);
            lcd.puts(425-60, 22, "GET CURVE");
            lcd.background(Black);
            //wait_us(1);
            if (lcd.TouchPanelReadable(&p)) {
            //lcd.foreground(Blue);
            //lcd.SetTextCursor(10, 15);
            //lcd.printf("(%3d,%3d)", p.x, p.y);
            //lcd.foreground(RGB(255,255,0));
            
            if (Intersect(PrintScreenRect, p)) {
            lcd.foreground(Red);
            lcd.puts(400-38, 20, "GET CURVE");
            //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
            //lcd.puts(425-120, 22, "ANTES de PRINT");                     //DEBUG
            print_VCO_curve(NAVIGATION_VMATRIX,0);                  // Valores recolectados
            wait(2);
            print_VCO_curve(NAVIGATION_VMATRIX,1);                  // Interpolados (puntos)
            wait(3);
            print_VCO_curve(NAVIGATION_V_SMOOTH_MTRX,1);            // Suavizado (puntos)
            wait(3);
        
            print_VCO_curve(NAVIGATION_VMATRIX,2);                  // Interpolados (lineas)
            wait(3);
            print_VCO_curve(NAVIGATION_V_SMOOTH_MTRX,2);            // Suavizados (lineas)
            wait(3);
            if (DEBUG2){
                print_VCO_data(NAVIGATION_VMATRIX);                     // Volcado de datos
                wait(4);
            }  
            //GetScreenCapture();  
            break;

            }
            
           }
             lcd.foreground(RGB(255,255,0));
        }
    }
    }