Autor Tema: Problema:Micro se Reseta al usar fprintf con variable tipo float  (Leído 4152 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Problema:Micro se Reseta al usar fprintf con variable tipo float
« en: 01 de Agosto de 2014, 20:04:48 »
Hola a todos, estoy ante un caso que me parece bastante raro, poniendo en contexto, CCS 5.025  pic24FJ64GA002 8Mhz FRC, me estoy comunicando con un GPS via uart, el gps esta enviando todas sus tramas por defecto al micro y este las recibe por interrupción uart y las guardo en un buffer. Obtengo del buffer la Latitud y la Longitud y las guardo en variable tipo float cada una, ahora bien, cuando intento imprimir estas variables el micro se me resetea  :8} , porque sé que se resetea? justo antes del entrar al loop enciendo un led e imprimo "RESET" y observo que el led enciende y apaga e inmediatamente  en el terminal aparece indefinidamente "RESET". Con cualquier float sucede lo mismo, si imprimo otras variables no se resetea , todo lo estoy probando en real y descarto problemas de hardware
 
Código: C
  1. VOID MAIN()
  2. {
  3. SET_PULLUP(TRUE, PIN_B7 );
  4. SET_PULLUP(TRUE, PIN_B8 );
  5. ENABLE_INTERRUPTS(INT_EXT0);
  6. ENABLE_INTERRUPTS(INT_RDA2);
  7. ENABLE_INTERRUPTS(INT_RDA);
  8. ENABLE_INTERRUPTS(GLOBAL);
  9. OFFLED5
  10. OFFLED6
  11. OFFLED7
  12.  
  13.  
  14. FPUTS("RESET",UART1);
  15.  
  16. WHILE(TRUE)
  17. {
  18.    
  19.    IF(TRAMA_READY==1)
  20.    {
  21.    ONLED7
  22.    FPRINTF(UART1,"%F",LATITUD) ;
  23.    WHILE(1){}
  24.    
  25.    }
  26.    
  27. }//FIN WHILE
  28. }//FIN VOID
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #1 en: 02 de Agosto de 2014, 08:16:57 »
tienes alguna rutina para gestionar las interrupciones?? Veo que las pones enable pero no veo la funcion de la interrupcion.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #2 en: 02 de Agosto de 2014, 09:23:59 »
Hola, ¿por qué pones %F en vez de %f?

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #3 en: 02 de Agosto de 2014, 13:09:15 »
tienes alguna rutina para gestionar las interrupciones?? Veo que las pones enable pero no veo la funcion de la interrupcion.
si las tengo, no las puse porque también me pasa los mismo deshabilitando las interrupciones
tienes alguna rutina para gestionar las interrupciones?? Veo que las pones enable pero no veo la funcion de la interrupcion.
:mrgreen: constumbre de editar en mayúsculas, pero con %f sucede igual  :?

