Llevo casi un mes sin escribir en blogElectronica. Y es que por unas cosas o por otras me ha sido difícil encontrar tiempo estas últimas semanas … mucho trabajo, un proyecto personal que ha requerido mi atención más de lo habitual, una pequeña intervención en los párpados para quitarme unas manchitas (seguro que el otro día alguien se preguntó que me pasaba en los ojos ;)   ) y estos últimos días malito con gripe. A partir de ahora espero volver a lo habitual, un artículo cada semana más o menos.

Bueno, pues vamos con el tema, un artículo fácil para coger el ritmo. Vamos a ver un ejemplo de cómo obtener la fecha / hora en nuestos módems Siemens/Cinterion TC65 (por supuesto todo ésto vale para los terminales, como el MTX65, MTX65+G y TC65T).

Seguro que en alguna ocasión hemos tenido la necesidad de disponer de la fecha/hora actual en nuestro programa java para éstos módems. ¿Que para qué? Pues por ejemplo para guardar la hora en un log junto a unos datos, o para realizar alguna tarea a una hora concreta, …etc etc.  Es decir, hay múltiples situaciones en las que es necesario disponer de la hora correcta. Como seguro sabéis, el TC65 dispone de una RTC, pero a menos de que dispongamos de una batería de backup para esta RTC (el MTX65 dispone de la huella para ella), al arrancar el equipo no tendremos la hora.

RFC868

¿Y cómo obtener la fecha/hora?

Pues hay varias maneras. Si estamos hablando de un equipo con GPS, como el XT65 (o MTX65+G) es mucho más fácil, pues puede extraerse de la trama de posición. Es decir, si leemos la posición con el comando AT^SGPSR=0 obtendremos la respuesta:

  ^SGPSR: [GpsDate, GpsUTCTime, GpsLatitude, NS-Indicator, GpsLongitude, EW-Indicator, GpsAltitude, GpsSpeed, GpsCourse, GpsStatus]

donde en GpdDate y GPSUTCTime tendremos la fecha y hora respectivamente.
Pero no todos los módems, como es el caso de los TC65, MTX65 y TC65T disponen de GPS. De hecho hasta para los XT65 / MTX65+G podemos necesitar saber la hora incluso si no tenemos cobertura GPS.

¿Cómo solucionarlo entonces?

Pues una manera típica y muy sencilla es enviarse a uno mismo un mensaje SMS. Cuando reciba el SMS, al final del mismo, podré extraer la fecha/hora. Una vez la extraiga del SMS de vuelta puedo establecerla en el módem con el comando AT+CCLK. La precisión horaria con este método no es muy alta, como podéis deducir fácilmente.

La mejor manera de obtener la fecha/hora es sin duda usando NTP (Network Time Protocol). NTP permite sincronizar el reloj en redes con latencia variable, como es el caso de Internet, con una precisión muy alta. Para este método se emplean paquetes UDP. Sin embargo este protocolo tiene cierta complejidad y en la inmensa mayoría de aplicaciones tampoco es imprescindible tener una precisión de milisegundos.

¿Y cómo obtener una hora con cierta precisión y de forma muy sencilla?

Pues con el protocolo Time Protocol (RFC868). Es muy muy sencillo. Existen multitud de servidores de hora en Internet que ofrecen el Time Protocol, como por ejemplo:

time-a.timefreq.bldrdoc.gov
time-b.timefreq.bldrdoc.gov
time-c.timefreq.bldrdoc.gov
utcnist.colorado.edu
time-nw.nist.gov
nist1.nyc.certifiedtime.com
nist1.dc.certifiedtime.com
nist1.sjc.certifiedtime.com
nist1.datum.com
ntp2.cmc.ec.gc.ca
ntps1-0.uni-erlangen.de
ntps1-1.uni-erlangen.de
ntps1-2.uni-erlangen.de
ntps1-0.cs.tu-berlin.de
time.ien.it
ptbtime1.ptb.de
ptbtime2.ptb.de


Muy bien ¿y cómo funciona esto?

Pues básicamente estos servidores están escuchando en el puerto TCP/UDP 37 y el procedimiento es el siguiente, para TCP:

