Autor Tema: Filtrar sentencias NMEA recibidas de GPS  (Leído 2730 veces)

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

Desconectado rhochoa

  • PIC10
  • *
  • Mensajes: 11
Filtrar sentencias NMEA recibidas de GPS
« en: 03 de Mayo de 2016, 16:21:30 »
Saludos escribo para solicitar alguna ayuda, estoy intentando filtrar una sentencia en protocolo nmea recibida de un gps a un PIC 16F877A y mostrarla en la PC, ya logre recebir las sentencias y mostrarlas en pantalla ahora necesito filtrar y guardar  solo la sentencia RMC para no ocupar tanto espacio en la memoria RAM (adjunto imagen de lo que recibo en pantalla)

las sentencia que recibo son de este tipo: GGA,152812,1017.0032,N,06734.0493,W,2,08,224632,1017.0419,N,06733.9866,W,0,00

esta es la subrutina para filtrar
REC_NMEA
       btfss PIR1,RCIF            ; chequea el bufer recepcion, 1 si esta lleno, 0 si esta vacio
      goto $-1   
      movfw   RCREG         ; hasta aqui el programa esta recibiendo perfectamente   (se estan usando las interrupciones)
      subwf nma1,            ; chequeo si coincide con nma1 (R) sino salgo  de la subrutina
      btfss STATUS, Z                           ; chequeo si son iguales, sino sale de la subrutina
      return
      btfss PIR1,RCIF            ; chequea el bufer recepcion, 1 si esta lleno, 0 si esta vacio
      goto $-1
      movfw   RCREG         
      subwf nma2,0            ; chequeo si coincide con nma2 (M) sino salgo  de la subrutina
      btfss STATUS, Z
      return
      btfss PIR1,RCIF            ; chequea el bufer recepcion, 1 si esta lleno, 0 si esta vacio
      goto $-1
      movfw   RCREG         ; hasta aqui el programa esta recibiendo perfectamente   
      subwf nma3,0            ; chequeo si coincide con nma3 (C) sino salgo  de la subrutina
      btfss STATUS, Z
      return
      btfss PIR1,RCIF
      goto $-1
      decfsz skip
      goto $-4
      incf FSR
      btfss PIR1,RCIF                           ; si se logra hacer el filtro, entonces guardo en la memoria Ram los datos de esa sencia
      goto $-1
      movwf INDF
      decfsz count,1
      goto $-6
      call SEND_NMEA
      return

el problema es que no me hace el filtro, al parecer nunca coinciden lo que se esta recibiendo con las referencias,
si alguno tiene experiencia en el tema y me puede ayudar quizás algún detalle en la subrutina, estaré muy agradecido estoy pendiente a sus comentarios.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #1 en: 03 de Mayo de 2016, 18:50:42 »
Unas preguntas que tengo antes de continuar:

Solo queres guardar la sentencia GPRMC no es asi ? Por que en tu ejemplo de la NMEA pusiste una que dice GGA.

La otra pregunta es .. que parte deseas guardar ? o queres guardar todo y luego lo parseas en otro lugar ?

Podrias decir que tiene al final cada trama ? es decir ademas de los caracteres alfanumericos, hay un salto de linea y/o retorno de carro ? O te interesa el checksum ?

Siempre tienen la misma cantidad de numeros?

Por ahora lo unico que puedo decir es que tenes que buscar el $GPRMC , una ves encontrado eso lo restante es guardarlo. Esta "simple" de realizar, pero quiero que contestes las preguntas anteriores.

Desconectado rhochoa

  • PIC10
  • *
  • Mensajes: 11
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #2 en: 04 de Mayo de 2016, 09:56:37 »
Saludos Killerjd, con repectos a tus preguntas pues,
 -* Si Necesito solo la GPRMC, coloque como ejemplo la GGA porque era la que tenia a la mano pero realmente necesito extraer la RMC.
 -* lo que quiero guardar es toda la sentencia desde RMC hasta el Checksum, pienso guardarlo en el banco_1, para luego poder mandar solo esa información a la pantalla.

 -* al final de cada trama esta el checksum, mira este ejemplo generico
($--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a*hh), como solo quiero obtener la RMC habia pensado contar el numero de caracateres, que son 59 maximo, y colocar un contador que decremente y salte cuando llegue a cero y asi poder saber cual es el final.
 -* No el GPS arroja distintas sentencias y cada una tiene un numero de carcateres diferentes. Pero solo necesito guardar la RMC.

que tal te parece el codigo que que mostre, el problema es que cuando hago el subwf nma, al parecer no me esta haciendo la comparación  o por lo menos eso es lo que noto.

Seguiré intentando hacer funcionar el codigo que tengo probando ideas, agradeceria tu ayuda para poder encontrar la solución, saludos. 

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #3 en: 04 de Mayo de 2016, 15:48:32 »
Hay algo "raro" en tu codigo, por que estas preguntando por la bandera y ademas tenes loops infinito, cuando segun tus comentarios estas es una interrupcion

Lo primero que deberias revisar es que llegue el $GPRMC , el $ te va a dar el comienzo de lo que queres.

Ahora, para checkear eso tenemos que comparar. Vos lo estas haciendo con el SUBWF y comparando solo RMC lo cual esta bien si es que no hay ningun otra trama con un RMC. Usando acceso directo te quedaria asi:

Voy a suponer:

- Que se trata de una interrupcion y que llamas a esta funcion con un CALL
- Que no te interesa guardar el checksum, solo habria que cambiarle un par de cosas si quisieras tenerlo tambien, ( Cambia el '*' por '$' y listo )