simulado va perfecto
« Última modificación: 02 de Agosto de 2014, 13:14:06 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #4 en: 03 de Agosto de 2014, 13:37:47 »
Se me ocurre que te esté faltando configurar algo de la uart1. Con esas macros que pones no se puede saber.  :(

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #5 en: 03 de Agosto de 2014, 19:44:34 »
ya me tiene loco el problemita este, despues de darle vueltas y vueltas he observado que es un problema con la interrupción asociada a la llegada de caracteres del GPS (el gps esta enviando Todas sus tramas) ,  pongo el código que uso y con el que se resetea el micro

Código: C
  1. #INCLUDE <24FJ64GA002.h>
  2. #INCLUDE <MATH.H>
  3. #INCLUDE <STDLIB.H>
  4. #FUSES ICSP1, NOWDT, NODEBUG, NOPROTECT, NOJTAG, FRC, NOWINDIS, NOPR, IOL1WAY, OSCIO, NOCKSFSM, NOIESO
  5. #USE DELAY(clock=8000000)
  6. #PIN_SELECT U2TX=pin_b2
  7. #PIN_SELECT U2RX=pin_b3
  8. #PIN_SELECT U1TX=pin_b5
  9. #PIN_SELECT U1RX=pin_b4
  10.  
  11. #use rs232(baud=9600, Xmit=pin_b5, rcv=pin_b4,   STREAM=UART1)  //PC
  12. #use rs232(baud=9600, Xmit=pin_B2, rcv=pin_b3,   STREAM=UART2) //GPS
  13. #DEFINE PB1       PIN_B7
  14. #DEFINE PB2       PIN_B8
  15.  
  16. #DEFINE LED5      PIN_B10
  17. #DEFINE LED6      PIN_B12
  18. #DEFINE LED7      PIN_B6
  19. #DEFINE PWRKEY    PIN_B13
  20.  
  21. #DEFINE ONLED5 OUTPUT_LOW(LED5);
  22. #DEFINE ONLED6 OUTPUT_LOW(LED6);
  23. #DEFINE ONLED7 OUTPUT_LOW(LED7);
  24.  
  25. #DEFINE OFFLED5 OUTPUT_HIGH(LED5);
  26. #DEFINE OFFLED6 OUTPUT_HIGH(LED6);
  27. #DEFINE OFFLED7 OUTPUT_HIGH(LED7);
  28.  
  29. #DEFINE CR 0x0D
  30. #DEFINE LF 0x0A
  31.  
  32. #DEFINE BUFFER_LENGTH 47
  33. #define R   (6372797.560856)
  34.  
  35. UNSIGNED CHAR GPS_BUFFER[48];                                                    //TRAMA DE GPS 48 CARACTERES ASCII, SIN INCLUIR CR LF
  36. UNSIGNED CHAR DATA_GPS=0;
  37. UNSIGNED CHAR ESTADO=0;
  38. UNSIGNED CHAR BUFFER_INDEX=0;
  39. UNSIGNED CHAR TRAMA_READY=0;
  40. UNSIGNED CHAR C2;
  41. FLOAT lat1=3.425205;
  42. FLOAT lon1=-76.495073;
  43. FLOAT lat2=3.428493;
  44. FLOAT lon2=-76.498281;
  45. FLOAT LATITUD;
  46. FLOAT LONGITUD;
  47.  
  48. #INT_RDA
  49. VOID ISR_RDA1()
  50. {
  51. char c1;
  52. c1=fgetc(uart1);
  53. fputc(c1,uart2);
  54.  
  55. }
  56.  
  57. #INT_RDA2
  58. VOID ISR_RDA2()
  59. {
  60.  
  61. C2=FGETC(UART2);
  62. ADD_TO_BUFFER(C2);
  63. }
  64.  
  65.  
  66. VOID MAIN()
  67. {
  68. FPUTS("RESET",UART1);
  69. SET_PULLUP(TRUE, PIN_B7 );
  70. SET_PULLUP(TRUE, PIN_B8 );
  71. ENABLE_INTERRUPTS(INT_EXT0);
  72. ENABLE_INTERRUPTS(INT_RDA2);
  73. WHILE(TRUE)
  74. {
  75.  
  76.  
  77. GPS_DISTANCIA(lat1, lon1, lat2, lon2);
  78.  
  79.  
  80. }//FIN WHILE
  81. }//FIN VOID
  82.  
  83. VOID  GPS_DISTANCIA(FLOAT lat1, FLOAT lon1, FLOAT lat2, FLOAT lon2)
  84. {
  85.     FLOAT lat1r,lat2r,d_lat,d_lon,a,c,d;
  86.      
  87.     lat1r=deg2rad(lat1);
  88.     lat2r=deg2rad(lat2);
  89.    
  90.    
  91.     d_lat=deg2rad(lat2-lat1);
  92.     d_lon=deg2rad(lon2-lon1);
  93.    
  94.     a=sin(d_lat/2.0) *  sin(d_lat/2.0) +  cos(lat1r) *  cos(lat2r) *  sin(d_lon/2.0) *  sin(d_lon/2.0);
  95.     c = 2.0 * atan2(sqrt(a), sqrt(1.0-a));
  96.     d = R * c;
  97.    
  98.    FPRINTF(UART1,"la distancia es: %f",d);
  99.    
  100.  
  101. }

adjunto la captura de pantalla con este código

Ahora, en la segunda captura he comentado la linea que activa la interrupción de la uart2(GPS) , como ven si se imprime bien y no se resetea.

La rutina de recepción de la uart2 es una máquina de estado donde solo almaceno en buffer la trama de interés que para mi es la GLL

Mañana probaré aumentando la Frecuencia del micro, saludos ;-)
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #6 en: 04 de Agosto de 2014, 10:30:02 »
A mí me chocó el SIM908... todo lo que le mandaba me lo repetía con eco. Le deshabilité el eco para reducir el número de bytes a recibir en el PIC y por lo tanto el overhead de procesamiento que eso conlleva.

Si no mal recuerdo el comando es ATE... algo.

Saludos.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #7 en: 04 de Agosto de 2014, 17:07:13 »
ya he podido  inicializar el gps para que solo envie la trama GLL y la trama por defecto luego de que se ha ubicado correctamente.
la trama que envia es del tipo
 
Código: C
  1. $GNGLL,3150.6792,N,11711.9345,E,032946.000,A,A*4C

la trama por defecto
Código: C
  1. $GPTXT,01,01,02,ANTSTATUS=OK*3B

y otra trama de un tamaño menor que la anterior, y esto ocurre cada 1 seg, asi el micro ya no esta saturado con tanto bytes.

