Autor Tema: si me espero, ... se para  (Leído 4055 veces)

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

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
si me espero, ... se para
« en: 27 de Noviembre de 2004, 13:07:00 »
Hola a tod@s:

Ya puedo leer los datos del GPS y sigo adelante con mi programa, pero tengo un pequeño problema.

Este es el programita:

#INCLUDE <16F876.H>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=16000000)
#use RS232 BAUD=4800,RCV=PIN_C7,PARITY=N,BITS=8,XMIT=PIN_C6)

#include "miLCD.c"      
#include <string.h>
#include <stdlib.h>

//DEFINICION DE FUNCIONES
void leer_gps();

//VARIABLES GLOBALES
struct
{
   char hora_utc[7];
   char estado;
   int8 lat_g;
   float lat_m;
   char lat_ns;
   int8 lon_g;
   float lon_m;
   char lon_ew;
   float velo;
   float track_angle;
   char fecha[7];
}gps;

////////////////////////////  INICIO PROGRAMA   //////////////////////////////////////

void main()
{
   lcd_init();
   lcd_putc("fIniciando...
");
   delay_ms(2000);
   lcd_putc("f");

   while(1)
   {
      leer_gps();                         //leo datos              
      lcd_gotoxy(1,1);                //los muestro
      printf(lcd_putc,"L%U*%F*%C",gps.lat_g,gps.lat_m,gps.lat_ns);

      //delay_ms(1000);  // SI UTILIZO ESTA PAUSA, SE CUELGA
   }

}


void leer_gps()
{
   int8 n;
   char c;
   char buffer[10];
   char sentencia_gps[6];

   strcpy(sentencia_gps,"GPRMC");          //Este es la sentencia que interesa

   while(1)
   {
      if(kbhit())
      {
         c = getc();
         if(c=="$")        //Caracter indicativo inicio comando
         {
            for(n=0;n<=4;n++) buffer[n]=getc();  //leo 5 caracteres sentencia
            buffer[n]="";

            if(!strcmp(buffer,sentencia_gps))  // Si es la correcta
            {
               c=getc();                                                         //quito la coma
               for(n=0;n<=5;n++) gps.hora_utc[n]=getc();  //leo 6 caracteres, hora
               gps.hora_utc[n]="";                                      
               c=getc();                                                         //quito la coma
               gps.estado=getc();                                        //leo estado
               c=getc();                                                        //quito la coma
               for(n=0;n<=1;n++) buffer[n]=getc();            //leo 2 car., grados latitud
               buffer[n]="";
               gps.lat_g=atoi(buffer);                                  
               for(n=0;n<=4;n++) buffer[n]=getc();             //leo 5 car., minutos lat.    
               buffer[n]="";
               gps.lat_m=atof(buffer);
               c=getc();                                                        //quito la coma
               gps.lat_ns=getc();                                         //leo hemisferio
               
               break;                               // Salgo bucle while
            }
         }
      }
   }
}

El GPS envia repetidamente una serie de sentencias  de la forma siguiente:

$GPWPL,3733.60,N,00116.00,W,MAZ*4A
$GPGLL,3745.76,N,00129.27,W*72
$GPRMC,182049,A,3745.76,N,00129.27,W,015.0,125.7,231003,002.6W*79
estas y otras mas, cuando termina vuelta a empezar...

Lo que quiero hacer es leer la puerta serie hasta encontrar la sentencia que me interesa, recoger los datos y operar con ellos, una vez haya terminado los calculos, volver a leer la puerta serie, y asi sucesivamente...

El programa funciona bien... pero tengo algunos problemas:

1- Si cuando inicio el programa, el pin de recepcion de la puerta serie esta conectado la mayoria de las veces el programa no hace nada. Para que arranque bien tengo que iniciar el programa y despues conectar el pin.

2- Si despues de leer los datos pongo algun delay para mostrar la informacion o me entretengo demasiado en hacer otras cosas, cuando vuelvo a leer el GPS el programa se queda colgado.
Si no pongo el delay, el programa lee y muestra los datos continuamente.

No se que hacer, ayuda please....

Gracias
Saludos

Desconectado rferrero

  • PIC16
  • ***
  • Mensajes: 113
RE: si me espero, ... se para
« Respuesta #1 en: 28 de Noviembre de 2004, 06:04:00 »

    Hola. Se me ocurren un par de cosas:
 
    1- Pon un pequeño retraso al inicio para que se inicialice todo correctamente. Esto equivale a conectarlo más tarde, lo que haces para que funcione correctamente.

     2- Uf. Eso es más complicado de saber a priori. Dónde se queda colgado?? Ese el quid de la cuestión. Prueba con printf y puerto serie RS232 conectado al PC (o donde tengas). En  if(kbhit()), qué ocurre?? Salta? Entra ahí? Prueba a ver.
         Con retrasos inferiores a un segundo, como tienes puesto, también se cuelga?? Para qué quieres un retraso? Pon, acaso, uno pequeño a ver. Si se queda colgado es porque los datos pasan mientras está el micro parado y no se hace nada con ellos. Esos datos se pierden? Qué ocurre? Tiene el GPS algún tipo de detección de pérdida de esos datos? Con ellos no se hace nada.
     
     No se me ocurre más. Un saludo.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: si me espero, ... se para
« Respuesta #2 en: 28 de Noviembre de 2004, 06:30:00 »
Deberias capturar los datos mediante el uso de interrupción,eso te facilitaría bastante las cosas y seguramente te quitará de mas de un quebradero de cabeza.

Codigo:


char caracter;

#int_rda
void recepcion_serie()    // Rutina de interrupción por recepción serie
   {
    caracter = getc();
   }




En vez de meter el dato en una variable cada vez,puedes crear un buffer y capturar varios valores antes de procesarlos y ver si te interesan o no

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
RE: si me espero, ... se para
« Respuesta #3 en: 28 de Noviembre de 2004, 13:58:00 »
Hola

rferrero

1- He puesto un retardo de 2 ms y hace lo mismo.

2- He puesto unos led para saber por donde va, y sorprendentemente nunca se para en el mismo sitio.
Con un retardo de mas de 5ms se cuelga.
El retardo no vale para nada, lo he puesto para que veais que si me entretengo unos pocos ms antes de volver a leer la puerta serie se queda colgado. Esto sucedera irremediablemente cuando avance en el programa y tenga que hacer otras cosas antes de volver a leer la puerta serie.
No me importa que se pierdan datos, el GPS los envia repetidamente.
No creo que el GPS tenga ningun sistema de deteccion de perdida de datos, solo tiene 2 cables, el Tx y el RX (aparte la alimentacion).


Modulay

No creo que sea el mejor caso para utilizar interrupciones.

Yo las interrupciones las utilizaria cuando se que tengo que recibir en algun momento una trasmision, y no quiero estar parado esperando, y no quiero perder ningun dato. No es mi caso, el GPS esta continua y repetidamente trasmitiendo datos desde el principio.

Programa sin interrupciones:
- leer gps, hasta obtener el dato requerido
- hacer unos calculos
- volver a empezar

Programa con interrupciones:
- habilitar interrupcion (saltaria la interrupcion inmediatamente)
- leer gps, hasta obtener el dato requerido
- deshabilitar interrupcion (Necesito un poco de tiempo para operar con el dato)
- hacer unos calculos
- volver a empezar

Si te das cuenta tendria el mismo problema, en ambos casos, hay un periodo de tiempo en el cual tengo que dejar de leer la puerta serie, para hacer otras cosas. Y es ese tiempo que estoy sin recoger los datos de la puerta serie (que no paran de llegar), que ocurre algun tipo de desbordamiento (u otra cosa) que provoca que se pare el programa.

De todas formas probare para ver lo que pasa.

Gracias por vuestro interes.

A los demas les pido que si se les ocurre algo me lo comenten please.

Garacias a todos.
Saludos Sonrisa


 Una vez obtenido el dato, tendria que deshabilitar la interrupcion porque ya no quiero seguir leyendo la puerta serie, ahora lo que tengo que hacer es operar con el dato, y hacer otras cosas. Cuando termine todas las tareas, volvere a habilitar la

Desconectado rferrero

  • PIC16
  • ***
  • Mensajes: 113
RE: si me espero, ... se para
« Respuesta #4 en: 28 de Noviembre de 2004, 14:24:00 »

   Buenas.
   
   1- Uhm ... prueba a poner un retardo algo mayor, de unos 50 ms. Como mucho, 100 ms.
 
    2- Estoy pensando. Cuando se me ocurra algo, te contaré.

   Un saludo.

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: si me espero, ... se para
« Respuesta #5 en: 28 de Noviembre de 2004, 15:25:00 »
es un crimen no usar la interrupcion para capturar los datos, de la forma que lo haces no sabes si comienzas a leer en medio de un mensaje, al final, al princio...
prueba con el codigo que colge en mi web para recibir usando un timeout con la interrupcion serie....

funcionaria asi:

el gps manda una cadena de datos y espera un cierto tiempo para enviar la siguiente..... cuando termina de enviar esa cadena tu interrupcion de timeout activa un flag indicando que hay un nuevo paquete de datos...desde el main estas constantemente chequeando ese flag y cuando se pone a uno haces lo que quieras con los datos y lo vuelves a poner a cero...


saludos

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
RE: si me espero, ... se para
« Respuesta #6 en: 28 de Noviembre de 2004, 17:13:00 »
Hola

Siento disentir de un gran maestro como tu, pacalaconcurso pero...

El GPS envia sin interrupcion 10 sentencias diferentes del tipo:
$GPWPL,3733.60,N,00116.00,W,MAZ*4A $GPGLL,3745.76,N,00129.27,W*72 $GPRMC,182049,A,3745.76,N,00129.27,W,015.0,125.7,231003,002.6W*79
.....
luego hace una pausa de unos pocos ms y vuelta a empezar.
Esto lo hace desde el mismo momento que enciendo el GPS y no para hasta que lo apago.

Si es mejor leer un trozo de cadena larga y luego trocearla, o leer los datos directamente segun van entrando, seria discutible..., pero no es el problema.

El que yo lea, mejor al principio o en medio de esta larga cadena, y que se pierdan o no datos, seria discutible..., pero no es el problema.

El problema es otro:
Tanto de la forma como yo lo hago, o utilizando interrupciones, tengo que dejar de atender la puerta serie el tiempo suficiente para poder procesar los datos recibidos, calcular rumbos, mostrar informacion...etc. Es ahora cuando la puerta serie se satura y se bloquea.
El proposito del programa no es solo leer datos de la puerta serie y mostrarlos en un LCD, (es lo unico que puedo hacer sin que se pare), es mucho mas, tiene que hacer otras cosas en funcion de esos datos recibidos, y cuando termine de procesar todo entonces volver a leer de la puerta serie....

Hay que saber porque se satura la puerta serie, si no se recogen los datos.

Gracias por tu interes.
Saludos Sonrisa

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: si me espero, ... se para
« Respuesta #7 en: 29 de Noviembre de 2004, 04:32:00 »
Dispongo de experiencia en estos temas  habiendo realizado diseños de este tipo en C en ensamblador y con distintos PIC y mi opinion es realizar la adquisición por interrupción. Cuando levantas un flag indicativo de tener el string se puede desactivar la interrupción de la UART por lo que mientras comparas los valores no serás interrumpido, esa es la manera que  funciona mejor. RebotadoRebotado

Pero si deseas hacerlo por scaneo no hay problema pero no lo hagas online, coge el string y luego comparalo si no SIEMPRE se te parará la UART de los PIC a veces hace esas cosas si abres, cierras escribes mientras lees etc.. por lo que yo lo arí como sigue:

Codigo:

char leer_gps()
{
char buffer[180];

gets(buffer);
return (buffer);

}

void evaluar_GPS(char *buffer)
{

// aki recorres el string trankilamente

}



Como puedes ver la adquisición es mucho mas facil, y tienes todo el tiempo para recorrer el string.

Otra cosa, verdad que no necesitas los otros parametros del GPS? tendrías que revissar los comandos NMEA y podrás hacer que solo te envie el RMS y a intervalos que desees por ejemplo cada 5 segundos, estarás más seguro con el código y consumirá menos. Sonrisa GiganteSonrisa GiganteSonrisa Gigante
- T0ni0 -
30RCF112

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: si me espero, ... se para
« Respuesta #8 en: 29 de Noviembre de 2004, 15:19:00 »
yo uso un gps fortuna y los datos los recibo perfectamente, entre cadena y cadena (al menos en mi caso) hay al menos un "silencio" de mas del periodo de transmision de tres byte.

para solucionar tu cuelgue añade ,errors al #use rs232.....

si tengo tiempo voy a prepararte un codigo para probar que por muy compleja que sea tu interpretacion de la cadena, no vas a perder ni un solo dato si usas la interrupcion, creeme, la int corre en background si la usas bien, pero con tu recepcion en el main seguro que provocas un overrun del buffer, lo que unido a que no limpias el error (o  no tienes el ERRORS...) es igual a un cuelgue de la usart.

es un tema muy interesante y ademas, cuanto mas discutamos mas aprendemosGiñoSonrisa

saludos

Desconectado rferrero

  • PIC16
  • ***
  • Mensajes: 113
RE: si me espero, ... se para
« Respuesta #9 en: 30 de Noviembre de 2004, 03:31:00 »

   Ehm ... puedes explicar un poco más lo del overrun del búfer y demás??  loco
 
    Gracias.

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
RE: si me espero, ... se para
« Respuesta #10 en: 30 de Noviembre de 2004, 14:10:00 »
Hola

pacalaconsurso, eres cojonudo.  Gracias master RebotadoRebotadoRebotadoRebotadoRebotado

Solo he tenido que añadir a mi programa la instruccion ERROS y funciona estupendamente, yo ni se cuelga al inicio, ni parando de leer la puerta serie durante mas de 10 segundos, ni nada... Sonrisa

No quiero parecer obstinado y desagradecido, pero...

Estoy absolutamente convencido que la mejor manera de trabajar con la usart es con interrupciones, creeme. Pero en este caso en concreto no lo tengo tan claro.

Vosotros me proponeis la siguiente secuencia de programa:
1- habilitar int.
2- deshabilitar int., para tener tiempo de operar con los datos
3- leer con gets
4- trocear y sacar valores
5- volver a empezar

pero yo le veo varios fallos:
1- en el mismo instante que habilite la int., se va a activar , porque el gps esta siempre trasmitiendo, ¿que diferencia hay si empiezo a leer sin utilizar la int.?
3- puesto que irremediablemente va a ver un tiempo en el que no recoga los car. de la usart, cuando utilice gets, no se donde va a empezar a leer, al principio o en medio de la cadena, con lo cual no se que trozo va a leer, y llegar a encontar la cadena que yo quiero va a ser arto dificil.
4 - todos los valores no estan solamente delimitados por comas, por ejemplo: ...,3743.75,..., no es un dato, son dos, latitudg=37 grados, y latitudm=43.75 minutos, por lo que el algoritmo de trocear se  complica un poco. al final es mas facil utilizar getc y asignar directamente los valores.

Las int. estan bien para cuando la trasmision es mas intermitente, y no se va a perder nincun car., por lo que todas las cadenas leidas van a empezar y terminar correctamente.

Mi unica motivacion es comprender y aprender.

Espero vuestros comentarios al respecto, y si es posible algun ejemplo.

Saludos Sonrisa

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: si me espero, ... se para
« Respuesta #11 en: 01 de Diciembre de 2004, 02:26:00 »
Escrito originalmente por juanelete
Hola

No quiero parecer obstinado y desagradecido, pero...

Estoy absolutamente convencido que la mejor manera de trabajar con la usart es con interrupciones, creeme. Pero en este caso en concreto no lo tengo tan claro.

Vosotros me proponeis la siguiente secuencia de programa:
1- habilitar int.
2- deshabilitar int., para tener tiempo de operar con los datos
3- leer con gets
4- trocear y sacar valores
5- volver a empezar



Pues NO,

1- Habilita
2- entra en la int y captura, bien por gets bien por getc, cuando tengas el string levantas flag y deshabilitas
3- leer que tienes en el buffer si no es $GPRMC sales y habilitas de lo contrario lo tratas y habilitas


Escrito originalmente por juanelete

pero yo le veo varios fallos:
1- en el mismo instante que habilite la int., se va a activar , porque el gps esta siempre trasmitiendo, ¿que diferencia hay si empiezo a leer sin utilizar la int.?
3- puesto que irremediablemente va a ver un tiempo en el que no recoga los car. de la usart, cuando utilice gets, no se donde va a empezar a leer, al principio o en medio de la cadena, con lo cual no se que trozo va a leer, y llegar a encontar la cadena que yo quiero va a ser arto dificil.
4 - todos los valores no estan solamente delimitados por comas, por ejemplo: ...,3743.75,..., no es un dato, son dos, latitudg=37 grados, y latitudm=43.75 minutos, por lo que el algoritmo de trocear se  complica un poco. al final es mas facil utilizar getc y asignar directamente los valores.

Las int. estan bien para cuando la trasmision es mas intermitente, y no se va a perder nincun car., por lo que todas las cadenas leidas van a empezar y terminar correctamente.

Mi unica motivacion es comprender y aprender.

Espero vuestros comentarios al respecto, y si es posible algun ejemplo.

Saludos Sonrisa


1- y que si se habilita? tu a lo tuyo que la int también hace lo suyo para eso está, ah!!! has mirado los comandos NMEA (no me hacen caso)?

2- te lo has dejado, que empieze donde quiera, tu vas a tener un string, comparas el principio con $GPRMC y listo a por otro
fijate que lo que hacias tu era if (c=="$") o incluso comparas con la cabezera, pero si estan llegando datos!!! si ese if tarda mucho que haremos
puedes asegurar que tardaran menos tus instrucciones de comparación de la llegada de datos? por que limitas tu velocidad de llegada, que haras con un GPS 9600 o 12900?

3- da igual las comas puntos, si lo transformas a decimal.d o lo que quieras hacer, nadie te molesta eres el rey del String

CREEME A LA LARGA ACABARAS HACIENDO POR INTERRUPCIÓN
O LA OPCIÓN QUE TE COMENTÉ DES DE UN PRINCIPIO EN DONDE NO SE CAPTURA AL VUELO.

Saludos y estudiate los comandos ok?RebotadoRebotado
- T0ni0 -
30RCF112

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: si me espero, ... se para
« Respuesta #12 en: 01 de Diciembre de 2004, 14:54:00 »
totalmente de acuerdo con  TOniOGiño

la mejor prueba de que no lo haces bien es que se te activa el error de la usart hardware.

como bien te dicen puedes analizar el caracter que sacas de la usart para saber cuando empieza una cadena válida por el "$"

tambien firmo que terminaras usando int. te vuelvo a recomendar el ejemplo que puse  en mi webGiño

saludo

manten informado de tus adelantosIdeaIdea

Desconectado rferrero

  • PIC16
  • ***
  • Mensajes: 113
RE: si me espero, ... se para
« Respuesta #13 en: 01 de Diciembre de 2004, 15:10:00 »

    Pacalaconcurso, porfa, en qué consiste eso del errors y demás que comentáis más arriba??

Rebotado

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: si me espero, ... se para
« Respuesta #14 en: 02 de Diciembre de 2004, 02:38:00 »
Manual CCS

ERRORS
Indica al compilador que guarde los errores recibidos en la
variable RS232_ERRORS para restablecerlos cuando se
producen.Sonrisa Gigante




Pues eso, si se produce un error en la recepción como Overrun Error bit o Framing pues lo limpia y no se queda el PIC parado, seguramente cuando estabas comparando if() se debía dar de leches los caracteres RebotadoRebotadoRebotado
- T0ni0 -
30RCF112


 

anything