Código: ASM
  1. REC_NMEA
  2.         MOVF    ESTADO, W
  3.         ADDWF   PCL, F
  4.         GOTO    SENSAR_R
  5.         GOTO    SENSAR_M
  6.         GOTO    SENSAR_C
  7. Guardado:
  8.         MOVF    RCREG, W
  9.         MOVWF   INDF
  10.         INCF    FSR, F          ;Supongo no Overflow y que alcanza la memoria!!
  11.         XORLW   '*'
  12.         BTFSC   STATUS, Z
  13.         CLRF    ESTADO
  14.         RETURN
  15.  
  16. Sensar_R:
  17.         MOVF    RCREG, W
  18.         XORLW   'R'
  19.         BTFSC   STATUS, Z
  20.         INCF    ESTADO, F
  21.         RETURN
  22.  
  23. Sensar_M:
  24.         MOVF    RCREG, W
  25.         XORLW   'M'
  26.         BTFSC   STATUS, Z
  27.         INCF    ESTADO, F
  28.         RETURN
  29.  
  30. Sensar_C:
  31.         MOVF    RCREG, W
  32.         XORLW   'C'
  33.         BTFSS   STATUS, Z
  34.         RETURN 
  35.         INCF    ESTADO, F
  36.         MOVLW   0x40            ;0x400
  37.         MOVWF   FSR, F
  38.         BCF     STATUS, IRP
  39.         RETURN

Con acceso indirecto todo, seria algo asi ( usando la RAM, sin usar la flash ):


Código: ASM
  1. FSR_INICIAL     EQU     0x40            ; Direccion inicial
  2. LARGO_CABECERA  EQU     0x03            ; Cantidad de letras cabecera ( RMC )
  3.  
  4. ;En la inicializacion de los datos:
  5.  
  6.         BCF     STATUS, IRP
  7.         MOVLW   FSR_INICIAL
  8.         MOVWF   FSR
  9.         MOVLW   'R'
  10.         MOVWF   INDF
  11.         INCF    FSR, F
  12.         MOVLW   'M'
  13.         MOVWF   INDF
  14.         INCF    FSR, F
  15.         MOVLW   'C'
  16.         MOVWF   INDF
  17.         INCF    FSR, F
  18.         MOVLW   FSR_INICIAL
  19.         MOVWF   FSR
  20.  
  21.  
  22. ; Rutina de interrupcion
  23.  
  24.  
  25. REC_NMEA
  26.         BTFSS   MODO, 0
  27.         GOTO    Comparar
  28.  
  29. Guardado:
  30.         MOVF    RCREG, W
  31.         MOVWF   INDF
  32.         INCF    FSR, F          ;Supongo no Overflow y que alcanza la memoria!!
  33.         XORLW   '*'
  34.         BTFSS   STATUS, Z
  35.         RETURN
  36.         BCF     MODO, 0
  37.         MOVLW   FSR_INICIAL
  38.         MOVWF   FSR
  39.         RETURN
  40.  
  41. Comparar:
  42.         MOVF    RCREG, W
  43.         SUBWF   INDF, W
  44.         BTFSS   STATUS, Z
  45.         RETURN
  46.         INCF    FSR, F
  47.         MOVLW   (LARGO_CABECERA + FSR_INICIAL)
  48.         SUBWF   FSR, W
  49.         BTFSS   STATUS, Z
  50.         BSF     MODO, 0         ; En caso que llego a la direccion de destino
  51.         RETURN

Y luego te queda el caso en que tengas los datos en la flash, sea realizado con RETLW o con lecturas desde la EEPROM.

En el primer codigo, lo que te ahorras en la "configuracion" es decir no cargas en RAM el RMC, lo tenes al enviarlo ya que tenes que escribir el RMC y luego lo demas.
En el segundo codigo, se puede extender a cualquier cantidad de letras solo cargando un poco mas las cosas en la inicializacion, pero al reenviarlo es mas simple ya que posicionas el FSR en la posicion FSR_INICIAL y envias todo hasta encontrar nuevamente el '*'

Desconectado rhochoa

  • PIC10
  • *
  • Mensajes: 11
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #4 en: 05 de Mayo de 2016, 14:43:49 »
Saludos Killerjc, bueno pregunto por la bandera solo por un formalismo no es necesario como bien lo dices, el loop es para que se actualicen los datos siempre, eso es lo que busco, de igual manera puedo tener errores ya que soy nuevo en esto de programar PIC y es mi primer programa.

Muchísimas gracias por tu atención y por las molestatias que te tomaste, voy a probar tu codigo y te escribo.

Nuevamente muchas gracias, estoy muy agradecido.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #5 en: 05 de Mayo de 2016, 17:42:08 »
Acabo de darme cuenta que no di la condicion de que si le erra, vuelva al comienzo. En ambos codigos, asi que seguro que no van a funcionar del todo correctamente.

Desconectado rhochoa

  • PIC10
  • *
  • Mensajes: 11
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #6 en: 10 de Mayo de 2016, 14:54:51 »
saludos, gracias por la información y por atender mis dudas, en realidad tome algunas de tus ideas para mejorar mi código y ya pude hacer el filtro. 
adjunto imagen de como se ve en pantalla.

Seguiré trabajando en mi proyecto y viendo las mejoras que pueda hacer,
de nuevo mil gracias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Filtrar sentencias NMEA recibidas de GPS
« Respuesta #7 en: 10 de Mayo de 2016, 15:06:04 »
Genial te que haya servido. Excelente trabajo!