Xwork's Blog

The lord is waiting to take your hand.

Learning Machine #9 - Conociendo a los archivos GPX.

No hay comentarios.
Hola a todos, el día de hoy vamos a ver cómo es que funcionan los archivos GPX.
Hace poco tiempo, cansado de no hacer nada por la mañana, decidí que sería buena idea volver a hacer un poco de ejercicio. Correr no es una opcion por ahora, estoy tan fuera de forma que probablemente muera de un infarto al primer kilometro, pero no dejare que eso sea un impedimento, así que opte por hacer un recorrido en bicicleta.
Yo soy de esas persona a las que le gusta tener cuantificado todo, asi que si por ejemplo, decidiera correr, necesitaria algo para medir los pasos y en el caso de la bicicleta, algo para medir la distancia.
Una de las maneras más sencillas para hacerlo, es usar mi telefono, al disponer de tantos sensores, debia de haber uno que me ayudara en lo que queria hacer. El GPS que tiene integrado, ayuda a obtener las coordenadas del trayecto.
Actualmente existen muchas aplicaciones que sirven para medir la distancia, velocidad y altitud de un trayecto, la mayoria de las aplicaciones que probé, guardaban toda la informacion en un archivo de extension *.GPX.

Los archivos GPX.

GPX, o GPS eXchange Format (Formato de Intercambio GPS) es un esquema XML pensado para transferir datos GPS entre aplicaciones. Se puede usar para describir puntos (waypoints), recorridos (tracks), y rutas (routes). (Wikipedia/GPX)
En resumidas cuentas, un archivo GPX es solamente un archivo XML en el cual se guardan los datos que se obtienen del GPS (u otras fuentes), pero ¿cómo saber que etiquetas se deben de usar? Bueno, las mas importantes (y que usaremos en futuros proyectos) son las siguientes:

  • <gpx> Indica el inicio del archivo, aqui se definen los esquemas a utilizar
    • <metadata> Indica el inicio de los meta datos.
      • <createtime> Fecha de creación.
      • <starttime> Fecha y hora de inicio del registro.
      •  <endtime> Fecha y hora del final del registro.
      • <distance> Distancia (en metros).
      • <duration> Duración del registro.
      • <maxspeed> Velocidad máxima (Km/h).
      • <avgspeed> Velocidad promedio (Km/h).
      • <vehicle> Tipo de vehículo.
      • <description> Descripción.
    • <trk> Indica el inicio de una pista.
    • <trkseg> Indica el inicio de un segmento de la pista.
    • <trkpt lat="00.0000000" lon="-00.0000000"> Un punto de la pista, cómo atributos se usa "lat" para almacenar la latitud y "lon" para almacenar la longitud.
    • <ele> Indica la elevación en este punto.
    • <speed> Indica la velocidad en este punto.
    • <currentdistance> Indica la distancia total actual.
    • <timeelapsed> Indica el tiempo transcurrido en este punto.
    • <time> Fecha y hora en la que se registro este punto.
Con lo anterior, entonces podemos crear un archivo cómo el que sigue:

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1" creator="Speed View GPS" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
   <metadata>
	  <createtime>2017-10-13T09:07:03Z</createtime>
	  <starttime>2017-10-13 08:32:23</starttime>
	  <endtime>2017-10-13 09:07:02</endtime>
	  <distance>7081.146</distance>
	  <duration>00:34:38</duration>
	  <maxspeed>7.91</maxspeed>
	  <avgspeed>3.406369</avgspeed>
	  <vehicle>car</vehicle>
	  <description>oct. 13, 2017 8:32:23</description>
   </metadata>
   <trk>
	  <trkseg>
		 <trkpt lat="19.2873547" lon="-98.9054489">
			<ele>2229.5</ele>
			<speed>4.17</speed>
			<currentdistance>4890.514</currentdistance>
			<timeelapsed>00:17:36</timeelapsed>
			<time>2017-10-13T08:49:59Z</time>
		 </trkpt>
		 <trkpt lat="19.2873004" lon="-98.9052929">
			<ele>2229.6</ele>
			<speed>4.68</speed>
			<currentdistance>4908.041</currentdistance>
			<timeelapsed>00:17:40</timeelapsed>
			<time>2017-10-13T08:50:03Z</time>
		 </trkpt>
		 <trkpt lat="19.2872414" lon="-98.9051528">
			<ele>2229.2</ele>
			<speed>5.6099997</speed>
			<currentdistance>4924.208</currentdistance>
			<timeelapsed>00:17:43</timeelapsed>
			<time>2017-10-13T08:50:06Z</time>
		 </trkpt>
		 <trkpt lat="19.2871614" lon="-98.9049907">
			<ele>2228.5</ele>
			<speed>6.16</speed>
			<currentdistance>4943.435</currentdistance>
			<timeelapsed>00:17:46</timeelapsed>
			<time>2017-10-13T08:50:09Z</time>
		 </trkpt>
		 <trkpt lat="19.2871065" lon="-98.9048134">
			<ele>2227.8</ele>
			<speed>6.6099997</speed>
			<currentdistance>4963.037</currentdistance>
			<timeelapsed>00:17:49</timeelapsed>
			<time>2017-10-13T08:50:12Z</time>
		 </trkpt>
		 <trkpt lat="19.2870293" lon="-98.9046317">
			<ele>2228.4</ele>
			<speed>6.8599997</speed>
			<currentdistance>4983.9917</currentdistance>
			<timeelapsed>00:17:52</timeelapsed>
			<time>2017-10-13T08:50:15Z</time>
		 </trkpt>
		 <trkpt lat="19.2869668" lon="-98.9044324">
			<ele>2229.5</ele>
			<speed>7.0699997</speed>
			<currentdistance>5006.054</currentdistance>
			<timeelapsed>00:17:55</timeelapsed>
			<time>2017-10-13T08:50:18Z</time>
		 </trkpt>
		 <trkpt lat="19.2868996" lon="-98.9042383">
			<ele>2229.0</ele>
			<speed>6.22</speed>
			<currentdistance>5027.7915</currentdistance>
			<timeelapsed>00:17:58</timeelapsed>
			<time>2017-10-13T08:50:21Z</time>
		 </trkpt>
		 <trkpt lat="19.2868314" lon="-98.9040744">
			<ele>2229.4</ele>
			<speed>5.42</speed>
			<currentdistance>5046.6025</currentdistance>
			<timeelapsed>00:18:01</timeelapsed>
			<time>2017-10-13T08:50:24Z</time>
		 </trkpt>
		 <trkpt lat="19.2867868" lon="-98.9039388">
			<ele>2229.3</ele>
			<speed>5.17</speed>
			<currentdistance>5061.6934</currentdistance>
			<timeelapsed>00:18:04</timeelapsed>
			<time>2017-10-13T08:50:27Z</time>
		 </trkpt>
		 <trkpt lat="19.2867203" lon="-98.9037992">
			<ele>2229.0</ele>
			<speed>5.42</speed>
			<currentdistance>5078.158</currentdistance>
			<timeelapsed>00:18:07</timeelapsed>
			<time>2017-10-13T08:50:30Z</time>
		 </trkpt>
		 <trkpt lat="19.2866701" lon="-98.9036398">
			<ele>2229.2</ele>
			<speed>5.75</speed>
			<currentdistance>5095.8345</currentdistance>
			<timeelapsed>00:18:10</timeelapsed>
			<time>2017-10-13T08:50:33Z</time>
		 </trkpt>
		 <trkpt lat="19.2866279" lon="-98.9035024">
			<ele>2229.4</ele>
			<speed>4.94</speed>
			<currentdistance>5111.036</currentdistance>
			<timeelapsed>00:18:13</timeelapsed>
			<time>2017-10-13T08:50:36Z</time>
		 </trkpt>
		 <trkpt lat="19.2865573" lon="-98.903338">
			<ele>2230.8</ele>
			<speed>5.35</speed>
			<currentdistance>5130.0107</currentdistance>
			<timeelapsed>00:18:17</timeelapsed>
			<time>2017-10-13T08:50:40Z</time>
		 </trkpt>
		 <trkpt lat="19.2865119" lon="-98.9031719">
			<ele>2232.1</ele>
			<speed>5.7</speed>
			<currentdistance>5148.191</currentdistance>
			<timeelapsed>00:18:20</timeelapsed>
			<time>2017-10-13T08:50:43Z</time>
		 </trkpt>
		 <trkpt lat="19.2864684" lon="-98.9030063">
			<ele>2231.6</ele>
			<speed>5.2999997</speed>
			<currentdistance>5166.3203</currentdistance>
			<timeelapsed>00:18:23</timeelapsed>
			<time>2017-10-13T08:50:46Z</time>
		 </trkpt>
		 <trkpt lat="19.2864122" lon="-98.9028658">
			<ele>2231.3</ele>
			<speed>4.96</speed>
			<currentdistance>5182.3594</currentdistance>
			<timeelapsed>00:18:26</timeelapsed>
			<time>2017-10-13T08:50:49Z</time>
		 </trkpt>
		 <trkpt lat="19.2863534" lon="-98.9026856">
			<ele>2231.1</ele>
			<speed>5.0899997</speed>
			<currentdistance>5202.404</currentdistance>
			<timeelapsed>00:18:30</timeelapsed>
			<time>2017-10-13T08:50:53Z</time>
		 </trkpt>
		 <trkpt lat="19.286309" lon="-98.9025323">
			<ele>2230.1</ele>
			<speed>5.73</speed>
			<currentdistance>5219.2666</currentdistance>
			<timeelapsed>00:18:33</timeelapsed>
			<time>2017-10-13T08:50:56Z</time>
		 </trkpt>
		 <trkpt lat="19.2862376" lon="-98.9023771">
			<ele>2230.8</ele>
			<speed>5.62</speed>
			<currentdistance>5237.3994</currentdistance>
			<timeelapsed>00:18:36</timeelapsed>
			<time>2017-10-13T08:50:59Z</time>
		 </trkpt>
		 <trkpt lat="19.286167" lon="-98.902229">
			<ele>2230.1</ele>
			<speed>5.7999997</speed>
			<currentdistance>5254.8184</currentdistance>
			<timeelapsed>00:18:39</timeelapsed>
			<time>2017-10-13T08:51:02Z</time>
		 </trkpt>
		 <trkpt lat="19.2861174" lon="-98.9020688">
			<ele>2229.7</ele>
			<speed>5.19</speed>
			<currentdistance>5272.635</currentdistance>
			<timeelapsed>00:18:42</timeelapsed>
			<time>2017-10-13T08:51:05Z</time>
		 </trkpt>
		 <trkpt lat="19.2860754" lon="-98.9019254">
			<ele>2229.5</ele>
			<speed>5.14</speed>
			<currentdistance>5288.4106</currentdistance>
			<timeelapsed>00:18:45</timeelapsed>
			<time>2017-10-13T08:51:08Z</time>
		 </trkpt>
		 <trkpt lat="19.2860339" lon="-98.9017654">
			<ele>2228.9</ele>
			<speed>4.89</speed>
			<currentdistance>5306.137</currentdistance>
			<timeelapsed>00:18:48</timeelapsed>
			<time>2017-10-13T08:51:11Z</time>
		 </trkpt>
		 <trkpt lat="19.2859513" lon="-98.9016034">
			<ele>2227.7</ele>
			<speed>4.52</speed>
			<currentdistance>5325.536</currentdistance>
			<timeelapsed>00:18:52</timeelapsed>
			<time>2017-10-13T08:51:15Z</time>
		 </trkpt>
		 <trkpt lat="19.285881" lon="-98.901449">
			<ele>2227.4</ele>
			<speed>4.81</speed>
			<currentdistance>5343.5986</currentdistance>
			<timeelapsed>00:18:56</timeelapsed>
			<time>2017-10-13T08:51:19Z</time>
		 </trkpt>
		 <trkpt lat="19.2858317" lon="-98.9013101">
			<ele>2228.0</ele>
			<speed>4.54</speed>
			<currentdistance>5359.328</currentdistance>
			<timeelapsed>00:18:59</timeelapsed>
			<time>2017-10-13T08:51:22Z</time>
		 </trkpt>
		 <trkpt lat="19.2857715" lon="-98.9011595">
			<ele>2228.3</ele>
			<speed>4.48</speed>
			<currentdistance>5376.5923</currentdistance>
			<timeelapsed>00:19:03</timeelapsed>
			<time>2017-10-13T08:51:26Z</time>
		 </trkpt>
		 <trkpt lat="19.2857089" lon="-98.9010114">
			<ele>2228.3</ele>
			<speed>4.35</speed>
			<currentdistance>5393.6396</currentdistance>
			<timeelapsed>00:19:07</timeelapsed>
			<time>2017-10-13T08:51:30Z</time>
		 </trkpt>
		 <trkpt lat="19.2856641" lon="-98.9008596">
			<ele>2228.6</ele>
			<speed>3.6799998</speed>
			<currentdistance>5410.394</currentdistance>
			<timeelapsed>00:19:11</timeelapsed>
			<time>2017-10-13T08:51:34Z</time>
		 </trkpt>
		 <trkpt lat="19.2855949" lon="-98.9006918">
			<ele>2228.4</ele>
			<speed>4.63</speed>
			<currentdistance>5429.6284</currentdistance>
			<timeelapsed>00:19:15</timeelapsed>
			<time>2017-10-13T08:51:38Z</time>
		 </trkpt>
		 <trkpt lat="19.2855428" lon="-98.9005373">
			<ele>2228.0</ele>
			<speed>4.48</speed>
			<currentdistance>5446.902</currentdistance>
			<timeelapsed>00:19:19</timeelapsed>
			<time>2017-10-13T08:51:42Z</time>
		 </trkpt>
		 <trkpt lat="19.2855065" lon="-98.9003938">
			<ele>2227.8</ele>
			<speed>5.7</speed>
			<currentdistance>5462.5405</currentdistance>
			<timeelapsed>00:19:22</timeelapsed>
			<time>2017-10-13T08:51:45Z</time>
		 </trkpt>
		 <trkpt lat="19.2854442" lon="-98.9002132">
			<ele>2227.5</ele>
			<speed>6.69</speed>
			<currentdistance>5482.7666</currentdistance>
			<timeelapsed>00:19:25</timeelapsed>
			<time>2017-10-13T08:51:48Z</time>
		 </trkpt>
		 <trkpt lat="19.2853641" lon="-98.9000407">
			<ele>2227.6</ele>
			<speed>6.8399997</speed>
			<currentdistance>5502.969</currentdistance>
			<timeelapsed>00:19:28</timeelapsed>
			<time>2017-10-13T08:51:51Z</time>
		 </trkpt>
		 <trkpt lat="19.2853049" lon="-98.8998464">
			<ele>2228.1</ele>
			<speed>6.7999997</speed>
			<currentdistance>5524.433</currentdistance>
			<timeelapsed>00:19:31</timeelapsed>
			<time>2017-10-13T08:51:54Z</time>
		 </trkpt>
		 <trkpt lat="19.2852443" lon="-98.8996762">
			<ele>2228.1</ele>
			<speed>6.25</speed>
			<currentdistance>5543.546</currentdistance>
			<timeelapsed>00:19:34</timeelapsed>
			<time>2017-10-13T08:51:57Z</time>
		 </trkpt>
		 <trkpt lat="19.2851887" lon="-98.8994991">
			<ele>2229.2</ele>
			<speed>6.6</speed>
			<currentdistance>5563.195</currentdistance>
			<timeelapsed>00:19:37</timeelapsed>
			<time>2017-10-13T08:52:00Z</time>
		 </trkpt>
		 <trkpt lat="19.2851245" lon="-98.8993265">
			<ele>2229.4</ele>
			<speed>6.25</speed>
			<currentdistance>5582.688</currentdistance>
			<timeelapsed>00:19:40</timeelapsed>
			<time>2017-10-13T08:52:03Z</time>
		 </trkpt>
		 <trkpt lat="19.2850556" lon="-98.8991673">
			<ele>2230.2</ele>
			<speed>6.44</speed>
			<currentdistance>5601.079</currentdistance>
			<timeelapsed>00:19:43</timeelapsed>
			<time>2017-10-13T08:52:06Z</time>
		 </trkpt>
		 <trkpt lat="19.2850039" lon="-98.8989882">
			<ele>2231.2</ele>
			<speed>6.43</speed>
			<currentdistance>5620.7734</currentdistance>
			<timeelapsed>00:19:46</timeelapsed>
			<time>2017-10-13T08:52:09Z</time>
		 </trkpt>
		 <trkpt lat="19.284942" lon="-98.8988195">
			<ele>2230.0</ele>
			<speed>6.42</speed>
			<currentdistance>5639.808</currentdistance>
			<timeelapsed>00:19:49</timeelapsed>
			<time>2017-10-13T08:52:12Z</time>
		 </trkpt>
		 <trkpt lat="19.2848768" lon="-98.8986502">
			<ele>2229.3</ele>
			<speed>6.33</speed>
			<currentdistance>5659.0356</currentdistance>
			<timeelapsed>00:19:52</timeelapsed>
			<time>2017-10-13T08:52:15Z</time>
		 </trkpt>
		 <trkpt lat="19.2848074" lon="-98.8984819">
			<ele>2228.3</ele>
			<speed>6.2999997</speed>
			<currentdistance>5678.3735</currentdistance>
			<timeelapsed>00:19:55</timeelapsed>
			<time>2017-10-13T08:52:18Z</time>
		 </trkpt>
		 <trkpt lat="19.2847355" lon="-98.8983052">
			<ele>2227.7</ele>
			<speed>6.24</speed>
			<currentdistance>5698.695</currentdistance>
			<timeelapsed>00:19:58</timeelapsed>
			<time>2017-10-13T08:52:21Z</time>
		 </trkpt>
		 <trkpt lat="19.2846779" lon="-98.8981337">
			<ele>2227.4</ele>
			<speed>6.24</speed>
			<currentdistance>5717.8203</currentdistance>
			<timeelapsed>00:20:01</timeelapsed>
			<time>2017-10-13T08:52:24Z</time>
		 </trkpt>
		 <trkpt lat="19.2846228" lon="-98.8979652">
			<ele>2227.3</ele>
			<speed>6.0899997</speed>
			<currentdistance>5736.634</currentdistance>
			<timeelapsed>00:20:04</timeelapsed>
			<time>2017-10-13T08:52:27Z</time>
		 </trkpt>
		 <trkpt lat="19.2845703" lon="-98.8978222">
			<ele>2228.1</ele>
			<speed>5.62</speed>
			<currentdistance>5752.7866</currentdistance>
			<timeelapsed>00:20:07</timeelapsed>
			<time>2017-10-13T08:52:30Z</time>
		 </trkpt>
		 <trkpt lat="19.2845295" lon="-98.8976665">
			<ele>2228.6</ele>
			<speed>5.0299997</speed>
			<currentdistance>5769.9194</currentdistance>
			<timeelapsed>00:20:10</timeelapsed>
			<time>2017-10-13T08:52:33Z</time>
		 </trkpt>
		 <trkpt lat="19.2844665" lon="-98.8974973">
			<ele>2228.4</ele>
			<speed>5.3199997</speed>
			<currentdistance>5789.093</currentdistance>
			<timeelapsed>00:20:14</timeelapsed>
			<time>2017-10-13T08:52:37Z</time>
		 </trkpt>
		 <trkpt lat="19.2844181" lon="-98.8973579">
			<ele>2228.4</ele>
			<speed>5.3199997</speed>
			<currentdistance>5804.718</currentdistance>
			<timeelapsed>00:20:17</timeelapsed>
			<time>2017-10-13T08:52:40Z</time>
		 </trkpt>
		 <trkpt lat="19.284345" lon="-98.8971953">
			<ele>2228.7</ele>
			<speed>5.46</speed>
			<currentdistance>5823.6953</currentdistance>
			<timeelapsed>00:20:20</timeelapsed>
			<time>2017-10-13T08:52:43Z</time>
		 </trkpt>
		 <trkpt lat="19.2843003" lon="-98.8970488">
			<ele>2228.7</ele>
			<speed>5.6099997</speed>
			<currentdistance>5839.8765</currentdistance>
			<timeelapsed>00:20:23</timeelapsed>
			<time>2017-10-13T08:52:46Z</time>
		 </trkpt>
		 <trkpt lat="19.2842265" lon="-98.8968865">
			<ele>2230.9</ele>
			<speed>5.7599998</speed>
			<currentdistance>5858.798</currentdistance>
			<timeelapsed>00:20:26</timeelapsed>
			<time>2017-10-13T08:52:49Z</time>
		 </trkpt>
		 <trkpt lat="19.2841685" lon="-98.8967161">
			<ele>2229.8</ele>
			<speed>5.7599998</speed>
			<currentdistance>5877.8633</currentdistance>
			<timeelapsed>00:20:29</timeelapsed>
			<time>2017-10-13T08:52:52Z</time>
		 </trkpt>
		 <trkpt lat="19.2840928" lon="-98.8965554">
			<ele>2230.3</ele>
			<speed>5.52</speed>
			<currentdistance>5896.795</currentdistance>
			<timeelapsed>00:20:32</timeelapsed>
			<time>2017-10-13T08:52:55Z</time>
		 </trkpt>
		 <trkpt lat="19.2840414" lon="-98.8964041">
			<ele>2230.1</ele>
			<speed>5.83</speed>
			<currentdistance>5913.686</currentdistance>
			<timeelapsed>00:20:35</timeelapsed>
			<time>2017-10-13T08:52:58Z</time>
		 </trkpt>
		 <trkpt lat="19.2839835" lon="-98.8962396">
			<ele>2230.4</ele>
			<speed>6.31</speed>
			<currentdistance>5932.1357</currentdistance>
			<timeelapsed>00:20:38</timeelapsed>
			<time>2017-10-13T08:53:01Z</time>
		 </trkpt>
		 <trkpt lat="19.2839417" lon="-98.8960511">
			<ele>2230.1</ele>
			<speed>5.81</speed>
			<currentdistance>5952.5576</currentdistance>
			<timeelapsed>00:20:41</timeelapsed>
			<time>2017-10-13T08:53:04Z</time>
		 </trkpt>
		 <trkpt lat="19.2838761" lon="-98.8958997">
			<ele>2230.2</ele>
			<speed>5.79</speed>
			<currentdistance>5970.072</currentdistance>
			<timeelapsed>00:20:44</timeelapsed>
			<time>2017-10-13T08:53:07Z</time>
		 </trkpt>
		 <trkpt lat="19.283805" lon="-98.8957721">
			<ele>2229.7</ele>
			<speed>5.31</speed>
			<currentdistance>5985.7344</currentdistance>
			<timeelapsed>00:20:47</timeelapsed>
			<time>2017-10-13T08:53:10Z</time>
		 </trkpt>
		 <trkpt lat="19.2837329" lon="-98.8956155">
			<ele>2228.8</ele>
			<speed>4.69</speed>
			<currentdistance>6004.08</currentdistance>
			<timeelapsed>00:20:51</timeelapsed>
			<time>2017-10-13T08:53:14Z</time>
		 </trkpt>
		 <trkpt lat="19.2836277" lon="-98.8955173">
			<ele>2229.0</ele>
			<speed>5.2599998</speed>
			<currentdistance>6019.7734</currentdistance>
			<timeelapsed>00:20:54</timeelapsed>
			<time>2017-10-13T08:53:17Z</time>
		 </trkpt>
		 <trkpt lat="19.2835321" lon="-98.8953833">
			<ele>2229.3</ele>
			<speed>5.47</speed>
			<currentdistance>6037.611</currentdistance>
			<timeelapsed>00:20:57</timeelapsed>
			<time>2017-10-13T08:53:20Z</time>
		 </trkpt>
		 <trkpt lat="19.2834933" lon="-98.8952368">
			<ele>2229.5</ele>
			<speed>5.35</speed>
			<currentdistance>6053.6636</currentdistance>
			<timeelapsed>00:21:00</timeelapsed>
			<time>2017-10-13T08:53:23Z</time>
		 </trkpt>
		 <trkpt lat="19.2834481" lon="-98.8950919">
			<ele>2228.7</ele>
			<speed>5.22</speed>
			<currentdistance>6069.696</currentdistance>
			<timeelapsed>00:21:03</timeelapsed>
			<time>2017-10-13T08:53:26Z</time>
		 </trkpt>
		 <trkpt lat="19.283385" lon="-98.8949165">
			<ele>2228.7</ele>
			<speed>4.7799997</speed>
			<currentdistance>6089.425</currentdistance>
			<timeelapsed>00:21:07</timeelapsed>
			<time>2017-10-13T08:53:30Z</time>
		 </trkpt>
		 <trkpt lat="19.2833551" lon="-98.8947334">
			<ele>2229.2</ele>
			<speed>4.8399997</speed>
			<currentdistance>6108.9653</currentdistance>
			<timeelapsed>00:21:11</timeelapsed>
			<time>2017-10-13T08:53:34Z</time>
		 </trkpt>
	  </trkseg>
   </trk>
</gpx>

Que tendrá cómo resultado algo cómo lo de la imagen siguiente:
Puedes ver el archivo GPX en http://maplorer.com/
No todos las etiquetas son necesarias para que el archivo funcione, pero por default la aplicación que use crea todas las etiquetas anteriores. Cómo eso se me hace un desperdicio, en el siguiente post, vamos ver cómo hacer uso del GPS en un dispositivo android (con GPS, obviamente) y crear nuestros propios archivos GPX para poder llevar un registro de los recorridos en bicicleta que haga.

Por ahora es todo, los leo luego.

No hay comentarios. :

Publicar un comentario

Vamos a programar #43 - Actualizando clock view.

No hay comentarios.
Hola de nuevo a todos, el día de hoy vamos a ver una actualizacion del código de clock view.
Cómo recordarás, hace un buen rato dije que iba a actualizar el código, pero por varias razones lo pospuse, hasta que finalmente casí lo olvide. No se le hicieron muchos cambios, solo optimizaron algunas partes y se saco un poco más de provecho a las partes que ya se usaban y se agregaron unas cuantas más. Sí previamente ya habías hecho el proyecto, solo bastará con cargar el código al arduino, de cualquier forma, el código estará disponible para su descarga.

El código.

El código actualizado del Clock View es el siguiente:
//Clockview 2.0
#include <DS1302.h>
#include "LedControl.h"
#include <SD.h>
/*
	Para la conexión del modulo SD se siguen los siguientes:
	** MOSI - pin 11
	** MISO - pin 12
	** CLK - pin 13
	** CS - pin 10 - Este es el que se puede cambiar
*/
//Pin SD
int CS_PIN = 10;
//Constantes para los pines usados en la matriz
const int MaxDIn = 9;
const int MaxCS = 8;
const int MaxCLK = 7;
int MaxNDevices = 3;
bool IsConnected = false;
//Constantes para los pines usados en el reloj
const int kCePin = 6;  // RST
const int kIoPin = 5;  // Dat
const int kSclkPin = 4;  // Serial Clock
//Inicializacion de la matriz
//DIN,CLK,CS
LedControl lc = LedControl(MaxDIn, MaxCLK, MaxCS, MaxNDevices);
//Inicializacion del reloj
DS1302 rtc(kCePin, kIoPin, kSclkPin);
//Algunas variables
File Archivo;
char Texto[24];
int MatrixB = 10;
bool H24 = true;
bool HalfSecond = true;
bool IsScreenEnable = true;
bool ShowSeconds = true;
bool SDCardReady = false;
bool EditMode = false;
bool ShowDate = false;
bool Demo = false;
//Matriz con los "Numeros"
const unsigned char Numbers[] = {
	B11111110, B10000010, B11111110, //0
	B10000100, B11111110, B10000000, //1
	B11110010, B10010010, B10011110, //2
	B10000010, B10010010, B11111110, //3
	B00011110, B00010000, B11111110, //4
	B10011110, B10010010, B11110010, //5
	B11111110, B10010010, B11110010, //6
	B00000010, B00000010, B11111110, //7
	B11111110, B10010010, B11111110, //8
	B00011110, B00010010, B11111110, //9
	B11111110, B00010010, B11111110, //A - 10
	B11111110, B00011100, B11111110, //M - 11
	B11111110, B00010010, B00011110, //P - 12
	B11111110, B00010000, B11111110, //H - 13
	B11111110 ,B00110010, B11011110, //R - 14
};
//Definimos simbolos
const unsigned char Symbols[] = {
	B01000100, B00101000, B00010000, B11111110, B01010100, B00101000, //BT 0
	B00111100, B01000110, B01011010, B01001010, B01001010, B00111100, //Clock Adjust 1
	B11010110, B10111010, B01000100, B01000100, B10111010, B11010110//Brightness 2
};
//Imprimir simbolos
void PrintSymbol(byte Index,byte SymDevice){
	for (int Y = 1; Y < 7; Y++){
		lc.setRow(SymDevice, Y, Symbols[Index * 5 + Y - 1]);
	}
}
//Funcion para escribir los numero en la matriz.
void PrintNumber(byte NumberOne, byte NumberTwo, byte Device){
	for (int X = 1; X < 8; X++){
		if (X < 4){
			lc.setRow(Device, X, Numbers[NumberOne * 3 + X - 1]);
		}
		if (X == 4){
			lc.setRow(Device, 4, 0);
		}
		if (X > 4){
			lc.setRow(Device, X, Numbers[NumberTwo * 3 + X - 5]);
		}
	}
}
void printDate(){
	Time t = rtc.time();
	const String day = dayAsString(t.day);
	char buf[50];
	snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
	day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
	int ShortYear = t.yr % 100;
	PrintNumber(t.date / 10, t.date % 10, 0);
	PrintNumber(t.mon / 10, t.mon % 10, 1);
	PrintNumber(ShortYear / 10, ShortYear % 10, 2);
}
//Imprimir el tiempo en las matrices y en el monitor serie.
void printTime(){
	Time t = rtc.time();
	const String day = dayAsString(t.day);
	char buf[50];
	snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
		day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
	PrintNumber(AdjustTime(t.hr, H24) / 10,AdjustTime(t.hr, H24) % 10, 0);
	PrintNumber(t.min / 10, t.min % 10, 1);
	if (ShowSeconds){
		PrintNumber(t.sec / 10, t.sec % 10, 2);	
	}else{
		if(H24)
			PrintNumber(13, 14, 2);
		if(!H24 && t.hr < 13)
			PrintNumber(10, 11, 2);
		if(!H24 && t.hr > 12)
			PrintNumber(12, 11, 2);
	}
	//PrintSymbol(0, 2);
	if (IsScreenEnable == true)
	{
		if (HalfSecond == true){
			digitalWrite(3, HIGH);
			HalfSecond = false;
		}else{
			digitalWrite(3, LOW);
			HalfSecond = true;
		}
	}
	Serial.println(buf);
}
//Demo directo del ejemplo de la libreria
void ScreenDemo(){
	int devices=lc.getDeviceCount();
	for(int row=0;row<8;row++) {
		for(int col=0;col<8;col++) {
			for(int address=0;address<devices;address++) {
				int DemoButton = analogRead(A5);
				if(DemoButton < 200){
					Demo = false;
					break;
				}
				delay(40);
				lc.setLed(address,row,col,true);
				delay(40);
				lc.setLed(address,row,col,false);
			}
		}
	}
}
//Ajustar la hora
int AdjustTime(int Hour, bool In24Hformat){
	if(In24Hformat == true){
		return Hour;
	}
	if(In24Hformat == false && Hour > 12){
		Hour = Hour - 12;
		return Hour;
	}else{
		return Hour;
	}
}
//Guardar los ajustes
void SaveSettings(){
	Archivo = SD.open("Settings.clv", O_WRITE | O_CREAT);
	char SaveBuf[8];
	snprintf(SaveBuf, sizeof(SaveBuf), "%s%02d",">SETB", MatrixB);
	Serial.println(SaveBuf);
	if (Archivo){
		Archivo.seek(0);
		Archivo.println(SaveBuf);
		if(H24)
			Archivo.println(">SETF");
		else
			Archivo.println("XSETF");
		if (ShowSeconds)
			Archivo.println(">DISS");
		else
			Archivo.println("XDISS");
			Archivo.flush();
			Archivo.close();
		Serial.println("Guardado");
	} else {
		Serial.println("error writing test.txt");
	}
}
//Enviar un resumen de las configuraciones actuales
void SendResume(){
	
}
//Cargar los ajustes
void LoadSettings(){
	Archivo = SD.open("Settings.clv", FILE_READ);
	int B = 0;
	byte CurRead;
	char SettBuf[22];
	if (Archivo) {
		while (Archivo.available() > 0){
			CurRead = Archivo.read();
			if	(CurRead != 10 && CurRead != 13){
				SettBuf[B] = CurRead;
				B++;
				Serial.print(B);
			}else{
				CheckPetition(SettBuf, false);
				Serial.print(B);
				B = 0;
				for (int BF = 0; BF < 22; BF++)
					SettBuf[BF]=0;
			}
		}
		Archivo.close();
	}else{
		Serial.println("error opening file");
	}	
}
//Comprobar si hay algun comando
void CheckPetition(char DATA[], bool Save){
	int i = 0;
	int j = 0;
	String Texto(DATA);
	//>SETH2016122119001004
	if (Texto.startsWith(">DISS")){
		ShowSeconds = !ShowSeconds;
		if (Save)
			SaveSettings();
		Serial.print("No/Se muestran los segundos");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, !IsScreenEnable);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	if (Texto.startsWith(">SCRA")){
		IsScreenEnable = !IsScreenEnable;
		Serial.print("Las matrices se apagaron/encendieron");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, !IsScreenEnable);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}	
	if (Texto.startsWith(">RESET")){
		SD.remove("Settings.clv");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, !IsScreenEnable);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}	
	if (Texto.startsWith(">SETF")){
		H24 = !H24;
		if (Save)
			SaveSettings();
		Serial.print("EL reloj cambio de formato 12H-24H");
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	if (Texto.startsWith(">SETH")){
		AdjustTime(Texto.substring(9, 5).toInt(),Texto.substring(11,9).toInt(),Texto.substring(13, 11).toInt(),
		Texto.substring(15, 13).toInt(), Texto.substring(17, 15).toInt(), Texto.substring(19, 17).toInt(),
		Texto.substring(21, 19).toInt());
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	if (Texto.startsWith(">SETB")){
		MatrixB = Texto.substring(5).toInt();
		if (Save)
			SaveSettings();
		Serial.println("El brillo se cambio");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.setIntensity(CurrentDevice, MatrixB);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	else {
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
}
//Convertir los dias
String dayAsString(const Time::Day day){
	switch (day){
		case Time::kSunday: return "DOM";
		case Time::kMonday: return "LUN";
		case Time::kTuesday: return "MAR";
		case Time::kWednesday: return "MIE";
		case Time::kThursday: return "JUE";
		case Time::kFriday: return "VIE";
		case Time::kSaturday: return "SAB";
	}
	return "(unknown day)";
}
//Ajustar la hora
void AdjustTime(int Year,int Month, int Day, int Hour, int Minute, int Second, int DayOfWeek){
	Time::Day CurrentDay;
	switch (DayOfWeek){
		case 1:
			CurrentDay = Time::kSunday;
			break;
		case 2:
			CurrentDay = Time::kMonday;
			break;
		case 3:
			CurrentDay = Time::kTuesday;
			break;
		case 4:
			CurrentDay = Time::kWednesday;
			break;
		case 5:
			CurrentDay = Time::kThursday;
			break;
		case 6:
			CurrentDay = Time::kFriday;
			break;
		case 7:
			CurrentDay = Time::kSaturday;
			break;
	}
	//Esta parte se usa para actualizar la hora.
	rtc.writeProtect(false);
	rtc.halt(false);
	Time t(Year, Month, Day, Hour, Minute, Second, CurrentDay);
	rtc.time(t);	
}
//Inicializar la tarjeta SD para usarla
void InitializeSD(){
	pinMode(CS_PIN, OUTPUT);
	if (SD.begin()){
		SDCardReady = true;
		Serial.println("La tarjeta SD esta lista");
	}else{
		SDCardReady = false;
		Serial.println("La tarjeta SD no esta lista");
		return;
	}
}
//Setup
void setup(){
	Serial.begin(9600);
	for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
		lc.shutdown(CurrentDevice, false);
		lc.setIntensity(CurrentDevice, MatrixB);
		lc.clearDisplay(CurrentDevice);
	}
	InitializeSD();
	pinMode(A2, INPUT_PULLUP);
	pinMode(A3, INPUT_PULLUP);
	pinMode(A4, INPUT_PULLUP);
	pinMode(A5, INPUT_PULLUP);
	pinMode(3, OUTPUT);
	if(SDCardReady){
		LoadSettings();
	}else{
		Serial.println("La tarjeta no está lista");
	}
}
//Loop
void loop(){
	int SetEditButton = analogRead(A2);
	int ShowDateButton = analogRead(A3);
	int TurnOffMatrixButton = analogRead(A4);
	int DemoButton = analogRead(A5);
	
	while (Demo == true){
		ScreenDemo();
	}
	if(DemoButton < 200){
		Demo = !Demo;
	}
	Serial.println(SetEditButton);	
	if(SetEditButton < 200){
		EditMode = !EditMode;
	}
	if(ShowDateButton < 200){
		ShowDate = true;
	}
	if(TurnOffMatrixButton < 200){
		IsScreenEnable = !IsScreenEnable;
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, IsScreenEnable);
		}
	}	
	if(ShowDate){
		printDate();
		delay(3000);
		ShowDate = false;
	}
	if(EditMode){
		int PotB = analogRead(A0);
		// print out the value you read:
		int MatrixB = map(PotB, 0, 1000, 1, 15);
		char SaveBuf[8];
		snprintf(SaveBuf, sizeof(SaveBuf), "%s%02d",">SETB", MatrixB);
		CheckPetition(SaveBuf, false);
		PrintNumber(MatrixB / 10,MatrixB % 10, 2);
		PrintSymbol(2,1);
		delay(100);
	}else{
		int i = 0;
		printTime();
		delay(100);
		if (Serial.available()) {
			while (Serial.available() > 0) {
				Texto[i] = Serial.read();
				i++;
			}
			Texto[i] = '\0';
		}
		CheckPetition(Texto, true);	
	}
}



El código es funcional, pero demostrativo. Uno de los cambios más notorios que se puede observar, es que los número son más grandes.
Los números eran de 3x5 LEDs, en su lugar, ahora son de 7x3
Además se hace uso de pulsadores para que tambien sea manipulable, en este caso, el código hace uso de 4, pero tal vez en un futuro, se usen solo 3, he visto muchos relojes que solo hacen el uso de ese número.
El código se actualizará nuevamente, pero por ahora lo público así para que te sientas libre de probar con tus propios ajustes. Si no dispones de pulsadores, no te preocupes, aun es totalmente utilizable solo por medio de bluetooth. El código anterior lo puedes descargar de la seccion de descargas y si quieres hacer uso de este, basta con copiarlo; todas las conexiones vienen en el código.
Por ahora es todo, los leo luego.

No hay comentarios. :

Publicar un comentario