Ir al contenido



Foto

Leer datos de gps atravez de upd con indy

gps indy

  • Por favor identifícate para responder
10 respuestas en este tema

#1 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 407 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 12 abril 2018 - 01:02

Hola amigos, estoy tratando de hacer una app que recibe los datos de un gps, este manda los datos a una ip por un puerto con udp.

el problema que tengo recibo transmision , pero por algun motivo solo me da un espacion en blanco:


delphi
  1. procedure TForm3.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  2. const AData: TIdBytes; ABinding: TIdSocketHandle);
  3. begin
  4. msg := BytesToStringRaw(AData);
  5. Memo1.Lines.Add('data: '+msg);
  6. end;

Cada vez que entra una transmision lo que veo es :


delphi
  1. data:
  2. data:
  3. data:
  4. data:

para probar que realmente estoy recibiendo datos del gps  , tengo otra app que no hice yo, esta app escucha el puerto tal cual yo lo hago y recibe informacion sin problemas...

 

alguien tiene experiencia en GPS o tiene alguna idea de que puede ser?


  • 0

#2 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 93 mensajes

Escrito 12 abril 2018 - 04:05

 

o tiene alguna idea de que puede ser?

 

Me pasó hace poco que TMemo no se lleva bien con el tipo StringRaw, puede ser eso.

 

Saludos.


  • 0

#3 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 12 abril 2018 - 04:18

Hola,
 
Adjunto te dejo una pequeña utilidad que hice hace tiempo, que permite escuchar en un puerto udp y muestra por pantalla la que recibe.
 
El codigo fuente no se si te sera de mucha ayuda porque esta hecho directamente usando la API de windows y no Indy, pero como son solo unas pocas lineas es bastante facil de entender y puede que saques alguna idea.
 
Lo que seria interesante es que lo pongas a escuchar en el puerto del GPS y ver lo que recibes (el programa lo muestra en texto y hexadecimal) para ver si esta colando algun cero y por eso aparece la cadena vacia.
 
Para usarlo:

bash
  1. udp 123

Donde 123 es el puerto por el que se reciben los datos del GPS
 
Veras algo como esto

bash
  1. Pulsa Ctrl+C para salir ...
  2.  
  3. Puerto: 1978 IP: 127.0.0.1
  4.  
  5. 00000000: 4D 65 6E 73 61 6A 65 20 64 65 6C 20 47 50 53 0A |Mensaje.del.GPS.|

Asi sabremos que es lo que manda el gps y podremos ayudarte mejor
 
Saludos

Archivos adjuntos

  • Archivo adjunto  udp.zip   30,82KB   1 descargas

  • 0

#4 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 407 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 12 abril 2018 - 05:02

Hola gracias amigo:

haciendo un pequeño cambio logre obtener esto:


delphi
  1. memo1.Lines.Add('gps: '+ToHex( AData) );

Resultado en el memo:


delphi
  1. gps: 00040200202020202020202020322020202020202020202020202020202020203530303020244750524D432C3232353934342E30302C412C313533312E3736323933392C4E2C30383830322E3530373831332C572C302E302C302E302C3132303431382C312E362C572C412A33430D0A202020202032303430383800

Hola,
 
Adjunto te dejo una pequeña utilidad que hice hace tiempo, que permite escuchar en un puerto udp y muestra por pantalla la que recibe.
 
El codigo fuente no se si te sera de mucha ayuda porque esta hecho directamente usando la API de windows y no Indy, pero como son solo unas pocas lineas es bastante facil de entender y puede que saques alguna idea.
 
Lo que seria interesante es que lo pongas a escuchar en el puerto del GPS y ver lo que recibes (el programa lo muestra en texto y hexadecimal) para ver si esta colando algun cero y por eso aparece la cadena vacia.
 
Para usarlo:


bash
  1. udp 123

Donde 123 es el puerto por el que se reciben los datos del GPS
 
Veras algo como esto

bash
  1. Pulsa Ctrl+C para salir ...
  2.  
  3. Puerto: 1978 IP: 127.0.0.1
  4.  
  5. 00000000: 4D 65 6E 73 61 6A 65 20 64 65 6C 20 47 50 53 0A |Mensaje.del.GPS.|

Asi sabremos que es lo que manda el gps y podremos ayudarte mejor
 
Saludos

 

 

con el udp que me pasaste:

esto es lo que me da:


delphi
  1. Puerto: 3333 IP: 127.0.0.1
  2.  
  3. 00000000: 00 04 02 00 20 20 20 20 20 20 20 20 20 32 20 20 |.............2..|
  4. 00000010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 |................|
  5. 00000020: 35 30 30 30 20 24 47 50 52 4D 43 2C 32 32 35 33 |5000..GPRMC.2253|
  6. 00000030: 30 34 2E 30 30 2C 41 2C 31 35 33 31 2E 37 36 32 |04.00.A.1531.762|
  7. 00000040: 39 33 39 2C 4E 2C 30 38 38 30 32 2E 35 30 37 38 |939.N.08802.5078|
  8. 00000050: 31 33 2C 57 2C 30 2E 30 2C 30 2E 30 2C 31 32 30 |13.W.0.0.0.0.120|
  9. 00000060: 34 31 38 2C 31 2E 36 2C 57 2C 41 2A 33 32 0D 0A |418.1.6.W.A.32..|
  10. 00000070: 20 20 20 20 20 32 30 34 30 38 38 00 |.....204088.|
  11.  
  12.  
  13. Puerto: 3333 IP: 127.0.0.1
  14.  
  15. 00000000: 00 04 03 00 |....|

logre encontrar el manual del fabricante que habla acerca de esto aqui


  • 1

#5 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 13 abril 2018 - 12:04

Parece que todo encaja con la documentación. Una cabecera de 4 bytes que indica que es un mensaje de tipo "ASCII Event Data" y a continuación el mensaje que parece que es un texto en ASCII

 

En concreto es interesante esta parte:


php
  1. $GPRMC,225944.00,A,1531.762939,N,08802.507813,W,0.0,0.0,120418,1.6,W,A*3C

Este mensaje sigue el estandar GPMRC: http://gonzalo.aro.c...standard-gprmc/ así que no será difícil descifrarlo.

 

Simplemente descarta los cuatro primeros bytes de la cabecera y en el resto del mensaje busca una cadena de texto que empieza por $GPRMC y termina por #13#10 (salto de linea)

 

Para hacer pruebas puedes usar cualquier decodificador online, por ejmplo este: https://rl.se/gprmcque me dice que estas en Honduras

 

Saludos

 

 

Nota: Edite el mensaje para añadir enlace a la documentacion de GPRMC y dejarlo mas ordenado


  • 1

#6 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 13 abril 2018 - 05:08

Acabo de recordar que hace tiempo habia hecho algo parecido en php, y usaba el mismo tipo de mensaje gps

 

http://delphiaccess....-gps-del-movil/

 

Y ahi aparecia un enlace muy bueno describiendo el estandar GPMRC: http://gonzalo.aro.c...standard-gprmc/

 

Saludos


  • 1

#7 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 407 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 13 abril 2018 - 10:06

Parece que todo encaja con la documentación. Una cabecera de 4 bytes que indica que es un mensaje de tipo "ASCII Event Data" y a continuación el mensaje que parece que es un texto en ASCII

 

En concreto es interesante esta parte:


php
  1. $GPRMC,225944.00,A,1531.762939,N,08802.507813,W,0.0,0.0,120418,1.6,W,A*3C

Este mensaje sigue el estandar GPMRC: http://gonzalo.aro.c...standard-gprmc/ así que no será difícil descifrarlo.

 

Simplemente descarta los cuatro primeros bytes de la cabecera y en el resto del mensaje busca una cadena de texto que empieza por $GPRMC y termina por #13#10 (salto de linea)

 

Para hacer pruebas puedes usar cualquier decodificador online, por ejmplo este: https://rl.se/gprmcque me dice que estas en Honduras

 

Saludos

 

 

Nota: Edite el mensaje para añadir enlace a la documentacion de GPRMC y dejarlo mas ordenado

 

Gracias amigo.!

Caramba. no tenia idea de fuera asi, interesante.,  o sea que despues de obtener el texto del GPS tengo que hacer una funcion en delphi para decodificar los datos no?

Justo ahora tengo problemas al convertir el AData a una cadena, ¿Podrias darme un tip de como convertirlo?, seria algo asi como ASCII to text?


delphi
  1. procedure TForm3.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  2. const AData: TIdBytes; ABinding: TIdSocketHandle);
  3. var msg :string;
  4. begin
  5. msg := BytesToString(AData,IndyTextEncoding_ASCII);
  6. Memo1.Lines.Add('data: '+msg);
  7. end;


  • 0

#8 seoane

seoane

    Advanced Member

  • Administrador
  • 1.243 mensajes
  • LocationEspaña

Escrito 13 abril 2018 - 11:08

He hecho un ejemplo con Indy:


delphi
  1. function calcChecksum(Str: AnsiString): Byte;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result:= 0;
  6.   for i:= 1 to Length(Str) do
  7.     Result:= Result xor Byte(Str[i]);
  8. end;
  9.  
  10. procedure TfrmMain.udpServerUDPRead(AThread: TIdUDPListenerThread;
  11.   const AData: TIdBytes; ABinding: TIdSocketHandle);
  12. var
  13.   i, j: Integer;
  14.   texto, gprmc, campos, checksum: String;
  15. begin
  16.   // Comprobamos la cabecera (recuerda que los bytes estan invertidos en los integer)
  17.   if (Length(AData) > 4) and (PInteger(@AData[0])^ = $00020400) then
  18.   begin
  19.     texto:= Copy(PAnsiChar(@AData[4]), 1, Length(AData) - 4);
  20.     i:= Pos('$GPRMC', texto);
  21.     if (i > 0) then
  22.     begin
  23.       j:= Pos(#13#10, texto, i);
  24.       if (j > 0) then
  25.       begin
  26.         // Tenemos la cadena que nos interesa
  27.         gprmc:= Copy(texto, i, j - i);
  28.  
  29.         i:= Pos('*', gprmc);
  30.         if i > 0 then
  31.         begin
  32.           // Separamos la suma de comprobacion del resto de la cadena
  33.           campos:= Copy(gprmc, 2, i-2);
  34.           checksum:= Copy(gprmc, i+1, 2);
  35.  
  36.           // Comprobamos la suma de comprobacion
  37.           if calcChecksum(campos) = StrToInt('$'+checksum) then
  38.           begin
  39.             // Separamos los campos
  40.             with TStringList.Create do
  41.             try
  42.               StrictDelimiter:= TRUE;
  43.               Delimiter:= ',';
  44.               DelimitedText:= campos;
  45.  
  46.               // Por ejemplo la latitud seria
  47.               ShowMessage(Strings[3]);
  48.  
  49.             finally
  50.               Free;
  51.             end;
  52.           end;
  53.         end;
  54.       end;
  55.     end;
  56.   end;
  57. end;

Si tienes alguna duda dimelo

 

Saludos


  • 2

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.857 mensajes
  • LocationMéxico

Escrito 13 abril 2018 - 11:26


Vaya no sabía ese dato que los bytes deben estar invertidos. Tantas veces que lo he visto y no había reparado en ese detalle, como asumimos las cosas sin analizarlas detalladamente.  :s

 

Gracias por la nota. (y)

Saludos


  • 1

#10 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 407 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 13 abril 2018 - 11:45

He hecho un ejemplo con Indy:


delphi
  1. function calcChecksum(Str: AnsiString): Byte;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result:= 0;
  6.   for i:= 1 to Length(Str) do
  7.     Result:= Result xor Byte(Str[i]);
  8. end;
  9.  
  10. procedure TfrmMain.udpServerUDPRead(AThread: TIdUDPListenerThread;
  11.   const AData: TIdBytes; ABinding: TIdSocketHandle);
  12. var
  13.   i, j: Integer;
  14.   texto, gprmc, campos, checksum: String;
  15. begin
  16.   // Comprobamos la cabecera (recuerda que los bytes estan invertidos en los integer)
  17.   if (Length(AData) > 4) and (PInteger(@AData[0])^ = $00020400) then
  18.   begin
  19.     texto:= Copy(PAnsiChar(@AData[4]), 1, Length(AData) - 4);
  20.     i:= Pos('$GPRMC', texto);
  21.     if (i > 0) then
  22.     begin
  23.       j:= Pos(#13#10, texto, i);
  24.       if (j > 0) then
  25.       begin
  26.         // Tenemos la cadena que nos interesa
  27.         gprmc:= Copy(texto, i, j - i);
  28.  
  29.         i:= Pos('*', gprmc);
  30.         if i > 0 then
  31.         begin
  32.           // Separamos la suma de comprobacion del resto de la cadena
  33.           campos:= Copy(gprmc, 2, i-2);
  34.           checksum:= Copy(gprmc, i+1, 2);
  35.  
  36.           // Comprobamos la suma de comprobacion
  37.           if calcChecksum(campos) = StrToInt('$'+checksum) then
  38.           begin
  39.             // Separamos los campos
  40.             with TStringList.Create do
  41.             try
  42.               StrictDelimiter:= TRUE;
  43.               Delimiter:= ',';
  44.               DelimitedText:= campos;
  45.  
  46.               // Por ejemplo la latitud seria
  47.               ShowMessage(Strings[3]);
  48.  
  49.             finally
  50.               Free;
  51.             end;
  52.           end;
  53.         end;
  54.       end;
  55.     end;
  56.   end;
  57. end;

Si tienes alguna duda dimelo

 

Saludos

 

Gracias amigo, ha ido como la seda!, funciona a la perfeccion..., estudiare el codigo..


  • 0

#11 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 407 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 13 abril 2018 - 03:48

Hola amigos , estube haciendo mas pruebas y estaba tratando de hacer lo siguiente:


delphi
  1. procedure TForm3.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
  2. var
  3. i, j: Integer;
  4. texto, gprmc, campos, checksum: String;
  5. atComm:string;
  6. begin
  7.  
  8. atComm := 'AT&V';
  9.  
  10. ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, ToBytes( atComm ));
  11.  
  12. ...
  13. end;

 esto es para enviarle un comando at, pero no veo ningun comportamiento...

 

que podra ser?

 

update:

 

en realidad hay comportamiendo, pero no puedo ver nada porque me da espacios en blanco

 

imagino que aqui esta el asunto:


delphi
  1. texto:= Copy(PAnsiChar(@AData[4]), 1, Length(AData) - 4);

que puedo hacer para modificar esto de manera que me transforme a texto todo el contenido que entre por aqui?


  • 0





Etiquetado también con una o más de estas palabras: gps, indy