1.- Nos conectamos al servidor horario por el puerto TCP37
2.- El servidor, tras la conexión, sin que nosotros le enviemos nada, nos envía un dato de 4 bytes con la fecha/hora (realmente con los segundos transcurridos desde las 00:00:00 del 1/1/1990).
3.- El servidor cierra el socket.

Así de fácil.

Efectivamente no es tan preciso como usando NTP, pues el tiempo desde que el servidor envía el paquete de 4 bytes con la hora hasta que nos llega puede ser un pelín variable, pero como dije antes, una precisión de uno ó tal vez dos segundos no es para nada importante en la mayoría de nuestras aplicaciones.

Ejemplo en Java.

Os pongo un ejemplo en java aquí para el MTX65/MTX65+G para quien lo necesite. Únicamente hace lo que os comentaba antes. Se conecta a un servidor horario, obtenemos los 4 bytes con la hora y calculamos la fecha/hora. ¿Es fácil verdad?

El programa es muy simple, pero para que nadie se me despiste voy a comentar las siguientes líneas del código:

//Calculamos los segundos transcurridos desde el 1/1/1900
segundosDesde1900=buffer[0]*16777216 + buffer[1]*65536 + buffer[2]*256 + buffer[3];

//Calculamos ahora los segundos desde 1/1/1970
milisegundosDesde1970=segundosDesde1900-Long.parseLong(“2208988800″);

//Como java necesita los milisegundos (no segundos)para
//calcular la fecha desde 1/1/1970 multiplicamos por 1000
milisegundosDesde1970=milisegundosDesde1970*1000;

//Obtenemos la fecha/hora actual (GMT)
date = new Date(milisegundosDesde1970);
System.out.println(“Fecha/Hora:  ” + date.toString());

El protocolo indicado en la RFC868 indica que el servidor nos devuelve los segundos que han transcurrido desde el 1/1/1900 a las 00:00:00 y es lo que calculo y almaceno en la variable segundosDesde1900.

Pero en java, el constructor de la clase Date, necesita los milisegundos (mili, no segundos) transcurridos desde el 1/1/1970. Es por ello que primeramente restamos, de los segundos transcurridos desde el año 1900 hasta hoy, los segundos transcurridos desde el año 1900 al 1970 (esos 2208988800 segundos), obteniendo los segundos transcurridos desde hoy en día hasta el 1/1/1970. Después multiplicamos el valor por 1000, pues necesitamos trabajar con milisegundos, no segundos. El resto del programa ya es muy sencillo.

Bueno, espero que hayáis encontrado de interés el artículo. Otro día más. Sed buenos ;)


Post relacionados:

  1. Añadir datos a ficheros con módems Siemens-Cinterion desde java En bastantes ocasiones me ha llegado la pregunta de cómo...
  2. Localizando fallos difíciles de reproducir en los módems Cinterion TC65, XT65 Si desarrollas aplicaciones en Java para los módems gprs TC65,...
  3. Ejemplos Java para módems de Siemens A lo largo de los últimos meses he ido poniendo...
  4. Ejemplo FTP Java para módems Siemens Hoy pongo un brevísimo post con un nuevo ejemplo Java...
  5. Autoarranque de aplicaciones Java en módems Siemens Muy buenas. Hoy voy a poner un pequeño post relacionado con...








Etiquetas: , , , , , , , ,
15 Respuestas a “Cómo obtener la hora con los terminales MTX y módems Siemens / Cinterion”
  1. Lt_Henry dice:

    Hace poco que estoy trabajando con este terminal, y tengo un problema con los sockets que aun no he podido sacar adelante. Creo la conexion, creo el socket y lo abro, envio los datos (y llegan al otro lado) pero cuando vuelvo a lanzar un AT^SISW, se queda bloqueado, aunque sea para hacer un query de el estado de la transmision. La sentencia en cuestion es esta:

    “AT^SISW=0,” + data.length() + “,0,0\r”

    pero vamos, esta sacado de los ejemplos. Lo unico que me desconcierta un poco en lo que estoy haciendo, es que me llega un evento al hacer el primer SISW tal que:

    ^SISW: 0,1

    Por lo que entiendo de la documentacion (algo en lo que Siemens suele suspender) es que el cnfWriteLength es de 1, y no puedo mandar mas de 1 byte a la vez?

    Como veis estoy mas perdido que un pulpo en un garaje. ¿Algun idea?

  2. Currumblera dice:

    Hablando del tema de la hora….

    Tengo 2 MTX-65+G V3, y cuando activo los URC´s del GPS, o leo GPSData, tengo una hora menos de la real. ¿Alguien sabe si hay que configurar algo, o como se hace correctamente?. Supongo que habrá que configurar algo, porque la fecha, hora y demas datos los coge de los satélites.
    Espero vuestra ayuda, gracias.

  3. blogElectronica dice:

    Hola Currumblera,

    los satélites no envían la hora del lugar en el que estás. (Es decir, un GPS en Canarias no va a recibir una hora menos que un GPS en Madrid, para entendernos. En todos los lugares del planera vas a leer la misma hora).

    El GPS te va a devolver la hora UTC (Coordinated Universal Time). Mira este link:

    http://es.wikipedia.org/wiki/Coordinated_Universal_Time

    Fíjate en España. La hora en España es UTC+1 en Invierno y UTC+2 en verano.

    Espero haberte ayudado.

    Salu2.

  4. Currumblera dice:

    Gracias blogElectronica , está clara tu respuesta. Otra cuestión. ¿has probado ya si se puede grabar a la FFS, la lectura de almanac y ephemeris? (para el MTX-65+g V3)
    ¿cual sería el procedimiento para hacerlo?. Es que implantar un A-GPS, lo considero imprescindible en una aplicación final. Gracias por este magnífico foro.

  5. blogElectronica dice:

    Hola Lt_Henry,

    el URC: ^SISW: 0,1 te indica que ya puedes enviar más datos. Es decir, en cuanto te conectes con el SISO, al cabo de un instante recibirás un ^SISW: 0,1 indicándote que ya puedes escribir datos. En el ejemplo java, para que fuese breve, he puesto una simple pausa (prometo cambiarlo) pero no habría en enviar datos hasta recibir ese URC. Cuando envíes datos con SISW espera a recibir el SISW: 0,1 para enviar más datos, a ver si a si no tienes problemas.

    P.D. no me digas que Siemens suspende en documentación que me cabreo … :) ) Si algo tiene bueno Siemens es la gran cantidad de documentación, a lo mejor el problema es ese, que hay demasiada …

    Salu2

  6. blogElectronica dice:

    Lt_HEndry,

    me olvidaba, por supuesto puedes mandar más de 1 byte a la vez. En la documentación te lo indica, 1500 bytes.

    Salu2.

  7. Lt_Henry dice:

    Vale, es cierto, cuando hago el SISO al instante me llega el evento SISW: 0,1. Me espero hasta entonces, envio los datos (que llegan correctamente), sin embargo, aun con esperas de varios minutos, no vuelve a llegar ningun otro evento SISW, y cualquier llamada a comandos AT que tengan que ver con la conexion TCP bloquea el terminal (SISW, SISC, …) lo he probado con el eodFlag a 0 y a 1, con un \r en los datos, con un \n con un \n\r ….
    Es como si se perdiera el ACK de los datos enviados, pero llegar si que llegan siempre.

    Ya no se por donde seguir.

    Otra cosa que no acabo de entender, es porque en ningun ejemplo he visto AT^SICO (que ya perdi varios dias con esta tonteria), sin este comando no se establece una conexion con el APN :S

    PD: La documentacion de siemens es abundante….en numero de páginas, pero no te da la sensacion de que todo lo que lees le falta siempre algo? Lo dejan como para darle intriga xD Es que me he tenido que pelear (no hay otro verbo) con un control numerico y vaya tela me dio :S

  8. blogElectronica dice:

    Lt_Henry,

    ¿Has probado realizar lo que intentas hacer con el programa java desde un hyperterminal? ¿Cómo estás haciendo el programa java? ¿no estarás dando vueltas en un while cerrado “en el main” sin un Thread.sleep sin dar opción a que salte el URC?

    Por otro lado, AT^SICO no es necesario para ninguna conexión con el APN y no te hace falta para nada para abrir una sesión GPRS. Cuando haces un SISO ya realiza, en ese momento, la conexión con el APN, es decir, ya se inicia la sesión gprs y después se abre el socket automáticamente. SICO se utiliza para que no te cierre la sesión GPRS cuando no hay un servicio (socket) abierto al cabo del tiempo espedificado en inactTO como ocurre con SISO. En los ejemplos no hace falta y por eso no se ha puesto.

    Salu2

  9. Lt_Henry dice:

    Que raro lo del SICO…seria una coincidencia pues. Volviendo al otro tema. El programa ahora mismo no tiene bucle alguno, simplemente abre conexion, socket, envia un par de datos y luego cierra. Para esperar el SISW al principio le meti 60 segundos entre el primer envio y el segundo, pero al no ser suficientes, en mi funcion escribeSocket hice una espera para no poder mandar nada hasta que no llegue el evento SISW: 0,1 y ahora, pues se queda enganchado ahi, porque eso no sucede nunca. (solo la primera vez al hacer el SISO). La verdad es que no he probado ha lanzarlo a mano desde el hyperterminal, creo que es lo siguiente que deberia probar, pero lo que si te puedo decir es que ni SISO ni SISW devuelven un error. :\

    Me estaba preguntando si no es algo de la operadora, que en este caso es SIMYO. No entiendo nada :\

  10. Lt_Henry dice:

    He probado con esperas de hasta 60 segundos, y ahora mismo hay una espera en mi funcion escribeSocket que no realiza otro envio hasta recibir el anterior URC de SISW. Y como eso solo sucede una vez, el segundo envio no sucede nunca.

    No he probado a hacerlo a mano desde el hyperterminal, ciertamente es lo proximo que deberia de probar, no obstante ni SISO ni SISW devuelven un error y temo que sea algo de la operadora, porque no tiene sentido :\

    Esto se supone que deberia de funcionar !!!! :_C

  11. blogElectronica dice:

    Hola Lt_Henry,

    como es navidad y hay que ser generosos , he dedicado un ratillo de mi primer día de vacaciones a prepararte un ejemplo java que realiza 2 envíos, uno detrás del otro. Lo acabo de probar y funciona correctamente.

    Te lo pongo aquí:
    http://www.blogelectronica.com/TEMP/EJEMPLO_ConexionTCP3.zip

    Te aseguro que funciona, primero envía “Hola” y después “Adios”.

    A ver que tal …

    Salu2 y felices fiestas.

  12. Pablo dice:

    Tengo un problema, recibo 4 bytes que son byte[0] = -51, byte[1] = 18, byte [2] = 6 y byte[3] =77, pero el valor que obtengo depués de las operaciones no me da una fecha correcta, supongo que será por el valor negativo que recibo del primer byte. Qué hago mal? Estoy recibiendo mal los datos? Sólo recibo esos 4 bytes. Está mal la codificación? Utilizo para recibir los bytes un array declarado como byte [ ] bytes = new byte [ 4 ]. Qué hago mal?
    Gracias por anticipado

  13. Pablo dice:

    Vale, ya me lo he resuelto solo, el problema, como sospechaba estaba en la codificación. El -51 del primer byte es en realidad 256-51, es decir, 205. El resto de bytes son correctos y al usar la fórmula sale la fecha correcta. Gracias por este fantástico tutorial.

  14. Nico dice:

    He posteado una duda en el foro sobre sincronización horaria con la red GSM en lugar de vía internet…por si a alguien le interesa.

    http://www.blogelectronica.com/forum/tc65-xt65-mtx65-mtx65g/sobre-la-sincronizacion-horaria/#p23

    Saludos!

  15. Gen dice:

    Hola,

    estoy utilizando un XT75 y me encuentro con un problema gordo. Al recibir una trama GPS comparo la hora recibida con la del sistema y si nos igual la actualizo con el comando at+cclk, pero cual es mi sorpresa que la hora del sistema no se actualiza hasta que reinicias el modem, y la coge del valor del RTC, por lo que las clases DAte y Calendar cogen la hora antigua.

    Como puedo hacer que la hora del sistema corresponda con la que grabo en el RTC con el comando at+cclk sin reiniciar el equipo?? La necesito para hacer sincronizaciones horarias en la aplicacion java si tener que apagar el modem.

    Gracias de antemano.

    Saludos

  16.  
Deja una Respuesta

Puedes publicar un comentario aquí si quieres, pero te recomiendo que uses el nuevo foroElectronica.com para introducir comentarios. Te contestaré más rápido. Recuerda que debes registrarte si no lo estás para publicar un comentario.