Adjunto el main que estoy compilando
Código: C
  1. VOID MAIN()
  2. {
  3.  
  4. FPUTS("\nRESET\n\r",UART1);
  5. ESTADO=0;
  6. BUFFER_INDEX=0;
  7. SET_PULLUP(TRUE, PIN_B7 );
  8. SET_PULLUP(TRUE, PIN_B8 );
  9. ENABLE_INTERRUPTS(INT_EXT0);
  10. ENABLE_INTERRUPTS(INT_RDA2);
  11. ENABLE_INTERRUPTS(INT_RDA);
  12. ENABLE_INTERRUPTS(GLOBAL);
  13.  
  14.  // $GNGLL,3150.6792,N,01711.9345,E,032946.000,A,A*4C<CR>
  15. WHILE(TRUE)
  16. {
  17.  
  18. IF(TRAMA_READY==1)
  19. {
  20. TRAMA_READY=0;
  21. FPUTS("$PMTK314,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\n\r",UART2);
  22. GET_GPSPOINT();
  23. FPRINTF(UART1,"%4.5f\n\r",LATITUD);
  24.  
  25. }

Este es el codigo con el que recibo los datos del gps,  detecto la cabecera que me interesa y almaceno, cuando la trama es valida siempre se espera un numero fijo y conocido de bytes, por lo tanto puedo saber cuando la trama esta completa, cuando esta completa entonces pongo la variable TRAMA_READY=1.
Código: C
  1. VOID ADD_TO_BUFFER(UNSIGNED CHAR DATO_GPS)
  2. {
  3.  
  4. DATA_GPS=DATO_GPS;
  5.  
  6.    SWITCH(ESTADO)
  7.    {
  8.    
  9.    CASE 0: IF(DATA_GPS=='$')
  10.             {
  11.                ESTADO++;
  12.                
  13.             }
  14.             ELSE
  15.             {
  16.              RESET_FSM();  
  17.             }
  18.                BREAK;
  19.                
  20.    CASE 1: IF(DATA_GPS=='G')
  21.             {
  22.                STORE_IN_BUFFER();
  23.                ESTADO++;
  24.             }
  25.             ELSE
  26.             {
  27.               RESET_FSM();  
  28.             }
  29.                BREAK;
  30.                
  31.    CASE 2: IF((DATA_GPS=='N') | (DATA_GPS=='P') )
  32.             {
  33.                STORE_IN_BUFFER();
  34.                ESTADO++;
  35.             }
  36.             ELSE
  37.             {
  38.               RESET_FSM();
  39.             }
  40.             BREAK;
  41.                
  42.    CASE 3: IF(DATA_GPS=='G')
  43.             {
  44.                STORE_IN_BUFFER();
  45.                ESTADO++;
  46.             }
  47.             ELSE
  48.             {
  49.              RESET_FSM();  
  50.             }
  51.             BREAK;  
  52.                
  53.    CASE 4: IF(DATA_GPS=='L')
  54.             {
  55.                STORE_IN_BUFFER();
  56.                ESTADO++;
  57.             }
  58.             ELSE
  59.             {
  60.               RESET_FSM();
  61.             }
  62.             BREAK;
  63.                
  64.    CASE 5: IF(DATA_GPS=='L')
  65.             {
  66.                STORE_IN_BUFFER();
  67.                ESTADO++;
  68.                
  69.             }
  70.             ELSE
  71.             {
  72.              RESET_FSM();  
  73.             }
  74.             BREAK;
  75.                
  76.    CASE 6: IF((DATA_GPS==CR) | (DATA_GPS==LF) )
  77.               {
  78.                   IF(BUFFER_INDEX>BUFFER_LENGTH)
  79.                      {
  80.                         TRAMA_READY=1;
  81.                        
  82.                         BUFFER_INDEX=0;
  83.                         RESET_FSM();
  84.                          
  85.                      }
  86.                   ELSE
  87.                      {
  88.                         RESET_FSM();
  89.                         CLEAR_BUFFER_GPS();
  90.                      }
  91.               }
  92.            ELSE
  93.             {
  94.                GPS_BUFFER[BUFFER_INDEX++]=DATA_GPS;
  95.                
  96.             }
  97.             BREAK;
  98.    
  99.  }//FINI SWITCH
  100. }//FIN FUNCION ADD
  101.  
  102.  
  103. VOID GET_GPSPOINT()
  104. {
  105. UNSIGNED CHAR LAT_ASCII[10];                                                   //9 CARACTERES EN LATITUD + NULL= 10
  106. UNSIGNED CHAR LON_ASCII[11];                                                   //10 CARACTER  EN LONGI   + NULL= 11
  107. UNSIGNED CHAR CONT_LAT=6;                                                      //COORDENADA LAT INICIA EN GPS_BUFFER[6]
  108. UNSIGNED CHAR CONT_LON=18;                                                     //COORDENADA LAT INICIA EN GPS_BUFFER[18]
  109. UNSIGNED CHAR I=0;
  110.  
  111. FOR(CONT_LAT=6;CONT_LAT<=14;CONT_LAT++)
  112.    {
  113.    LAT_ASCII[I]=GPS_BUFFER[CONT_LAT];
  114.    I++;
  115.    }
  116.    
  117. I=0;
  118.  
  119. FOR(CONT_LON=18;CONT_LON<=27;CONT_LON++)
  120.    {
  121.    LON_ASCII[I]=GPS_BUFFER[CONT_LON];
  122.    I++;
  123.    }  
  124.  
  125. LATITUD=ATOF(LAT_ASCII);
  126. LONGITUD=ATOF(LON_ASCII);
  127. LONGITUD*=-1;
  128.  
  129. }

 
Sin embargo sigue reseteandose  :5] ,  lo peor es que se resetea y queda bloqueado sin hacer nada mas, no vuelve a imprimir nada
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #8 en: 04 de Agosto de 2014, 19:27:07 »
¿Ya lo corriste paso a paso y determinaste en dónde ocurre el error?

Me refiero a ver por qué el fprintf truena. Yo sigo sospechando de un buffer overflow en el que escribes datos más allá de lo que el arreglo puede almacenar.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #9 en: 05 de Agosto de 2014, 17:11:22 »
He descartado que sea que a 8Mhz el micro no puede con los bytes del GPS porque he puesto al micro a enviar todo lo que llega por la uart hacia el pc y no se resetea, sin embargo lo subi a 16Mhz e inicializo el gps para que no envíe tramas innecesarias.

He deshabilitado las interrupciones y todo lo que tiene que ver con la Uart y dejo en bucle infinito impriendo un float y funciona perfecto. Entonces creo que se puede descartar algún problema con el fprintf.

Entonces creo que no queda  otra que el reseto sea debido a un overflow en el buffer uart, sin embargo yo atiendo byte a byte cada en la interrupcion
 :angry: :huh:


Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #10 en: 06 de Agosto de 2014, 00:30:12 »
Oyeee... ¿tienes un mutex para no escribir datos en tu arreglo de recepción mientras lo estás analizando?

Es decir... que cuando estés buscando tramas en tu arreglo ya recibido... no estés recibiendo más datos todavía.

 :shock:

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #11 en: 06 de Agosto de 2014, 12:29:52 »
vaaaa, cierto el buffer siempre esta guardando  :?
 :mrgreen: pruebo y comento
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #12 en: 08 de Agosto de 2014, 14:19:59 »
he solucionado el problema parcialmente pero no de la forma que esperaba, si bien el buffer estaba actualizandose constantemente lo que pretendí hacer era deshabilitar la interrupción de la uart, resulta que puedo deshabilitarla pero al volverla a habilitar el micro queda bloqueado. Hice un programa de prueba donde el micro hace un eco hacia el pc de todo lo que recibe del gps. Me he llevado la sorpresa de que el programa hace el eco sin que Yo habilite el permiso global de interrupciones es decir sin que ponga la instrucción enable_interrupts(global), preocupante detalle :shock:

Como no he podido prescindir de dicha interrupción, lo que he hecho es poner el GPS en modo standby, de esta forma el gps no envia sus tramas y entra en modo bajo consumo, y le toma máximo dos segundos volverse a ubicar.
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #13 en: 09 de Agosto de 2014, 14:35:17 »
En el SIM908 yo pido las tramas GPS cuando quiero.

AT+CGPSINF=2

Así puedo hacer otras cosas como pedir estado de batería, bajar/subir archivos FTP, etc.

No las pido si el GPS aún no es válido.

AT+CGPSSTATUS?

Además, tengo deshabilitado su eco con ATE0. Todo lo que le mando no me lo regresa. Sólo me manda sus respuestas.

Saludos.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema:Micro se Reseta al usar fprintf con variable tipo float
« Respuesta #14 en: 10 de Agosto de 2014, 22:16:33 »
si,  el tema es que este es solo GPS, se trata del L26 de quectel, inmediatamente se alimenta empieza a enviar las tramas con sus campos vacios y a medida que empieza a tener conexion asi mismo empieza a llenar las tramas, solo cuando se ha posicionado entonces se completa la trama RMC y la GLL. Lo que si puedo hacer deshabilitar las tramas que no quiero que envíe o ponerlo en modo en stand by u otros modos de bajo consumo donde no hay actividad de la uart.
Saludos, gracias
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA