Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
UNIVERSIDAD ANDRÉS BELLO
Facultad de Ingeniería
Escuela de Industrias
TELEMETRICS: SISTEMA DE TELEMETRIA BASADO EN PLATAFORMAS
ANDROID-ARDUINO CON TRANSMISIÓN DE DATOS VÍA BLUETOOTH-
TCP/IP E INTERFAZ DE USUARIO EN LABVIEW PARA
GEOPOSICIONAMIENTO Y CONTROL DE FLOTA
Tesis de pregrado para optar al título de Ingeniero en Automatización y Robótica
Autor:
Francis Valerio Serrano Vargas
Profesor Guía: Néstor Palominos González
Santiago de Chile, 2015
ii
UNIVERSIDAD ANDRES BELLO
FACULTAD DE INGENIERÍA
ESCUELA DE INDUSTRIAS
INGENIERÍA EN AUTOMATIZACIÓN Y ROBÓTICA
DECLARACIÓN DE ORIGINALIDAD Y PROPIEDAD
Yo, Francis Valerio Serrano Vargas, declaro que este documento no incorpora material
de otros autores sin identificar debidamente la fuente.
Santiago, Diciembre de 2015
_____________________________
Firma del alumno
iii
Dedicado a todos quienes confiaron en mí,
a mis padres Bernardo y Yanella,
a mi hermana Yanella,
a mis suegros Orlando y Cecilia,
a mi novia Valentina que ha
sido elemental en esta constante lucha
y a todos quienes crean que los límites
sólo existen en la mente de las personas.
Francis Valerio Serrano Vargas
iv
AGRADECIMIENTOS
Agradecimientos especiales para quienes confiaron en mis capacidades desde
un comienzo, mis padres, que aunque no fue fácil, me apoyaron en todas las
decisiones que tomé, siempre guiándome por el camino correcto y entregándome
aliento en los momentos más extenuantes.
Agradezco a mi novia Valentina, quien estuvo conmigo en los momentos más
complejos y extenuantes, en donde sin su incondicional apoyo hubiese sido
imposible seguir luchando por obtener esta recompensa.
Agradezco a mi profesor guía, Néstor Palominos, que, como un amigo, me
enseñó herramientas a lo largo de toda mi etapa formativa, que me servirán para
el desarrollo y potenciación de mis habilidades en esta nueva etapa que
comienza.
v
ÍNDICE GENERAL
AGRADECIMIENTOS ................................................................................................................... iv
RESUMEN .................................................................................................................................. xvi
ABSTRACT............................................................................................................................... xviii
ANTECEDENTES GENERALES .......................................................................................... 1
INTRODUCCION ........................................................................................................... 1
OBJETIVOS ................................................................................................................... 4
OBJETIVO GENERAL ........................................................................................... 4
OBJETIVOS ESPECÍFICOS .................................................................................. 4
ORGANIZACIÓN Y PRESENTACIÓN DEL TRABAJO ................................................. 5
MARCO TEÓRICO ................................................................................................................ 6
ESTADO DEL ARTE ...................................................................................................... 6
DESCRIPCIÓN DE LA PROBLEMÁTICA ........................................................... 10
IMPACTO DEL PROYECTO ................................................................................ 10
HERRAMIENTAS UTILIZADAS ................................................................................... 11
GPS ...................................................................................................................... 11
BLUETOOTH ....................................................................................................... 17
TCP/IP .................................................................................................................. 21
IRC ....................................................................................................................... 33
MYSQL ................................................................................................................. 38
SMARTPHONE .................................................................................................... 39
RASPBERRY PI ................................................................................................... 40
ARDUINO ............................................................................................................. 43
ANDROID ............................................................................................................. 45
LABVIEW ......................................................................................................... 51
DESARROLLO DEL PROYECTO....................................................................................... 64
vi
MODELAMIENTO DE LA SOLUCIÓN ......................................................................... 64
VENTAJAS Y APLICACIONES DEL PROYECTO ...................................................... 72
SENSORES DEL PROTOTIPO ................................................................................... 73
SENSOR DIGITAL DEL PROTOTIPO ................................................................. 73
DESCRIPCIÓN DEL CÓDIGO ANDROID ................................................................... 74
SOCKET TCP/IP .................................................................................................. 76
SOCKET BLUETOOTH ....................................................................................... 89
ELEMENTOS DE PROCESAMIENTO .............................................................. 104
INTERFAZ GRÁFICA ......................................................................................... 116
RASPBERRY PI ......................................................................................................... 121
IP ESTÁTICA ..................................................................................................... 122
ACCESO SSH .................................................................................................... 123
REDIRECCIÓN DE PUERTOS .......................................................................... 126
DNS DINÁMICA ................................................................................................. 128
INSTALACIÓN DEL SERVIDOR IRC ................................................................ 131
BASE DE DATOS MYSQL ................................................................................. 133
CLIENTE IRC EN JAVA ..................................................................................... 139
INTERFAZ EN LABVIEW ........................................................................................... 149
TOOLKIT LABSQL ADO .................................................................................... 150
CONECTOR ODBC ........................................................................................... 152
PANEL FRONTAL .............................................................................................. 156
DIAGRAMA DE BLOQUES ................................................................................ 163
ANÁLISIS DE LA SITUACIÓN .......................................................................................... 201
ANÁLISIS FODA ........................................................................................................ 201
MODELO CANVAS .................................................................................................... 202
ESTIMACIÓN DE LA DEMANDA .............................................................................. 203
PRESUPUESTO ........................................................................................................ 204
vii
CARTA GANTT .......................................................................................................... 204
ANALISIS DE RESULTADOS ........................................................................................... 205
ALCANCES Y LIMITACIONES DEL PROYECTO ..................................................... 205
PRUEBAS DE FUNCIONAMIENTO .......................................................................... 206
PRUEBA DE FUNCIONAMIENTO ESTÁTICO ................................................. 207
PRUEBA DE FUNCIONAMIENTO MÓVIL ........................................................ 221
PRUEBA DE FUNCIONAMIENTO FINAL ......................................................... 227
CONCLUSIONES .............................................................................................................. 232
GLOSARIO ................................................................................................................................ 234
REFERENCIAS ......................................................................................................................... 237
ANEXOS .................................................................................................................................... 247
viii
ÍNDICE DE FIGURAS
Figura 2.1. Noticia alusiva al robo de combustible en LUN ..................................................... 7
Figura 2.2. Noticia alusiva al robo de combustible en La Segunda Online ........................... 9
Figura 2.3. Noticia alusiva al robo de combustible en el diario La Nación Online ................ 9
Figura 2.4. Modelo de triagulación de satélites geoestacionario ......................................... 12
Figura 2.5. Formato y ejemplo de la trama GPRMC ............................................................... 13
Figura 2.6. Margen de error de una curvatura para el Teorema de Pitágoras ..................... 14
Figura 2.7. Distancia que contempla el radio de curvatura de la Tierra ............................... 15
Figura 2.8. Artículo referente a los beneficios del sistema GPS en el transporte .............. 16
Figura 2.9. Banda de la frecuencia utilizada por la tecnología Bluetooth. .......................... 17
Figura 2.10. Formato de trama Bluetooth en la Capa Banda Base ....................................... 18
Figura 2.11. Transmisión de Paquetes Bluetooth ................................................................. 19
Figura 2.12. Ejemplo del “Salto de Amplio Espectro de frecuencias” ................................. 20
Figura 2.13. Diagrama de la comunicación por TCP/IP .......................................................... 21
Figura 2.14. Capas del Modelo OSI. ......................................................................................... 22
Figura 2.15. Comunicación bidireccional mediante un socket ............................................. 24
Figura 2.16. Segmento TCP....................................................................................................... 25
Figura 2.17. Datagrama IP ......................................................................................................... 26
Figura 2.18. Estructura de la trama Ethernet .......................................................................... 27
Figura 2.19. Encapsulado de un dato ...................................................................................... 28
Figura 2.20. Estructura de datos según el protocolo TCP ..................................................... 29
Figura 2.21. Diagrama del funcionamiento de la red 3G y GPS ............................................ 33
Figura 2.22 Esquema del sistema de chat IRC........................................................................ 34
Figura 2.23. Anatomía de la botnet creada .............................................................................. 36
Figura 2.24 Raspberry Pi ........................................................................................................... 40
Figura 2.25. Logotipo de Raspbian .......................................................................................... 41
Figura 2.26. Acceso a la Raspberry Pi a través de SSH ......................................................... 41
Figura 2.27. Detalle de elementos de entrada y salida de Raspberry Pi. ............................. 42
Figura 2.28. Arduino Mega ........................................................................................................ 44
Figura 2.29. Funciones de la barra de herramientas del Arduino IDE. ................................. 44
Figura 2.30. Ventana Principal del Arduino IDE ...................................................................... 45
Figura 2.31. Inicio del Eclipse IDE ............................................................................................ 47
Figura 2.32. Versión del IDE a descargar ................................................................................ 48
ix
Figura 2.33. Porcentaje del uso actual de las versiones de Android. .................................. 49
Figura 2.34. Panel frontal. ......................................................................................................... 52
Figura 2.35.Controles e indicadores booleanos. .................................................................... 53
Figura 2.36. Controles e indicadores numéricos. ................................................................... 53
Figura 2.37. Controles e indicadores de tipo String ............................................................... 54
Figura 2.38. Control e indicador de tipo Path ......................................................................... 54
Figura 2.39. Control e indicador del tipo Timestamp ............................................................. 54
Figura 2.40. Ejemplo: Suma de dos números. ........................................................................ 55
Figura 2.41. Conectores e ícono de un VI ................................................................................ 56
Figura 2.42. Barra de herramientas del modo Run ................................................................. 56
Figura 2.43. For Loop. ................................................................................................................ 57
Figura 2.44. While Loop. ............................................................................................................ 58
Figura 2.45. Estructuras condicionales ................................................................................... 59
Figura 2.46. Flat Sequence. ....................................................................................................... 59
Figura 2.47. Suma de dos números con nodo de fórmula. .................................................... 60
Figura 2.48. Arrays (numérico, booleano, String). ................................................................. 61
Figura 2.49. Clúster. ................................................................................................................... 61
Figura 2.50. Waveform Chart .................................................................................................... 62
Figura 2.51. Waveform Graph ................................................................................................... 62
Figura 2.52. XY Graph ................................................................................................................ 63
Figura 3.1. Diagrama de bloques del proyecto ....................................................................... 64
Figura 3.2. Forma de la trama de adquisición de datos ......................................................... 65
Figura 3.3. Prueba de funcionamiento con BlueTerm. ........................................................... 65
Figura 3.4. Forma de la trama de envío de los datos ............................................................. 66
Figura 3.5. Cabecera de la aplicación ...................................................................................... 67
Figura 3.6. Trama enviada al servidor IRC y recibida por el cliente en Java ....................... 67
Figura 3.7. Diagrama de flujo del funcionamiento del Timer ................................................. 68
Figura 3.8. Comandos enviados por el programador desde el canal de chat ..................... 69
Figura 3.9. Tablas en la base de datos .................................................................................... 70
Figura 3.10. Elementos almacenados en una tabla de la base de datos. ............................ 70
Figura 3.11. Aplicación Android enviando datos. .................................................................. 71
Figura 3.12. Ventana principal de la interfaz de usuario en LabVIEW .................................. 72
Figura 3.13. Sensor analógico del prototipo ........................................................................... 73
Figura 3.14. Sensor digital de infrarrojos CNY70 ................................................................... 74
Figura 3.15. Diagrama de flujo de la estructura de la aplicación Android ........................... 76
x
Figura 3.16. Diagrama de flujo de conexión al Socket TCP/IP .............................................. 81
Figura 3.17. Diagrama de flujo de la función TCP/IP del timer .............................................. 82
Figura 3.18. Diagrama de flujo del botón 'Enviar' ................................................................... 83
Figura 3.19. Diagrama de flujo del botón 'Trama' ................................................................... 84
Figura 3.20. Comando PING en ejecución ............................................................................... 87
Figura 3.21. Permisos requeridos para la función TCP/IP ..................................................... 89
Figura 3.22. Conexión HC-06 al microcontrolador Arduino MEGA ...................................... 90
Figura 3.23. Diagrama de flujo del funcionamiento del Microcontrolador ........................... 92
Figura 3.24. Diagrama de flujo de la función Bluetooth ......................................................... 96
Figura 3.25. Diseño de la interfaz gráfica .............................................................................. 116
Figura 3.26. Detalle de la interfaz gráfica .............................................................................. 120
Figura 3.27. Raspberry Pi conectada al router...................................................................... 121
Figura 3.28. Router TP-LINK TL-WR740N .............................................................................. 122
Figura 3.29. Parámetros de red de la Raspberry Pi .............................................................. 123
Figura 3.30. Ícono de PuTTy ................................................................................................... 124
Figura 3.31. Ventana principal de PuTTy ............................................................................... 125
Figura 3.32. Terminal SSH ....................................................................................................... 126
Figura 3.33. Página de inicio del router ................................................................................. 126
Figura 3.34. Parámetros para la redirección de puertos ...................................................... 127
Figura 3.35. Puertos abiertos en el router ............................................................................. 127
Figura 3.36. Configuración del DDNS .................................................................................... 130
Figura 3.37. Diagrama de funcionamiento de la DDNS ........................................................ 130
Figura 3.38. Acceso al servidor de chat IRC ......................................................................... 132
Figura 3.39. Ventana principal del canal de chat .................................................................. 132
Figura 3.40. Tablas de la base de datos ................................................................................ 135
Figura 3.41. Estructura de la base de datos .......................................................................... 136
Figura 3.42. Detalle de los elementos de una tabla .............................................................. 136
Figura 3.43. Permisos para el usuario admin........................................................................ 137
Figura 3.44. Permisos para el usuario labview ..................................................................... 138
Figura 3.45. Diagrama de flujo del Cliente IRC ..................................................................... 140
Figura 3.46. Trama reciibida por el Cliente IRC .................................................................... 146
Figura 3.47. Recorrido realizado por el bus .......................................................................... 149
Figura 3.48. VI para la creación de la conexión a la BD ....................................................... 150
Figura 3.49. VI para el inicio de la conexión a la BD. ........................................................... 150
Figura 3.50. VI que ejecuta comandos en la BD ................................................................... 151
xi
Figura 3.51. VI que cierra la conexión a la BD. ..................................................................... 151
Figura 3.52. VI que destruye la conexión a la BD. ................................................................ 151
Figura 3.53. Sitio de descarga del conector ODBC .............................................................. 152
Figura 3.54. Herramientas Administrativas del equipo ........................................................ 153
Figura 3.55. Orígenes de datos ODBC ................................................................................... 153
Figura 3.56. Administrador de conectores ODBC ................................................................ 154
Figura 3.57. Driver a utilizar para el conector ODBC ........................................................... 154
Figura 3.58. Configuración del conector ODBC.................................................................... 155
Figura 3.59. Prueba de conexión satisfactoria. .................................................................... 155
Figura 3.60. Estado de la conexión a la BD. .......................................................................... 156
Figura 3.61. Elección del nombre del bus a analizar. ........................................................... 157
Figura 3.62. Elección de la fecha de medición. .................................................................... 157
Figura 3.63. Medidores de velocidad, combustible, distancia y posición de la tapa........ 158
Figura 3.64. Información obtenida desde la base de datos ................................................. 159
Figura 3.65. Ejemplo: Gráfico de consumo de combustible ............................................... 160
Figura 3.66. Ejemplo del Trazado del recorrido de un bus .................................................. 162
Figura 3.67. Inicialización de variables .................................................................................. 163
Figura 3.68. Inicialización de variables .................................................................................. 164
Figura 3.69. Inicialización de variables .................................................................................. 164
Figura 3.70. Inicialización de variables .................................................................................. 165
Figura 3.71. Inicialización de variables .................................................................................. 166
Figura 3.72. Diagrama de flujos del estado del servidor ..................................................... 167
Figura 3.73. Verificación de la conexión - Caso No Error .................................................... 167
Figura 3.74. Verificación de la conexión - Caso Error .......................................................... 168
Figura 3.75. Diagrama de flujos del combobox de nombres de bus .................................. 169
Figura 3.76. Mostrar nombres de buses en combobox. ...................................................... 170
Figura 3.77. Diagrama de flujo del combobox de Fechas .................................................... 171
Figura 3.78. Mostrar fechas en combobox. ........................................................................... 171
Figura 3.79. Diagrama de flujo de la distancia total ............................................................. 172
Figura 3.80. Mostrar distancia total recorrida - Caso false .................................................. 173
Figura 3.81. Mostrar distancia total recorrida - Caso true ................................................... 173
Figura 3.82. Diagrama de flujos de la redirección al Home ................................................. 174
Figura 3.83. Redirección al home ante la elección de otro nombre de bus. ...................... 174
Figura 3.84. Diagrama de flujo de los combobox ................................................................. 175
Figura 3.85. Habilitación de la extracción de datos. ............................................................ 176
xii
Figura 3.86. Extracción de datos - Caso false ...................................................................... 176
Figura 3.87. Diagrama de flujo de la extracción de datos .................................................... 177
Figura 3.88. Extracción de información - Caso true ............................................................. 178
Figura 3.89. Diagrama de flujo del botón Detener ................................................................ 178
Figura 3.90. Destrucción de la conexión a la base de datos. .............................................. 179
Figura 3.91. Separación de la tabla en columnas ................................................................. 179
Figura 3.92. Conversión de la fecha y la hora y finalización del ciclo. .............................. 180
Figura 3.93. Creación de los arreglos de latitud y longitud................................................. 181
Figura 3.94. Creación del array de posición de la tapa. ....................................................... 182
Figura 3.95. Procesamiento de las coordenadas geográficas. ........................................... 183
Figura 3.96. Condicional para el cálculo de la distancia - Caso true ................................. 184
Figura 3.97. Comprobación del cálculo de la distancia ....................................................... 184
Figura 3.98. Cálculo y almacenamiento de la distancia y la velocidad .............................. 185
Figura 3.99. Cálculo del tiempo entre mediciones ............................................................... 186
Figura 3.100. Diagrama de flujo del procesamiento de datos ............................................. 187
Figura 3.101. Acción del botón Graficar. ............................................................................... 188
Figura 3.102. Diagrama de flujo del botón 'Graficar' ............................................................ 189
Figura 3.103. Acción del botón Home .................................................................................... 189
Figura 3.104. Diagrama de flujo del botón 'Home' ................................................................ 190
Figura 3.105. Obtención y visualización de los últimos valores medidos. ........................ 190
Figura 3.106. Diagrama de flujo del botón 'Trayectoria' ...................................................... 191
Figura 3.107. Acción del botón Trayectoria - Frame 1 ......................................................... 192
Figura 3.108. Acción del botón Trayectoria - Frame 2 ......................................................... 193
Figura 3.109. Diagrama de flujo del código de la trayectoria .............................................. 195
Figura 3.110. Diagrama de flujo del botón 'ODBC' ............................................................... 199
Figura 3.111. Acción del botón ODBC ................................................................................... 199
Figura 3.112. Diagrama de flujo del botón 'Mostrar datos' .................................................. 200
Figura 3.113. Acción del botón Mostrar datos ...................................................................... 200
Figura 4.1. Matriz FODA de Telemetrics ................................................................................ 201
Figura 4.2. Modelo Canvas de Telemetrics ........................................................................... 202
Figura 4.3. Número de buses por empresa. .......................................................................... 203
Figura 4.4. Participación por empresa en la red Transantiago ........................................... 203
Figura 4.5. Carta Gantt del proyecto ...................................................................................... 204
Figura 4.6. Detalle de la tabla de la Carta Gantt .................................................................... 204
Figura 5.1. Montaje del prototipo ........................................................................................... 206
xiii
Figura 5.2. Energización del prototipo ................................................................................... 207
Figura 5.3. Icono de la aplicación ........................................................................................... 207
Figura 5.4. Indicación del establecimiento de la conexión Bluetooth ................................ 208
Figura 5.5. Valor mínimo del sensor analógico .................................................................... 208
Figura 5.6. Valor máximo del sensor analógico ................................................................... 209
Figura 5.7. Valor '0' del sensor digital .................................................................................... 209
Figura 5.8. Valor '1' del sensor digital .................................................................................... 210
Figura 5.9. Acceso al servidor de chat .................................................................................. 210
Figura 5.10. Ventana principal del canal de chat .................................................................. 211
Figura 5.11. Comparación de la trama enviada y de las coordenadas GPS recibidas ..... 211
Figura 5.12. Obtención de la dirección del vehículo ............................................................ 212
Figura 5.13. Ejecución del comando dir ................................................................................ 212
Figura 5.14. Comprobación de los comandos nivel y tapa ................................................. 213
Figura 5.15. Comprobación del comando tapa cuando el valor es igual a '0' ................... 213
Figura 5.16. Comprobación del comando fecha ................................................................... 213
Figura 5.17. Cambio de nombre del bus a través del comando bus .................................. 214
Figura 5.18. Acceso a la Raspberry Pi via SSH .................................................................... 214
Figura 5.19. Ejecución del programa Cliente IRC ................................................................. 215
Figura 5.20. Ingreso del cliente IRC al canal de chat ........................................................... 215
Figura 5.21. Tabla del bus dentro de la base de datos ........................................................ 216
Figura 5.22. Tramas enviadas por el Cliente IRC hacia la base de datos .......................... 216
Figura 5.23. Visualización del valor máximo de los sensores en LabVIEW ...................... 217
Figura 5.24. Visualización del valor mínimo de los sensores en LabVIEW ....................... 217
Figura 5.25. Visualización del valor medio aproximado del sensor analógico ................. 218
Figura 5.26. Comparación de las tramas enviadas .............................................................. 219
Figura 5.27. Gráfico del nivel de combustible....................................................................... 220
Figura 5.28. Gráfico de la posición de la tapa ....................................................................... 220
Figura 5.29. Extracto de los datos contenidos en la base de datos ................................... 221
Figura 5.30. Tabla en LabVIEW con el extracto de la información de la base de datos ... 222
Figura 5.31. Gráfico de velocidad ........................................................................................... 223
Figura 5.32. Gráfico de velocidad aumentado ...................................................................... 223
Figura 5.33. Trayectoria trazada del vehículo ....................................................................... 224
Figura 5.34. Medición de la velocidad instantánea y distancia total .................................. 225
Figura 5.35. Direcciones cercanas a los puntos de circulación del vehículo ................... 225
Figura 5.36. Tabla con las velocidades alcanzadas por el automóvil ................................ 226
xiv
Figura 5.37. Prueba de funcionamiento al interior de un bus de Transantiago ................ 227
Figura 5.38. Tabla con las mediciones realizadas al interior del bus ................................. 228
Figura 5.39. Recorrido realizado para la prueba final .......................................................... 229
Figura 5.40. Gráfico de velocidad ........................................................................................... 230
Figura 5.41. Gráfico de consumo de combustible ................................................................ 230
Figura 5.42. Gráfico de posición de la tapa ........................................................................... 231
ÍNDICE DE TABLAS
Tabla 2.1. Variables de la trama GPRMC ................................................................................. 13
Tabla 2.2. Frecuencia de operación en diferentes países. .................................................... 18
Tabla 2.5. Comandos ampliamente utilizados en IRC ............................................................ 38
Tabla 2.6. Datos técnicos de hardware de la Raspberry Pi ................................................... 42
Tabla 3.1. Listado de funciones de TCP/IP .............................................................................. 78
Tabla 3.2.Variables TCP/IP ........................................................................................................ 78
Tabla 3.3. Listado de funciones del Socket Bluetooth ........................................................... 91
Tabla 3.4. Variables del microcontrolador ............................................................................... 93
Tabla 3.6. Variables Bluetooth .................................................................................................. 97
Tabla 3.6. Comandos para la obtención de datos ................................................................ 105
Tabla 3.7. Variables del metodo dir () .................................................................................... 107
Tabla 3.8. Elementos del primer layout ................................................................................. 118
Tabla 3.9. Elementos del segundo layout .............................................................................. 119
Tabla 3.10. Elementos del tercer layout ................................................................................. 120
Tabla 3.11. Parámetros de conexión SSH ............................................................................. 125
Tabla 3.12. Puertos abiertos en el router ............................................................................... 128
Tabla 3.13. Instrucciones SQL utilizadas para el proyecto ................................................. 139
Tabla 3.14. Detalle del funcionamiento del menú de navegación. ...................................... 159
Tabla 3.15. Cursores disponibles para gráficos. .................................................................. 161
Tabla 3.16. Herramientas de visualización de gráficos. ....................................................... 161
Tabla 3.17. Comandos de la Google Maps API ..................................................................... 195
Tabla 4.1. Tabla de presupuesto ............................................................................................ 204
xv
ÍNDICE DE ECUACIONES
Ecuación 2.1. Teorema de Pitágoras para el cálculo de distancias ..................................... 14
Ecuación 2.2. Fórmula del Semiverseno ................................................................................. 15
Ecuación 3.1. Conversión de grados a radianes .................................................................. 182
Ecuación 3.2. Ecuación de velocidad. ................................................................................... 185
Ecuación 3.3. Fórmula para el cálculo del tiempo entre muestras. .................................... 186
xvi
RESUMEN
El problema del robo de combustible (denominado coloquialmente como “Robo
Hormiga”) a buses destinados para fines de transporte público, específicamente
los pertenecientes a la red Transantiago; se ha ido transformando en una de las
grandes dificultades que las entidades concesionarias de estos vehículos han
tenido que enfrentar con el paso de los años. Estas empresas han tenido que
asumir muchas veces pérdidas millonarias que podrían evitarse si contaran con
un sistema que les permitiese conocer el estado del nivel de combustible de sus
buses en tiempo real. La solución propuesta consiste en implementar un sistema
de telemetría que monitoree en tiempo real las variables necesarias para elaborar
un buen plan de optimización de recursos, siendo éstas principalmente, el nivel
de combustible, la ubicación del vehículo, la posición de la tapa del tanque, la
fecha y la hora de cada medición.
En este contexto, Telemetrics juega un papel elemental a la hora de rentabilizar
recursos, incorporando todas las ventajas que presentan las nuevas tecnologías,
específicamente las basadas en la plataforma Android para teléfonos inteligentes
o smartphones, los cuales de por sí incorporan sistema de navegación GPS,
conexión inalámbrica Bluetooth, conexión a Internet mediante 3G o Wi-Fi, entre
otras funcionalidades ampliamente favorables para el desarrollo de este tipo de
soluciones.
En este proyecto, el teléfono actúa a la par con un microcontrolador Arduino Mega
y su respectivo módulo Bluetooth HC-06 para adquirir datos desde los sensores
instalados en el bus, también actúa una microcomputadora “Raspberry Pi” que
toma los datos enviados por el teléfono celular y los guarda en una base de datos
MySQL remota, la cual, finalmente, es consultada periódicamente por un
programa desarrollado en LabVIEW , el cual otorga al usuario la facilidad de
visualizar en pantalla el nivel de combustible actual, la posición actual de la tapa
xvii
y la velocidad actual; así como desplegar una tabla con el histórico de los datos,
visualizar la evolución de las variables consultadas a través de gráficos y conocer
el recorrido realizado por el bus en un mapa de la API de Google Maps.
Telemetrics es un sistema completamente innovador que proporciona una
herramienta sumamente útil a la hora de combatir la problemática del robo de
petróleo, además de garantizar un seguimiento eficiente para la flota de buses.
Conceptos Clave: Telemetrics, “Robo Hormiga”, Transantiago,
Smartphone, Android, GPS, 3G, Bluetooth, Arduino Mega, TCP/IP,
Raspberry PI, LabVIEW, Interfaz Gráfica, MySQL.
xviii
ABSTRACT
The problem of fuel theft to buses intended for public transport, specifically the
buses belonging to the companies to the Transantiago network; it has gone
transforming in one of the biggest difficulties that this companies have had that
confront with the passage of the years. These companies have had to assume
many times with million in losses, that could have been avoided if they could have
had a monitoring system that it allow to know the fuel level state in real time. The
proposed solution consists in implement a telemetry system for monitoring in real
time the required variables for make a good resources optimization plan. This
variables are, mainly, the fuel level, the bus position, the tank cap position, the
date and time of each measure.
In this context, this new tool that it's called Telemetrics, play a transcendental role
at the moment of optimize resources, incorporating all the advantages that
presents the new technologies based, specifically, in the operative system
Android for Smartphones, which already has with Navigation System GPS,
Bluetooth wireless connection, Internet Connection via 3G or WiFi, between
others functionalities widely favorable for the development of solutions. In this
project, the cell phone acts abreast of an Arduino Mega Microcontroller and his
respective Bluetooth HC-06 Module for the work of data acquisition from the
installed sensors in the bus. A Raspberry Pi microcomputer has the work of take
the data delivered for the cellphone and save this information in a remote MySQL
database, which is queried periodically from an GUI developed in LabVIEW,
giving to the user the possibilities of visualize in the screen the current fuel level,
the current tank cap position, the current velocity and the total distance traveled.
Also is possible to deploy a table that contains the data historical, visualize the
evolution of this three variables too and monitoring the route followed for the bus
in a Google Maps map.
xix
Telemetrics is a completely innovative system that provides a very useful tool at
the moment of confront the problem of the fuel theft and do an efficient and safe
monitoring for the fleet of buses.
Keywords: Telemetrics, Fuel Theft, Transantiago, Smartphone, Android,
GPS, 3G, Bluetooth, Arduino Mega, TCP/IP, Raspberry PI, LabVIEW, GUI,
MySQL.
1
ANTECEDENTES GENERALES
INTRODUCCION
El sistema de transporte público de Santiago de Chile, Transantiago, ha sido
susceptible con el paso de los años a diversos problemas de carácter social y
económico, ejemplificando en este último caso el tema de la evasión y el robo de
combustible.
En esta última problemática es donde nos detendremos y plantearemos una
solución que sea capaz de solventar las millonarias pérdidas producidas a raíz
de la sustracción de petróleo por parte de los mismos choferes encargados de
las máquinas y que, a su vez, repercute fuertemente en las alzas al costo del
pasaje cobrado a los usuarios. Es por esta razón, que el proyecto Telemetrics,
nace bajo el alero de encontrar una solución óptima para este inconveniente a
través del beneficio que prestan las nuevas tecnologías, funcionando como útiles
herramientas capaces de otorgar un buen desempeño y un efectivo manejo de la
información para beneficio de los concesionarios del servicio de buses, así como
de los mismos usuarios de forma indirecta.
Antes de conocer el funcionamiento básico del proyecto, hay que destacar que
se trabajó siguiendo la arquitectura que toman los virus informáticos con el
modelo de backdoor o puerta trasera, es decir, cuando se tiene acceso mediante
un proceso en segundo plano a un sistema operativo y a toda la información que
se le puede extraer. Parelalemente, los bots serían en este caso cada celular
implantado dentro de los buses, en donde se ha utilizado un principio original
para fines maliciosos, en algo que realiza una labor sumamente útil.
La solución está basada en introducir a la máquina un microcontrolador Arduino
MEGA 2560 con su respectivo módulo de comunicación Bluetooth para realizar
2
la tarea de adquisición de datos desde los sensores. Dicha información será
enviada a través de una primera trama a un teléfono móvil también instalado
dentro del vehículo, con el objetivo de que con la aplicación Android desarrollada
para este proyecto sea posible incorporar estas mediciones a una segunda trama
de datos que está conformada por la fecha y hora de la medición, el nombre
asignado a la máquina, los valores del sensor analógico para nivel y digital para
la posición de la tapa, la latitud y la longitud en grados determinada por el GPS
del celular.
La aplicación móvil propiamente tal, está enlazada con un servidor de chat IRC
montado en una Raspberry Pi que almacena las cadenas de texto enviadas por
el Smartphone y en donde se crea una especia de sistema operativo capaz de
interactuar con el programador mediante una serie de comandos previamente
definidos, por ejemplo, si se escribe el comando “gps” en un mensaje privado, el
cliente IRC del celular enviará la coordenada geográfica en la que se encuentra
actualmente el bus.
De la misma manera, en la Raspberry Pi se encuentra montado un cliente IRC
programado en Java que recoge las tramas de datos enviadas desde cada bus y
las almacena tablas ordenadas según el nombre asignado a cada bus en una
base de datos MySQL. Finalmente, el usuario final puede visualizar, a través de
una interfaz gráfica desarrollada en el software LabVIEW de National
Instruments, los niveles actuales de combustible y la posición actual de la tapa,
así como el histórico de los datos enviados desde el Smartphone, el que
contempla las coordenadas geográficas, las variables aludidas anteriormente y
la distancia y velocidad instantáneas calculadas a partir de la latitud y longitud
asociadas a cada medición y el tiempo transcurrido entre éstas. También con
esta interfaz es posible obtener la trayectoria realizada por la máquina
desplegada como una línea que marca la ruta seguida en un mapa perteneciente
a la API de Google Maps.
3
Como última herramienta, es posible obtener las gráficas de velocidad, posición
de tapa y consumo de combustible para cada bus, otorgando una idea de la
evolución de las variables medidas en el tiempo. Cabe destacar que para el caso
específico de esta tesis, el sensor analógico y el sensor digital que representan
al sensor de nivel y al sensor de posición de la tapa respectivamente, son
simulados a escala pequeña por una resistencia variable (potenciómetro) y un
sensor infrarrojo CNY 70, los cuales presentan el mismo desempeño que si se
tratase de los sensores reales, pudiendo ser reemplazados en una próxima
innovación de este proyecto por los transductores propios de estos vehículos, en
donde se destaca la posible utilización de un sensor ultrasónico de nivel para
minimizar el error en las mediciones.
En cuanto a la orientación de esta tesis, ésta se encuentra enfocada en el
desarrollo del proyecto como tal, pasando por fases investigativas de la
problemática existente, desarrollo de protocolos de comunicación y
procesamiento de datos en distintas plataformas tecnológicas de trabajo.
Si bien, Telemetrics está enfocado principalmente a la prevención del hurto de
gasolina desde una flota de buses, específicamente de la red Transantiago,
puede abrirse también a un amplio espectro de útiles usos, desde la
monitorización de máquinas de vending hasta la gestión del transporte privado.
4
OBJETIVOS
OBJETIVO GENERAL
Desarrollar un sistema de telemetría que permita conocer a distancia las
variables requeridas para elaborar un plan de optimización de recursos,
enfocados principalmente a la supervisión del nivel de combustible y
geoposicionamiento de los buses pertenecientes a la red de transporte
urbano Transantiago mediante una interfaz gráfica de usuario.
OBJETIVOS ESPECÍFICOS
Implementar un sistema de adquisición de datos basado en el
microcontrolador Arduino Mega 2560 que envíe las mediciones realizadas
desde un sensor digital y un sensor analógico hacia un Smartphone que
ejecute una aplicación Android desarrollada para este proyecto.
Desarrollar una aplicación Android que reciba una trama de datos con la
información de los sensores y la encapsule en una segunda trama que
incorpore la fecha y hora de cada medición, enviándola a un servidor de
chat IRC que actúe como medio de traspaso de la información siguiendo
el principio de funcionamiento de los virus informáticos, conocido como
backdoor.
Almacenar la información contenida en la trama de datos proveniente
desde la aplicación Android y el servidor IRC en una base de datos MySQL
montada en una Raspsberry Pi a través de un programa capturador de
datos desarrollado en Java.
5
Desarrollar una interfaz gráfica de usuario en LabVIEW que permita al
usuario visualizar amigablemente la información necesaria que entrega el
sistema para elaborar un plan de optimización de recursos.
ORGANIZACIÓN Y PRESENTACIÓN DEL TRABAJO
La estructura del desarrollo del presente trabajo se encuentra distribuida de la
siguiente manera:
En el Capítulo 1 se introduce al contexto del problema, identificando los objetivos
generales y específicos que se buscarán obtener tras el desarrollo del proyecto.
En el Capítulo 2 se aborda la problemática existente con respecto al robo de
combustible, situando al lector en el entorno de esta situación y conociendo el
impacto que tendría el proyecto para solucionar este inconveniente, así como la
descripción de las herramientas empleadas en la solución.
En el Capítulo 3 se explica el desarrollo del proyecto en sí, describiendo el
modelamiento de la solución y el funcionamiento de los elementos utilizados.
En el Capítulo 4 se analiza la situación del proyecto dentro del contexto del
mercado, indicando sus potencialidades, debilidades y sus futuras posibles
relaciones con los proveedores y clientes.
En el Capítulo 5, se analizarán los resultados de las tres pruebas de
funcionamiento realizadas, siempre considerando los alcances y limitaciones de
la fase de prototipo.
Finalmente, en el Capítulo 6 se presentan las conclusiones de los resultados
obtenidos, así como la evaluación de los problemas y soluciones ocurridos
durante el desarrollo del proyecto, dejando abierta la posibilidad de incorporar
nuevas innovaciones a futuro.
6
MARCO TEÓRICO
ESTADO DEL ARTE
En la actualidad, los sistemas de monitoreo para flotas de vehículos son una
herramienta imprescindible para el control logístico en variados segmentos
industriales, tanto privados como estatales. Sin embargo, los sistemas existentes
muchas veces solamente contemplan el uso de dispositivos GPS para conocer
la posición exacta del vehículo en un determinado momento, sin considerar otras
variables igualmente importantes, como por ejemplo el nivel de combustible,
quedando esta tarea relegada a un segundo plano. Es en estas circunstancias
donde los delincuentes aprovechan de sustraer el petróleo desde el tanque del
vehículo, el cual desprovisto de sistemas de seguridad eficientes, cede ante la
habilidad de los antisociales para efectuar el hurto. Mediante la prensa es posible
percatarse de esta realidad, así como de las enormes pérdidas generadas a
Transantiago, las que van desde el orden de los 80 millones de pesos hasta los
1000 millones de pesos aproximadamente, donde la Policía de Investigaciones
(PDI) y la Brigada de Investigación Criminal de la Policía Civil han sorprendido a
choferes de buses del transporte público extrayendo el combustible desde las
máquinas de forma indiscriminada para luego revenderlo en el mercado informal,
como se puede apreciar en los siguientes periódicos que han dado cobertura a
este tipo de hechos (La Segunda Online, 2013), (La Nación Online, 2008).
7
Figura 2.1. Noticia alusiva al robo de combustible en LUN
“Eran las once de la noche del jueves y un bus oruga de la línea 406, del recorrido Catagallo-
Pudahuel, circulaba por Avenida Las Condes hacia el poniente. Iba con las luces intermitentes
prendidas y a muy baja velocidad, no se veían pasajeros y el letrero “en tránsito” estaba prendido.
Nada parecía extraño.
Pero la cosa no era tan inocente, como constató personal de la PDI, que justo andaba patrullando
por ahí. De pronto los policías vieron subir a dos sujetos cargando cuatro tambores de plástico
de sesenta litros. Uno de ellos se bajó al tiro y se subió a una camioneta negra que comenzó a
andar lentamente al lado de la micro, que no circulaba a más de 15 kilómetros por hora.
8
Varias cuadras más abajo, la micro detuvo su marcha y entre el chofer, el único pasajero y el
sujeto que manejaba la camioneta, bajaron los bidones, esta vez visiblemente pesados.
¿Qué pasó entre medio?
Eso lo explicó la policía una vez que detuvo a los tres tipos y requisó todo el material que andaban
trayendo, camioneta incluida. Básicamente robaron petróleo, algo que en Alsacia, la empresa
propietaria de la máquina, dicen que viene ocurriendo desde por lo menos el 2011.
Según la policía, lo hacían con el bus en movimiento para evitar que el GPS diera cuenta de una
detención anómala. Y según Patricio Ibarra, jefe de seguridad de la empresa, tenían un sistema
muy bien armado. Una vez que se subían, los sujetos iban derechito al asiento del medio de la
última fila, que habían intervenido convirtiéndolo en una especie de tapa atornillada que daba
justo a la manguera de distribución del combustible. Intervenían esa manguera y con una
pequeña bomba manual extraían el petróleo.
¿Peligroso? El profesor de ingeniería mecánica del DUOC Carlos González, dice que
potencialmente sí. “Si hubiera una mezcla de los gases de la máquina con el petróleo, podría
ocurrir rápidamente un incendio, que quemaría la micro muy rápido, porque son de material
ligero”, explica.
Patricio Ibarra contó que esta vez alcanzaron a sacar 200 litros, aunque el estanque tiene
capacidad para 360. Por cierto, estos buses rinden 2,1 kilómetros por litro y tienen capacidad
para un máximo de 160 pasajeros.
Desde el 2011, agregó Ibarra, Alsacia ha perdido por lo menos ochenta millones de pesos por
este tipo de robo (cada litro cuesta más o menos 615 pesos). Por eso, los tres sujetos fueron
detenidos y formalizados por hurto. Eso sí, quedaron libres y con firma quincenal” (Guzmán,
2013).
9
Figura 2.2. Noticia alusiva al robo de combustible en La Segunda Online
Figura 2.3. Noticia alusiva al robo de combustible en el diario La Nación Online
10
DESCRIPCIÓN DE LA PROBLEMÁTICA
El problema que radica principalmente para las entidades concesionarias
de Transantiago, quienes trabajan en conjunto con el Gobierno de Chile
para la concesión del combustible; es la inexistencia de un sistema de
telemetría en el cual basar de forma fidedigna sus planes de eficiencia y
ahorro de petróleo, así como reconocer a la brevedad casos de “Robo
Hormiga. Si bien, estas empresas trabajan actualmente con sistemas de
geoposicionamiento que permiten detectar los tiempos en que el bus
permanece en movimiento, éste no resulta óptimo para combatir la
problemática anteriormente descrita ya que muchas veces, al momento en
que el ilícito queda al descubierto ya se han generado pérdidas millonarias
para estas empresas (Mondaca, Ayala, & Vargas, 2015).
IMPACTO DEL PROYECTO
Al ver este escenario tan adverso, es donde el papel de este proyecto se
torna elemental, al permitir a las empresas concesionarias de este tipo de
buses a que puedan conocer con antelación el momento en que se
encuentran ante una situación de esta índole, incorporando elementos
propios de las nuevas tecnologías como las comunicaciones Bluetooth y
TCP/IP (Internet) mediante Teléfonos Móviles Inteligentes, Arduino Mega,
Raspberry Pi y LabVIEW, en conjunto con herramientas ya existentes pero
que se les atribuirá una nueva misión, como es el caso de los servidores
IRC y el sistema de navegación GPS, proyectando, de esta manera, un
decremento de las actividades ilícitas en cuanto a sustracción de Diésel se
refiere, descendiendo significativamente las millonarias pérdidas para
Transantiago.
11
HERRAMIENTAS UTILIZADAS
GPS
HISTORIA
El sistema de posicionamiento global GPS (en inglés: Global Positioning
System) nació originalmente como un proyecto de navegación
desarrollado por el Departamento de Defensa de los Estados Unidos con
el objetivo de establecer un sistema preciso de posicionamiento geográfico
para submarinos nucleares con los mínimos de errores posibles y siendo
capaz de operar en tiempo real, ampliando, posteriormente, los horizontes
del proyecto para su utilización de forma global.
FUNCIONAMIENTO
Básicamente, consiste en una red de aproximadamente 24 satélites
operativos y tres satélites de respaldo, que orbitan el planeta a una altura
de 20.200 km. de manera geoestacionaria, de forma que sus trayectorias
logren abarcar la totalidad de la superficie del planeta. Para ubicar un
punto geográfico, el dispositivo receptor (en este caso el teléfono móvil)
establece una conexión con al menos tres satélites, de quienes obtiene
una trama de datos entre los cuales es posible identificar la posición y el
tiempo de reloj de cada unidad espacial, que es medido de forma muy
precisa gracias al reloj atómico incorporado al satélite; donde la variable
tiempo de reloj es sincronizada por el aparato de GPS, para poder calcular
así, la distancia entre dicho dispositivo y cada uno de los satélites mediante
el tiempo que demoran dichas señales en ser entregadas
12
satisfactoriamente al elemento citado. De este modo, cada unidad espacial
calcula la distancia existente entre esta y el aparato de GPS mediante el
principio de triangulación, donde una vez conocidas estas distancias, es
posible obtener la posición relativa del terminal GPS con respecto a los
tres satélites mencionados, pudiendo obtener a partir de este resultado,
las coordenadas geográficas reales desde punto de medición (Menéndez-
Barzanallana, 2015), (MiTAC Intl., 2010), (Giménez & Elena, 2009-2010),
(Gutovnik, 1999).
Figura 2.4. Modelo de triagulación de satélites geoestacionarios. Barzanallana, R (2014). Telecomunicaciones [artículo de blog].
Recuperado de: http://www.um.es
EL PROTOCOLO DEL SISTEMA GPS
Los dispositivos GPS realizan la recepción y envío de información
siguiendo el formato GPRMC creado por NMEA (National Marine
Electronics Association), en donde existe una trama que contiene distintas
variables separadas por comas calculadas por el satélite al momento de
enviar los datos, así como la ubicación del localizador GPS, siguiendo la
estructura de la Figura 2.5. (Sharma, Electron. & Commun. Eng., Singh,
13
Sharma, & Singh, 2015). Las variables almacenadas en la trama GPRMC
se encuentran detalladas en la Tabla 2.1.
Figura 2.5. Formato y ejemplo de la trama GPRMC
Variable Ejemplo Función
$GPRMC $GPRMC Formato que rige a la trama
time (hhmmss) 040113 Hora en que se obtuvo la
posición del GPS en UTC.
(A o V) A La letra ‘A’ indica que se trata de
una trama válida.
La letra ‘V’ indica que la trama
es inválida.
ddmm.mmm 3653.10 Latitud en grados, minutos y
milésimas de minuto.
(N o S) S Hemisferio (Norte o Sur)
ddmm.mmm 17437.47 Longitud en grados, minutos y
milésimas de minuto.
(E o W) E Hemisferio (Este u Oeste)
kkk.k 000.6 Velocidad en nudos
ddd.d 074.4 Rumbo en grados (0° a 360°)
ddmmyy 190903 Fecha en que se obtuvo la
posición del GPS en UTC.
,, ,, Dato nulo
*CS *03 Checksum
Tabla 2.1. Variables de la trama GPRMC
14
CÁLCULO DE DISTANCIAS
Para calcular distancias a partir de la latitud y longitud de dos coordenadas
geográficas obtenidas desde el sistema de navegación GPS, se utiliza la
Fórmula del Haversine o Semiverseno. Este método funciona muy bien
para el cálculo de cualquier distancia, ya que considera el radio de
curvatura de la Tierra que, aunque no siendo una esfera perfecta y no
resulte ser un valor ideal, se acerca bastante a un resultado lo
suficientemente bueno para conocer cuánto se recorrió desde un lugar a
otro, haciendo mucho más preciso el cálculo de distancias que si se
utilizase el Teorema de Pitágoras, por ejemplo, dado que este último
método solamente resulta óptimo para distancias sobre superficies planas.
𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎 = √((𝑥2−𝑥1)2 + (𝑦2−𝑦1)2)
Ecuación 2.1. Teorema de Pitágoras para el cálculo de distancias
Figura 2.6. Margen de error de una curvatura para el Teorema de Pitágoras
Como se puede apreciar en la Figura 2.6, cuando se requiere calcular una
distancia con el Teorema de Pitágoras que no contempla la curvatura de
la Tierra, se hace presente un margen de error que imposibilita la exactitud
del resultado. Esto no ocurre para la fórmula del Semiverseno, en donde
15
se necesitan las latitudes y longitudes de los dos puntos geográficos en
radianes y el radio de curvatura de la Tierra (R) que es igual a 6371 km,
para llevar a cabo la resolución de esta fórmula .
𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎 = 𝐴𝑟𝑐𝑐𝑜𝑠(sin(𝑙𝑎𝑡𝑛−1) ∗ sin(𝑙𝑎𝑡𝑛) + cos(𝑙𝑎𝑡𝑛−1) ∗ cos(𝑙𝑎𝑡𝑛) ∗
cos(𝑙𝑜𝑛𝑛 − 𝑙𝑜𝑛𝑛−1)) ∗ 𝑅
Ecuación 2.2. Fórmula del Semiverseno
Figura 2.7. Distancia que contempla el radio de curvatura de la Tierra Aguilar, J. Geotag-Geopoint your entries using Azure Mobile Services.
Recuperado de: http://giventocode.com/
EL SISTEMA GPS EN EL TRANSPORTE
Según estudios realizados, todo indica que la utilización de sistemas de
GPS en el transporte, durante los años 2007 al 2012, incrementó
exponencialmente, aumentando en un 85% la calidad en servicios de
despacho y en un 75% la reducción de diversos gastos asociados a la
distribución (Hernández Zapata, Álvarez Uribe, & Arango Alzate, 2012).
En el transporte público esta realidad es similar, considerando esta
tecnología un gran apoyo para la gestión de flota, ya que incorpora
16
información que otorga una gestión óptima de los servicios en vía, para
así poder realizar una toma de decisiones acertada.
"La gestión de una flota de 6 mil buses en la calle, con todo lo que
significa circular por la ciudad de Santiago, es impensable sin esta
tecnología. Por esta razón, seguiremos avanzado en nuevas
posibilidades de su utilización, incorporando por ejemplo algunas
aplicaciones que corren sobre GPS con funciones de seguridad del bus,
internet y mensajería” (Ediciones Especiales El Mercurio, 2013).
Figura 2.8. Artículo referente a los beneficios del sistema GPS en el transporte
17
BLUETOOTH
CONCEPTO Y FUNCIONAMIENTO
“Bluetooth es un estándar desarrollado por un grupo de fabricantes
electrónicos que permite que cualquier tipo de equipo electrónico – desde
computadoras y teléfonos celulares, hasta teclados y audífonos –
establezca sus propias conexiones, sin cables u otra acción directa de un
usuario”. (Franklin & Layton, 2000)
El funcionamiento de esta tecnología se basa en un dispositivo de radio,
capaz de modular y transmitir la señal, y de un controlador digital. El
dispositivo Bluetooth opera normalmente en la banda de radiofrecuencias
ISM (Industrial, Scientific, Medical) de los 2,45 GHz. Si bien, el rango de
las frecuencias descritas anteriormente, en la mayoría de los países del
mundo va desde los 2400 MHz a los 2483,5 MHz, en algunos estados
existen limitaciones nacionales respecto al rango de frecuencias anterior.
Para esto, se han diseñado algoritmos especiales y dispositivos que
implementan bandas reducidas de frecuencia en estos países, aunque
sólo pueden ser utilizados a nivel país dada la incompatibilidad de banda
de frecuencia existente. (Camargo Olivares, 2009), (Sevilla & Sánchez,
2005/2006)
Figura 2.9. Banda de la frecuencia utilizada por la tecnología Bluetooth. La Róvere, C., Plaza J., Silva W., Urbano A., Utrera V. (2003). Bluetooth.
Recuperado de: http://ldc.usb.ve/
18
Lugar Rango de frecuencias (GHz) Canales de RF
USA, Europa y la
mayoría de los países
2,4 – 2,4835 f = 2402 + k MHz
k=0,…,78
Francia 2,4465 – 2,4835 f = 2454 + k MHz
k=0,…,22
Tabla 2.2. Frecuencia de operación en diferentes países.
Archundia, F. (2003). Wireless Personal Area Network (WPAN) & Home Networking
Recuperado de: http://catarina.udlap.mx/
Bluetooth soporta solamente 780 Kbps en materia de transferencia de
datos, por lo que puede tomar dos configuraciones posibles:
1) Utilizar 721 Kbps en transferencia de datos unidireccional y 57,6
Kbps en la dirección de retorno.
2) Utilizar 432,6 Kbps en transferencia de datos simétrica, de forma
bidireccional.
La información es enviada a través de paquetes, donde cada
encapsulado de datos se transmite en una frecuencia diferente dentro
de una ranura de tiempo, como se explicará en el siguiente párrafo, para
así evitar interferencias y caídas de la señal, siendo condicionados a la
utilización de un canal ranurado en fracciones de tiempo, en donde cada
ranura mencionada anteriormente tiene una duración de 6,25 µs.
(Archundia Papacetzi, 2003)
Figura 2.10. Formato de trama Bluetooth en la Capa Banda Base. La Róvere, C., Plaza J., Silva W., Urbano A., Utrera V. (2003). Bluetooth.
Recuperado de: http://ldc.usb.ve/
19
Figura 2.11. Transmisión de Paquetes Bluetooth La Róvere, C., Plaza J., Silva W., Urbano A., Utrera V. (2003). Bluetooth.
Recuperado de: http://ldc.usb.ve/
CONTROL DE INTERFERENCIAS
Para impedir que interferencias con otros dispositivos electrónicos
entren a un protocolo de comunicación, Bluetooth envía señales débiles
que van desde 1 mW (mili Watt) a 3 W (Watt) de potencia, que, aunque
esta situación garantiza seguridad ante el cruce de señales, el bajo
poder de la señal enviada también limita el alcance del dispositivo a unos
10 metros como máximo.
De igual manera, esta tecnología posee un algoritmo especialmente
diseñado para evitar la intercepción de frecuencias entre distintos
dispositivos Bluetooth con una técnica llamada “Salto Amplio de
Espectro de Frecuencias” (en inglés: Spread-Spectrum Frecuency
Hopping), la cual utiliza 79 frecuencias individuales elegidas de manera
aleatoria dentro de un rango específico, alternando entre ellas cada
cierto tiempo. Los transmisores Bluetooth cambian de frecuencia 1600
veces por segundo, resultando improbable que dos dispositivos
20
irrumpan entre sí a la misma frecuencia (La Róvere, Plaza, Silva,
Urbano, & Utrera, 2003).
Figura 2.12. Ejemplo del “Salto de Amplio Espectro de frecuencias” La Róvere, C., Plaza J., Silva W., Urbano A., Utrera V. (2003). Bluetooth.
Recuperado de: http://ldc.usb.ve/
DIRECCIÓN FÍSICA
La dirección física o dirección MAC (del inglés: Media Access Control,
Control de Acceso al Medio) corresponde a un código único de 48 bits
representado por seis grupos de dígitos hexadecimales separados por dos
puntos, que tiene como objetivo identificar a un elemento de hardware de
red a nivel mundial. La primera mitad de la dirección MAC representa al
fabricante del dispositivo, en cambio, los últimos 24 bits son un número
único asignado por el mismo fabricante. El adaptador Bluetooth utiliza esta
dirección para identificarse, lo que permite que cada dispositivo que
trabaje bajo el alero de la tecnología Bluetooth sea único, para que en el
caso de que se requiera establecer una comunicación con únicamente un
dispositivo en particular, sea posible discriminar a través de la MAC para
emparejarse exclusivamente con este equipo (The GNOME Project,
2014), (Internet Manía, s.f.).
21
TCP/IP
CONCEPTO
TCP/IP es el protocolo de comunicación más usado en Internet
actualmente. Su nombre deriva de TCP (Protocolo de Control de
Transmisión) y de IP (Protocolo de Internet) y permite establecer una
conexión e intercambiar datos entre dos equipos que cuenten con una
Tarjeta de Red, ya sea de forma cableada o inalámbrica, de área extensa
o local; garantizando que durante la comunicación no se pierda ningún
paquete de información y estos sean recibidos en el mismo orden en el
que fueron enviados (Riffo Gutiérrez, 2009), (Hernando, 2002), (Baltazar
Gálvez & Campuzano Ramírez, 2011).
Figura 2.13. Diagrama de la comunicación por TCP/IP. Palominos, N. (2014), Apuntes del curso de Redes de Datos.
MODELO OSI
Las redes como las conocemos en la actualidad se encuentran regidas por
el modelo de referencia OSI (en inglés: Open System Interconnection), el
22
que es una abstracción propuesta por la ISO (Organización Internacional
para la Estandarización) para lograr normalizar de forma global a los
protocolos de comunicaciones que operaban con redes de equipos.
El modelo OSI se conforma por siete capas, donde en cada una de ellas
se incorporan protocolos de comunicación distintos que van desde la parte
física más orientada al hardware empleado hasta el nivel absolutamente
lógico, más cercano al nivel usuario. (Li, Cui, Zhang, & Li, 2011)
Figura 2.14. Capas del Modelo OSI. (De León Ferreira, J., 2009).
Diseño y administración de seguridad en redes.
23
Las capas del modelo OSI tienen diferentes funcionalidades como se verá a
continuación:
1) Capa Física: Maneja elementos relacionados con el hardware, tal como
conectores, cables y componentes de la interfaz, mediante voltajes y
pulsos eléctricos sin seguir una estructura definida.
2) Capa de Enlace de Datos: Proporciona el control de flujo de los datos
y el acceso al medio. Organiza el flujo de los bits mediante “tramas” de
datos, las cuales incorporan una secuencia especial al inicio y al final
para notificar al receptor de la llegada o término de la información. De
la misma manera, posee un mecanismo de detección de errores que
utiliza reconocimientos, así como la retransmisión de las tramas.
3) Capa de Red: Secciona los mensajes de la capa de Transporte en
paquetes de información, para luego direccionar el envío de los datos
a un destinatario determinado.
4) Capa de Transporte: Regula el flujo de la información, garantizando
que ésta llegue a destino sin errores y en el orden en que fue enviada,
identificando a las distintas aplicaciones y gestionando el envío de los
paquetes de datos a los distintos destinos.
5) Capa de Sesión: Proporciona a los usuarios las herramientas para
mantener la comunicación entre distintos hosts, coordinando las
peticiones y respuestas de servicio entre las aplicaciones en dos
máquinas.
6) Capa de Presentación: Establece la representación de los datos
mediante la estructuración de los datos a transmitir, siguiendo una
24
sintaxis y una semántica de la información para que pueda ser
comprendida por el receptor final.
7) Capa de Aplicación: Relaciona a las distintas aplicaciones o programas
que harán uso de los servicios de red.
SOCKET
El concepto de Socket se establece como un proceso existente entre dos
equipos que mantienen una comunicación bajo un protocolo, en este caso
TCP/IP pero que también puede ser Bluetooth por ejemplo, de manera que
hay una máquina con el papel de cliente que realiza peticiones de
información y otra con la figura de servidor que espera que el otro inicie
la comunicación, la cual será de forma bidireccional para que ambos
puedan leer y escribir la información que será transmitida por las capas
que vimos anteriormente (Palominos, 2014).
Figura 2.15. Comunicación bidireccional mediante un socket. (Palominos, 2014)
Apuntes del curso de Redes de Datos.
Para hacer efectivo el concepto anterior es necesario que existan dos
recursos imprescindibles para establecer la comunicación:
25
1) Una dirección que identifique a la computadora de origen y a la de
destino, que en este caso será nuestra dirección IP.
2) Números de puerto que determinan la ubicación de un programa
dentro de una computadora, de forma que la conexión pueda
establecerse desde diferentes lugares dentro de la máquina.
PROTOCOLOS PRINCIPALES
El protocolo TCP/IP involucra dos protocolos principales, de los que debe
su nombre:
1) Protocolo TCP: Trabaja en la capa de transporte y asegura que los
datos sean recibidos de la misma manera en que fueron enviados a
destino. Al ser un protocolo orientado a la conexión, permite establecer
una comunicación entre dos o más equipos asignando la calidad de
cliente y servidor a determinadas máquinas. El protocolo TCP permite
también que los datos se formen en segmentos de diferentes tamaños
que serán luego traspasados al protocolo IP.
Figura 2.16. Segmento TCP (DeRedes, 2015), Protocolo TCP
Recuperado de : http://deredes.net
26
2) Protocolo IP: Opera en la capa de Red. El protocolo IP tiene el trabajo
de desarrollar y enviar los datagramas o paquetes de datos, aunque
deja el trabajo de garantizar su entrega al protocolo anterior. IP
determina al destinatario de la información mediante los tres campos
siguientes:
a) Dirección IP: Dada por la dirección del equipo que envía el mensaje
b) Máscara de subred: Permite al protocolo definir la parte de la
dirección IP que está relacionada con la red.
c) Puerta de enlace predeterminada: Entrega al protocolo la
información del receptor del mensaje.
Figura 2.17. Datagrama IP
(Hernando, R., 2002), TCP/IP Recuperado de: http://www2.rhernando.net
27
ENCAPSULAMIENTO DE LOS DATOS
Los datos enviados con el protocolo TCP/IP se rigen bajo una estructura
de paquetes, la cual relaciona directamente la unión de los protocolos TCP
e IP enviados a través de una red Ethernet, en donde la suma de ellos en
la capa de Aplicación lleva por nombre stack de protocolo.
Cada protocolo llama al paquete de datos de diferente manera, donde para
el protocolo IP será datagrama IP, para TCP segmento TCP y para el envío
mediante la red Ethernet será frame o trama. Dentro de cada capa se
insertará una nueva cabecera con la información de dicho protocolo, pero
conservando siempre el dato de usuario enviado dentro de un campo
específico.
Figura 2.18. Estructura de la trama Ethernet (Marhuenda, M, 2005/2006), Tecnología Ethernet
Recuperado de: http://redesdecomputadores.umh.es/
La capa de aplicación realiza el envío del flujo de datos hacia la capa de
transporte, en donde se subdivide la información en los segmentos TCP,
propios de este protocolo. Posteriormente, se asigna un nuevo
encabezado al segmento y se transmite hacia la capa de Red o Internet,
marcada por el uso del protocolo IP, realizando un CRC o suma de
comprobación de los datos. En la capa de red se crea el datagrama IP que
añadirá un nuevo encabezado con la información del protocolo e indicará
la dirección de origen y destino de la información. Se envía, luego, el
datagrama y se recalcula el CRC.
28
En la capa de enlace de datos se transfiere el datagrama IP a una trama
Ethernet que irá dirigida al computador de destino. Cuando se alcanza el
destinatario de los datos, la capa 2 del modelo OSI, descarta el
encabezado del paquete recibido y lo envía a la capa de Red del receptor.
Se verifica, posteriormente el encabezado del paquete y se realiza la
comprobación de errores a través del CRC, en donde si la suma coincide
con la realizada en la fase de envío, se descarta el encabezado y se envía
este segmento TCP a la capa de transporte. Si las sumas no coinciden, se
descarta el datagrama.
Figura 2.19. Encapsulado de un dato (Castillo G. G., 2005)
Sistemas de comunicaciones
Al igual que para la capa anterior, se calcula nuevamente la suma de
verificación, donde si coincide con el valor transmitido y el paquete se
encuentra en la secuencia que le corresponde, se descarta el encabezado
29
del segmento y se envía un reconocimiento al computador receptor, donde
posteriormente se transferirán los datos del paquete que recibirá la capa
de aplicación. En caso contrario, se descarta este segmento.
Finalmente, el destinatario recibe el flujo de bytes tal y como si viniese
directamente desde el destinatario. (Castillo G. G., 2005)
Figura 2.20. Estructura de datos según el protocolo TCP (Castillo G. G., 2005)
Sistemas de comunicaciones
TIPOS DE DIRECCIONES IP
La dirección IP, como se ha visto anteriormente, tiene como función
identificar a un equipo conectado en una red, siendo ésta de carácter local
(LAN) o pública (WAN). No obstante, dependiendo del entorno en el que
nos encontremos se podrán distinguir cuatro tipos de direcciones IP
30
distintas que, aunque conservan el mismo formato original, prestan
servicios diferentes.
1) IP Local: Este tipo de dirección IP permite al equipo identificarse
dentro de una red privada o de área local (LAN).
2) IP Pública: Este tipo de dirección IP permite identificar al equipo
dentro de la red global de Internet. Ésta puede clasificarse como
Dinámica o Estática.
a. IP Pública Dinámica: Este tipo de IP es asignado al equipo
por el proveedor de servicios de Internet (ISP) cada vez que
la máquina se conecte a Internet, siendo distinta en cada
conexión.
b. IP Pública Estática: Este tipo de IP se refiere a una dirección
fija asignada al equipo, es decir, que no cambiará en el
tiempo cada vez que se realice una conexión a la red.
DIRECCIONAMIENTO EN INTERNET
Para acceder a un determinado punto de servicio entro de la red de
Internet utilizamos una dirección que nos permite identificar un servicio
dentro de la red global. Esta dirección tiene el nombre de URL (Uniform
Resource Locator) y presenta cuatro campos fundamentales que permiten
alcanzar el destino solicitado:
1) Protocolo: Define el protocolo al que hace alusión la URL. Por
ejemplo, http hace referencia a una página web.
31
2) Nombre del servidor: Establece la dirección DNS o dirección IP del
servidor al que se desea acceder.
3) Puerto: Específica el número de socket TCP/IP por el cual se hace
efectivo el acceso al servidor. Por ejemplo, para acceder
normalmente con el protocolo http se utiliza el puerto 80.
4) Ruta: Indica la ubicación del documento solicitado dentro del
servidor.
DNS DINÁMICA
“El Servicio de Nombres de Dominios Dinámicos (DDNS) es un servicio
usado para asignar nombres de dominios a la dirección IP dinámica de un
dispositivo de red. […]” (QNAP Systems, Inc., 2015) . En otras palabras,
los DDNS son utilizados para acceder de forma remota y desde cualquier
lugar a un determinado equipo conectado a la red, el cual al router
asignarle IP dinámicas continuamente, este equipo la redireccionará a un
nombre de dominio fijo. Existen muchos proveedores de este servicio, pero
el más utilizado a nivel global es No-IP, debido a que permite obtener un
DNS dinámico de forma gratuita. (Wilkinson, Dept. of Comput. Sci.,
Edward Chow, & Cai, 2004)
32
TECNOLOGÍAS INALÁMBRICAS MÓVILES
La tecnología inalámbrica móvil está situada en un escalafón privilegiado
dentro de toda la gama de tecnologías existentes en la actualidad, gracias
a la constante evolución de este tipo de redes móviles que han pasado de
entregar un servicio limitado únicamente para llamadas de voz y mensajes
de texto con el servicio GSM hasta proveer conexión a Internet de forma
ilimitada y a grandes velocidades con la tecnología 3G y 4G.
El sistema de comunicación móvil de segunda generación (2G) o GSM
(Global System for Mobile Communications) fue el primer servicio de
telefonía completamente digital, el cual permite a los usuarios disponer de
comunicación de voz y envío de mensajes cortos (SMS). Su velocidad
máxima de transmisión de datos alcanza los 9,6 kbps.
La evolución de la tecnología anterior, fue GPRS (General Packet Radio
Service) o 2.5G, la cual permitió la incorporación del envío de mensajes
multimedia (MMS), mensajería instantánea y la posibilidad de entablar
conexión a Internet continuamente a través del protocolo WAP (Wireless
Application Protocol) que utilizaba un nombre punto de acceso llamado
APN (Access Point Name), el cual contenía los datos de acceso del
operador del servicio para el teléfono móvil. Según Birchler, Smyth,
Martinez y Baker, la velocidad de transmisión máxima ofrecida por GPRS
era de 40 kbps, mientras que según Sonera, el servicio 2.5G podía ofrecer
hasta 55 kbps.
Una de los servicios utilizados actualmente en la vida moderna y
específicamente para el desarrollo de Telemetrics, es la tecnología móvil
de tercera generación (3G), la cual en sus inicios comenzó entregando
velocidades de transmisión de hasta 384 kbps. Sin embargo, su
rendimiento ha sido mejorado notoriamente gracias al advenimiento de la
33
tecnología HSDPA (High-Speed Downlink Packet Access) provee una
velocidad de hasta 2 Mbps, y que mantiene al teléfono conectado a
Internet de forma permanente (Zhiyuan, Dept. of Comput. Inf. Eng., Xinji,
Qingquan, & Mei, 2013).
Como se aprecia en la Figura 2.21, el teléfono móvil se conecta a la red
3G a través de una estación base que, enlazada con un servidor web y
una puerta de enlace 3G, se proporciona la conexión del dispositivo a la
red de Internet (Devikiruba, 2013), (Informática-HOY, 2012), (Krendzel,
Inst. of Commun. Eng., Koucheryavy, Harju, & Lopatin, 2004), (Proctor &
Roke Manor Res. Ltd., 2003).
Figura 2.21. Diagrama del funcionamiento de la red 3G y GPS
(Zhiyuan, Dept. of Comput. Inf. Eng., Xinji, Qingquan, & Mei, 2013)
Mobile learning system over 3G based on triple play
IRC
FUNCIONAMIENTO
IRC (en inglés: Internet Relay Chat) es un sistema de chat multi-usuario y
multi-canal que permite establecer una conversación entre muchos
34
usuarios a la vez, siguiendo la arquitectura de cliente-servidor a través del
puerto 6667 de la máquina. (González, 2005)
Para esto, es imprescindible contar con un programa que tome el papel de
“cliente”, de manera que permita conectar al usuario a un servidor
preparado para cumplir esta función. Sin embargo, es imposible pensar en
entablar una conversación entre más de mil personas a la vez, razón por
la cual el servidor IRC se subdivide en los denominados “canales”, que son
simplemente lugares virtuales donde los usuarios charlan en grupos o de
forma privada, siendo moderados por usuarios llamados operadores de
canal que gozan de atribuciones especiales como expulsar miembros,
declarar el canal como privado, etc.
El número de personas que pueden participar en un canal, y la cantidad
de canales que se puedan crear en un servidor IRC son ilimitados, ahora
bien, existe un concepto en donde los usuarios participantes son scripts
automatizados que permiten extraer datos o realizar publicidad masiva
dentro de un canal de chat, denominados bots.
Figura 2.22 Esquema del sistema de chat IRC. Martínez-Chacón, J., Reguera, A. (2002). IRC
Recuperado de: http://www.uam.es/
35
BOTNET
Una botnet (del inglés: Robot Network) es una red donde los clientes que
participan son, principalmente, máquinas programadas que tienen como
misión entregar información si se le envía algún comando en específico,
extraer información específica o simplemente enviar mensajes masivos a
modo de Spam, siendo ampliamente utilizadas por los delincuentes
informáticos para tales fines (Naseem, Shafqat, Sabir, & Shahzad, 2010),
(Microsoft Corporation, 2012), (Kaspersky Lab, 2015).
Particularmente para este proyecto, se diseñará una botnet en donde cada
máquina será la aplicación desarrollada para el Smartphone instalado
dentro de cada uno de los buses de la flota, enviando la información de las
variables requeridas al servidor IRC, para su posterior procesamiento.
Siguen el concepto de backdoor o puerta trasera, un término informático
ampliamente utilizado por troyanos, gusanos y otros códigos maliciosos,
donde se accede a una máquina de forma remota y discreta con procesos
en segundo plano, de la cual se obtiene información en tiempo real y
control total a distancia.
Si bien, esta arquitectura se usa principalmente para el diseño de virus,
Telemetrics toma esta herramienta y la utiliza para fines completamente
diferentes pero siguiendo el mismo sistema del backdoor.
36
Figura 2.23. Anatomía de la botnet creada
IDENTIFICACIÓN
Dentro del entorno de IRC se utilizan los denominados nicknames, que
corresponden a un nombre o pseudónimo que los usuarios usan para
identificarse dentro de la red IRC. El nickname o simplemente nick debe
ser único y como máximo tener una longitud de 9 caracteres
alfanuméricos, donde además debe establecerse un nickname principal y
otro secundario, en caso de que el primero ya esté siendo utilizado por
otro usuario.
COMANDOS
En el entorno de IRC se utilizan instrucciones que permiten al usuario
realizar acciones específicas, como por ejemplo enviar un mensaje privado
a otro usuario o acceder a otro canal de chat, entre varias opciones más.
Estas instrucciones reciben el nombre de comandos y tienen como
37
característica principal que siempre comienzan con el símbolo “/”, en
donde toda cadena de texto que no comience por dicho carácter se
considerará un mensaje ordinario (Oikarinen & Reed, 1999). Algunos
comandos frecuentemente utilizados en IRC son los siguientes:
Comando <parámetro> Nombre Función
/JOIN <#canal> Mensaje de entrada
al canal
Se envía la petición de
usuario para acceder a un
canal específico, en donde
el servidor determinará si el
usuario tiene permitido el
ingreso.
/NICK <nickname> Mensaje de Nick Se utiliza para asignarle al
usuario un nuevo Nick o
que él mismo cambie su
Nick actual.
/KICK <#canal>
<nickname>
Expulsión Temporal Se expulsa a un usuario del
canal de manera forzada
de forma temporal. Esta
acción sólo es ejecutable
por operadores de canal.
/USER <nickname>
<host> <servidor>
<nombre real>
Mensaje de usuario Se utiliza al inicio de cada
conexión para registrar
nuevos usuarios en la base
de datos del canal.
Contiene el Nick utilizado
por el usuario, el host y el
servidor al que se le pedirá
la conexión y el nombre
real del usuario para
verificación de identidad.
38
/PRIVMSG <receptor>
<mensaje>
Mensaje privado Se utiliza para enviar
mensajes que tienen como
destinatario a un usuario
en específico. El campo
<receptor> es el Nick del
receptor y el campo
<mensaje> es la cadena de
texto a enviar
/PING <servidor> Mensaje de “PING” Tiene como objetivo
verificar si existe conexión
entre quien realiza la
petición y un servidor en
específico. En caso de
tener conexión, se recibirá
un mensaje de PONG
confirmando que el
servidor está activo.
/PONG <servidor> Mensaje de “PONG” Este mensaje es la
respuesta al mensaje de
“PING” e indica que
efectivamente el servidor
se encuentra activo.
Tabla 2.3. Comandos ampliamente utilizados en IRC
MYSQL
MySQL consiste en un sistema de gestión de bases de datos relacionales
de código abierto multiplataforma basado en un lenguaje de consultas
estructurado (SQL), que albergan la información en tablas separadas que
se enlazan a través de relaciones, permitiendo combinar los datos
almacenados al momento en que el usuario realiza una petición de
información (Enríquez, Maldonado, Nakamura, & Nogueron, 2014).
39
Sus principales ventajas son su bajo consumo de memoria física para
poder ser ejecutado en máquinas con bajo rendimiento, su facilidad de
configuración e instalación y su velocidad al realizar las operaciones
necesarias (Cambra, 2008).
MySQL puede ser operado vía web por phpMyAdmin, herramienta de
software escrita en lenguaje PHP que integra una interfaz gráfica de
usuario para el fácil manejo de la base de datos (Liblab, Dept. of Printing
& Packaging Technol., & Nimnual, 2010); como también a través de línea
de comandos vía SSH.
SMARTPHONE
Como se ha establecido anteriormente, se utilizará un Smartphone como
nexo entre la fase de adquisición de datos y la fase de transmisión de la
información hacia la base de datos. Se ha utilizado un teléfono inteligente
debido a que por sí solo reúne todas las características necesarias para
realizar esta labor. Estos requerimientos, esenciales para la incorporación
de un dispositivo móvil al proyecto Telemetrics, se detallan en la siguiente
sección.
REQUERIMIENTOS DEL TELÉFONO
Los requerimientos que debe tener un teléfono inteligente para ser parte
del proyecto Telemetrics son los siguientes:
Sistema de navegación GPS
Sistema operativo Android 4.4 KitKat o superior
40
Conexión a Internet vía Wi-Fi, 3G o 4G
Conexión inalámbrica con dispositivos vía Bluetooth
Conexión con el PC a través de un cable USB.
RASPBERRY PI
Esta microcomputadora de bajo coste resulta más eficiente de utilizar para
tareas específicas que un ordenador personal, ya que dada su fisionomía
de hardware reducida, su consumo de recursos es muy bajo en
comparación con el de un PC, por lo que es posible mantener a la
Raspberry Pi operativa durante tiempo indefinido. Sin embargo, no posee
grandes capacidades de memoria ni espacio de almacenamiento ni
memoria de vídeo como para realizar exactamente las mismas funciones
que una computadora personal (Dhaval, Darde, & Chitalia, 2013).
Figura 2.24 Raspberry Pi. Sola, A. Raspberry Pi – First Steps
Recuperado de: http://pucomi.blogspot.cl
CARACTERÍSTICAS DEL SOFTWARE
El Sistema Operativo oficial para este dispositivo es Raspbian, el que es
una distribución exclusiva para el uso en Raspberry Pi. Está basada en la
41
distribución de GNU/LINUX, Debian y para ser instalada debe grabarse la
imagen de Raspbian en la tarjeta SD. Ofrece acceso tanto a través de línea
de comandos o Secure Shell (SSH), como de un escritorio gráfico basado
en LXDE (Entorno de Escritorio X11 Liviano) (Lamine, Dept. Technol. Inf.
of ISET of Sfax, & Abid, 2014).
Figura 2.25. Logotipo de Raspbian
Recuperado de: https://www.raspbian.org/
Figura 2.26. Acceso a la Raspberry Pi a través de SSH
CARACTERÍSTICAS DEL HARDWARE
El hardware de esta microcomputadora presenta las siguientes
características (Escola Tècnica Superior d'Enginyeria Informàtica,
Universitat Politècnica de València, 2013):
DATOS TÉCNICOS
Dimensión 85x54 mm.
SoC (System-on-a-Chip) Broadcom BCM2835
42
Procesador ARM
Velocidad del procesador 1 GHz
Memoria RAM Expandible hasta 512 Mb
Procesador gráfico GPU VideoCore IV
Tabla 2.4. Datos técnicos de hardware de la Raspberry Pi. Raspberry Shop. Raspberry Pi.
Recuperado de: http://www.raspberryshop.es/
Para alimentar la tarjeta, se debe de conectar a un adaptador AC/DC con
salida de 5 V de tipo micro-USB. En cuanto a los elementos de entrada y
salida, al igual que una computadora personal, tenemos varios puertos de
acceso para periféricos que cumplen esta función:
Puerto de salida de vídeo HDMI
Puerto de salida de vídeo RCA
Puerto de salida de audio Jack 3.5 mm
Puertos USB 2.0 para conexión de Teclado y Mouse
Puerto Ethernet RJ-45 para conexión de Internet
Ranura para Tarjeta SD como medio de almacenamiento de datos
Figura 2.27. Detalle de elementos de entrada y salida de Raspberry Pi. Recuperado de: http://histinf.blogs.upv.es
43
ARDUINO
Arduino consiste en una plataforma de código abierto que proporciona al
usuario un sistema de hardware y software accesibles y de fácil manejo.
Está conformado por una placa electrónica basada en un microcontrolador
Atmel AVR de 8 bits que es el responsable de controlar las tareas lógicas
del dispositivo, además de administrar las entradas y salidas que pueden
conectarse a la tarjeta, tales como sensores y/o actuadores (Lambert
Sarango, 2014).
El modelo de la placa Arduino utilizada para este proyecto es el Arduino
Mega, el cual cuenta con tres puertos seriales, siendo posible utilizarlo
para establecer comunicación simultánea con el dispositivo Bluetooth y el
PC desde donde se hará la programación, para también efectuar un
monitoreo de las tramas enviadas por la tarjeta en tiempo real.
CARACTERÍSTICAS DEL HARDWARE
Una de las tarjetas Arduino que ofrecen mayor cantidad de funcionalidades
es la placa Arduino Mega que presenta las siguientes características
(Pomares, 2009):
Microcontrolador ATmega1280
Tensión de alimentación: 5V USB o Voltaje DC (12 V máx.)
Pines digitales: 54 (14 con PWM)
Entradas analógicas: 16 canales
EEPROM: 4 kB
Velocidad de reloj: 16 MHz
44
Figura 2.28. Arduino Mega. Arduino. Arduino MEGA ADK
Recuperado de: https://www.arduino.cc
CARACTERÍSTICAS DEL SOFTWARE
Arduino opera con un lenguaje de programación llamado Wiring (Kushner,
2011), el cual está basado en la plataforma Processing - C/C++. El entorno
de compilación que utiliza Arduino es el Ambiente de Desarrollo Integrado
(en inglés: IDE, Integrated Development Environment) homónimo, Arduino
IDE (Mancha García, 2015). En este entorno de programación se escribe
el programa que se desea ejecutar en la tarjeta, de modo que es posible
utilizar distintas funciones disponibles en una barra de herramientas
detallada en la siguiente figura:
Figura 2.29. Funciones de la barra de herramientas del Arduino IDE.
45
Figura 2.30. Ventana Principal del Arduino IDE
ANDROID
Android es un sistema operativo basado en Linux, diseñado para
ejecutarse principalmente en teléfonos inteligentes y tabletas creado por
Android Inc. en el año 2005 y posteriormente vendido a Google Inc.
Actualmente Android es el S.O. más utilizado en el mundo, donde el 50.9%
de la población mundial tiene un dispositivo móvil con esta tecnología
(ESET, 2012), (Escola Tècnica Superior d'Enginyeria Informàtica,
Universitat Politècnica de València, 2012).
APLICACIONES MÓVILES
Día a día, la tecnología móvil se hace cada vez más popular y por ende el
desarrollo de aplicaciones móviles genera cada vez más demanda. En
este contexto es donde estos softwares diseñados para dispositivos
46
móviles permiten al usuario interactuar de mejor manera con el entorno de
Android, a la vez de poder gozar de múltiples herramientas al alcance de
su mano (Comisión Federal de Comercio del gobierno de los Estados
Unidos, 2015).
Para esto, es necesario que la aplicación posea una interfaz gráfica (en
inglés: GUI (Graphical User Interface)) que sea intuitiva, llamativa y fácil
de manejar para el usuario. Del mismo modo, la aplicación móvil
necesitará de ciertos permisos a los que el usuario debe acceder para
ejecutar una aplicación. Por ejemplo, si la app utiliza sistema de
navegación GPS, el usuario debe estar de acuerdo en que el software
utilice la localización geográfica de móvil. Finalmente, la aplicación en
cuestión debe seguir una serie de instrucciones determinadas por el
programador para que realice las tareas específicas a las que está
destinada su ejecución.
De la descripción anterior podemos rescatar tres fases que toda aplicación
móvil debe tener y que para programarlas es necesario disponer de un
entorno de desarrollo capaz de crear un proyecto, compilarlo y cargar al
teléfono el archivo ejecutable con extensión “.apk” (Gironés, Ficheros y
carpetas de un proyecto Android, 2015). Las tres fases citadas son:
Interfaz Gráfica: Para programarse debe editarse el archivo “main.xml”,
contenido dentro del directorio “res/layout”, pudiendo ser tanto
gráficamente como mediante código.
Permisos necesarios: Para que la app pueda ejecutarse sin problemas
si utiliza las funcionalidades del teléfono (Bluetooth, GPS, etc.), el
usuario debe haberle permitido el uso de éstos. Está ligado al archivo
“AndroidManifest.xml”, ubicado en la carpeta principal del proyecto
(Xataka Android, 2014).
47
Programación del funcionamiento: Gestiona toda la ejecución de las
tareas propias de la aplicación programadas por el desarrollador. Está
contenida dentro del archivo “MainActivity.java”, almacenado en el
directorio “src/com/example/NombreProyecto/MainActivity.java”.
ENTORNO DE DESARROLLO
El entorno de compilación utilizado para desarrollar la aplicación Android
es el Eclipse IDE. Si bien también pudiese haberse optado por utilizar el
programa “Android Studio”, se hizo uso de Eclipse dada la experiencia
alcanzada al momento de comenzar a desarrollar este proyecto para este
entorno de desarrollo.
Figura 2.31. Inicio del Eclipse IDE
El primer paso para comenzar a programar en esta plataforma móvil, es
instalar un conjunto de herramientas necesarias para alcanzar tal objetivo.
48
Estos elementos son el kit de desarrollo de Android (Android SDK), el
plugin Android ADT (Android Development Tools) y el kit de desarrollo de
Java (JDK), ya que el lenguaje de programación Android se basa
principalmente en Java (Google, Inc., 2015), (Aprende Android, 2012).
Para instalar estos complementos y el Eclipse IDE deben seguirse las
siguientes instrucciones:
1) Debemos entrar al sitio oficial del proyecto Eclipse
(http://www.eclipse.org/downloads/) y descargar la versión para
desarrolladores de Java, donde una vez en el disco duro será necesario
descomprimirla en una carpeta.
Figura 2.32. Versión del IDE a descargar
2) Descargar el SDK Android desde el repositorio oficial de Google
(http://developer.android.com/sdk/index.html), eligiendo la opción
“Stand-alone SDK tools” y descomprimir en el disco duro, recordando
la ubicación en donde se desempaquetó el archivo.
3) Descargar el kit de desarrollo de Java (JDK) en su última versión
(versión 8 actualmente) desde la página oficial de Oracle,
seleccionando el sistema operativo y descomprimiendo el archivo una
vez alojado en el disco duro.
49
4) Una vez instalados el JDK 8, el SDK Android y descomprimido el Eclipse
IDE, ejecutamos la herramienta SDK Manager al momento de finalizada
la instalación del kit de desarrollo de Android. Se desplegará una
pantalla en donde podremos elegir los drivers, sistemas operativos y
elementos que consideremos útiles para comenzar a desarrollar nuestra
aplicación.
5) Se recomienda instalar la versión 4.4.2 de Android, ya que según
estadísticas es la versión más utilizada en la actualidad, o en su defecto
la última versión de la plataforma. También es necesario adquirir el driver
USB que permitirá cargar nuestra app al teléfono móvil. Una vez
seleccionados los paquetes a instalar, se debe pulsar el botón “Install ‘n’
packages…”, donde ‘n’ es el número de paquetes a instalar. Se acepta
todo y se pulsa el botón instalar.
Figura 2.33. Porcentaje del uso actual de las versiones de Android.
50
6) En este momento, disponemos de dos herramientas que no se
encuentran vinculadas entre sí: el Eclipse IDE y el SDK Android. Para
enlazar estos dos programas, debemos instalar el plugin ADT (Android
Development Tool) para Eclipse, dado que de forma predefinida
este software no posee la capacidad de compilar el lenguaje para
teléfonos móviles.
7) Para instalar el plugin debemos dirigirnos al menú “Help” y seleccionar:
“Install New Software”.
8) Se abrirá una ventana que nos solicitará introducir un nombre para
identificar al ADT, así como la dirección del repositorio desde donde se
obtendrá el plugin: https://dl-ssl.google.com/android/eclipse/
9) Enseguida, debemos marcar la opción “Developer Tools” y pulsar el
botón “Siguiente”.
10) Los siguientes pasos de instalación requieren que se presione el botón
“Siguiente” y se acepte la licencia del producto, finalizando con el reinicio
de Eclipse para aplicar los nuevos cambios.
11) Finalmente, tras reiniciarse Eclipse, éste nos preguntará si deseamos
instalar el SDK o utilizar una versión ya existente, optando por la
segunda opción. Ingresamos a URL del directorio donde se encuentra
alojada nuestra versión del Kit de desarrollo de Android que hemos
instalado en un comienzo. Pulsamos siguiente y en la siguiente ventana
pulsamos el botón Finalizar.
51
12) En este momento ya tenemos vinculados el Eclipse IDE con el SDK
Android, por lo que ya podemos comenzar a programar un nuevo
proyecto. Comprobamos esta situación con la aparición de una nueva
barra de herramientas existente en la ventana principal de Eclipse.
LABVIEW
EL ENTORNO DE LABVIEW
LabVIEW es un entorno de desarrollo gráfico que mediante la unión de
bloques de funciones o VIs (Virtual Instruments), es posible realizar
programas que cuentan de por sí con un panel frontal que es visible al
usuario a modo de interfaz gráfica, no así el código o diagrama de bloques
que, siguiendo la estructura de un diagrama de flujo, ejecuta todas las
tareas asociadas a la funcionalidad que tendrá el programa desde un
segundo plano. En esta plataforma de software existen diferentes
elementos que son comunes a la mayoría de los lenguajes de
programación conocidos, aunque también existen algunos que son
exclusivos de LabVIEW, los cuales se detallarán a continuación (National
Instruments, 2015).
Panel frontal: Corresponde a la ventana donde se crea la interacción con
el usuario con el programa, a través de elementos de control y
visualización de datos.
52
Figura 2.34. Panel frontal.
Controles e indicadores: Los controles son elementos de entrada de
datos. Pueden ser controles campos de texto, botones, barras deslizantes,
listas desplegables (combobox), entre otros. Paralelamente, los
indicadores son elementos de salida que permiten mostrar información al
usuario a través de gráficos, luces, campos de texto, tablas, etcétera.
En LabVIEW existen cinco tipos que rigen a los controles e indicadores:
booleanos, numéricos, strings, paths y tiempo, que se entrarán a detallar
a continuación:
a) Booleanos: Se representan a través de luces y botones
asociadas a los elementos indicadores y de control del diagrama
de bloques. Cabe destacar que los controles booleanos tienen
una opción denominada Mechanical Action que establece el
comportamiento del botón al momento de hacer click sobre él.
Se representan con el color verde.
53
Figura 2.35.Controles e indicadores booleanos.
b) Numéricos: En LabVIEW, existen distintos elementos que
devuelven valores numéricos pero que actúan de forma
dinámica como termómetros, barras deslizantes, tanques o
elementos de selección múltiple como Text ring o Tabs Controls
que dependiendo del elemento o de la pestaña respectivamente
se tendrá un valor numérico. El color anaranjado se utiliza para
el formato double, mientras que el color azul es para el formato
int.
Figura 2.36. Controles e indicadores numéricos.
54
c) Strings o cadenas: Los elementos tales como combobox, y
cuadros de texto trabajan con este formato. Se representan en
color rosa.
Figura 2.37. Controles e indicadores de tipo String
d) Path o Ruta: Elementos de control y visualización de rutas a
directorios o carpetas. Se representan por el color calipso.
Figura 2.38. Control e indicador de tipo Path
e) Timestamp: Son elementos que siguen el formato tiempo que
contiene la fecha y la hora. Se representan con el color marrón.
Figura 2.39. Control e indicador del tipo Timestamp
55
Diagrama de bloques: El diagrama de bloques es el equivalente al código
fuente de los lenguajes de programación, en donde se deben ir uniendo
objetos que realizan tareas específicas a través de cables. En el diagrama
de bloques, los elementos de control y visualización tienen su salida
directa al front panel, siendo diferente para el caso de los demás
elementos. En la siguiente figura se representa la suma de dos números
que utiliza como sumandos los datos ingresados por el usuario.
Figura 2.40. Ejemplo: Suma de dos números.
Terminales: Los terminales son la representación de elementos de
entrada y salida de datos en el diagrama de bloques. Desde ellos
provienen o se dirigen los datos que serán procesados por el programa
creado. En la figura anterior, los terminales son de color anaranjado
porque pertenecen al formato de doble entero (DBL) y corresponden a los
controles e indicador respectivos.
VI (Virtual Instrument): Los Vis corresponden a los programas
desarrollados y que se representan por bloques de funciones que cuentan
56
con su propio ícono. Cuando un VI es insertado dentro de otro VI se toma
como un Sub-VI, el cual debe tener especificados sus conectores de
entrada y salida de datos para enviar a los indicadores y recibir desde los
controles respectivamente. Para el ejemplo anterior podría tenerse un
ícono y conectores como los de la siguiente figura:
Figura 2.41. Conectores e ícono de un VI
Modo edición y modo Run: Un instrumento virtual puede estar en modo
edición que es donde se realizará la labor de programación, y en modo
Run que es donde se pondrá en funcionamiento el VI. Existe una barra de
herramientas principal con funciones de ejecución y depuración, en donde
los elementos principales son el ícono de ejecución para iniciar el
programa, de ejecución cíclica para iniciar el programa indefinidamente,
es decir, en un ciclo infinito, de detención del programa y de pausa.
Figura 2.42. Barra de herramientas del modo Run
Estructuras: Son cuadros de funciones que encierran el proceso a
ejecutar al momento de ser invocados. Existen estructuras iterativas,
condicionales y secuenciales, las cuales se detallarán a continuación:
57
a) Estructuras iterativas: Tienen como objetivo ejecutar tareas
repetitivas dentro de un VI, ya sea un determinado número de
veces o indefinidamente hasta que se cumpla cierta condición
booleana.
- For Loop: Ejecuta el código que aloja en su interior el
número de veces igual al valor introducido dentro de la
variable N que lleva por nombre Count Terminal, pudiendo
cablear una constante a su conector. El elemento iteration
terminal contiene el número de la iteración ejecutada en el
momento, siendo desde 0 hasta N-1.
-
Figura 2.43. For Loop.
- While Loop: Ejecuta el código que aloja en su interior
indefinidamente hasta que un booleano cableado al
conditional terminal alcance el valor de verdadero. Esto se
comprueba al final de cada iteración. Al igual que para el For
Loop, el iteration terminal posee el valor de la iteración
actual.
58
Figura 2.44. While Loop.
b) Estructuras condicionales: Ejecutan condiciones de la forma
if-then-else de los lenguajes de programación. Cada caso está
contenido dentro de un diagrama independiente que están
determinados por el Selector Terminal, es decir, si el elemento
cableado a la estructura es un booleano, se presentarán sólo
dos casos: Verdadero y Falso. Si se cablea un valor numérico,
se determinará un número de casos igual a la cantidad de
valores que puede tomar el selector siendo del tipo switch-case.
Finalmente, también es posible cablear el resultado de un error
de alguna operación de procesamiento, es decir, si se obtuvo o
no un error al momento de ejecutar una tarea, se presentan dos
casos: Error y No Error.
59
Figura 2.45. Estructuras condicionales
c) Estructuras secuenciales: Para establecer, en algunos casos,
una secuencia de ejecución ordenada de las tareas realizadas
se utiliza el siguiente elemento de LabVIEW, ya que, a diferencia
de los otros lenguajes de programación que se ejecutan de
forma lineal, en esta plataforma se realiza el funcionamiento
como un diagrama de flujo que no sigue esta estructura lineal
del código.
- Flat Sequence: Contiene en diferentes diagramas los
programas a ejecutar de forma secuencial, es decir, primero
el subdiagrama 0, seguido del 1 y así sucesivamente.
Figura 2.46. Flat Sequence.
60
d) Nodos de fórmula: Es un elemento que permite la integración
de fórmulas matemáticas al entorno de LabVIEW simplificando
la inserción de fórmulas complejas en el diagrama de bloques.
Se añaden entradas y salidas que están asociadas a las
variables propias de cada fórmula. Es importante destacar que
cada fórmula debe terminar con el símbolo ‘;’.
Figura 2.47. Suma de dos números con nodo de fórmula.
Matrices y Arrays: En LabVIEW es posible interactuar con matrices y
arreglos, que consisten en una colección de elementos del mismo tipo con
una o más dimensiones. Se accede a los elementos a través del índice de
posición del elemento en la matriz, pudiendo éste variar entre 0 y n-1,
siendo n el número de elementos de la matriz. Si la matriz es
unidimensional se le denomina arreglo o array, a la cual es posible
procesar de diferentes maneras, por ejemplo extrayendo o insertando
elementos, ordenando los objetos, entre otras tareas. Soportan todo tipo
de datos exceptuando gráficos.
61
Figura 2.48. Arrays (numérico, booleano, String).
Clústeres: Un tipo de elementos alterno a los matrices y arreglos son los
clústeres, que se diferencian de los anteriores por el hecho de permitir
agrupar en su interior cualquier tipo de elemento. Por ejemplo, un clúster
puede contener al mismo tiempo tanto controles numéricos como luces
indicadoras. Regularmente se utilizan para el traspaso de datos hacia los
gráficos.
Figura 2.49. Clúster.
Gráficas: Existen tres tipos de gráficas en esta plataforma, los cuales, aunque
presentan semejanzas visuales, ambas basan su funcionamiento de una
forma muy diferente.
a) Waveform Chart: Permiten representar una o más variables
simultáneas e irlas actualizando para efectuar comparaciones en
tiempo real. Soporta datos de tipo numérico (DBL).
62
Figura 2.50. Waveform Chart
b) Waveform Graph: Representa funciones pertenecientes a una sola
variable de una sola vez, sobre puntos espaciados uniformemente,
desplegado en una forma de onda que varía en función del tiempo. Al
igual que el anterior, soporta datos del tipo numérico (DBL).
Figura 2.51. Waveform Graph
c) XY Graph: A diferencia de los anteriores, este tipo de gráfico
representa matrices de datos de dos dimensiones en una gráfica del
tipo XY. Soporta solamente el tipo de datos clúster, que debe contener
los dos arrays de las dos variables a representar.
63
Figura 2.52. XY Graph
64
DESARROLLO DEL PROYECTO
MODELAMIENTO DE LA SOLUCIÓN
La estructura del proyecto comienza con un mecanismo de adquisición de datos
que consta de dos sensores que proporcionan los datos del nivel de combustible
instantáneos del bus y de la posición de la tapa del tanque, teniendo ésta dos
posibles estados: abierta o cerrada. Estos sensores son simulados en el prototipo
del proyecto por una resistencia variable (potenciómetro) como sensor analógico
y por un sensor digital infrarrojo CNY70 que representa el transductor de la tapa.
En una implementación futura del proyecto en una flota de buses o camiones,
estos sensores de prueba deberán ser reemplazados por el sensor de nivel por
flotación (o ultrasonido si fuera el caso) y un sensor infrarrojo especial para la
supervisión de la apertura del tanque.
Figura 3.1. Diagrama de bloques del proyecto
65
En la fase de adquisición de datos, la información obtenida desde los sensores
es leída y encapsulada en una trama que se rige bajo un protocolo creado
específicamente para este proyecto. El microcontrolador Arduino MEGA 2560 se
comunica mediante puerto serial (Serial 2 en los pines 16 [TX2] y 17 [RX2]) con
el módulo Bluetooth HC-06. La forma de la trama se expresa en la Figura 3.2.
Figura 3.2. Forma de la trama de adquisición de datos
En la figura siguiente se visualiza una lectura de prueba con la aplicación móvil
“BlueTerm” que emula un terminal de comunicaciones serial entre el teléfono y
un adaptador Bluetooth, en este caso, el HC-06.
Figura 3.3. Prueba de funcionamiento con BlueTerm.
66
Para actuar como nexo entre la fase de adquisición de datos y la fase de
almacenamiento de los mismos, adquiere un rol fundamental la aplicación móvil
programada en la plataforma Android para este proyecto. El teléfono recibe la
trama proveniente desde el módulo Bluetooth, y la encadena a una nueva trama
que está estructurada según un segundo protocolo creado únicamente para este
proyecto, la cual contiene, además de los datos de los sensores, la fecha y hora
de la recepción de los datos, un nombre específico asignado al bus y la
coordenada geográfica aproximada en dónde se encuentra el vehículo al
momento de efectuada la medición. Los datos se encuentran separados por
punto y coma (;) y delimitados inicialmente por el signo peso ($) y al final por el
signo porcentaje (%). La forma general se puede apreciar en la siguiente figura:
Figura 3.4. Forma de la trama de envío de los datos
En la Figura 3.5 se visualiza una captura de pantalla de la aplicación Android que
elabora esta nueva trama con los datos obtenidos a través de Bluetooth y la envía
a través de Internet hacia un servidor de chat IRC remoto que se ejecuta en la
microcomputadora Raspberry Pi por el puerto 6667. La utilización de IRC para
este propósito se radica en que esta plataforma tiene la particularidad de poseer
una estructura de comunicaciones ordenada, estable y fácil de modificar para el
desarrollo de este tipo de aplicaciones.
67
Figura 3.5. Cabecera de la aplicación
Figura 3.6. Trama enviada al servidor IRC y recibida por el cliente en Java
La aplicación tiene una tarea programada con un temporizador que se ejecuta
cada 30 segundos. Esta tarea tiene la misión de reconectar la comunicación
Bluetooth y del socket TCP/IP si se detecta que se perdió la comunicación en el
transcurso de la medición, además de enviar continuamente los nuevos valores
tomados por los sensores y el GPS del teléfono en el tiempo.
68
Figura 3.7. Diagrama de flujo del funcionamiento del Timer
Cabe destacar que el programador tiene la posibilidad de interactuar con el
teléfono a través de cualquier programa cliente de chat IRC, como por ejemplo el
cliente online “Kiwi IRC” (http://kiwiirc.com), en donde si su nickname es igual
a la palabra “root”, se accede a un pequeño sistema operativo creado a través de
comandos determinados por programa, con los cuales podemos obtener
información en tiempo real de algunas variables interesantes de conocer
momento a momento, las cuales se detallan en la sección .
69
Figura 3.8. Comandos enviados por el programador desde el canal de chat
Como cada máquina tendrá incorporada un Smartphone con una tarjeta Arduino,
cada bus funcionará como un cliente de chat que se conecta a este servidor IRC,
de manera que permitirá monitorear el estado en tiempo real de muchos
vehículos a la vez de forma constante.
En cuanto a las tramas, éstas se van enviando al servidor IRC desde el
Smartphone a medida que actúa el temporizador, siendo tomadas por un cliente
IRC programado en Java que reside dentro de la misma Raspberry Pi y separa
cada variable delimitada por punto y coma (;) de la cadena, se conecta a través
de un conector JDBC (Java Database Connectivity) a una base de datos instalada
también en esta microcomputadora y guarda la información en una tabla que
lleva por nombre el del bus asignado.
70
Figura 3.9. Tablas en la base de datos
Figura 3.10. Elementos almacenados en una tabla de la base de datos.
Para que el usuario final pueda visualizar la información de forma amigable e
intuitiva, se desarrolló una interfaz gráfica de usuario en el software LabVIEW
2013 que muestra el valor actual de velocidad, nivel de combustible, posición de
71
la tapa y distancia total recorrida. Además, tiene la opción de desplegar el historial
de datos recibidos en forma de tabla obtenidos directamente desde la base de
datos. También permite al usuario visualizar la evolución del consumo de
combustible, de la apertura de la tapa del tanque y la velocidad en función del
tiempo en gráficas respectivas, en donde cada punto está asociado a una fecha
y hora determinadas. Finalmente, el usuario puede ver en pantalla a través de la
incorporación de la API de Google Maps y un código HTML que traza la
trayectoria seguida por el bus desde el inicio hasta el final de su recorrido. Este
programa ejecuta consultas hacia la base de datos MySQL remota de la
Raspberry Pi mediante un conector ODBC (Open Data Base Connectivity) que
gestiona los parámetros necesarios para acceder de forma segura a la BD.
Figura 3.11. Aplicación Android enviando datos.
72
Figura 3.12. Ventana principal de la interfaz de usuario en LabVIEW
VENTAJAS Y APLICACIONES DEL PROYECTO
Las principales ventajas que presenta Telemetrics como proyecto son su relativo
bajo costo, dada la comparación entre este sistema y otro del mismo tipo que en
lugar de un teléfono inteligente emplee las herramientas de comunicación y
localización en forma separada (modem GPRS, dispositivo GPS, etc),
incrementando el costo de inversión del proyecto. Del mismo modo, otra principal
ventaja es su arquitectura modular, la que permite distribuir de mejor manera las
tareas que cada bloque de hardware y software realiza. Otra gran ventaja es su
versatilidad, ya que no sólo puede utilizarse para la prevención del robo de
combustible, sino que es totalmente flexible a la hora de ser implementado para
algún otro objetivo que requiera de un medición a distancia de variables, por
ejemplo, bien podría aplicarse para la monitorización de máquinas de vending.
73
SENSORES DEL PROTOTIPO
Las pruebas del prototipo del proyecto se realizaron simulando los sensores
correspondientes al medidor de nivel de combustible con una resistencia variable
de 1 KΩ cuyo valor de salida fluctúa entre 0 - 5 V, y el sensor digital infrarrojo de
la tapa del tanque con el sensor infrarrojo CNY 70 conectados al pin analógico
A0 y al pin digital 22, respectivamente.
Figura 3.13. Sensor analógico del prototipo
SENSOR DIGITAL DEL PROTOTIPO
El CNY70 es un sensor infrarrojo de corto alcance que basa su
funcionamiento en la detección de un haz infrarrojo generado por un LED
iR, el cual es reflejado por un obstáculo hacia un fototransistor en la misma
dirección que detecta el rayo y entrega un voltaje relacionado con la
cantidad de luz recibida por este componente. Es necesario que en la
salida se obtenga un ’1’ al momento en que se detecte un objeto, mientras
que en caso contrario se requerirá un ‘0’. No obstante, el sensor por sí solo
no entrega un valor normalizado, por lo que es necesario disponer del
74
circuito integrado UA741CN que es un amplificador operacional. Este C.I.
garantiza que si el voltaje entregado por el sensor supera un umbral
configurado manualmente a través de una resistencia variable, se obtiene
un valor lógico normalizado de ‘1’ (Salmerón, 2005), (Trastejant, 2011),
(Daud, Fac. of Biosci. & Med. Eng., Mohd Sobani, Ramiee, & Mahmood,
2013).
Figura 3.14. Sensor digital de infrarrojos CNY70
DESCRIPCIÓN DEL CÓDIGO ANDROID
El código de una aplicación basada en la plataforma Android, como se explicó
en el marco teórico, se subdivide en tres etapas principales:
1) Interfaz gráfica
2) Permisos necesarios
3) Funcionamiento de la aplicación
75
Primero se procederá a describir el funcionamiento de la aplicación, para luego
continuar con los permisos requeridos para la ejecución de la app y finalmente
mostrar la interfaz gráfica de usuario que presentará la aplicación. Los dos
primeros puntos se detallarán mediante la subdivisión en tres bloques de
funciones principales, los cuales presentan las herramientas necesarias para
establecer comunicación para con la tarjeta Arduino y a su vez con el servidor
IRC instalado en la microcomputadora Raspberry Pi, además de los distintos
elementos necesarios para efectuar el envío y procesamiento de los datos a
monitorear, como por ejemplo la obtención de la ubicación geográfica, el uso de
timers para la automatización de tareas, la detección de eventos, entre otros.
Estas secciones presentan una serie de métodos y tareas propias que le permiten
cumplir su propósito específico en el proyecto, las cuales son:
1) Socket TCP/IP: Gestiona la conexión y el envío de los datos desde y hacia
el servidor IRC.
2) Socket Bluetooth: Gestiona la conexión y el envío de los datos desde el
módulo Bluetooth HC-06 y la tarjeta Arduino.
3) Elementos de procesamiento: Se refiere a todos los demás elementos que
actúan para elaborar la trama de los datos, así como la interacción del
programador mediante el cliente IRC.
76
Figura 3.15. Diagrama de flujo de la estructura de la aplicación Android
SOCKET TCP/IP
Con el término Socket TCP/IP nos referimos a la comunicación que se
gestiona entre el teléfono móvil y la Raspberry Pi, actuando como cliente
y servidor respectivamente. Esta conexión se realiza por el puerto 6667
del servidor http://fserranovargas.no-ip.org, que corresponde a un
nombre de dominio dinámico (DNS dinámica) adquirido gratuitamente en
el portal No-ip.org (www.no-ip.org) que realiza la tarea de redireccionar la
77
dirección IP pública dinámica que el proveedor de servicios de Internet
(ISP) entrega a un determinado equipo conectado a la red, en este caso
la Raspberry Pi, la cual posee un script instalado para lograr que el servidor
de No-IP conozca a cada momento la dirección IP asignada. En otras
palabras, para acceder a la Raspberry Pi sólo tendremos que ingresar con
este DNS desde cualquier lugar de la red, independientemente de la
dirección IP pública que tenga asignada.
LISTADO DE FUNCIONES
Los métodos que permiten al socket TCP/IP ejecutar la tarea que le
corresponde son los siguientes:
Código Función
ConectarIRC() Inicia la conexión del socket TCP/IP entre la
aplicación y el servidor IRC.
initializeTimerTask() Inicia el conjunto de tareas que se ejecutarán
con cada ciclo del timer.
btnSend.setOnClickListener(…) Se envían los datos del cuadro de texto de la
derecha del botón “Send” cuando éste se
presiona.
btnTrama.setOnClickListener(…) Se envía la trama al servidor IRC de forma
manual al presionar el botón “Trama”
String ip() Obtiene la IP actual que tiene asignado el
teléfono móvil.
sendMessageToServer(…) Envía un determinado mensaje a la ventana
principal del servidor IRC.
receiveMsg() Recibe los mensajes enviados desde el servidor
IRC
displayMsg(…) Muestra en el cuadro de texto principal los
mensajes recibidos y enviados desde y hacia el
servidor IRC
78
Enviar(…) Devuelve un comando específico como mensaje
privado al usuario “root”.
Tabla 3.1. Listado de funciones de TCP/IP
CÓDIGO ANDROID (TCP/IP)
Las variables globales definidas en el bloque TCP/IP se detallan a
continuación:
private Handler handler = new Handler();
public static String host="fserranovargas.no-ip.org";
public static Socket socket=null;
public static BufferedReader in = null;
public static PrintWriter out=null;
public String str="";
Variable Función
Handler handler Objeto que gestiona los datos provenientes desde el
servidor para mostarlos en el cuadro de texto
String host Dirección del servidor IRC
Socket socket Objeto que crea el socket usado para establecer la
comunicación con el servidor.
BufferedReader in Objeto que almacena los datos que van hacia el
servidor para luego traspasarlos al socket.
PrintWriter out Objeto que envía al socket los parámetros de conexión
al servidor IRC
String str Variable que guarda los datos que se mostrarán en el
cuadro de texto principal
Tabla 3.2.Variables TCP/IP
79
En esta sección iniciamos el método ConectarIRC() y establecemos que
si el socket se encuentra conectado, lo cerramos. Además, se utiliza la
función try/catch para gestionar las excepciones que puedan presentarse.
public static void ConectarIRC()
try
socket.close();
catch (Exception e)
De igual manera, se hizo uso de un try/catch en esta parte del código,
iniciando la comunicación con el servidor IRC, para luego realizar la
petición al host que aloja el servidor IRC en el puerto 6667. Luego se
asigna la variable out a un método de escritura de datos que va ligado al
socket de salida, almacenando y enviando los parámetros necesarios al
servidor para entablar la comunicación.
try
socket = new Socket(host,6667);
out = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())),true);
Se establece el mensaje de Nickname (predefinido como “BUS-”) más un
número aleatorio para que de esta manera el nick creado sea único si es
la primera vez que el teléfono se conecta, sino conservará el último Nick
utilizado, ya sea el creado por programa o establecido por el programador
vía mensaje privado con el comando “bus Nombre_de_bus”.
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), "bus.txt");
if(file.exists())
String txt1="bus.txt";
nombreBus(txt1);
else
String txt1="bus.txt";
int numero = (int) (Math.random() *1000) + 1;
nick="BUS-"+numero;
grabar(txt1, nick);
nombreBus(txt1);
80
Se especifican los campos del mensaje de usuario, y la petición de acceso
al canal llamado “mychannel”. Finalmente, liberamos los datos contenidos
en el socket y atrapamos las excepciones de las que queremos prescindir.
out.println("NICK "+nick+'\n');
out.println("USER mynick 0 * :Real Name" + '\n');
out.println("JOIN #mychannel" + '\n');
out.flush();
catch(...)
81
Figura 3.16. Diagrama de flujo de conexión al Socket TCP/IP
82
Posteriormente, se presenta la función initializeTimerTask que verifica si
en cada ejecución del timer el socket se encuentra desconectado, en
donde si esta condición es verdadera, realiza la reconexión de la
comunicación indicándola con mensaje Toast.
public void initializeTimerTask()
timerTask = new TimerTask()
public void run()
thandler.post(new Runnable()
public void run()
try
if(!socket.isConnected())
Toasty("Reconectando");
ConectarIRC();
catch(NullPointerException e)
Figura 3.17. Diagrama de flujo de la función TCP/IP del timer
La tarea que se ejecuta cuando se pr esiona el botón “Send” se basa
principalmente en realizar el envío de la cadena de caracteres escrita en
el cuadro de texto principal llamado “txtEdit” en conjunto con la trama de
datos contenedora de las variables a monitorear.
btnSend.setOnClickListener(new View.OnClickListener()
83
@Override
public void onClick(View v)
final EditText txtEdit = (EditText)
findViewById(R.id.txt_inputText);
str=str+"\r\n"+txtEdit.getText().toString();
sendMessageToServer(txtEdit.getText().toString());
et.setText(str);
Una vez que se ejecuta la tarea, el EditText elimina su contenido para
aceptar textos posteriores en el futuro.
txtEdit.setText("");
Se conforma nuevamente la trama con la información a enviar, y se envía
luego al servidor de chat a través del Socket.
trama="$"+Fecha()+";"+bus+";"+nivel+";"+tapa+";"+lat+";"+lon+"%";
tramaText.setText(trama, TextView.BufferType.EDITABLE);
sendMessageToServer(trama);
);
Figura 3.18. Diagrama de flujo del botón 'Enviar'
84
La acción que desencadena el presionar el botón “Trama” consiste en
enviar esta cadena de datos al servidor IRC, mostrarla en el cuadro de
texto “tramaText” y desplegarla en un Toast.
btnTrama.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
trama="$"+Fecha()+";"+bus+";"+nivel+";"+tapa+";"+lat+";"+lon+"%";
sendMessageToServer(trama);
tramaText.setText(trama);
Toasty(trama);
Figura 3.19. Diagrama de flujo del botón 'Trama'
El siguiente extracto de código se encarga de obtener la dirección IP local
que le es asignada al teléfono dentro de una red si se está conectado a la
red y si la dirección no apunta al mismo dispositivo (loopback), donde se
inicia referenciando a la versión de Android mínima que soporta esta API.
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressLint("NewApi")
static String ip() throws SocketException
Enumeration<NetworkInterface> nis =
NetworkInterface.getNetworkInterfaces();
NetworkInterface ni;
while (nis.hasMoreElements()) ni = nis.nextElement();
if (!ni.isLoopback() && ni.isUp()
for (InterfaceAddress ia : ni.getInterfaceAddresses())
//Filtro para detectar si la IP es version 4 o 6
if (ia.getAddress().getAddress().length == 4)
//4 para ipv4, 16 para ipv6
return ia.getAddress().toString();
85
En el siguiente método denominado sendMessageToServer, se realiza el
envío de una cadena String determinada, de forma que al momento de
invocar el método en la sección principal del código se debe definir como
argumento el mensaje que se desea enviar al servidor IRC.
En el método se define nuevamente la variable out, responsable de
realizar la acción de escritura en el socket para con el servidor IRC.
public static void sendMessageToServer(String str)
final String str1=str;
new Thread(new Runnable()
@Override
public void run()
try
out = new PrintWriter(new BufferedWriter(
En la siguiente línea se define el parámetro PRIVMSG, que como
sabemos, le entrega al servidor la información contenida en la variable
String str1 dentro de un mensaje privado.
OutputStreamWriter(socket.getOutputStream())),true);
out.println("PRIVMSG #mychannel :"+str1);
out.flush();
catch (...)
Finalmente, atrapamos las excepciones que puedan causar problemas,
liberamos el socket y con la expresión .start(), iniciamos el funcionamiento
del thread.
).start();
86
En el método receiveMsg() se programa cómo la aplicación recibe los
mensajes provenientes desde el servidor IRC mediante un nuevo Thread
public void receiveMsg()
new Thread(new Runnable()
@Override
public void run()
Para lograr esto, se le asigna a una memoria de lectura de los datos al
socket de entrada.
try
in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
catch (...)
Se ejecutará cíclicamente la recepción de los datos desde el socket.
while(true)
String msg = null;
try
msg = in.readLine();
String comando="";
Si se recibe un mensaje privado desde el servidor,se separa mediante el
delimitador ‘:’, que selecciona qué parte del mensaje corresponde al
remitente y cuál al comando a ejecutar
if(msg.indexOf("PRIVMSG")!=-1)
if(msg.indexOf(":")!=-1)
String[] parts = msg.split(":");
comando=parts[parts.length-1];
remitente=msg.substring(msg.indexOf(":")
+1,msg.indexOf("!"));
87
Posteriormente, sólo si el remitente es igual a “root” se procede a ejecutar
la serie de comandos estipulados en la sección 3.3.4.
if(remitente.equals("root"))
try
Enviar("PRIVMSG "+ remitente+ " :remitente: *"+
remitente+"* comando: *"+ comando+"*");
catch (...)
ProcesarComando(comando);
Del mismo modo, si se recibe un mensaje de PING para verificar si nuestro
bot está activo en el canal, se responde con un mensaje de PONG y lo
notifica por mensaje privado.
else if(msg.indexOf("PING")!=-1)
if(msg.indexOf(":")!=-1)
String[] parts = msg.split(":");
comando=parts[parts.length-1];
try
out = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())),true);
out.println("PONG :"+comando);
out.println("PRIVMSG #mychannel : He recibido un
PING "+comando);
out.flush();
str="";
comando="";
Figura 3.20. Comando PING en ejecución
88
Finalmente, si el mensaje recibido no es nulo se muestra en el cuadro de
texto principal y se inicia el thread.
if(msg == null)
break;
else
displayMsg(msg);
...).start();
Para mostrar la información proveniente desde el servidor IRC a manera
de poder visualizar lo que ocurre momento a momento, se ejecuta el
método displayMsg. Este método toma desde un objeto Handler la
información proporcionada por el socket que realiza la conexión, y en un
nuevo hilo muestra estos datos en el cuadro de texto principal llamado “et”.
public void displayMsg(String msg)
final String mssg=msg;
handler.post(new Runnable()
@Override
public void run()
str=str+"\n\r>"+mssg;
et.setText(str);
Como última tarea del método, se baja hasta el final del EditText a medida
que se van actualizando los datos.
int position = et.getText().length();
Editable editObj= et.getText();
Selection.setSelection(editObj, position);
El siguiente método que lleva por nombre Enviar, realiza el envío de
mensajes privados al usuario root, siendo utilizado ampliamente para el
uso de comandos.
89
public static void Enviar(String txt)
try
out = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())),true);
out.println(txt);
out.flush();
catch(...)
Los permisos requeridos para la ejecución del bloque de TCP/IP se
encuentran en el Android Manifest, siendo éstos precisamente los que se
muestran en la Figura 3.21.
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name =
"android.permission.WRITE_EXTERNAL_STORAGE"/>
Figura 3.21. Permisos requeridos para la función TCP/IP
SOCKET BLUETOOTH
En este apartado, se analizará el término de socket como la comunicación
bidireccional bajo la tecnología Bluetooth, específicamente entre el módulo
HC-06 conectado al Arduino MEGA y el teléfono móvil con la aplicación
Android que gestiona la conexión.
90
MÓDULO BLUETOOTH HC-06
Para que el microcontrolador transfiera la información adquirida hasta el
teléfono móvil se utilizó el módulo Bluetooth HC-06, que consiste en un
dispositivo periférico que debe ir conectado por puerto serie al Arduino
MEGA para coordinar el envío de esta información a través de este
protocolo inalámbrico (Jing, Zhang, Arce, & Farajidavar, 2014) . El
hardware del dispositivo presenta cuatro pines que tienen las funciones
que se detallan a continuación:
1) RX: Pin desde donde se reciben los datos que serán enviados al
Smartphone desde el puerto serial del microcontrolador a 9600
baudios de velocidad de transmisión. (PIN 16 RX2 ARDUINO MEGA)
2) TX: Pin desde donde se envían datos al Arduino desde el
Smartphone si se requiere realizar una comunicación bidireccional.
La velocidad de transmisión de igual manera es a 9600 baudios.
(PIN 17 TX2 ARDUINO MEGA)
3) GND: Pin conectado al GND del microcontrolador.
4) VCC: Pin de alimentación que irá conectado a la salida de 5V en c.c.
entregada por el microcontrolador.
Figura 3.22. Conexión HC-06 al microcontrolador Arduino MEGA
91
LISTADO DE FUNCIONES
Los métodos que se utilizan para el bloque de la comunicación Bluetooth
se mencionan en la siguiente tabla y representan las distintas fases que
toma el proceso de conexión con el módulo HC-06.
Método Función
Handler BluetoothIn Maneja la trama recibida desde el microcontrolador y la
procesa para obtener las variables de forma separada,
agregándolas a la trama.
initializeTimerTask() Inicia el conjunto de tareas que se ejecutarán con cada
ciclo del timer
onResume() Crea la conexión Bluetooth con el módulo y verifica si la
conexión se encuentra establecida
checkBTState() Chequea el estado del adaptador Bluetooth, es decir, si se
encuentra apagado, encendido, inhabilitado, etc.
ConnectedThread… Thread que crea los sockets de entrada y salida y se
mantiene constantemente leyendo la trama proveniente
desde el módulo BT.
createBluetoothSocket(…) Método que crea el objeto que permite la conexión con el
módulo.
write(…) Método que permite la escritura de datos desde la
aplicación hacia el módulo para la comprobación de la
conexión.
BroadcastReceiver() Función que detecta el estado actual de la conexión
Bluetooth, es decir, si está o no conectada gatilla distintos
eventos.
Tabla 3.3. Listado de funciones del Socket Bluetooth
92
FUNCIONAMIENTO DEL MICROCONTROLADOR
Figura 3.23. Diagrama de flujo del funcionamiento del Microcontrolador
93
El programa desarrollado en la tarjeta Arduino que se encarga de realizar
la tarea de adquisición de datos comienza con la inicialización de las
variables globales.
const int analogInPin0 = A0;
int digitalSensor = 22;
int estado = 0;
float sensorValue = 0;
float voltageValue = 0;
Variable Función
cons int analogInPin0 Variable que define el sensor analógico en el
pin A0 del Arduino
int digitalSensor Variable que define el sensor digital en el pin
22 del Arduino
int estado Inicializamos en cero la variable leída del
sensor digital
float sensorValue Variable que almacena el valor leído desde el
sensor en un rango de 0 a 1024.
float voltageValue Variable que escala el valor leído desde el
sensor a un rango de 0 a 5 volts.
Tabla 3.4. Variables del microcontrolador
Se establece el método de inicialización del Arduino y se especifica
el puerto serie a utilizar, siendo en este caso el Serial 2 en los pines 16
(RX2) y 17 (TX2) a una velocidad de transmisión de 9600 baudios.
void setup()
Serial2.begin(9600);
Una vez que se establece la conexión, se notifica a través del puerto serie
y se define la variable asignada al sensor digital como entrada.
Serial2.println("Conectado");
pinMode(digitalSensor,INPUT);
94
Luego, se comienza el ciclo principal que realiza la extracción de los datos
de forma contínua, comenzando por asignar a la variable estado el valor
leído desde el sensor digital si el puerto serie se encuentra disponible.
void loop()
if(Serial2.available()>0)
estado=digitalRead(digitalSensor);
El siguiente paso es invocar a los métodos que leen y escalan los valores
de los transductores y los envían por el puerto serial al módulo Bluetooth
HC-06, finalizando con un tiempo de espera de 2 segundos entre cada
medición.
readSensor();
getVoltageValue();
sendAndroidValues();
delay(2000);
Para leer los datos desde el sensor analógico se ejecuta el método llamado
readSensor y que guarda el valor leído desde el sensor análogo en la
variable sensorValue, obteniendo un valor que va desde 0 a 1023
directamente relacionado con la conversión desde 0 a 5 V que realiza el
convertidor análogo-digital del microcontrolador, con una resolución de 10
bits.
void readSensor()
sensorValue = analogRead(analogInPin0);
La función sendAndroidValues, como su nombre lo indica, envía la
información completa de las lecturas de ambos sensores a través de una
única trama de datos. Primero, establece un delimitador de inicio con el
símbolo “#”. Después anexa el valor del sensor analógico ya escalado a
95
niveles de voltaje, es decir, de 0 a 5, el cual concatena con el símbolo “+”
y agrega el valor del sensor digital. Finaliza con un delimitador dado por el
símbolo “~”, un salto de línea y un delay de 10 ms.
void sendAndroidValues()
Serial2.print('#');
Serial2.print(voltageValue);
Serial2.print('+');
Serial2.print(estado);
Serial2.print('~');
Serial2.println();
delay(10);
La última función que realiza el microcontrolador es la de escalar el valor
leído desde el sensor análogo, el que es convertido por el ADC a un
número en el rango de 0 a 1023. Este método es sumamente útil para
visualizar la variable analizada en lugar del valor de conversión entregado
por el ADC, estando en este caso en unidades de voltaje desde 0 a 5 volt.
void getVoltageValue()
voltageValue = ((sensorValue/1023)*5);
96
CÓDIGO ANDROID (BLUETOOTH)
Figura 3.24. Diagrama de flujo de la función Bluetooth
97
Las variables globales para esta función se muestran a continuación:
TextView txtString;
Handler bluetoothIn;
final int handlerState = 0;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
private static final UUID BTMODULEUUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
<tipo> Variable Función
Textview txtString Variable asignada al cuadro de texto que muestra la trama
recibida desde el módulo Bluetooth
Handler bluetoothIn Gestiona el traspaso de información entre el thread que
recibe los datos y la interfaz gráfica
int handlerState Variable que actúa como identificador del mensaje que
gestiona el handler.
BluetoothAdapter
btAdapter
Representa al dispositivo Bluetooth del teléfono
propiamente tal.
BluetoothSocket
btSocket
Representa a la conexión existente entre el teléfono y un
dispositivo Bluetooth
StringBuilder
recDataString
Objeto que actúa como una cadena de caracteres con la
cual es posible concatenar los elementos de forma continua
y dinámica, sin importar su longitud.
ConnectedThread
mConnectedThread
Variable asociada al hilo de conexión del socket Bluetooth.
Con esta variable es posible iniciar o detener dicho thread.
UUID BTMODULE UUID UUID (Identificador Único Universal) es una cadena
numérica única de 16 bytes que representa exclusivamente
la comunicación Bluetooth en un dispositivo Android
deviceName Especifica el nombre del módulo Bluetooth al que se
conectará el teléfono.
deviceMAC Especifica la dirección física del módulo Bluetooth al que se
conectará el teléfono.
Tabla 3.5. Variables Bluetooth
98
Comenzamos el código perteneciente al bloque de comunicación
Bluetooth con dos IntentFilters asociados a un BroadcastReceiver que se
explicará detalladamente más adelante. Su función es la de almacenar en
estas respectivas variables el estado actual de la conexión del socket
Bluetooth, es decir, si se encuentra conectado o desconectado.
IntentFilter filter1 = new
IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
IntentFilter filter3 = new
IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiver, filter1);
this.registerReceiver(mReceiver, filter3);
El siguiente método que nos encontramos corresponde al que está
asociado directamente con la tarea del Handler, el cual trae la información
obtenida por el Thread, la anexa a una nueva cadena de caractere y
muestra en el txtString la trama contenida en el mensaje hasta que se
encuentra con el delimitador de fin de línea (~).
bluetoothIn = new Handler()
public void handleMessage(android.os.Message msg)
try
String readMessage = (String) msg.obj;
recDataString.append(readMessage);
int endOfLineIndex =
recDataString.indexOf("~");
if (endOfLineIndex > 0)
String dataInPrint = recDataString.substring(0,
endOfLineIndex);
txtString.setText("Datos recibidos = " +
dataInPrint);
Finalmente, separa los valores de cada sensor y vacía la cadena de caracteres creada.
if (recDataString.charAt(0) == '#')
nivel = recDataString.substring(1, 5);
99
tapa = recDataString.substring(6, 7);
recDataString.delete(0,
recDataString.length());
dataInPrint = " ";
catch(...)
Se define el objeto btAdapter como la representación del adaptador
Bluetooth propio del teléfono móvil y se chequea el estado actual de éste,
en otras palabras, si está apagado o no.
btAdapter = BluetoothAdapter.getDefaultAdapter();
checkBTState();
Se define un método que crea el objeto que representa al socket Bluetooth.
Este método requiere que se le entregue una variable representativa del
dispositivo Bluetooth al cual nos conectaremos, además utiliza la variable
global BTMODULEUUID que definimos anteriormente.
private BluetoothSocket createBluetoothSocket(BluetoothDevice
device) throws IOException
return
device.createRfcommSocketToServiceRecord(BTMODULEUUID);
El método onResume()1 es ejecutado al momento en que la aplicación va
a comenzar a interactuar con el usuario a través de la GUI, además de las
veces que es invocado por las tareas cíclicas del Timer y del Broadcast
Receiver cuando el socket se desconecta.
Se comienza por buscar los dispositivos Bluetooth activos en el entorno.
@Override
public void onResume()
super.onResume();
BluetoothDevice result = null;
1 http://droideando.blogspot.cl/2011/02/ciclo-de-vida-de-una-aplicacion-android.html
100
Set<BluetoothDevice> devices =
btAdapter.getBondedDevices();
Posteriormente, verifica si se encuentra el módulo Bluetooth al que nos
conectaremos, comparando el nombre y la dirección física de referencia
que están especificadas en el programa.
if (devices != null)
for (BluetoothDevice device : devices)
if(deviceName.equals(device.getName())&&(deviceMAC.eq
uals(device.getAddress())))
result = device;
break;
else if(devices==null)
try
catch(...)
Una vez que se ha encontrado el dispositivo al cual nos conectaremos, se
creará un nuevo socket Bluetooth.
try
btSocket = createBluetoothSocket(result);
catch (...)
Toast.makeText(getBaseContext(), "Fallo en la
creación del Socket", Toast.LENGTH_LONG).show();
catch(...)
101
Luego, se realiza la conexión del socket Bluetooth. Si se genera alguna
excepción en esta tarea, el socket se cerrará automáticamente.
try
btSocket.connect();
catch(...)
try
btSocket.close();
catch (...)
Se crea e inicia el hilo encargado de realizar conexión mediante sockets y
la obtención de datos desde el HC-06.
try
mConnectedThread = new ConnectedThread(btSocket);
catch (...)
mConnectedThread.start();
Conforme a lo anterior, se ejecuta el envío de un mensaje de prueba al
módulo Bluetooth para comprobar si efectivamente la comunicación está
operativa. En caso contrario, se notificará al sistema Android y se atrapará
la excepción mediante un try/catch.
try
mConnectedThread.write("x");
catch (...)
El método checkBTState(), como su nombre lo indica, chequea el estado
actual del adaptador Bluetooth para solicitar al usuario la activación de
éste si se encontrase apagado. En caso contrario, no realiza ninguna
acción y continúa con el programa. Si no se encontrase adaptador
Bluetooth en el dispositivo, lo notifica con un Toast.
102
private void checkBTState()
if(btAdapter==null)
Toast.makeText(getBaseContext(), "El dispositivo no soporta
BT", Toast.LENGTH_LONG).show();
else
if (btAdapter.isEnabled())
else
Intent enableBtIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
El subproceso que lleva por nombre ConnectedThread, primero crea un
socket de entrada y uno de salida para establecer una comunicación
bidireccional entre ambas partes.
private class ConnectedThread extends Thread
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket)throws
IOException
InputStream tmpIn = null;
OutputStream tmpOut = null;
try
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
catch (...)
mmInStream = tmpIn;
mmOutStream = tmpOut;
103
Lo siguiente que realiza este Thread, es ejecutar en segundo plano la
obtención de datos de forma continua, es decir, todo el tiempo estará
tomando y enviando al handler las muestras recibidas desde Arduino y su
modulo HC-06.
public void run()
byte[] buffer = new byte[256];
int bytes;
while (true)
try
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0,
bytes);
bluetoothIn.obtainMessage(handlerState, bytes,
-1, readMessage).sendToTarget();
catch (...)
break;
En esta función se abre la posibilidad de escribir mensajes en el socket de
salida hacia microcontrolador, ya sea para comprobar si la comunicación
está establecida o para otros fines prácticos.
public void write(String input) throws IOException
byte[] msgBuffer = input.getBytes();
mmOutStream.write(msgBuffer);
El Broadcast Receiver es una herramienta que se comentó anteriormente,
tiene la facultad de identificar los cambios de estado en la conexión
Bluetooth entre el teléfono y otro dispositivo, permitiendo realizar
diferentes acciones cuando el socket se desconecta o en su caso
contrario. En este caso, si el socket se desconecta, lo notifica a través de
un Toast, de un mensaje al servidor IRC y además cambia el estado de
las variables asociadas a los sensores analógico y digital, interpretando
104
que si se desconectase el HC-06, el valor medido no corresponde a ningún
número (NaN).
public final BroadcastReceiver mReceiver = new
BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))
Toasty("BT is disconnected
sendMessageToServer("BT is disconnected");
nivel="NaN";
tapa="NaN";
onResume();
else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED))
Toasty("BT is connected");
sendMessageToServer("BT is connected");
;
ELEMENTOS DE PROCESAMIENTO
COMANDOS
Para obtener información en tiempo real desde los buses de la flota, a
través de un sistema fácilmente accesible se asignó mediante código una
serie de comandos que permiten al programador extraer datos importantes
desde el teléfono, como la fecha, la localización, entre otros. Funcionando
como una especie de sistema operativo accesible desde cualquier cliente
IRC que pueda al servidor IRC de la Raspberry Pi. Los comandos que es
posible ingresar para obtener resultados se detallan en la siguiente tabla:
105
Comando Función
fecha Entrega la fecha y hora exacta al momento de hacer la
petición
dir Muestra al usuario las carpetas y archivos almacenados
en el directorio actual del teléfono.
gps Entrega las coordenadas geográficas actuales del
vehículo.
bus+nombre_del_bus Establece el nombre deseado al bus consultado,
sobrescribiendo el que trae por defecto.
nivel Indica el nivel de combustible actual medido por el sensor
analógico
tapa Entrega la posición actual de la tapa determinada por el
estado del sensor digital.
direccion Indica la dirección domiciliaria aproximada en la que se
encuentra ubicado el móvil actualmente.
Tabla 3.6. Comandos para la obtención de datos
CÓDIGO PARA LA FUNCIÓN DE COMANDOS
El método que establece las reglas predefinidas que el programa debe
seguir si el usuario ingresa algunos de los comandos establecidos
anteriormente se detalla a continuación, en donde se comienza con extraer
desde el argumento el comando ingresado, comparándolo y devolviendo
una cadena de caracteres que contiene la información requerida.
public static void ProcesarComando(String cmd)
String[] cmdparts = cmd.split(" ");
String comando=cmdparts[0];
106
Si se ingresa el comando fecha, se retorna la fecha y hora del sistema al
momento de efectuada la consulta a través del método Fecha().
if(comando.equals("fecha"))
Enviar("PRIVMSG "+ remitente +" : fecha-hora sistema: "+
Fecha());
El método Fecha() devuelve una variable de tipo String que almacena la
fecha y hora del sistema. Se obtiene a través de la librería java.util.Date().
public static String Fecha()
FechaHora =(DateFormat.format("ddMMyy;HHmmss", new
java.util.Date()).toString());
return FechaHora;
Si se ingresa el comando dir, se ejecuta el método dir() que retorna el
nombre de los archivos y carpetas que se encuentran en el directorio raíz
del teléfono. Esta función trata de emular la que realiza la misma función
en los sistemas operativos de computadoras.
if(comando.equals("dir"))
dir();
La función dir() comienza definiendo dos variables asociadas a los
archivos que se mostrarán como parte de la carpeta principal del
Smartphone para luego obtener los nombres de todos los archivos y
subcarpetas presentes en el directorio hasta que no existan más
elementos para mostrar.
107
public static void dir()
File f = new
File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/");
File[] files = f.listFiles();
try
for (int i = 0; i < files.length; i++)
File file = files[i];
if (!file.isDirectory())
Enviar("PRIVMSG "+ remitente+ " : *"+ "-"+file.getName());
catch(...)
Variable Función
File f Define cada archivo que se localizará dentro del directorio raíz de Android.
File[] files Crea una lista modificable con los nombres de los archivos encontrados.
Tabla 3.7. Variables del metodo dir ()
Si se ingresa el comando nivel, se retorna en este caso el valor actual
obtenido desde el sensor analógico.
if(comando.equals("nivel"))
try
Enviar("PRIVMSG "+ remitente+ " : Nivel: "+ nivel);
catch(...)
Si se ingresa el comando tapa, se obtiene el valor actual del sensor digital,
indicando que si es igual a cero, la tapa está Abierta. En caso contrario,
estará Cerrada si es igual al valor 1.
if(comando.equals("tapa"))
try
if(tapa.equals("0"))
Enviar("PRIVMSG "+ remitente+ " : Posicion de
la tapa: Abierta");
else
Enviar("PRIVMSG "+ remitente+ " : Posicion de
la tapa: Cerrada");
catch(...)
108
Si se ingresa el comando direccion, se visualiza la dirección aproximada
en la que se encuentra la máquina. Esta acción se realiza a través de una
función especial proveniente del método que obtiene las coordenadas del
GPS.
if(comando.equals("direccion"))
try
Enviar("PRIVMSG "+ remitente+ " :"+ direccion);
catch(...)
Al Igual que el comando dirección, la variable lat y lon están definidas en
el método de obtención de las coordenadas geográficas del Smartphone
que entraremos a ver en detalle en la siguiente sección.
if(comando.equals("gps"))
try
Enviar("PRIVMSG "+ remitente+ " : LAT="+ lat+" LON="+lon);
catch(...)
Finalmente, si se ingresa el comando bus acompañado por un nombre a
elección, el cliente IRC del teléfono cambia su nickname en el canal. Este
procedimiento comienza extrayendo este nuevo nombre, notificándolo a
través del socket con un mensaje de chat, y guardándolo en un archivo de
texto con el método grabar().
if(comando.equals("bus"))
bus=cmd.substring(cmd.indexOf(' ')+1,cmd.length());
try
Enviar("PRIVMSG "+ remitente+ " : bus="+bus);
String txt1="bus.txt";
String contenido = bus;
nick=bus;
out.println("NICK "+nick);
grabar(txt1, contenido);
catch(...)
109
Cuando la aplicación Android se inicia, leerá el archivo bus.txt creado por
el método nombreBus(). Se utilizará el nombre que esté escrito en la
última línea si no es la primera vez que y ese archivo existe. En caso
contrario, se asumirá un nuevo nombre que incorporará un número
aleatorio que evita la duplicidad de los nicks.
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), "bus.txt");
if(file.exists())
String txt1="bus.txt";
nombreBus(txt1);
else
String txt1="bus.txt";
int numero = (int) (Math.random() *1000) + 1;
nick="BUS-"+numero;
grabar(txt1, nick);
nombreBus(txt1);
Este método crea un nuevo archivo en la memoria del teléfono y escribe
en éste el texto que sea ingresado como argumento, para este caso, el
nombre propuesto por el programador mediante el mensaje de chat.
public static void grabar(String archivo, String txt)
try
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), archivo);
OutputStreamWriter osw = new
OutputStreamWriter(new
FileOutputStream(file,true));
BufferedWriter fbw = new BufferedWriter(osw);
fbw.write(txt);
fbw.newLine();
fbw.close();
catch (...)
110
El funcionamiento de este método comienza localizando un archivo en la
memoria interna del teléfono con el nombre especificado en el argumento.
public static void nombreBus(String txt)
File tarjeta = Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(), txt);
Luego, se leerá el archivo almacenando el contenido en un Buffer.
try
FileInputStream fIn = new FileInputStream(file);
InputStreamReader archivo = new InputStreamReader(fIn);
BufferedReader br = new BufferedReader(archivo);
String linea = br.readLine();
String todo = "";
String lineafinal = "";
Si se llega al final del archivo al momento de efectuar la lectura, se extrae
la última línea que contiene el último nombre de bus utilizado.
while (linea != null)
todo = todo + linea + "";
lineafinal=linea;
linea = br.readLine();
Finalmente, se asignará el valor extraído a la variable bus que indica el
nombre del bus en la trama. Acto seguido, se asigna el mismo nombre
como nuevo nick en el canal de chat.
bus=lineafinal;
nick=bus;
br.close();
archivo.close();
catch (IOException e)
111
GPS
Como una de las piezas claves de este proyecto es el geoposicionamiento
de la flota, es necesario utilizar el sistema GPS incorporado en el teléfono,
por lo que para hacer uso de él, primero debemos conferirle en el Android
Manifest los permisos de uso requeridos.
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission
android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/
>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.INTERNET"/>
Posteriormente, se crea el método setLocation que obtiene una lista de
direcciones cercanas al punto geográfico en donde se localiza el
dispositivo Android si la dirección es diferente de ‘0.0, 0.0’.
public void setLocation(Location loc)
if (loc.getLatitude() != 0.0&&loc.getLongitude() != 0.0)
try
Geocoder geocoder = new Geocoder(this,
Locale.getDefault());
List<Address> list = geocoder.getFromLocation(
loc.getLatitude(), loc.getLongitude(), 1);
Si la lista no está vacía, se guarda el primer elemento de esta lista en la
variable direccion.
if (!list.isEmpty())
Address address = list.get(0);
direccion=("Mi direccion es: "+
address.getAddressLine(0));
catch(...)
112
Esta clase que incorpora un LocationListener, funciona como un radar que
constantemente está atento ante los cambios de localización del GPS,
pudiendo realizar acciones ante tales eventos.
public class MyLocationListener implements LocationListener
MainActivity mainActivity;
public MainActivity getMainActivity()
return mainActivity;
public void setMainActivity(MainActivity mainActivity)
this.mainActivity = mainActivity;
Se obtiene el valor de la latitud y la longitud desde el método que detecta
cuándo la localización cambia.
@Override
public void onLocationChanged(Location loc)
lat=(double)loc.getLatitude();
lon=(double)loc.getLongitude();
String Text = "ubicacion: Lat= "+ loc.getLatitude() +
" Lon= " + loc.getLongitude();
gpsText.setText(Text);
this.mainActivity.setLocation(loc);
Esta clase también posee varios métodos que actúan cuando el GPS pasa
por distintos estados (desactivado, activado, fuera de servicio, etc), de los
cuales se utiliza solamente el que detecta cuando éste se encuentra
desactivado y cuándo ha cambiado la coordenada geográfica.
@Override
public void onProviderDisabled(String provider)
gpsText.setText("GPS Desactivado");
@Override
public void onProviderEnabled(String provider)
113
@Override
public void onStatusChanged(String provider, int status,
Bundle extras)
Para finalizar con esta funcionalidad, se crea una referencia a la clase
principal en el método onCreate() que inicializa todas las variables y
funciones principales de nuestro programa, para así llamar desde el
Listener al método setLocation() que envía la latitud y la longituid hacia los
campos de texto, los comandos y la trama propiamente tal.
LocationManager mlocManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
MyLocationListener mlocListener = new MyLocationListener();
mlocListener.setMainActivity(this);
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 0,(LocationListener) mlocListener);
IP
Otra funcionalidad de la aplicación es mostrar en un campo de texto la
dirección IP que se le asigna al teléfono dentro de una red local.
try
IPText.setText(ip());
catch (...)
Lo anterior se consigue con el método ip(), que retorna en una variable de
tipo String la dirección IP del teléfono móvil, solamente si existe una
conexión a la red.
114
Se crean las interfaces de red de las que se extraerá la dirección IP.
static String ip() throws SocketException
Enumeration<NetworkInterface> nis =
NetworkInterface.getNetworkInterfaces();
NetworkInterface ni;
Mientras haya elementos dentro de la lista de interfaces de red, se
analizará elemento a elemento para extraer la dirección.
while (nis.hasMoreElements())
ni = nis.nextElement();
if (!ni.isLoopback() && ni.isUp()*/)
for (InterfaceAddress ia :
ni.getInterfaceAddresses())
Se crea un filtro que discrimina si la dirección de red es version 4 o version
6, siendo ‘4’ para IPv4 Y ‘6’ para IPv6.
if (ia.getAddress().getAddress().length == 4)
//4 para ipv4, 16 para ipv6
return ia.getAddress().toString();
INICIO CON BOOT DE ANDROID
Para que la aplicación pueda iniciarse conjuntamente con el sistema
operativo del teléfono en caso de que éste tenga que ser forzado al
reinicio, implementamos un BroadcastReceiver que estará a la escucha de
esta situación, de modo que si ocurre el evento, lanzará la aplicación
instantáneamente (Pozo, 2013).
Los pasos para implementar esta operación en una aplicación Android son
los siguientes:
1) Como primer paso, debemos otorgarle permisos a la aplicación
para que pueda ejecutarse al momento que Android se inicie. Esto
115
lo hacemos abriendo el AndroidManifest.xml y agregando la
siguiente línea de código:
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2) Después debemos agregar en el mismo archivo al Receiver que
lanzará la aplicación agregando las siguientes líneas:
<receiver android:name=".BootReciever">
<intent-filter >
<action
android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
3) El tercero y último paso es crear una nueva Activity en nuestro
proyecto que lanzará un Intent con la Activity del programa que
deseamos ejecutar al inicio.
public class BootReciever extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
Intent myIntent = new Intent(context,
MainActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
116
INTERFAZ GRÁFICA
Una parte sumamente importante de una aplicación Android es su interfaz
gráfica, la cual representa cómo se podrá interactuar con el programa en
un entorno visual que debe resultar amigable para el usuario. La interfaz
gráfica o GUI, se puede programar mediante código en el archivo
/res/layout/activity_main.xml o gráficamente a través de la inserción de
elementos con el puntero del mouse, emulando un poco la programación
en Visual Basic.
Figura 3.25. Diseño de la interfaz gráfica
En el código de la GUI, primero nos encontramos con la especificación de
una serie de atributos que definirán las propiedades de la interfaz, como
por ejemplo la orientación, el tamaño, entre otros elementos. Muy
importante es mencionar que el identificador que posee la interfaz para ser
invocada desde la MainActivity se localiza en el atributo android:id.
117
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
Ahora definiremos los elementos que contendrá nuestra interfaz gráfica,
indicando atributos para cada uno como su identificador, altura y para el
caso de los botones, el texto que presentarán. Se presenta un primer
layout que contiene los objetos de la Tabla 3.8 ordenados de manera
horizontal.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btn_Trama"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Trama" />
<Button
android:id="@+id/btn_Send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.18"
android:text="Send" />
<EditText
android:id="@+id/txt_inputText"
android:layout_width="116dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:text="-" />
</LinearLayout>
118
<tipo> Objeto Función
Button btn_Trama Si se presiona, envía la trama de datos al
servidor IRC.
Button btn_Send Al presionarse, envía al servidor IRC un
mensaje escrito por el usuario acompañado
de la trama de datos.
EditText txt_inputText En este cuadro de texto el usuario escribe el
mensaje deseado a enviar al servidor de chat.
Tabla 3.8. Elementos del primer layout
De la misma manera, se presenta un segundo layout que ordena también
de forma horizontal los elementos alcanzados en la Tabla 3.9.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:id="@+id/IPText"
android:layout_width="114dp"
android:layout_height="29dp"
android:ems="10"
android:textSize="8sp" />
<EditText
android:id="@+id/gpsText"
android:layout_width="match_parent"
android:layout_height="29dp"
android:layout_weight="1"
android:ems="10"
android:textSize="8sp" >
<requestFocus />
</EditText>
</LinearLayout>
119
<tipo> Objeto Función
EditText IPText En este cuadro de texto se muestra la
dirección IP local del teléfono en la red.
EditText gpsText En este campo de texto se puede visualizar la
latitud y longitud instantáneas obtenidas
desde el GPS del teléfono.
Tabla 3.9. Elementos del segundo layout
Finalmente, aparece en escena un tercer layout que es el principal y que
estructura de manera vertical los elementos especificados en la tabla 3.10.
<EditText
android:id="@+id/tramaText"
android:layout_width="match_parent"
android:layout_height="29dp"
android:ems="10"
android:textSize="8sp" />
<TextView
android:id="@+id/txtString"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.13"
android:ems="10"
android:gravity="bottom"
android:textSize="7sp"
/>
</LinearLayout>
120
<tipo> Objeto Función
EditText tramaText Permite visualizar la trama de datos que se
enviará al servidor IRC.
TextView txtString Muestra la trama con los datos de los
sensores, recibida desde el módulo Bluetooth.
EditText editText1 Es el cuadro de texto principal, y en él se
muestra todo el contenido del chat IRC, tanto
cadenas recibidas como enviadas.
Tabla 3.10. Elementos del tercer layout
Figura 3.26. Detalle de la interfaz gráfica
121
RASPBERRY PI
En la microcomputadora Raspberry Pi mantendremos operativo el servidor de
chat IRC que es el medio de traspaso de los datos, un cliente IRC programado
en el lenguaje Java que actuará como puente entre el chat y una base de datos
MySQL también alojada dentro de la Raspberry Pi. Para acceder a la Raspberry
Pi lo realizaremos a través del protocolo Secure Shell (SSH) con el programa
PuTTy por el puerto 22 de la microcomputadora. Del mismo modo, es necesario
asignarle a la Raspberry Pi una IP fija dentro de la red local para acceder siempre
a la misma dirección por SSH y para que de esta manera el enrutador utilizado
(TP-LINK TL-WR740N) redirija el acceso desde un nombre de dominio dinámico
proporcionado por el sitio No-IP, el cual se mantendrá fijo a pesar de que la IP
pública cambie.
Figura 3.27. Raspberry Pi conectada al router
122
Figura 3.28. Router TP-LINK TL-WR740N
IP ESTÁTICA
Lo primero que hay que realizar en nuestra Raspberry Pi es asignarle una
IP estática dentro de la red local para que de esta manera, pueda ser
accesible todo el tiempo, ya que el enrutador por defecto le va asignando
distintas direcciones IP en el tiempo, provocando incertidumbre a la hora
de realizar la conexión vía SSH.
Para ejecutar la consigna anterior, debemos primero acceder al archivo de
configuración de red de la Raspberry Pi con el comando (neil-black.co.uk,
2015):
sudo nano /etc/network/interfaces
En este fichero, deberemos de configurar el campo address que
corresponde a la dirección IP que se quiere asignar, siendo para este caso
dada como 192.168.1.206. Los parámetros network y gateway
123
corresponden a la dirección IP del enrutador y de la máscara de subred
respectivamente.
Figura 3.29. Parámetros de red de la Raspberry Pi
ACCESO SSH
INSTALACIÓN
Al momento de utilizar por primera vez la Raspberry Pi, es necesario contar
con un mouse, un teclado y una pantalla para visualizar todo el proceso
de configuración e instalación. No obstante, luego de dejarla operativa ya
no será necesaria depender de estos elementos, ya que podremos
manejar la microcomputadora de forma remota a través del protocolo de
comunicaciones Secure Shell, necesitando únicamente la IP estática
asignada a la Raspberry Pi y habilitar este servicio dentro de la misma
(Bejarano, 2013).
Para instalar SSH dentro de la tarjeta debemos insertar el siguiente
comando:
sudo apt-get install ssh
124
Luego, será necesario iniciar el servicio a través de la siguiente sentencia:
sudo /etc/init.d/ssh start
Para finalizar, ingresamos la siguiente línea para que Secure Shell se
ejecute automáticamente al iniciar la microcomputadora:
sudo update-rc.d ssh defaults
PUTTY
Para acceder a la Raspberry Pi remotamente desde Windows, debemos
utilizar el programa PuTTy que es un cliente SSH para este sistema
operativo. Se descarga desde su web oficial (http://www.putty.org) y se
ejecuta inmediatamente sin necesidad de instalación.
Figura 3.30. Ícono de PuTTy
Iniciado ya el programa, se despliega la ventana principal en donde
deberemos insertar el nombre del servidor, el protocolo de comunicación
y el puerto de comunicaciones. Para este proyecto los parámetros
utilizados son:
125
Figura 3.31. Ventana principal de PuTTy
Parámetros
Servidor 192.168.1.206
Protocolo SSH
Puerto 22
Tabla 3.11. Parámetros de conexión SSH
Con los parámetros configurados se pulsa el botón Open y se abre un
terminal de comandos que pedirá el usuario y la contraseña de acceso
para la Raspberry Pi, donde una vez ingresados se da por iniciada la
sesión en la microcomputadora.
126
Figura 3.32. Terminal SSH
REDIRECCIÓN DE PUERTOS
Para acceder remotamente desde fuera de la red de área local donde la
Raspberry Pi está conectada, es necesario abrir un puerto en el enrutador
para luego redireccionarlo a un puerto específico de esta computadora
portátil (CyberAdmin Pro, 2011). Esto se realiza entrando a la
configuración del router mediante el navegador web con la dirección
192.168.1.1 e ingresando el nombre de usuario y contraseña requeridos,
abriéndose su ventana principal.
Figura 3.33. Página de inicio del router
127
Nos dirigimos al menú Forwarding que es donde configuraremos los
puertos a utilizar, presionamos el botón Add New e ingresamos los
parámetros de cada puerto a abrir.
Figura 3.34. Parámetros para la redirección de puertos
Configurados ya los puertos podemos ver que, efectivamente, se
encuentran plenamente configurados y listos para ser utilizados. En la
Tabla 3.12 se definen los puertos que se han configurado.
Figura 3.35. Puertos abiertos en el router
128
Puerto Función
53 DNS. Resolución de nombres de dominio para
el servicio No-IP.
21 FTP. Transferencia de archivos hacia y desde
la Raspberry Pi
80 HTTP. Protocolo de transferencia de
hipertexto, propio del servicio de sitios web.
22 SSH. Protocolo de acceso para computadoras
a través de una red.
3306 MySQL. Puerto de acceso desde y hacia la
base de datos MySQL.
6667 IRC. Puerto de acceso del servidor de chat
IRC.
Tabla 3.12. Puertos abiertos en el router
DNS DINÁMICA
Una DNS dinámica consiste en un nombre de dominio estático que está
referido a una dirección IP pública dinámica, la cual cambia en el tiempo,
por lo que sin esta herramienta sería imposible de acceder a la Raspberry
Pi desde fuera de la red de área local. Lo primero que debemos hacer es
crear un nuevo nombre de dominio en el sitio http://www.noip.com y
posteriormente, instalar el paquete No-IP para la microcomputadora con
el siguiente código (HumanLinks, 2011):
mkdir no-ip
cd no-ip
wget http://www.no-ip.com/client/linux/noip-duc-
linux.tar.gz
tar -zxvf noip-duc-linux.tar.gz
cd noip-2.1.9-1/
make
sudo make install
129
Se crea el archivo que contendrá los parámetros para el arranque del
servicio al iniciar la Raspberry Pi.
sudo nano /etc/init.d/noip2
#! /bin/bash
### BEGIN INIT INFO
# Provides: Servicio No-IP
# Required-Start: $syslog
# Required-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: arranque automatico para no-ip
# Description:
#
### END INIT INFO
sudo /usr/local/bin/noip2
Se guarda el archivo anterior y se agrega a la cola de arranque de la
Raspberry Pi. Ahora sólo resta configurar el Dynamic DNS en el enrutador
y se dará por finalizado este proceso.
sudo chmod +x /etc/init.d/noip2
sudo update-rc.d noip2 defaults
Como se mencionó anteriormente, falta por configurar el DNS Dinámico
en el enrutador, para que de esta manera sea posible entablar
comunicación desde el servicio No-IP con el dominio registrado
(http://fserranovargas.no-ip.org) hasta el equipo que necesitará el
redireccionamiento, en este caso, nuestra Raspberry Pi.
Para llevar a cabo lo estipulado en el párrafo anterior y estando dentro de
la interfaz de configuración del router, debemos dirigirnos a la opción
Dynamic DNS del menú principal, en donde debemos de ingresarlos datos
que ingresamos al momento de efectuar el registro en el sitio de No-IP.
130
Figura 3.36. Configuración del DDNS
Con lo anterior, la Raspberry Pi ya se encuentra completamente operativa
para realizar la labor de servidor y ser localizada de forma externa a la red
local en la que se encuentra conectada.
Figura 3.37. Diagrama de funcionamiento de la DDNS
131
INSTALACIÓN DEL SERVIDOR IRC
Para instalar el servidor IRC dentro de la Raspberry Pi es necesario
ejecutar las instrucciones que se describen a continuación (IRC server on
the raspberry pi, 2012):
1) Primero tendremos que proceder a instalar el servidor IRC ircd-hybrid
desde la terminal de la Raspberry Pi mediante el comando
sudo apt-get install ircd-hybrid
2) El siguiente paso a seguir es asignar una contraseña de administrador
para el servidor. Esto se realiza utilizando el comando
/usr/bin/mkpasswd “contraseña”
3) Ahora, se debe de abrir el archivo de texto que contiene la
configuración del servidor IRC. Para esto lo abrimos con el editor de
texto de nuestra preferencia, siendo en este caso el editor de texto
“GNU Nano” otorgándole permisos de administrador.
sudo nano /etc/ircd-hybrid/ircd.conf
4) Una vez abierto el archivo de configuración, buscaremos la sección de
código que comienza con la sentencia ‘listen‘, en donde cambiaremos
el campo host desde host=“127.0.0.1” a host=”0.0.0.0” para que no
discrimine entre las distintas clases de direcciones IP.
5) Posteriormente, definimos el puerto por el que el servidor aceptara las
conexiones entrantes, siendo en este caso el puerto “6667”.
6) Luego, nos dirigimos al apartado “operator“, y digitamos la
contraseña que establecimos en el paso n°2.
132
7) Finalmente, reiniciamos el servidor IRC para que adquiera la nueva
configuración con el comando:
sudo /etc/init.d/ircd-hybrid restart
8) Comprobamos el funcionamiento ingresando desde cualquier cliente
de chat ingresando al canal #mychannel del servidor IRC creado.
Figura 3.38. Acceso al servidor de chat IRC
Figura 3.39. Ventana principal del canal de chat
133
BASE DE DATOS MYSQL
El método de almacenamiento de los datos obtenidos desde el Arduino es
utilizando una base de datos MySQL que recibe esta información desde
un cliente IRC programado en Java y que se ejecuta en la Raspberry P a
través del puerto 3306. Para configurarla, se precisó de la interfaz web
gráfica llamada phpMyAdmin, propia para manipular este tipo de bases de
datos. La forma de insertar y recoger datos desde las distintas aplicaciones
implementadas es mediante una serie de comandos específicos en
lenguaje SQL.
INSTALACIÓN
La instalación de la base de datos para la microcomputadora Raspberry Pi
implica obtener de forma conjunta una serie de herramientas relacionadas
intrínsecamente entre sí, como son un servidor web Apache para entrar
gráficamente a la plataforma phpMyAdmin y el propio lenguaje PHP,
además de la base de datos en cuestión. Cabe destacar que este tipo de
bases de datos funciona mediante relaciones, por lo que es posible
vincular un cierto dato a partir de un cierto parámetro o de otro dato que
tenga relación con la información requerida. El contenido se aloja dentro
de tablas que se identifican con el nombre contenido en la trama principal
asignado a cada bus.
Cada tabla tiene una estructura definida que se verá en esta sección
donde se distribuyen las variables presentes en la trama en diferentes
columnas. Para conseguir la reseña anterior es necesario seguir una serie
de pasos definidos a continuación (Esquiva, 2013):
134
1) Ingresar el siguiente código para instalar el servidor MySQL.
sudo apt-get install mysql-server
2) En pleno proceso de instalación, se requerirá ingresar una contraseña
asociada al usuario Administrador de la base de datos que lleva el
nombre de root.
3) Ya está lista para ser utilizada la base de datos, así que el siguiente
paso es instalar PHP y phpMyAdmin para tener acceso a ella.
sudo apt-get install php5 apache2 libapache2-mod-php5
sudo apt-get install phpmyadmin
4) Nuevamente, se require configurar esta última herramienta, por lo que
se selecciona que el servidor web a utilizar será apache2, siendo éste
el servidor recién instalado. Conforme a lo anterior, se debe ingresar
posteriormente una nueva contraseña para la interfaz phpMyAdmin
intentando que sea igual a la usada para el acceso a la base de datos.
5) Luego, se debe de abrir el archivo de configuración de Apache para
incluir a la interfaz con la cual administraremos la base de datos. Esto
se realiza a través de la siguiente sentencia:
sudo nano /etc/apache2/apache2.conf
6) Se incluye en la parte inferior del fichero el siguiente comando:
/etc/phpmyadmin/apache.conf
7) Finalmente, se guarda el archivo y se reinicia el servidor web.
sudo /etc/init.d/apache2
135
8) Ahora se comprueba que la instalación fue exitosa ingresando a la
dirección http://fserranovargas.no-ip.org/phpmyadmin, en donde
debiese aparecer la pantalla de bienvenida de phpMyAdmin.
ESTRUCTURA
La base de datos que ha sido creada para términos de este proyecto, lleva
por nombre “sistema” y alberga en su interior tantas tablas de datos como
nombres de buses han sido creados en el servidor IRC. Estas tablas se
crean mediante código con conectores especializados para la realización
de esta tarea. No obstante, se mostrará la estructura que presentan en el
entorno web de phpMyAdmin para fines ilustrativos y de verificación de la
correcta inserción de los datos.
Figura 3.40. Tablas de la base de datos
La estructura de cada tabla está condicionada a su creación, realizada por
el Cliente IRC Java (detallado en el apartado 3.5.7.) y que distribuye los
136
datos de la trama generando una tabla con la forma presentada a
continuación:
Figura 3.41. Estructura de la base de datos
Se hace notorio que los campos anteriormente detallados corresponden a
los mismos que existen en la trama enviada por el Smartphone al servidor
IRC, a excepción del campo id que corresponde a un número identificador
de cada fila que incrementa según el número de datos ingresados a la
tabla va aumentando y que debe ser configurada como una variable
primaria y con la opción Auto-Increment habilitada.
Figura 3.42. Detalle de los elementos de una tabla
137
CUENTAS DE USUARIO
Para abrir la base de datos de forma remota, es necesario realizarlo a
través de cuentas de usuario que posean todos los privilegios necesarios
para modificar los elementos de la propia base de datos (Lara, 2012). Para
el cliente programado en Java se utilizó un usuario denominado admin que
tiene habilitados todos los permisos necesarios para manejar la base de
datos de forma local, mientras que para la interfaz gráfica desarrollada en
LabVIEW se creó el usuario llamado labview que también goza de los
privilegios para modificar elementos de la base de datos pero de forma
remota. Para el usuario labview, el servidor especificado será el símbolo
‘%’ que representa que podrá acceder desde cualquier servidor.
Figura 3.43. Permisos para el usuario admin
138
Figura 3.44. Permisos para el usuario labview
INSTRUCCIONES SQL
Las sentencias del lenguaje SQL más utilizadas para el desarrollo de
Telemetrics, ya sea para solicitar o insertar información a la base de datos
“sistema” están detallados en la siguiente tabla:
Instrucciones SQL Función
CREATE TABLE IF NOT EXISTS
`NOMBRE_DE_TABLA`(params);
Este comando crea una nueva tabla en la
base de datos con una serie de parámetros
definidos en el caso de que no haya sido
creada anteriormente. Si la tabla existe, esta
instrucción es omitida.
params:
Variable TIPO(longitud*)
*Sólo si el campo lo requiere
Los parámetros incluidos en la creación de la
tabla responden a los campos con los cuales
se quiere estructurar. Un ejemplo de esto
sería:
fecha DATE
hora VARCHAR(20)
139
INSERT INTO
`NOMBRE_DE_TABLA` (params)
VALUES(valores);
Inserta campos columna en la base de datos
con un valor asociado.
Ejemplo:
INSERT INTO `BUS-000` (fecha, hora)
VALUES (`23-11-2015`, 20:48:00)
SHOW FULL TABLES FROM
`BASE_DE_DATOS`
Muestra todas las tablas existentes dentro de
la base de datos consultada.
SELECT params FROM
`NOMBRE_DE_TABLA`
Selecciona los datos de los campos
especificados en la instrucción.
Ejemplo:
SELECT fecha, hora FROM `BUS-000`
SELECT params FROM
`NOMBRE_DE_TABLA` WHERE
condición
Selecciona los datos de las columnas
especificadas en la instrucción que cumplan
con la condición requerida.
En el ejemplo se obtienen los datos de la fila
en donde el campo id es igual a 2, excluyendo
los demás resultados.
Ejemplo:
SELECT fecha, hora, latitud, longitud
FROM `BUS-000` WHERE id=2
Tabla 3.13. Instrucciones SQL utilizadas para el proyecto
CLIENTE IRC EN JAVA
Como se ha mencionado anteriormente, dentro de la Raspberry Pi se
ejecuta a la par con los servidores IRC y MySQL, un script programado en
Java cuya labor es actuar como mediador entre las herramientas
anteriores, tomando las tramas enviadas desde cada Smartphone al canal
de chat, separándolas por elemento y guardando estos datos dentro de
una nueva tabla de la base de datos, la cual lleva por nombre el
correspondiente al bus del que se extraen las mediciones.
140
Figura 3.45. Diagrama de flujo del Cliente IRC
141
Este cliente IRC utiliza un driver especializado para el manejo de bases de
datos en Java denominado Conector JDBC (Java DataBase Connector),
obtenido a partir del repositorio de Raspbian (García & Navarro, 2014),
(Berkland, 2013).
CONECTOR JDBC
Para obtener la librería que contiene el conector JDBC se obtiene a partir
de la inserción del siguiente comando en la terminal de la Raspberry Pi.
sudo apt-get install libmysql-java
Para utilizar el driver JDBC se debe insertar la siguiente instrucción al
momento de ejecutar el script que requiere de esta librería, en donde
Cliente es el programa en Java que utiliza este conector.
sudo java -cp .:/usr/share/java/mysql-connector-java-
5.1.16.jar Cliente
CÓDIGO
Las librerías que se importan al programa se detallan en el siguiente
extracto de código, destacando las pertenecientes al manejo propio de la
base de datos con java.sql.*.
import java.io.*;
import java.net.*;
import java.util.Properties;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.sql.*;
142
Se crea una nueva clase que incorpora la interfaz Runnable para ejecutar
todo el proceso de extracción de datos en un subproceso o hilo
independiente del principal. Se crean dos variables globales que
representan la dirección IP del servidor de la base de datos, localhost para
este caso, y la URL de la base de datos MySQL, incluyendo el puerto de
conexión, el nombre de la base de datos y un encabezado jdbc: que hace
referencia al uso del conector JDBC implementado para este programa.
public class Cliente implements Runnable
public static String ip="127.0.0.1";
public static String url =
"jdbc:mysql://"+ip+":3306/sistema";
public static void main(String[] args) throws
IOException
Thread c=new Thread(new Cliente());
c.start();
public void run()
Ya dentro del proceso que se ejecutará en segundo plano, creamos las
variables correspondientes al remitente del mensaje enviado, la dirección
IP del servidor IRC, y los nombres de nick y de usuario que identifcarán al
Cliente de chat en el canal #mychannel.
try
String remitente="";
String server = "192.168.1.206";
String nick = "Caleuche";
String login = "Caleuche";
Connection conn = null;
String channel = "#mychannel";
143
Se crea el socket de entrada y salida que conectará el programa al servidor
IRC por el puerto 6667 de la Raspberry Pi referenciada con el dominio
fserranovargas.no-ip.org.
Socket socket = new Socket(server, 6667);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream( )));
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream( )));
Se especifican los parámetros de conexión para el servidor IRC que
involucran nickname y nombre de usuario. Luego se libera el flujo de datos
en el socket de escritura.
writer.write("NICK " + nick + "\r\n");
writer.write("USER " + login + " 8 * : Traspaso de datos\r\n");
writer.flush( );
Se leen las líneas recibidas desde el servidor hasta que se accede
satisfactoriamente al servidor. Cabe destacar que en IRC existen códigos
numéricos que representan estados en el cual se encuentran los usuarios,
por ejemplo el 004 representan que el usuario ha accedido exitosamente.
Del mismo modo, el código 433 alude que el nick utilizado ya está siendo
utilizado por otro cliente.
String line = null;
while ((line = reader.readLine( )) != null)
if (line.indexOf("004") >= 0)
break;
else if (line.indexOf("433") >= 0)
System.out.println("Ese nick ya esta en uso!");
return;
144
Ya dentro del servidor, se hace ingreso al canal #mychannel, en donde
nos mantendremos leyendo indefinidamente los mensajes provenientes
desde el servidor.
writer.write("JOIN " + channel + "\r\n");
writer.flush( );
while ((line = reader.readLine( )) != null)
Si se recibe un mensaje de PING desde el servidor para verificar la
conexión del usuario, se responde automáticamente con un mensaje de
PONG para, que de esta forma, no se expulse al cliente del canal. Si no
se recibe esta alerta, se muestran los mensajes del servidor normalmente
en la consola de nuestro programa.
if (line.startsWith("PING "))
writer.write("PONG " + line.substring(5) + "\r\n");
writer.write("PRIVMSG " + channel + " :Recibi un PING!\r\n");
writer.flush( );
else
System.out.println(line);
Se extrae de la línea recibida el nombre del remitente de las tramas, es
decir, extrae el nombre de cada bus que envía los datos para ser utilizado
en el procesamiento posterior, el cual se encuentra delimitado por los
símbolos ‘:’ y ‘!’ de la línea recibida desde el servidor (Figura 3.46).
if(line.indexOf("PRIVMSG")!=-1)
if(line.indexOf(":")!=-1)
String[] parts= line.split(":");
String comando=parts[parts.length-1];
remitente=line.substring(line.indexOf(":")+1,line.ind
exOf("!"));
writer.write("PRIVMSG "
+channel+"Remitente:"+"`"+remitente+"`"+"\r\n");
El primer paso para traspasar la información a la base de datos es
conectarse a la misma a través del usuario creado para este propósito, en
145
donde, con el conector JDBC que incorpora los parámetros de usuario y
contraseña se crea una conexión y se abre la base de datos consultada.
try
try
Properties info = new Properties();
info.put("user", "admin");
info.put("password", "admin1234");
conn = DriverManager.getConnection(url, info);
if (conn != null)
System.out.println("Conexion exitosa con
la base de datos!");
System.out.println("-Abriendo base de
datos " + url + " - Ok");
Posteriormente al establecimiento de la comunicación con la base de
datos, en el caso de que no exista, se crea una nueva tabla que lleva por
nombre el respectivo al bus que envía la trama. Esta nueva tabla posee
todas las columnas que corresponden a las variables almacenadas vistas
anteriormente.
Statement st = conn.createStatement();
st.executeUpdate( "CREATE TABLE IF NOT EXISTS "+"`"+
remitente+"`"+" ("
+ "id INT AUTO_INCREMENT, "
+ "PRIMARY KEY(id), "
+ "fecha DATE, "
+ "hora VARCHAR(20), "
+ "nombre VARCHAR(20), "
+ "tapa VARCHAR(20), "
+ "nivel VARCHAR(20), "
+ "latitud VARCHAR(20), "
+ "longitud VARCHAR(20))" );
System.out.println("-Creada tabla ("+remitente+") - Ok");
Se crean las variables locales que almacenarán temporalmente cada
elemento de la trama recibida, la cual se obtiene de la cadena de texto
146
delimitada por los símbolos ‘$’ y ‘%’ de la línea recibida desde el servidor.
La trama completa se guarda en la variable de tipo String carril.
String strfecha="";
String strhora="";
String strnombre="";
String strnivel="";
String strtapa="";
String strlatitud="";
String strlongitud="";
String
carril=line.substring(line.indexOf("$")+1,line.indexOf("%"));
writer.write("PRIVMSG " + channel + " Trama:"+ carril +"\r\n");
Figura 3.46. Trama reciibida por el Cliente IRC
Se crea un arreglo que contendrá todos los elementos de la trama
separados por el símbolo ‘;’, los cuales se incluyen dentro de un ciclo for
que por cada iteración asignará estos elementos a cada variable String
creada anteriormente hasta completar el tamaño del array.
String[] arreglo = carril.split(";");
for (int i = 0; i < arreglo.length; i++)
strfecha=arreglo[0];
strhora=arreglo[1];
strnombre=arreglo[2];
strnivel=arreglo[4];
strtapa=arreglo[3];
strlatitud=arreglo[5];
strlongitud=arreglo[6];
Para el caso único de la fecha y la hora, se requerirá aplicar el formato
característico de estas dos variables, donde mediante un tratamiento de
147
Strings, se separan día, mes y año para el caso de la fecha y se
concatenan con el símbolo ‘-‘.
String dia=strfecha.substring(0,2);
String mes=strfecha.substring(2,4);
String anno=("20"+strfecha.substring(4,6));
strfecha=(anno+"-"+mes+"-"+dia);
Del mismo modo, para el caso de la variable hora, se extraen las horas,
los minutos y los segundos y se concatenan con el símbolo ‘:’.
String hh=strhora.substring(0,2);
String mm=strhora.substring(2,4);
String ss=strhora.substring(4,6);
strhora=(hh+":"+mm+":"+ss);
Para insertar los datos a la respectiva tabla, se utiliza la instrucción SQL:
INSERT INTO que utiliza como parámetro el nombre de la tabla, los
nombres de las columnas y los valores correspondientes a cada envío de
información de parte del teléfono, asociados a cada campo de columna
especificado.
st.executeUpdate("INSERT INTO "+"`"+remitente+"`"+" ("
+ "fecha, "
+ "hora, "
+ "nombre, "
+ "nivel, "
+ "tapa, "
+ "latitud, "
+ "longitud) "
+ "VALUES ("
+ "'"+strfecha+
"','"+strhora+
"','"+strnombre+
"','"+strnivel+
"','"+strtapa+
"','"+strlatitud+
"','"+strlongitud+
"' )");
System.out.println("-Agregard2 registros a la tabla - Ok");
148
Finalmente, se cierra la conexión a la base de datos y se da por terminado
el programa.
conn.close();// Cerrar base de datos
System.out.println("-Cerrar base de datos " + url + " -
Ok");
catch(...)
writer.flush( );
catch(...)
FUNCIONAMIENTO
Para ejecutar el código, se debe de ingresar mediante SSH a través de
PuTTY a la Raspberry Pi, y ejecutar el siguiente comando:
sudo nohup java -cp .:/usr/share/java/mysql-connector-java-
5.1.16.jar Cliente
En donde:
- Se confieren permisos de administrador con el comando sudo.
- Se ejecuta el programa en segundo plano con el comando nohup.
- Con java –cp se invoca el conector JDBC desde su ubicación
- Cliente corresponde al nombre del archivo .class compilado anteriormente
con el comando javac Cliente.java.
149
INTERFAZ EN LABVIEW
La realización de una interfaz gráfica en el software LabVIEW, perteneciente a
National Instruments consiste en una herramienta que es capaz de interactuar
con el usuario final de manera muy intuitiva, entregando funcionalidades, que si
bien pueden llegar a lograrse con algún otro lenguaje de programación como
PHP, se optó por LabVIEW debido a su versatilidad, gran cantidad de
funcionalidades y facilidad de manejo tanto para el usuario como para el
programador. En los siguientes puntos se detallará la configuración, la estructura
de la interfaz y el diagrama de bloques que realiza las tareas pertinentes.
Figura 3.47. Recorrido realizado por el bus
150
TOOLKIT LABSQL ADO
En LabVIEW existen paquetes de instrumentos virtuales llamados Toolkits
para alguna necesidad específica, ya sea conectar el programa al puerto
serial, a un hardware especial o algún otro software del que se requiera
algún procesamiento. Para este proyecto, se utilizó el Toolkit LabSQL
ADO que permite la comunicación con una base de datos tanto remota
como local para este tipo de bases de datos, que aunque tiene múltiples
VIs, existen cinco Vis esenciales que se requieren para efectuar esta tarea
(Barrera Pinto, 2011), (Halvorsen, 2011).
a) Create Connection: Crea un objeto de conexión para la base
de datos que entrega la referencia y el error que se utilizará en
el procedimiento.
Figura 3.48. VI para la creación de la conexión a la BD
b) Open Connection: Elemento que abre la conexión hacia la base
de datos. Se le debe de entregar la referencia, el error, y el nombre
del objeto ODBC creado en el panel de control.
Figura 3.49. VI para el inicio de la conexión a la BD.
151
c) SQL Execute: Elemento que envía comandos SQL a la base de
datos, tales como peticiones de información, inserción de datos,
creación de tablas, eliminación de tablas, etc. Requiere el comando
en formato String, la referencia, el error, y un booleano que
determinará si retornará o no datos (Para consultas marcar como
TRUE, y para insertar o borrar datos marcar como FALSE). En el
caso de retornar datos, se generará un arreglo de las dimensiones
de los datos consultados.
Figura 3.50. VI que ejecuta comandos en la BD
d) Close Connection: Cierra la conexión que se había iniciado.
Requiere la referencia y el error.
Figura 3.51. VI que cierra la conexión a la BD.
e) Destroy Connection: Destruye la conexión iniciada. Normalmente
se utiliza al final del programa para evitar que la conexión siga
creada. Requiere la referencia y el error.
Figura 3.52. VI que destruye la conexión a la BD.
152
CONECTOR ODBC
De la misma forma que el cliente IRC de la Raspberry Pi necesita del
conector JDBC para entablar una conexión con la base de datos, el
programa desarrollado en LabVIEW también necesita de un driver que
gestione el manejo de la información para la base de datos. Este driver
lleva por nombre MySQL ODBC Connector y es necesario obtenerlo desde
el repositorio oficial de MySQL a través de la dirección especificada debajo
del párrafo, seleccionando el instalador para la versión del sistema
operativo requerido, siendo para este caso la versión ejecutable para 32
bits (Barrera Pinto, 2011):
https://dev.mysql.com/downloads/connector/odbc/
Figura 3.53. Sitio de descarga del conector ODBC
153
Una vez descargado e instalado, se debe configurar el driver entrando al
Panel de Control del equipo, seleccionando la opción Herramientas
Administrativas y luego el ítem Orígenes de datos ODBC.
Figura 3.54. Herramientas Administrativas del equipo
Figura 3.55. Orígenes de datos ODBC
154
La siguiente pantalla muestra los conectores ODBC ya configurados, en
donde para crear uno nuevo se debe pulsar el botón Agregar y elegir el
driver que se ha descargado, es decir, el que tiene por nombre MySQL
ODBC 5.3 Unicode Driver.
Figura 3.56. Administrador de conectores ODBC
Figura 3.57. Driver a utilizar para el conector ODBC
155
El siguiente y último paso es configurar los parámetros de conexión al
servidor, indicando la dirección, el puerto, el nombre del elemento conector
que llamaremos desde LabVIEW, la información del usuario con el que se
hará acceso a la base de datos y el nombre de la misma.
Figura 3.58. Configuración del conector ODBC
Si se desea comprobar la conexión con la base de datos desde esta
terminal, bastará con pulsar el botón Test, en donde recibiremos un
mensaje que indicará si la comunicación fue exitosa.
Figura 3.59. Prueba de conexión satisfactoria.
156
PANEL FRONTAL
El Panel Frontal es la interfaz gráfica que permite al usuario interactuar
con el programa desarrollado. El proyecto Telemetrics cuenta con un panel
frontal que resulta ser muy intuitivo a la hora de efectuar el análisis y la
visualización de los datos. A continuación se detalla el funcionamiento y
las partes que componen esta sección del proyecto (National Instruments,
2015), (Kyle Senkevich, 2009).
HOME
Al ejecutar el programa, lo primero que se muestra en pantalla es la
verificación de conexión con el servidor, indicando si la comunicación está
o no establecida. En el caso de que haya fallado, se reintentará establecer
la comunicación nuevamente con el servidor hasta que ésta resulte
exitosa.
Figura 3.60. Estado de la conexión a la BD.
Si la conexión con el servidor está establecida, se muestra en un
Combobox o lista desplegable todas las tablas existentes en la base de
datos, las cuales están asociadas a cada uno de los buses de la flota. A
medida que van ingresando nuevos buses a la base de datos, esta lista se
va actualizando en tiempo real.
157
Figura 3.61. Elección del nombre del bus a analizar.
Ya elegido el bus, se procede a elegir desde un segundo Combobox las
fechas de las mediciones realizadas en el bus escogido.
Figura 3.62. Elección de la fecha de medición.
Se puede comprobar que al realizar el paso anterior, se muestran
automáticamente los últimos valores medidos, es decir, el último valor del
nivel de combustible, de la posición de la tapa y del cálculo de la velocidad,
así como la distancia total recorrida. Cabe destacar, que estos valores se
actualizan cada un segundo, durante cada consulta a la base de datos,
por lo que es seguro decir que en una medición en tiempo real, los valores
visualizados en la pantalla de inicio representan el promedio entre el punto
actual y el punto anterior en el lapso del tiempo de muestreo que equivale
a 30 segundos.
158
Figura 3.63. Medidores de velocidad, combustible, distancia y posición de la tapa.
En el costado izquierdo de la pantalla se hace presente un menú de
navegación con seis botones que permiten al usuario acceder a diferentes
secciones del programa, como a elementos de configuración y a la
detención del mismo.
Botón Función
Muestra en pantalla la tabla que contiene la
información proveniente de la base de datos.
Permite al usuario visualizar la evolución de
las variables: Nivel de tanque, posición de la
tapa y Velocidad a través de sus respectivos
gráficos en función de la fecha y hora de cada
medición.
Otorga al usuario la posibilidad de visualizar al
instante la ruta seguida por el vehículo a lo
largo de su jornada de movilización.
Permite dirigirse directamente a la pantalla de
inicio.
Este botón tiene como tarea invocar a la
configuración del conector ODBC para realizar
159
pruebas de conexión u corrección de
parámetros.
Detiene por completo el funcionamiento del
programa.
Tabla 3.14. Detalle del funcionamiento del menú de navegación.
VISUALIZACIÓN DE DATOS
En este apartado del programa se muestra una tabla que muestra las ocho
columnas que se han consultado a la base de datos, además de una
columna adicional (Odómetro) que indica el resultado del cálculo de la
distancia entre la coordenada geográfica actual y la anterior con la fórmula
del verseno. De la misma forma, existe otra columna adicional (Velocidad)
que permite visualizar el resultado del cálculo de la velocidad a partir de la
distancia calculada y del tiempo transcurrido en segundos entre cada
muestra. Por encima de la tabla, existe un indicador numérico que muestra
el número de elementos que contiene la tabla.
Figura 3.64. Información obtenida desde la base de datos
160
GRÁFICOS
Los gráficos presentados en esta sección permiten analizar la evolución
de las variables velocidad (km/h), consumo de combustible (L) y posición
de la tapa (On/Off), en función del la fecha y hora de cada muestra. Cada
gráfica se encuentra insertada dentro de una pestaña de un Tab Control y
cuenta con seis herramientas de visualización al pulsar el símbolo de
Zoom y dos cursores a los costados, los cuales se detallan en las Tablas
3.15 y 3.16.
Figura 3.65. Ejemplo: Gráfico de consumo de combustible
161
Tabla 3.15. Cursores disponibles para gráficos.
Herramienta Función
Selecciona la sección rectangular del gráfico que se desea
acercar.
Selecciona la sección a lo largo del eje x que se desea
visualizar con más detalle.
Selecciona la sección a lo largo del eje y que se desea
agrandar.
Muestra todo el gráfico en su tamaño original.
Herramienta para acercar manualmente desde un punto del
gráfico.
Herramienta para alejar manualmente desde un punto del
gráfico.
Tabla 3.16. Herramientas de visualización de gráficos.
Cursor Función
Herramienta Cruz. Representa el cursor por defecto en
el entorno del gráfico.
Herramienta Zoom. Al pulsar este botón se despliega el
menú que contiene los elementos de la Tabla 3.16.
Herramienta Mano. Permite al usuario mover el gráfico
de forma manual.
162
TRAYECTORIA
El accionamiento del botón Trazar Trayectoria lleva al usuario a visualizar
en pantalla un mapa de la API de Google Maps que muestra el recorrido
realizado por el bus en la fecha correspondiente, mostrando el punto de
inicio y el punto de término de su trayectoria.
Figura 3.66. Ejemplo del Trazado del recorrido de un bus
163
DIAGRAMA DE BLOQUES
INICIALIZACIÓN DE VARIABLES
El código del programa comienza con todos los elementos que están
ubicados fuera del ciclo while principal, los cuales tienen como función
inicializar las diferentes variables y elementos utilizados. En la siguiente
figura se muestran la inicialización de la tabla de visualización de datos,
del valor mostrado en ambos combobox, de los arrays que contienen las
columnas con los datos del nivel y la velocidad, del array que contiene
todas las fechas y horas y dos variables internas que actúan como flags
inhibiendo que el proceso se ejecute más de una vez en una iteración del
ciclo while principal.
Figura 3.67. Inicialización de variables
Los elementos desplegados en la Figura 3.68 muestran que los combobox
inician vacíos, es decir, sin ningún valor en su interior. También se le
asignan valores de inicio y color blanco de fondo al indicador numérico que
entrega el número de elementos de la tabla. Del mismo modo, el campo
de texto Status inicia con la leyenda “Verificando Conexión” al momento
164
en que se ejecuta el programa. El estado del servidor inicia sin valores y
de color gris. Finalmente se puede apreciar que la terminal del Tab Control
2 que contiene los gráficos de velocidad, consumo y posición de la tapa
también se encuentra en este apartado. Se realiza, posteriormente, la
puesta en cero del gráfico de Velocidad que se reduce a un clúster con
elementos del tipo Timestamp y numérico del tipo double.
Figura 3.68. Inicialización de variables
Figura 3.69. Inicialización de variables
165
A continuación, se deshabilitan los botones Graficar, Trayectoria y Mostrar
datos al comienzo, para así evitar conflictos de que la tarea presente datos
nulos. Luego, se establece que solamente los elementos de la sección
Home sean visibles al inicio del programa entregándole un valor True al
Tab Control 2 que los contiene, por consiguiente, los demás objetos que
se muestran en las demás secciones (gráficos, mapa, indicadores, tabla,
etc.), iniciarán invisibles. El terminal status corresponde al indicador de
Strings que muestra el estado de la conexión hacia el servidor.
Figura 3.70. Inicialización de variables
El mapa de la API de Google Maps en el que se despliega la trayectoria
del bus, está contenido dentro de un navegador web insertado dentro de
la interfaz. Este navegador inicia invisible y con la página about:blank por
defecto. El combobox que muestra el nombre del bus a elegir, inicia con
una leyenda que invita al usuario a realizar esta acción. Finalmente, los
166
últimos valores medidos y que son mostrados al inicio del programa son
inicializados en cero, al igual que el Label que muestra la distancia total
recorrida. El terminal Fecha corresponde al combobox que despliega las
fechas de las mediciones como tal.
Figura 3.71. Inicialización de variables
VERIFICACIÓN DE LA CONEXIÓN
Una vez inicializadas las variables, lo siguiente es comprobar si la
conexión al servidor de la base de datos está operativa, por lo que dentro
del ciclo while se creará una conexión que proporcionará una referencia a
la misma y un error en caso de que éste ocurriese. Esta primera tarea es
insertada dentro de una estructura condicional para que sólo se ejecute al
inicio de cada iteración solamente. Una estructura secuencial se ha
insertado dentro del condicional para seguir un orden en los procesos.
El siguiente paso es abrir una conexión hacia la base de datos utilizando
el nombre del elemento conector que se ha creado en Orígenes de datos
ODBC, el cual si detecta que la conexión ha resultado fallida, arrojará un
error que se manejará con otra estructura condicional que indicará Fallo si
ocurriese esta situación, anulando el resto del proceso y reintentando
167
establecer la conexión al comienzo de una nueva iteración. Si la conexión
se ha establecido, se indica y se avanza al siguiente proceso.
Figura 3.72. Diagrama de flujos del estado del servidor
Figura 3.73. Verificación de la conexión - Caso No Error
168
Figura 3.74. Verificación de la conexión - Caso Error
169
MOSTRAR NOMBRES EN EL COMBOBOX
Si la conexión resulta exitosa, posteriormente se ejecutará una petición de
información a la base de datos mediante el VI denominado "SQL Execute",
el cual extrae todos los nombres de las tablas existentes en la base de
datos.
Figura 3.75. Diagrama de flujos del combobox de nombres de bus
Al realizar la acción, obtenemos un array de dos columnas que contiene el
nombre de la tabla y una descripción del tipo de tabla consultada (base
table). Se selecciona sólo la primera columna y se almacena cada
elemento en un clúster conformado por dos Strings, en donde se asignará
cada nombre al texto y al valor que necesita cada elemento del Combobox.
Una vez que ya están almacenados todos los valores, se activa el
indicador Fin_nombre y se da por terminada esta tarea.
170
Figura 3.76. Mostrar nombres de buses en combobox.
MOSTRAR FECHAS EN COMBOBOX
Si el campo "Nombre del Bus" no está vacío, se ejecuta el condicional que
agrega las fechas disponibles para consultas correspondientes a cada
bus, es decir, muestra los días en donde se han llevado a cabo los
registros de las variables. El proceso se inicia mediante una consulta a la
base de datos remota que devuelve un array de dos dimensiones, del cual
seleccionamos sólo la primera columna que contiene las fechas.
171
Figura 3.77. Diagrama de flujo del combobox de Fechas
Luego, en el primer ciclo FOR creamos un SHIFT REGISTER que
almacena los elementos pertenecientes al array mencionado, obtenemos
dichos elementos "indexando" este arreglo, es decir, asignando el índice
del elemento a cada iteración del ciclo, de manera que se extraen todos
los elementos.
Figura 3.78. Mostrar fechas en combobox.
172
Después, se compara el elemento actual con el elemento anterior, en
donde si éstos resultan ser diferentes, o si nos encontramos en la primera
iteración, ejecutamos la estructura IF. Si es la primera iteración, tomamos
la primera fecha y la reemplazamos por el primer elemento del arreglo. Si
en la comparación resultan diferentes los elementos, se toma la fecha que
es distinta y se reemplaza en la posición siguiente a la primera fecha
reemplazada, así con cuantas fechas diferentes existan, obteniendo un
nuevo arreglo que tiene n valores distintos al comienzo, luego se corta
dicho arreglo y se introduce en el combobox mediante un cluster en un
ciclo FOR.
MOSTRAR DISTANCIA TOTAL RECORRIDA
Al iniciar el programa y elegir un nombre de bus con su respectiva fecha
de consultas, aparece en la pantalla principal la distancia total que ha
recorrido el vehículo. Esto se obtiene convirtiendo el valor de la distancia
total, obtenida más adelante, a formato String, en donde si el valor resulta
ser menor a 1000, se muestra en metros (m), en cambio, si es mayor o
igual a 1000, la da a visualizar en kilómetros (km).
Figura 3.79. Diagrama de flujo de la distancia total
173
Figura 3.80. Mostrar distancia total recorrida - Caso false
Figura 3.81. Mostrar distancia total recorrida - Caso true
REDIRECCIÓN AL HOME
Si el usuario, habiendo ya consultado los datos de un bus, decide consultar
los datos de otro bus, debe cliquear en el primer combobox y seleccionar
el nombre del otro vehículo en la lista. Al elegir uno de ellos, se resetea el
valor del combobox de fecha, redirigiendo al usuario a la pantalla principal.
Esto se logra comparando con un Shift Register, el nombre anterior y el
nombre elegido por el usuario, en donde, si éstos son diferentes, se
procede a ejecutar la estructura condicional que invisibiliza todos los
elementos excepto el Tab Control 2 que contiene los objetos del Home.
174
Figura 3.82. Diagrama de flujos de la redirección al Home
Figura 3.83. Redirección al home ante la elección de otro nombre de bus.
175
HABILITACIÓN DE LA EXTRACCIÓN DE DATOS
Para consultar información a la base de datos, primero se debe comprobar
si el valor del combobox del nombre de bus y el combobox de fecha están
vacíos o en blanco. Si es así, se ejecuta a través de una compuerta not el
caso False, deshabilitando así los botones de función, vaciando el
contenido de la tabla, invisibilizando la tabla propiamente tal y asignandole
el valor false a la variable Fin Nombre, a fin de evitar que se ejecute la
extracción de información si no existen parámetros definidos, es decir, si
alguno de los valores del combobox es nulo o está en blanco, no se ejecuta
ninguna acción hasta que esta condición cambie.
Figura 3.84. Diagrama de flujo de los combobox
176
Es importante señalar que la variable flag comienza inicializada en false,
por lo que con el negador pasa a estado true, pasando solamente a
depender de Fin nombre la ejecución del condicional de extracción de
datos.
Figura 3.85. Habilitación de la extracción de datos.
Figura 3.86. Extracción de datos - Caso false
177
EXTRACCIÓN DE INFORMACIÓN
En caso de que el nombre del bus y la fecha sean valores no nulos ni
vacíos, primero se habilitan los botones de función y luego se realiza una
conexión con la base de datos y una posterior petición de información
solicitando las variables id, fecha, hora, nombre del bus, posición de la
tapa, nivel de combustible, latitud y longitud, pero con la condición de que
el día, el mes y el año correspondan a los de la fecha elegida por el usuario,
la cual se agrega a la consulta separando cada cifra con el símbolo ‘-‘.
Además las coordenadas del gps deben ser diferentes del valor 0.0, 0.0
para así evitar confusiones a la hora de trazar la trayectoria si el dispositivo
en plena medición pierde la señal del GPS. A la tabla que se obtiene, se
le agregan las columnas Odómetro (distancia) y Velocidad, donde esta
información se calcula en los procesos siguientes en base a las
coordenadas geográficas. Finalmente, se evalúa si la tabla está vacía o
no con un comparador que activa un Indicador que habilita o deshabilita la
ejecución de la estructura condicional principal de este proceso.
Figura 3.87. Diagrama de flujo de la extracción de datos
178
Figura 3.88. Extracción de información - Caso true
DESTRUCCIÓN DE LA CONEXIÓN
En caso de que el usuario presione el botón Detener, se da fin al ciclo while
principal, destruyendo antes la conexión a la base de datos para evitar
dejarla abierta.
Figura 3.89. Diagrama de flujo del botón Detener
179
Figura 3.90. Destrucción de la conexión a la base de datos.
PROCESAMIENTO DE DATOS
El procesamiento de los datos obtenidos desde la base de datos comienza
al separar la información de la tabla en seis columnas con un tamaño igual
al número de elementos de la matriz original, para así manejar de forma
independiente a cada una de las variables con las que se trabajará más
adelante.
Figura 3.91. Separación de la tabla en columnas
180
Las variables numéricas como el Nivel, son convertidas desde String a
formato numérico (DBL), mientras para las columnas de Fecha y Hora se
extrae elemento a elemento, los que luego serán concatenados para
quedar de la forma (dd-mm-AAAA HH:mm:ss). Este objeto, será
convertido a Timestamp y almacenado en un array de formato tiempo. El
indicador N°de elementos muestra el tamaño del array Nivel, aunque
podría haber estado cableada a cualquier otro arreglo, ya que todos
poseen el mismo número de objetos en su interior. Finalmente, ya
habiendo llegado al procesamiento del último elemento del arreglo, se
verifica esta situación, se declara como false las variables que actúan de
flags para controlar la ejecución de las estructuras condicionales, y se da
por terminado el funcionamiento de este ciclo while.
Figura 3.92. Conversión de la fecha y la hora y finalización del ciclo.
La latitud y la longitud son extraídas desde la tabla y son concatenadas
con el símbolo ‘,’ en un nuevo arreglo llamado GPS array. Originalmente,
se pensó en separar en las coordenadas geográficas que fueran iguales
al valor 0.0, 0.0 a través de un conector condicional a la salida de un ciclo
For, el cual discrimina que si el término no es el valor deseado, lo rechaza,
deshabilitando su paso hacia el array que se va a crear finalmente. No
181
obstante, y como se determinó anteriormente, se relegó esta lógica a un
plano estrictamente ilustrativo para dar cuenta de la posibilidad que ofrece
LabVIEW para este tipo de tareas. Lo siguiente es extraer cada uno de los
elementos no iguales a cero desde los arrays creados, como también
extraer la primera y última coordenadas de dichos arreglos para su
posterior procesamiento.
Figura 3.93. Creación de los arreglos de latitud y longitud.
182
De la tabla, se extrae la columna que contiene todos los valores obtenidos
desde el sensor digital desde tipo String, se extrae cada elemento y
nuevamente se crea un array con dichos valores pero de numérico (DBL).
Figura 3.94. Creación del array de posición de la tapa.
El cálculo de la distancia entre dos puntos geográficos que cuentan con
latitud y longitud se realiza mediante la fórmula del Verseno. Para realizar
esta operación, se deben convertir primero los elementos desde String a
número (DBL) y ya que esta fórmula necesita el punto anterior y el punto
actual para obtener el resultado, se utiliza un Shift Register que almacena
los valores n y n-1, siendo inicializado en cero. Estas dos coordenadas
geográficas se guardan en un clúster para ser convertidas desde grados a
radianes a través de la ecuación 3.1.
𝑅𝑎𝑑𝑖𝑎𝑛𝑒𝑠 =𝐺𝑟𝑎𝑑𝑜𝑠 ∗ 𝜋
180
Ecuación 3.1. Conversión de grados a radianes Math.com, Trigonometric Tables
Recuperado de: http://www.math.com/tables/trig/tables.htm
183
Posteriormente, se realiza la comprobación acerca de si las coordenadas
que entrarán a la fórmula son iguales a cero. Para esto, se crea un nuevo
arreglo que contiene la latitud y longitud actual y la latitud y longitud
anterior, las cuales son comparadas elemento a elemento si son iguales a
cero. Si alguna resulta ser igual a cero se obtiene el valor True que hace
que la distancia sea cero. Si todas son distintas de cero, se obtiene el valor
False que ejecuta el cálculo de la distancia a través de la fórmula del
Semiverseno.
Figura 3.95. Procesamiento de las coordenadas geográficas.
184
Figura 3.96. Condicional para el cálculo de la distancia - Caso true
En el caso de que las coordenadas geográficas sean diferentes de cero,
se inicia el funcionamiento de un nodo de fórmula que contiene la Fórmula
del Haversine [Sección 2.2.1.4], donde las entradas son la latitud anterior
(lat1), la longitud anterior (lon1), la latitud actual (lat2) y la longitud actual
(lon2). El resultado es la distancia entre estos dos puntos, los cuales son
almacenados dentro de un array con formato String. Es posible comprobar
el resultado mediante la utilización una calculadora de distancias online.
Figura 3.97. Comprobación del cálculo de la distancia
185
Como contraparte, se suma todos los elementos de un arreglo que
contiene todos los valores de distancia calculados, para así calcular la
distancia total recorrida.
Por otro lado, la velocidad se calcula mediante la relación de distancia y
tiempo, mostrada en la ecuación 3.2, donde una vez calculada se
almacena en un arreglo numérico y otro en formato String.
𝑉𝑒𝑙𝑜𝑐𝑖𝑑𝑎𝑑 =𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎
𝑡𝑖𝑒𝑚𝑝𝑜
Ecuación 3.2. Ecuación de velocidad.
Figura 3.98. Cálculo y almacenamiento de la distancia y la velocidad
El cálculo de la velocidad implica conocer el lapso de tiempo transcurrido entre
cada muestra, por lo que se calcula este tiempo en segundos con la información
de la base de datos. Primero se crea un shift register que almacena el valor
anterior y el valor actual de la hora, para luego extraer los elementos de estas
variables, es decir, horas, minutos y segundos. Posteriormente, se resta cada
186
variable de tiempo con su homóloga y se multiplican por su respectivo factor de
conversión para el cálculo de tiempo en segundos.
𝑇𝑖𝑒𝑚𝑝𝑜 (𝑠) = ((ℎ𝑜𝑟𝑎𝑛 − ℎ𝑜𝑟𝑎𝑛−1) ∗ 3600) + ((𝑚𝑖𝑛𝑢𝑡𝑜𝑛 − 𝑚𝑖𝑛𝑢𝑡𝑜𝑛−1) ∗ 60)
+ (𝑠𝑒𝑔𝑢𝑛𝑑𝑜𝑛 − 𝑠𝑒𝑔𝑢𝑛𝑑𝑜𝑛−1)
Ecuación 3.3. Fórmula para el cálculo del tiempo entre muestras.
Finalmente, el valor obtenido en (m/s), es convertido en (km/h) y se envía al
bloque encargado del cálculo de la velocidad.
Figura 3.99. Cálculo del tiempo entre mediciones
187
Figura 3.100. Diagrama de flujo del procesamiento de datos
188
ACCIÓN DEL BOTÓN GRAFICAR
Si se presiona este botón, primero se grafican los arrays numéricos de
Velocidad, Nivel y Posición de la tapa versus el array de Hora/Fecha, en
donde mediante la configuración del gráfico se realiza la visualización de
la evolución de estas variables para cada tiempo de medición. Luego, se
asignan el nombre al eje y de cada gráfico respectivamente. Para finalizar,
se invisibilizan todos los elementos excepto los tres gráficos y el Tab
Control que los contiene.
Figura 3.101. Acción del botón Graficar.
189
Figura 3.102. Diagrama de flujo del botón 'Graficar'
ACCIÓN DEL BOTON HOME
Si el usuario presiona este botón, se ocultan todos los elementos
exceptuando el Tab Control 2, el cual contiene todos los componentes que
conforman la pantalla de inicio del programa, entre ellos imágenes,
medidores y texto.
Figura 3.103. Acción del botón Home
190
Figura 3.104. Diagrama de flujo del botón 'Home'
MOSTRAR ÚLTIMOS VALORES
A medida que los valores se van actualizando en tiempo real, se van
mostrando en la pantalla de inicio a través de la serie de medidores
incorporados. A fin de cuentas, se muestra el último valor del arreglo, el
cual se actualiza a medida que se van adquiriendo nuevos datos.
Figura 3.105. Obtención y visualización de los últimos valores medidos.
191
ACCIÓN DEL BOTON DE TRAYECTORIA
Al pulsar este botón se ejecuta una estructura secuencial, en donde en el
primer frame se toma el arreglo que contiene las coordenadas geográficas
completas sacadas desde la base de datos, extrayendo elemento a
elemento, en donde originalmente y antes de implementar el filtro en el
apartado de extracción de información, se consideró comparar si cada
elemento era igual a "0.0, 0.0", lo que indicaba que el móvil no pudo ser
localizado en esa medición, ya que al estar situados en Santiago de Chile,
resulta ilógico que el valor “0.0, 0.0” sea una coordenada geográfica
coherente. Si el valor era igual a "0.0, 0.0", se discriminaba y evitaba
guardarse en el nuevo arreglo a crear, en donde se admitían solamente
los valores distintos de cero, para así garantizar que no se graficarían
puntos geográficos erróneos, además de distinguir los momentos en que
el teléfono no disponía de señal GPS.
Figura 3.106. Diagrama de flujo del botón 'Trayectoria'
192
La situación anterior, quedó relegada a un plano nada más que
demostrativo, ya que el problema se solucionó eficazmente al aplicar la
condición al momento de consultar la base de datos. Volviendo a la
visualización de la trayectoria en el mapa, se guarda el arreglo de
coordenadas en uno nuevo que se concatena a un comando HTML
variable que le entrega a la Google Maps API los puntos que se querrán
introducir al mapa. Ya que se está tratando directamente con la generación
de código HTML, se debe identificar cuándo se llegó al final del arreglo,
puesto que el separador entre cada elemento es el símbolo ‘,’, en cambio,
el delimitador de fin corresponde a ‘;’.
Figura 3.107. Acción del botón Trayectoria - Frame 1
193
Posteriormente, tomamos el primer y último elemento de los arrays de
latitud y longitud respectivamente, y los concatenamos con un comando
de HTML que crea las variables "lat", "lon", "latf" y "lonf" que representan
latitudes y longitudes iniciales y finales respectivamente. Luego, se leen
tres archivos de texto que están presentes en el espacio de trabajo y se
anexan estas variables al código HTML que almacenan dichos archivos,
de modo que se crea un último y nuevo archivo de texto que crea el sitio
web que alberga el mapa de la google maps API, incorporando el arreglo
de latitud y longitud que vimos en el paso anterior y las variables descritas
en este párrafo. El archivo html que contiene el mapa tiene el nombre de
recorrido.html y es definido como la dirección que deberá mostrar el
navegador insertado, además de declarar el Web Browser como único
objeto visible para este apartado.
Figura 3.108. Acción del botón Trayectoria - Frame 2
194
La API de Google Maps funciona a través de una serie de comandos que
mediante el ingreso de parámetros, permite visualizar a través de un
entorno web un mapa con todos los puntos geográficos necesarios para
trazar la trayectoria, así como el empleo de marcadores utilizados para
reconocer el inicio y el final del recorrido (Carrodeguas, 2015), (Exposito,
2012), (Li, Coll. of Inf. Eng., & Zhijian, 2010; Google, 2015). Los comandos
mencionados se encuentran detallados en la siguiente tabla:
Instrucción Función
google.maps.LatLng(latitud,longitud) Representa una coordenada geográfica a
partir de la latitud y la longitud.
google.maps.MapTypeId.Tipo_de_mapa Representa el tipo de mapa con el que se
trabajará, pudiendo ser ROADMAP (Mapa
de calles y rutas), SATELLITE (Mapa de
Google Earth), HYBRID (Mezcla de los dos
anteriores) y TERRAIN (Mapa físico con la
información del terreno).
google.maps.Map(document.getElementB
yId(“mapa”)
Objeto que representa a un mapa
contenido dentro de un documento HTML.
mapa = google.maps.Marker(position,
icon, map, title), …);
Objeto que representa a una imagen
utilizada como indicador de lugares que
requiere la posición del marcador, el icono
a mostrar, el mapa donde será insertado y
el título de la imagen.
google.maps.Polyline(path, map,
strokeColor, strokeHeight, strokeOpacity,
clickable)
Línea que une una serie de puntos
geográficos contenidos en la variable path.
La variable map indica el mapa donde será
insertada, la variable strokeColor indica el
color de la línea. Del mismo modo, la
variable strokeHeight indica el grosor de la
línea, mientras que strokeOpacity denota
la opacidad de la polilínea. Finalmente, el
195
campo clickable indicará si el usuario
podrá modificar la línea.
Tabla 3.17. Comandos de la Google Maps API
El código del archivo HTML que contiene el mapa basa su funcionamiento
en el llamado que se realiza al script de la API de Google Maps. A
continuación se explica la programación realizada.
Figura 3.109. Diagrama de flujo del código de la trayectoria
Iniciamos referenciando a la norma HTML utilizada, para luego comenzar
con el cuerpo del código, deshabilitando la scrollbar.
<!DOCTYPE html>
196
<html>
<head>
<body scroll="no">
Con la etiqueta viewport se controla el zoom inicial de la página, además
de impedir que el usuario pueda modificar el tamaño de la ventana.
<meta name="viewport" content="initial-scale=1.0, user-
scalable=no" />
Se declara la hoja de estilos del documento con el alto de la página y del
cuerpo de la misma, quitando el margen y el espaciado.
<style type="text/css">
html height: 588px
body height: 588px; margin: 0; padding: 0
Se asigna el tamaño al mapa y se crea el objeto que referencia al mapa,
configurando el tamaño del mismo.
#map_canvas height: 588px
</style>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?v=3.17&sensor=fals
e"/>
</script>
Se asignan al script los valores de las coordenadas geográficas iniciales
y finales.
<script type="text/javascript">
function initialize()
var lat=[Latitud del punto inicial];
var lon=[Longitud del punto inicial];
var latf=[Latitud del punto final];
var lonf=[Longitud del punto final];
Posteriormente, se establece la configuración inicial del mapa indicando el
punto en el cual se centrará, siendo en este caso el punto inicial. Del
mismo modo, se configura el zoom inicial y el tipo de mapa desplegado.
var myOptions =
197
center: new google.maps.LatLng(lat, lon),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
;
Luego se asignan los parámetros anteriores al mapa creado.
var map = new
google.maps.Map(document.getElementById("map_canvas"),
myOptions);
Los marcadores de inicio y término del recorrido se establecen en las
siguientes líneas de código.
INICIO = new google.maps.Marker(
position: new google.maps.LatLng(lat, lon),
icon: 'apointer.png',
map: map,
title: 'Inicio'
);
FINAL = new google.maps.Marker(
position: new google.maps.LatLng(latf, lonf),
icon: 'bpointer.png',
map: map,
title: 'Final'
);
Se le entrega a la API de Google Maps todos los puntos geográficos con
los que se realizará el trazado del recorrido.
var ruta = [
new google.maps.LatLng([Latitud del punto inicial],
[Longitud del punto inicial]),
new google.maps.LatLng([Puntos intermedios]),
new google.maps.LatLng([Latitud del punto final], [Longitud
del punto final])
];
198
Para finalizar el script, se establece la configuración de la línea trazada
indicando algunos de sus parámetros más importantes, como el color, el
ancho, la opacidad, entre otros.
var lineas = new google.maps.Polyline(
path: ruta,
map: map,
strokeColor: '#FF0000',
strokeWeight: 4,
strokeOpacity: 0.6,
clickable: false
);
</script>
</head>
Se culmina el código HTML indicando que al ejecutar el archivo se debe
cargar el método initialize() que realiza el proceso anteriormente descrito.
Del mismo modo, se establece el tamaño de la capa que contendrá al
mapa.
<body onload="initialize()">
<div id="map_canvas" style="width:660px; height:588px"></div>
</body>
</html>
ACCIÓN DEL BOTON ODBC
Si se presiona este botón, se llama al símbolo de sistema y se solicita que
inicie el archivo ejecutable correspondiente a Orígenes de datos ODBC
(C:\Windows\System32\Odbcad32), para facilitar el acceso a la interfaz de
configuración del conector ODBC con el cual se realiza el proceso de
conexión a la base de datos.
199
Figura 3.110. Diagrama de flujo del botón 'ODBC'
Figura 3.111. Acción del botón ODBC
ACCIÓN DEL BOTON MOSTRAR DATOS
Al presionar este botón se dejan invisibles todos los elementos excepto el
indicador del n° de elementos y la tabla que muestra las columnas de cada
variable y el cálculo de la distancia y la velocidad para cada elemento.
200
Figura 3.112. Diagrama de flujo del botón 'Mostrar datos'
Figura 3.113. Acción del botón Mostrar datos
201
ANÁLISIS DE LA SITUACIÓN
ANÁLISIS FODA
El análisis FODA es una herramienta que permite conocer la situación actual del
proyecto respecto a los factores internos y externos que afectan a la idea de
negocio. Dentro de los factores internos se encuentran las Fortalezas, todas
aquellas características que entregan a la organización una posición privilegiada
ante sus potenciales competidores. Del mismo modo, existen las Debilidades que
corresponden a la contraparte de las Fortalezas. Para los factores externos, se
cuenta con las Oportunidades, es decir, con todos aquellos puntos que permiten
al modelo de negocio obtener ventajas dentro de un entorno competitivo.
Finalmente, las Amenazas son la oposición de las Oportunidades, las cuales
representan situaciones provenientes del entorno competitivo que atentan contra
la permanencia de la empresa.
Figura 4.1. Matriz FODA de Telemetrics
202
MODELO CANVAS
El modelo Canvas permite conocer la propuesta de valor del proyecto,
garantizando el desarrollo de un modelo de negocio sólido y que plantea sus
objetivos de forma clara. Esta herramienta proporciona elementos que entregan
un valor agregado al negocio, dividiendo el proyecto en nueve módulos que
explican la forma en la que se generan los ingresos, así como las diferentes
maneras de abordar la relación con los clientes, los canales de distribución, los
proveedores y los costos e ingresos más importantes para el modelamiento de la
estructura del proyecto.
Figura 4.2. Modelo Canvas de Telemetrics
203
ESTIMACIÓN DE LA DEMANDA
Cada una de las empresas operadoras de Transantiago cuenta con una cierta
cantidad de buses, siendo las que controlan un mayor número de máquinas las
empresas Subus Chile, Buses Vulé S.A. y Express de Santiago Uno (Mondaca,
Ayala, & Vargas, 2015). En las siguientes figuras se aprecia el grado de
participación de cada empresa, así como la cantidad de vehículos operativos
dentro de la red, lo que nos permite tener una idea de la demanda que tendría
Telemetrics al momento de ser implantado en esta flota del transporte público.
Figura 4.3. Número de buses por empresa.
Figura 4.4. Participación por empresa en la red Transantiago
204
PRESUPUESTO
Cantidad Elemento Precio
1 Microcontrolador Arduino Mega 2560 $46.621
1 Microcomputadora Raspberry Pi $35.236
1 Módulo Bluetooth HC-06 $7.380
1 Sensor de combustible (ultrasónico) US $100
1 Sensor infrarrojo de tapa de tanque $106.967
1 Smartphone genérico $39.990
1 Router $14.990
1 Chip con plan de datos mensual $5.000
TOTAL $326.261
Tabla 4.1. Tabla de presupuesto
CARTA GANTT
Figura 4.5. Carta Gantt del proyecto
Figura 4.6. Detalle de la tabla de la Carta Gantt
205
ANALISIS DE RESULTADOS
ALCANCES Y LIMITACIONES DEL PROYECTO
Para la fase de prototipo de este proyecto existen limitaciones que están
directamente relacionadas con el funcionamiento de los sensores, dado que
teóricamente se tiene contemplada la adquisición de información desde el tanque
de combustible del bus. Sin embargo, al no disponer del acceso a un vehículo
real, se han simulado estos valores mediante la incorporación de un
potenciómetro como sensor analógico y un sensor digital por infrarrojos CNY-70
como el sensor digital que está asociado a la tapa del tanque de combustible.
Una segunda limitación está relacionada con la optimización de los códigos
fuente del proyecto. Como el desarrollo se encuentra en su fase de prueba, el
funcionamiento será satisfactorio, pero quizás no sea el más óptimo con respecto
a velocidad de procesamiento para la aplicación Android y la GUI en LabVIEW.
Como el prototipo mide las variables relacionadas con la localización geográfica
del móvil junto con las asociadas al nivel de combustible, se requirió de una
batería de 9 Volts para la alimentación de la maqueta de prototipos para la
extracción simultánea de estos elementos.
206
PRUEBAS DE FUNCIONAMIENTO
Para evaluar el desempeño de Telemetrics se han realizado tres pruebas de
funcionamiento en distintos escenarios, donde en cada una se analiza una
variable distinta según la forma del análisis. Primero, se ha realizado una prueba
de funcionamiento que deja de lado el cálculo de la trayectoria, enfocándose
solamente en la obtención, traspaso y visualización de los valores del sensor
analógico y del sensor digital. Posteriormente, se realizó una prueba de
funcionamiento móvil, la cual contempla únicamente el cálculo de la distancia, la
velocidad y el trazado de la trayectoria realizada por el vehículo. Finalmente, se
evaluó el funcionamiento del prototipo en movimiento, es decir, se realizó la
prueba en el interior de un bus del transporte público en conjunto con el prototipo
funcionando con una batería de 9V.
Figura 5.1. Montaje del prototipo
207
PRUEBA DE FUNCIONAMIENTO ESTÁTICO
Se inicia esta prueba con la energización del prototipo a través de un
adaptador de 5VDC con salida USB. El módulo Bluetooth comenzará a
parpadear, indicando que se encuentra energizado, mas sin comunicación
establecida.
Figura 5.2. Energización del prototipo
Luego, se debe iniciar la aplicación Android en el teléfono inteligente, la
cual como primera tarea se conecta inmediatamente al servidor de chat
IRC montado en la Raspberry, seguido de entablar la comunicación con
el módulo Bluetooth, indicando cuando se encuentre conectado.
Figura 5.3. Icono de la aplicación
208
Figura 5.4. Indicación del establecimiento de la conexión Bluetooth
Para verificar el correcto funcionamiento del sensor analógico, se cambió
el valor del potenciómetro de forma manual y se comprobó que,
efectivamente, se reflejaba exitosamente en la GUI de la aplicación. No
obstante, debido a la ausencia de filtros en el circuito, se presentaron
algunas señales de interferencia que provocaron un margen de error en el
valor medido, por lo que para una próxima innovación del proyecto sería
favorable contar con algún tipo de filtro que reduzca las señales de ruido.
Figura 5.5. Valor mínimo del sensor analógico
209
Figura 5.6. Valor máximo del sensor analógico
Se realizó el mismo procedimiento para el sensor digital, en donde sin
ningún obstáculo arrojó un valor de ‘0’ en la lectura. En cambio, al
momento de colocar un objeto sobre el sensor, cambió su estado a ‘1’.
Figura 5.7. Valor '0' del sensor digital
210
Figura 5.8. Valor '1' del sensor digital
Con los sensores funcionando, nos disponemos a realizar el envío de los
datos hacia el servidor IRC, por lo que accedemos mediante el cliente Kiwi
IRC al servidor montado en la Raspberry Pi.
Figura 5.9. Acceso al servidor de chat
211
Ya dentro del canal de chat, es posible comprobar que las tramas son
enviadas desde el teléfono al servidor exitosamente.
Figura 5.10. Ventana principal del canal de chat
Los comandos para la obtención de información son probados enviando
estas instrucciones al teléfono a través de un mensaje privado. Es posible
comparar que la información adquirida es casi idéntica a la que muestra la
interfaz gráfica del teléfono, en donde las mínimas variaciones presentes
son obra del tiempo en que demora el retorno de la información y de las
variaciones en la medición del GPS.
Figura 5.11. Comparación de la trama enviada y de las coordenadas GPS recibidas
Para el comando dirección, se comparó la dirección entregada por la
aplicación con las coordenadas geográficas obtenidas recientemente
ingresadas en el buscador Google, lo que permitió comprobar que la
dirección otorgada por la aplicación es verídica.
212
Figura 5.12. Obtención de la dirección del vehículo
El comando dir obtiene los archivos y carpetas presentes en el directorio
raíz del teléfono.
Figura 5.13. Ejecución del comando dir
Uno de los comandos más importantes son los que se detallarán a
continuación, en donde se visualiza el nivel de combustible medido a
través del comando nivel y de la posición de la tapa con el comando tapa.
213
Para este último valor, si resulta igual a ‘0’, asumirá que la tapa está
abierta. En caso contrario, estipulará que la tapa se encuentra cerrada.
Figura 5.14. Comprobación de los comandos nivel y tapa
Figura 5.15. Comprobación del comando tapa cuando el valor es igual a '0'
El comando fecha, devuelve la fecha y la hora del momento en que se
realiza la petición de información.
Figura 5.16. Comprobación del comando fecha
214
Es posible también cambiar tanto el nombre del bus dentro del canal de
chat como el que contiene la trama enviada por el teléfono. Esta acción se
realiza a través del comando bus NOMBRE.
Figura 5.17. Cambio de nombre del bus a través del comando bus
Lo siguiente a realizar es la extracción de las tramas desde el servidor de
chat para almacenarlas, posteriormente, en la base de datos MySQL. Para
esto accedemos via SSH a la Raspberry Pi y ejecutamos el programa del
cliente IRC que cumple este propósito.
Figura 5.18. Acceso a la Raspberry Pi via SSH
215
Figura 5.19. Ejecución del programa Cliente IRC
Cuando se inicia el funcionamiento del programa Cliente IRC se envían
automáticamente las tramas hacia la base de datos. Del mismo modo, se
envía una comprobación al canal de chat de que el programa se está
ejecutando exitosamente.
Figura 5.20. Ingreso del cliente IRC al canal de chat
En la base de datos se crea una nueva tabla que lleva por nombre el
asignado al bus que envía la información, la cual contiene dentro todos los
elementos enviados dentro de las tramas por el Cliente IRC.
216
Figura 5.21. Tabla del bus dentro de la base de datos
Figura 5.22. Tramas enviadas por el Cliente IRC hacia la base de datos
La interfaz gráfica de usuario desarrollada en LabVIEW, ejecutada en
tiempo real con los demás elementos del proyecto, muestra al instante los
valores que toman los sensores. A continuación se muestra cómo varían
los medidores del home cuando se cambia el valor del sensor analógico y
del sensor digital.
217
Figura 5.23. Visualización del valor máximo de los sensores en LabVIEW
Figura 5.24. Visualización del valor mínimo de los sensores en LabVIEW
218
Figura 5.25. Visualización del valor medio aproximado del sensor analógico
Otra de las posibilidades que ofrece la GUI desarrollada en LabVIEW es
la visualizar la tabla con todos los datos alusivos al bus seleccionado
almacenados en la base de datos. Es posible comparar la información
enviada al servidor de chat con la contenida en la tabla del programa,
resultando ser exactamente idéntica.
219
Figura 5.26. Comparación de las tramas enviadas
Al tratarse de una prueba estática, los gráficos que se despliegan a
continuación corresponden a la evolución del nivel de combustible y de la
posición de la tapa, dejando el de velocidad para la próxima prueba móvil,
al igual que el trazado de la trayectoria. Es importante recalcar que los
cálculos de distancia y velocidad para esta prueba, corresponden
notoriamente a valores cercanos a cero. Sin embargo, existen
imperfecciones en la medida entregada por el sistema de navegación
GPS, lo que deriva en errores en el resultado de estas variables.
Igualmente, en la gráfica es posible notar las fluctuaciones mencionadas
al inicio de esta prueba debido a la falta de un filtro que reduzca las
interferencias en el circuito electrónico.
220
Figura 5.27. Gráfico del nivel de combustible
Figura 5.28. Gráfico de la posición de la tapa
221
PRUEBA DE FUNCIONAMIENTO MÓVIL
En esta nueva prueba se evaluará únicamente lo relativo a las variables
distancia y velocidad a partir de las coordenadas geográficas obtenidas
desde el sistema GPS del teléfono, prescinciendo del análisis del consumo
de combustible y de la posición de la tapa. Se realizó una caminata y un
posterior viaje en automóvil con la aplicación ejecutándose continuamente
en el dispositivo móvil, obteniendo la latitud y longitud instantáneas para
cada medición efectuada, en intervalos de 30 segundos. Esta información
fue almacenada en la base de datos y luego mostrada en la tabla del
programa en LabVIEW, como se muestra a continuación.
Figura 5.29. Extracto de los datos contenidos en la base de datos
222
Figura 5.30. Tabla en LabVIEW con el extracto de la información de la base de datos
En la figura 5.31, la velocidad calculada responde a números relativamente bajos,
lo que tiene mucho sentido considerando que esta fase de la prueba se desarrolló
al momento de efectuar una caminata hacia el lugar donde se ubicaba el
automóvil.
En el gráfico de la figura 5.32 es posible apreciar que el valor de la velocidad
aumenta considerablemente a eso de las 12:00 hrs., momento en que se abordó
el vehículo para la ejecución de las pruebas en tiempo real. El resultado varía
conforme la velocidad del vehículo cambia en el intervalo de tiempo de cada
muestra.
223
Figura 5.31. Gráfico de velocidad
Figura 5.32. Gráfico de velocidad aumentado
224
La trayectoria seguida por el vehículo es trazada por el programa en
LabVIEW, indicando el punto de partida y el punto de término. Es
importante destacar, que para los momentos en que el dispositivo GPS
pierde la señal, el valor enviado por el teléfono móvil a la base de datos se
iguala a ‘0.0, 0.0’. No obstante, para filtrar este valor de la trayectoria
trazada y así evitar un recorrido erróneo, se consideró en un principio filtrar
esta coordenada mediante el código en LabVIEW, lo que resultó bastante
engorroso al momento de llevar a cabo el cálculo de la distancia y la
velocidad, ya que existía un desfase en el número de filas que era igual al
número de elementos iguales a cero. En otras palabras, esta técnica
aunque era viable de trabajar, presentó inconvenientes al momento de
presentar los datos de distancia y velocidad calculados e insertados en la
tabla. Por otra parte, finalmente se decidió realizar un filtro en la petición
de información desde la base de datos, considerando solamente todos los
elementos de la tabla que no posean latitud ni longitud igual a cero.
Figura 5.33. Trayectoria trazada del vehículo
225
Tal y como se describió anteriormente, el medidor de velocidad indica la
velocidad instantánea alcanzada por el vehículo al momento de efectuar
la medición, comparando el tiempo que demora en llegar de un punto
geográfico a otro. Si se consulta la dirección desde el servidor IRC, se
obtienen las diferentes direcciones cercanas a los puntos por donde circula
el vehículo.
Figura 5.34. Medición de la velocidad instantánea y distancia total
Figura 5.35. Direcciones cercanas a los puntos de circulación del vehículo
226
Las velocidades calculadas en la tabla de la figura 5.36 corresponden a
los niveles que el vehículo alcanzó al momento de efectuar las mediciones,
permitiendo afirmar que este proceso se ejecutó exitosamente.
Figura 5.36. Tabla con las velocidades alcanzadas por el automóvil
227
PRUEBA DE FUNCIONAMIENTO FINAL
Con las pruebas realizadas, ya es posible afirmar que el funcionamiento del
prototipo ha sido el esperado y que, aunque se encuentra en fase de prueba,
cumple con los objetivos básicos a los que se encuentra destinado, como lo
es el desarrollo de este sistema de telemetría. Sin embargo, se realizó una
última prueba al interior de un bus de la locomoción colectiva portando la
maqueta de prototipos que funcionaba alimentada a una batería de 9V, para
verificar si la medición de los sensores podría llevarse a cabo
simultáneamente con el cálculo de distancia y velocidad. Para esto, se
realizaron mediciones de prueba variando el valor del sensor analógico y
digital, al mismo momento en que el bus se dirigía al punto de término del
recorrido de evaluación para esta prueba.
Figura 5.37. Prueba de funcionamiento al interior de un bus de Transantiago
228
En la tabla de la siguiente figura se aprecia cómo varía la latitud y la
longitud en conjunto con los valores leídos desde ambos sensores. La
velocidad y la distancia, por su parte, toman valores coherentes para el
viaje realizado al interior del bus, permitiendo afirmar nuevamente que el
sistema cumple su cometido al monitorear las variables de
geoposicionamiento y de monitoreo de combustible.
Figura 5.38. Tabla con las mediciones realizadas al interior del bus
229
Figura 5.39. Recorrido realizado para la prueba final
A continuación se muestran los gráficos de las variables velocidad, consumo de
combustible y posición de la tapa, en donde el primero puede apreciarse que
varía entre diferentes escalones. Esto ocurre debido a que la medición no es
continua, sino que es discreta, es decir, el gráfico sólo toma los valores medidos
en los intervalos de tiempo de cada medición que son de 30 segundos. Para las
demás variables ocurre la misma situación, sólo que como ya es sabido, estos
valores son simulados manualmente.
230
Figura 5.40. Gráfico de velocidad
Figura 5.41. Gráfico de consumo de combustible
231
Figura 5.42. Gráfico de posición de la tapa
232
CONCLUSIONES
El desarrollo del proyecto Telemetrics para la realización de esta tesis dejó en
evidencia una realidad que muchas veces no se está acostumbrado a vivir en
relación al robo de combustible, quedando esta situación como una potencial
amenaza para las empresas operadoras de servicios de transporte, las cuales
requieren de la implementación de un sistema de telemetría que cumpla los
objetivos que propone Telemetrics.
El monitoreo del consumo de combustible, la posición de la tapa y la velocidad
son variables que pueden ser medidas en forma real solamente si se interviene
una máquina, razón por la cual para la fase de prototipo de este proyecto se
decidió simular estos valores a través de sensores electrónicos más pequeños,
pero con el mismo principio de funcionamiento, dada la complejidad para acceder
a la manipulación del tanque de combustible de un bus real.
La arquitectura modular que posee este proyecto le proporciona una versatilidad
de usos única, ya que al igual que la unión de varios bloques diferentes que
logran un objetivo en común, cada herramienta de adquisición, procesamiento y
visualización de los datos puede ser manejada de forma independiente sin
afectar los demás elementos de la solución.
La utilización del principio de backdoor y botnet abre una nueva gama de
posibilidades a la opción de utilizar estas tecnologías para usos diferentes que el
desarrollo de código malicioso. En otras palabras, es posible tomar la arquitectura
y funcionamiento utilizado por virus informáticos e implementarlo para tareas
distintas, como por ejemplo, el desarrollo de soluciones de ingeniería.
Sin embargo, el desarrollo de Telemetrics resultó en un principio complejo, ya
que no se disponía inicialmente de los conocimientos necesarios para desarrollar
un sistema de esta envergadura, en donde la investigación exhaustiva y la
233
adquisición de nuevas herramientas fueron indispensables para la obtención del
exitoso resultado final, pasando por fases donde los principales problemas que
existieron, se radicaron en la poca experiencia en la programación de la
aplicación Android y de la GUI en LabVIEW.
Aunque el prototipo de este proyecto logró un buen funcionamiento dentro de las
fases de prueba y los resultados obtenidos han sido sumamente satisfactorios,
queda sembrada la idea de que para el futuro en una próxima innovación del
proyecto se optimicen los códigos y se inserten, en donde se requiera, nuevas
tecnologías que entreguen mejores resultados para el objetivo principal que es
evitar el robo de combustible.
234
GLOSARIO
Shell: Corresponde a la interfaz de acceso a un sistema operativo consistente en
una línea de comandos, donde se carece de interfaz gráfica y los comandos se
realizan únicamente por teclado.
Flag: Se refiere a una variable interna del Sistema que a través de sus cambios
de estado lógico, se controlan acciones internas del programa.
Trama: Una trama es un método de encapsulación de datos, los cuales se
encuentra separados por delimitadores y son enviados como un único paquete.
Loopback: Dirección IP interna de una máquina que hace referencia a sí misma
para la comprobación del funcionamiento del adaptador de red o de un servidor
web alojado, como Apache
Toast: Mensaje emergente propio de la plataforma Android.
Shift Register: Herramienta del entorno de LabVIEW que permite almacenar
valores anteriores de los elementos de salida de una iteración, para su posterior
utilización en otros procesos.
Ping: Mensaje de comprobación de la existencia de comunicación entre dos
máquinas conectadas en una red.
NaN (Not a Number): Término que indica que el resultado de una operación
matemática no corresponde a un número válido.
Thread: Un thread (Del inglés: hilo) corresponde a un proceso ejecutado en
segundo plano que funciona de manera independiente al proceso principal,
quedando inhibido de modificar o insertar datos en éste último.
235
Handler: Un handler (Del inglés: manejador) puede entenderse como el puente
que existe entre un thread y el proceso principal, para que el primero le traspase
datos al segundo.
Socket: el término “Socket” hace referencia a la comunicación bidireccional
existente entre dos máquinas que toman los roles de cliente y servidor.
Timertask: Timertask es un conjunto de tareas que se ejecutan en segundo
plano y de forma cíclica, en un tiempo pre-definido por el programador.
Timer: Por Timer nos referimos al proceso que ejecuta la acción de automatizar
las tareas contenidas en el Timertask durante períodos pre-definidos por
programa.
BufferedReader: Con esta función es posible leer líneas de código desde
cualquier fuente, es decir, almacena en la memoria interna una porción de código
proveniente del usuario o del socket.
BufferedWriter: Paralelamente al BufferedReader, esta función permite escribir
una determinada línea de código pre-definida en alguna sección que requiera de
esta tarea. Por ejemplo, en un cuadro de texto (EditText).
LocationListener: LocationListener es una clase que detecta cambios en la
ubicación del teléfono a través de la señal del GPS de forma continua.
236
Excepciones: Una excepción corresponde a un error provocado en la aplicación,
el cual desestabiliza el correcto funcionamiento de ésta. Es posible prevenirlo
mediante la función try/catch, la cual atrapa la excepción que podría gestarse
dentro de una sección de código, haciendo que la aplicación se mantenga
funcionando incluso si el error se manifiesta.
Por ejemplo:
try
//Código susceptible a provocar errores
catch(TipoDeExcepcion variable)
//Indicador del error
Intents: Son objetos que permiten lanzar actividades desde una aplicación
principal o externa, de manera que permiten integrar invocación de eventos,
alarmas, entre otros servicios.
BroadcastReceiver: Es una clase que actúa como capturador de eventos en el
entorno de Android, es decir, estará todo el tiempo “escuchando” las acciones
que sucedan en el teléfono hasta que ocurra alguna que gatille un evento. Por
ejemplo, si el sistema operativo se inicia, que ejecute cierta aplicación.
237
REFERENCIAS
Abad Domingo, A., & Madrid Mateo, M. (1997). Redes de Área Local. (J. Ocaña Ávila, Ed.)
Madrid, España: McGraw-Hill/Interamericana de España, S.A.U.
Android Ayuda. (2012). (M. Á. Muñoz, Editor, & J. Sanz, Productor) Obtenido de Android Ayuda:
http://androidayuda.com/tutorial-de-ayuda-y-primeros-pasos/
Ángel, M. (2002). Manual del IRC. Obtenido de Amistad Sincera:
http://www.arrakis.es/~domitila/ayuda/irc.htm
Aprende Android. (2012). Instalación del entorno de desarrollo de Android ¿Eclipse o Android
Studio? Obtenido de Aprende Android:
http://www.aprendeandroid.com/l1/instalacion.htm
Archundia Papacetzi, F. M. (2003). Wireless Personal Area Network (WPAN) & Home
Networking. Universidad de las Américas Puebla, Departamento de Ingeniería
Electrónica, Cholula, Puebla, México. Obtenido de
http://catarina.udlap.mx/u_dl_a/tales/documentos/lem/archundia_p_fm/capitulo3.pdf
Baltazar Gálvez, J. M., & Campuzano Ramírez, J. C. (2011). Diseño e implementación de un
esquema de seguridad perimetral para redes de datos. Universidad Nacional Autónoma
de México, Facultad de Ingeniería, México, D.F. Obtenido de
http://www.ptolomeo.unam.mx:8080/xmlui/bitstream/handle/132.248.52.100/174/Version
%20Final.pdf?sequence=17
Barrera Pinto, J. J. (2011). Conexión Labview MySQL. Centro industrial de mantenimiento y
manufactura.
Bejarano, M. (25 de Septiembre de 2013). Conexión remota al Raspberry Pi usando SSH.
Obtenido de Frambuesa Pi Colombia: http://www.frambuesapi.co/2013/09/25/tutorial-5-
conexion-remota-al-raspberry-pi-usando-ssh/
Berkland, B. (30 de Septiembre de 2013). Java Program to Read GPS Data from a Sparkfun
Copernicus II GPS & Store it in a MySQL Database on a Raspberry Pi. Obtenido de
Brad's Raspberry Pi Blog: http://bradsrpi.blogspot.cl/2013/09/java-program-to-read-gps-
data-from.html
238
Camargo Olivares, J. (2009). Modelo de cobertura para redes inalámbricas de interiores.
Universidad de Sevilla, Departamento de Teoría de la Señal y Comunicaciones, Sevilla.
Obtenido de http://bibing.us.es/proyectos/abreproy/11761/fichero/Volumen1%252F6-
Cap%EDtulo2+-+Redes+inal%E1mbricas+de+%E1rea+personal+(WPAN).pdf
Cambra, P. (28 de Noviembre de 2008). Origen y futuro de MySQL. Obtenido de Cambrico:
http://cambrico.net/mysql/origen-y-futuro-de-mysql
Carrodeguas, N. (2015). Códigos para crear y mostrar mapas de Google Maps. Obtenido de
NorfiPC: https://norfipc.com/codigos/codigos-para-crear-mostrar-mapas-google-
maps.php
Castillo, G. G. (2005). Sistemas de comunicaciones. Universidad Tecnológica de la Mixteca,
Redes y Sistemas Distribuidos. Obtenido de
mixteco.utm.mx/~resdi/historial/materias/IPv4.pdf
Codina Barberà, M. (2013). 5213: Crear dispositivo para personas sordas (plataforma hardware
Arduino). Universitat Autònoma de Barcelona, Escola Tècnica Superior d’Enginyeria,
Bellaterra, Barcelona, España. Obtenido de
https://ddd.uab.cat/pub/trerecpro/2013/hdl_2072_233410/PFC_MarcCodinaBarbera.pdf
Comisión Federal de Comercio del gobierno de los Estados Unidos. (2015). Cómo funcionan las
aplicaciones móviles. Obtenido de Alerta en Línea:
https://www.alertaenlinea.gov/articles/pdf-s0004_0.pdf
Cruz Ledesma, C. H. (2010). El protocolo TCP/IP. Obtenido de Tesis de Redes: http://tesis-
redes.blogspot.cl/2010/03/el-protocolo-tcpip.html
CyberAdmin Pro. (19 de Julio de 2011). Guía de cómo redireccionar (mapear/forward) el puerto
del servidor web de CyberAdmin en router: Marca: TP-LINK Modelo:TL-WR741N.
Obtenido de CyberAdmin:
http://foros.cyberadmin.net/cakb/Guia_CyberAdmin_Redireccionar_Puerto_ROUTER_T
P-LINK_TL_WR741N.pdf
Daud, S., Fac. of Biosci. & Med. Eng., U. T., Mohd Sobani, S., Ramiee, M., & Mahmood, N. (28-
30 de Octubre de 2013). Application of Infrared sensor for shape detection. (IEEE, Ed.)
Photonics (ICP), 2013 IEEE 4th International Conference on, 145-147.
Devikiruba, B. (2013). Vehicle Speed Control System Using GSM/GPRS. (IJCSIT) International
Journal of Computer Science and Information Technologies, 983-987.
239
Dhaval, C., Darde, D., & Chitalia, S. (16 de Noviembre de 2013). Smart Projectors using Remote
Controlled Raspberry Pi. (IJCA, Ed.) International Journal of Computer Applications
(0975- 8887), 82, 6-11.
Ediciones Especiales El Mercurio. (9 de Mayo de 2013). Un buen aliado para el transporte
público. Ediciones Especiales El Mercurio. Obtenido de
http://www.edicionesespeciales.elmercurio.com
Enríquez, A., Maldonado, J., Nakamura, Y., & Nogueron, G. (2014). MySQL. Obtenido de
http://www.gridmorelos.uaem.mx/~mcruz//cursos/miic/MySQL.pdf
Epictia. (2008). ¿Qué es una dirección IP? Obtenido de Epictia:
http://www.epictia.es/Articulos/Que_es_una_direccion_IP.aspx
Escola Tècnica Superior d'Enginyeria Informàtica, Universitat Politècnica de València. (2012).
Android. Obtenido de Blog de la asignatura Historia de la Informática:
http://histinf.blogs.upv.es/2012/12/14/android/
Escola Tècnica Superior d'Enginyeria Informàtica, Universitat Politècnica de València. (2013).
Raspberry pi. (L. Contreras, Editor) Obtenido de Blog de la asignatura Historia de la
Informática de la Escuela Técnica Superior de Ingeniería Informática de la Universidad
Politécnica de Valencia: http://histinf.blogs.upv.es/2013/12/18/raspberry-pi/
ESET. (24 de Febrero de 2012). Mobile World Congress: ESET to Showcase ESET. Mobile
Security Solution for Android Smartphones and Tablets. Obtenido de ESET - Press
Releases: https://www.eset.com/me-ar/about/press/articles/article/mobile-world-
congress-eset-to-showcase-eset-mobile-security-solution-for-android-smartphones-and-
tablets/
Esquiva, A. (16 de Agosto de 2013). Instalación de Apache+PHP+MySQL. Obtenido de Geeky
Theory: https://geekytheory.com/tutorial-raspberry-pi-15-instalacion-de-apache-mysql-
php/
Everardo Pérez, F. O. (20 de Enero de 2009). Tecnología 3G. Obtenido de Slideshare:
http://es.slideshare.net/islas2287/tecnologa-3g-presentation
Exposito, J. (9 de Diciembre de 2012). ¿Como obtener la Ubicación actual con el GPS de
Android? Obtenido de ExpoCodeTech: http://expocodetech.com/expo-tips-como-
obtener-la-ubicacion-actual-con-el-gps-de-android/
240
Ferrer Delgado, D. (16 de Enero de 2013). Enviar y recibir acciones con BroadcastReceiver en
Android. Obtenido de Nosinmiubuntu: http://www.nosinmiubuntu.com/enviar-y-recibir-
acciones-con/
Franklin, C., & Layton, J. (28 de Junio de 2000). How Bluetooth Works. Obtenido de How Stuff
Works Website: http://electronics.howstuffworks.com/bluetooth.htm
García Bocanegra, N. (2 de Junio de 2012). Protocolo TCP/IP. Obtenido de Slideshare:
http://es.slideshare.net/neligarciaboc/protocolo-tcpip-13176705
García, A., & Navarro, K. (17 de Agosto de 2014). Comunicar Java con base de datos MySQL.
Obtenido de Panama Hitek: http://panamahitek.com/comunicar-java-con-base-de-datos-
mysql/
GCF Aprende Libre. (2014). Aprende Android: ¿Qué es Android? Obtenido de
GCFAprendeLibre.org:
http://www.gcfaprendelibre.org/tecnologia/curso/aprende_a_usar_android/aprende_a_d
escargar_aplicaciones/1.do
Giménez, T., & Elena, R. M. (2009-2010). Sistema de Posicionamiento Global (GPS).
Universidad de Murcia, Departamento de Física. Murcia, España: Gravitación y
Astrofísica. Obtenido de http://webs.um.es/bussons/GPSresumen_TamaraElena.pdf
Gironés, J. T. (2015). Componentes de una aplicación. (Universidad Politécnica de Valencia)
Obtenido de Diploma de especialización en desarrollo de aplicaciones para Android:
http://www.androidcurso.com/index.php/tutoriales-android/31-unidad-1-vision-general-y-
entorno-de-desarrollo/149-componentes-de-una-aplicacion
Gironés, J. T. (2015). Ficheros y carpetas de un proyecto Android. Obtenido de Diploma de
especialización en desarrollo de aplicaciones para Android:
http://www.androidcurso.com/index.php/tutoriales-android-fundamentos/31-unidad-1-
vision-general-y-entorno-de-desarrollo/148-ficheros-y-carpetas-de-un-proyecto-android
González, S. (2005). IRC: Internet Relay Chat. Escuela Preparatoria Lázaro Cárdenas, Técnicas
de Laboratorio, Michoacán, México. Obtenido de Técnicas de Laboratorio:
http://www.eplc.umich.mx/salvadorgs/optativa/opt.html
Google, I. (2015). Google Maps Javascript API. Obtenido de Google Developers:
https://developers.google.com/maps/documentation/javascript/tutorial
241
Google, Inc. (2015). Geocoder. Obtenido de Developers:
http://developer.android.com/intl/es/reference/android/location/Geocoder.html
Google, Inc. (2015). Developers Android. Obtenido de Developers Android Website:
http://developer.android.com/intl/es/index.html
GSMSPAIN. (2015). Glosario. Obtenido de GsmSpain:
http://www.gsmspain.com/glosario/?palabra=3g
Gutovnik, P. (1999). Cómo funciona el sistema GPS. Obtenido de
http://gutovnik.com/como_func_sist_gps.htm
Guzmán, M. (26 de Octubre de 2013). Banda robaba petróleo de un bus oruga en movimiento.
Las Últimas Noticias, pág. 16.
Halvorsen, H.-P. (2011). Database Communication in LabVIEW. Telemark University College,
Department of Electrical Engineering, Information Technology and Cybernetics,
Porsgrunn, Noruega.
Hernández Zapata, A., Álvarez Uribe, H., & Arango Alzate, B. (Mayo de 2012). Los Sistemas de
Monitoreo Satelital, una propuesta logística integral para el manejo. Revista Gestión de
las Personas y Tecnología.
Hernando, R. (27 de Enero de 2002). TCP/IP. Obtenido de
http://www2.rhernando.net/modules/tutorials/doc/redes/tcp.html
Historia de la Informática. (2012). Smartphones. Obtenido de Blog de la asignatura Historia de
la Informática de la Escuela Técnica Superior de Ingeniería Informática de la
Universidad Politécnica de Valencia: http://histinf.blogs.upv.es/2012/12/03/smartphones/
HumanLinks. (4 de Abril de 2011). Conectarnos por SSH a nuestra LAN con IP Dinámica – NO-
IP – Modem Tomson TG587 V7. Obtenido de Humanlinks:
https://humanliks.wordpress.com/conectarnos-por-ssh-a-nuestra-lan-con-ip-dinamica-
no-ip-modem-tomson-tg587-v7/
Informática-Hoy. (2010). ¿Qué es la tecnología 3G? Obtenido de Informática-Hoy:
http://www.informatica-hoy.com.ar/aprender-informatica/Que-es--la-tecnologia-3G.php
Informática-HOY. (2012). 1G, 2G, GSM, 3G, EDGE, HPSA, 4G y LTE: La evolución de las
conexiones móviles. Obtenido de Informática-HOY: http://www.informatica-
242
hoy.com.ar/soluciones-moviles/1G-2G-GSM-3G-EDGE-HPSA-4G-LTE-evolucion-
conexiones-moviles.php
IRC server on the raspberry pi. (20 de Diciembre de 2012). Obtenido de Raspberry Pi Server
Admin: https://raspadmin.wordpress.com/
Jing, Y., Zhang, L., Arce, I., & Farajidavar, A. (2 de Mayo de 2014). AndroRC: An Android
remote control car unit for search missions. (IEEE, Ed.) Systems, Applications and
Technology Conference (LISAT), 2014 IEEE Long Island, 1-5.
Kaspersky Lab. (2015). Amenazas de seguridad en Internet. Obtenido de Internet Security
Center: http://www.kaspersky.es/internet-security-center/threats/botnet-attacks
Krendzel, A., Inst. of Commun. Eng., T. U., Koucheryavy, Y., Harju, J., & Lopatin, S. (20-24 de
Junio de 2004). Method for estimating parameters of 3G data traffic. (IEEE, Ed.)
Communications, 2004 IEEE International Conference on, 7, 4312-4316 Vol.7.
Kushner, D. (26 de Octubre de 2011). The making of Arduino. IEEE Spectrum. Obtenido de
http://spectrum.ieee.org/geek-life/hands-on/the-making-of-arduino
Kyle Senkevich, N. L. (2009). Real Time weather Information using Labview and Onset HOBO
weather station.
La Nación Online. (28 de Junio de 2008). Detienen a dos choferes de alimentadores del
Transantiago por robo de petróleo. La Nación Online.
La Róvere, C., Plaza, J., Silva, W., Urbano, A., & Utrera, V. (2003). Bluetooth™. Universidad
Simón Bolivar, Redes de Computadoras II, Laboratorio Docente de Computación,
Caracas, Venezuela. Obtenido de
http://ldc.usb.ve/~poc/RedesII/Grupos/G1/tabla_de_contenidos.html
La Segunda Online. (25 de Octubre de 2013). Delincuentes robaban petróleo desde las
micros... ¡En movimiento! La Segunda Online.
Lambert Sarango, Y. (2014). Arduino para creativos, electrónica visual. (Slideshare, Ed.)
Guayaquil, Ecuador. Obtenido de http://es.slideshare.net/YamilLambert/arduino-historia-
ide-lenguaje-de-programacion-y-proyectos-por-msc-yamil-lambert
Lamine, H., Dept. Technol. Inf. of ISET of Sfax, H. I., & Abid, H. (21-23 de Diciembre de 2014).
Remote control of a domestic equipment from an Android application based on
243
Raspberry pi card. (IEEE, Ed.) Sciences and Techniques of Automatic Control and
Computer Engineering (STA), 2014 15th International Conference on, 903-908.
Lara, Á. (20 de Marzo de 2012). Conexión a MySQL server desde cualquier host. Obtenido de
Álvaro Lara, Programación & Media: http://www.alvarolara.com/2012/03/20/conexion-a-
mysql-server-desde-cualquier-host/
Li, H., Coll. of Inf. Eng., N. C., & Zhijian, L. (3-5 de Diciembre de 2010). The study and
implementation of mobile GPS navigation system based on Google Maps. (IEEE, Ed.)
Computer and Information Application (ICCIA), 2010 International Conference on, 87-
90.
Li, Y., Cui, W., Zhang, R., & Li, D. (27-29 de Mayo de 2011). Research based on OSI model.
Communication Software and Networks (ICCSN), 2011 IEEE 3rd International
Conference on, 554 - 557.
Liblab, C., Dept. of Printing & Packaging Technol., K. M., & Nimnual, R. (2-4 de Noviembre de
2010). packaging, Design of database for online self-learning in polymers for food.
(IEEE, Ed.) Computer Technology and Development (ICCTD), 2010 2nd International
Conference on, 522 - 525.
Maltez, C. (2015). El Smartphone. Obtenido de
http://smartphoneavancetecnologico.blogspot.cl/p/historia-y-evolucion-del-
smartphone.html
Mancha García, A. J. (2015). Curso de microcontroladores bajo la plataforma Arduino. (L. M.
Martin Martín, Editor) Obtenido de Sitio web del Departamento de Electrónica del IES
Emerita Augusta: http://platea.pntic.mec.es/~lmarti2/
Menéndez-Barzanallana, R. (2015). Telecomunicaciones. Universidad de Murcia, Informática
Aplicada a las Ciencias Sociales. Murcia, España: Grado en Ciencias Políticas y
Gestión Pública. Obtenido de Sitio de docencia de Rafael Barzanallana:
http://www.um.es/docencia/barzana/IACCSS/Telecomunicaciones.html
Microsoft Corporation. (2012). ¿Qué es un botnet? Obtenido de Centro de seguridad y
Protección: https://www.microsoft.com/es-es/security/resources/botnet-whatis.aspx
MiTAC Intl. (2010). Servicios MioMore: El GPS a fondo. Obtenido de Mio GPS Technology, the
leading navigation device manufacturer: http://eu.mio.com/es_es/sistema-
posicionamiento-global_4978.htm
244
Mondaca, A., Ayala, K., & Vargas, G. (2015). Proyecto Monitoreo de Combustible. Universidad
Andrés Bello, Escuela de Ingeniería Comercial.
Naseem, F., Shafqat, M., Sabir, U., & Shahzad, A. (Febrero de 2010). A Survey of Botnet
Technology and Detection. IEEE Xplore Digital Library.
National Instruments. (2015). Documentos de Soporte Técnico. Obtenido de National
Instruments.
neil-black.co.uk. (2015). neil-black.co.uk. Obtenido de Raspberry Pi Beginners Guide:
http://www.neil-black.co.uk/raspberry-pi-beginners-guide#.VmgEdtLhDIU
Nuñez, K. (18 de Julio de 2013). Sistema Operativo Android. Obtenido de Slideshare:
http://es.slideshare.net/karenonunez/sistema-operativo-android-versiones-historia
Oikarinen, J., & Reed, D. (1999). Protocolo de Charla Basado en Internet (Internet Relay Chat,
IRC). (C. García Argos, Ed.) Obtenido de RFC-ES: http://www.rfc-es.org/rfc/rfc1459-
es.txt
Palominos, N. (2014). Apuntes del curso de Redes de datos. Universidad Andrés Bello, Escuela
de Industrias.
Pomares, J. (2009). Manual de Arduino. Universidad de Alicante, Grupo de Innovación
Educativa en Automática, Alicante, España. Obtenido de
http://rua.ua.es/dspace/bitstream/10045/11833/1/arduino.pdf
Pozo, G. (21 de Febrero de 2013). Arrancar aplicación al iniciar Android. Obtenido de
Aprendiendo de Android y un más:
http://www.aprendiendodeandroidymas.com/2013/02/arrancar-aplicacion-al-iniciar-
android.html
Proctor, T., & Roke Manor Res. Ltd., R. U. (23-27 de Junio de 2003). Evolution to 3G services:
provision of 3G services over GERAN (GSM/EDGE radio access network). 3G Mobile
Communication Technologies, 2003. 3G 2003. 4th International Conference on (Conf.
Publ. No. 494), 78-82.
QNAP Systems, Inc. (18 de Noviembre de 2015). Configure un servicio DDNS para tener
acceso remoto por Internet a un QNAP Turbo NAS. Obtenido de QNAP Systems
Website: 2014
245
Raspberry Pi Server Admin. (2012). IRC Server on the Raspberry Pi. Obtenido de Raspberry Pi
Server Admin: https://raspadmin.wordpress.com/2012/12/20/irc-server-on-the-raspberry-
pi/
RaspiPress. (24 de Septiembre de 2012). Tutorial – Install PhpMyAdmin on your Raspberry Pi.
Obtenido de RaspiPress: http://raspipress.com/2012/09/tutorial-install-phpmyadmin-on-
your-raspberry-pi/
Riffo Gutiérrez, M. A. (2009). Vulnerabilidades de las redes TCP/IP y principales mecanismos
de seguridad. Universidad Austral de Chile, Escuela de Ingeniería Civil Electrónica,
Valdivia, Chile. Obtenido de
http://cybertesis.uach.cl/tesis/uach/2009/bmfcir564v/doc/bmfcir564v.pdf
Salmerón, S. (2005). Sensor CNY70. Obtenido de LA LUZ Y LA ELECTRÓNICA
INFRARROJOS: http://www.info-
ab.uclm.es/labelec/solar/otros/infrarrojos/sensor_cny70.htm
Sevilla, J. P., & Sánchez, P. (2005/2006). Comunicación entre dispositivos Bluetooth.
Universidad de Granada, E.T.S. De Ingenierías y Telecomunicación.
Sharma, P., Electron. & Commun. Eng., A. U., Singh, S., Sharma, M., & Singh, R. (19-20 de
Febrero de 2015). Development of LabVIEW based system for interfacing with GPS
receiver. (IEEE, Ed.) Signal Processing and Integrated Networks (SPIN), 2015 2nd
International Conference on, 203 - 206.
SI SAT. (2014). Características y Funcionamiento del GPS. Obtenido de Sitio corporativo de
SISAT: Sistema satelital de cobertura integral: http://www.gps-sisat.com.ar/Web-
%20datos.pdf
Trastejant. (2011). Sensores de infrarrojos CNY70. Obtenido de Trastejant:
http://www.trastejant.es/tutoriales/electronica/sensordeinfrarrojos_cny70.html
Vicente Vargas, F., Juárez Zepeda, J., Hernández, R., & Sánchez Quirino, M. (2000). Redes
Inalámbricas. (Centro de Estudios Superiores de Córdoba A.C.) Obtenido de
http://tsusistemas.tripod.com/julia.html
Wilkinson, D., Dept. of Comput. Sci., C. U., Edward Chow, C., & Cai, Y. (10-11 de Junio de
2004). Enhanced secure dynamic DNS update with indirect route. (IEEE, Ed.)
Information Assurance Workshop, 2004. Proceedings from the Fifth Annual IEEE SMC,
335 - 341.
246
Xataka Android. (2014). ¿Cómo funcionan los permisos y seguridad de los datos en Android?
Obtenido de Sitio web de Xataka Android:
http://www.xatakandroid.com/seguridad/como-funcionan-los-permisos-y-seguridad-de-
los-datos-en-android
Zhiyuan, Z., Dept. of Comput. Inf. Eng., C. T., Xinji, T., Qingquan, J., & Mei, L. (23-25 de Mayo
de 2013). Mobile learning system over 3G based on triple play. Software Engineering
and Service Science (ICSESS), 2013 4th IEEE International Conference on, 616-618.
247
ANEXOS
Código Android
Inicio de la app con el boot de Android
package com.example.androidirc;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootReciever extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent arg1)
// Esto deberia lanzar la clase que va a iniciar nuestra aplicación
Intent myIntent = new Intent(context, MainActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
Código principal de la aplicación Android
package com.example.androidirc;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
248
import java.util.UUID;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.Editable;
import android.text.Selection;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
//HANDLER GESTIONA DATOS PROVENIENTES DESDE EL SERVIDOR
private Handler handler = new Handler();
public ListView msgView;
public static String host="fserranovargas.no-ip.org";
public static Socket socket=null;
public static BufferedReader in = null;
public static PrintWriter out=null;
public String str="";
//VARIABLES BLUETOOTH
TextView txtString;
Handler bluetoothIn;
final int handlerState = 0;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
public String deviceMAC="20:14:05:22:16:56";
public String deviceName = "HC-06";
// IDENTIFICADOR DE LA COMUNICACIÓN ANDROID
private static final UUID BTMODULEUUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
249
//VARIABLES TXT
public static String txt;
public int lineas=0;
public int max_lineas=50;
public static String remitente="";
public static String nick="";
//VARIABLES TRAMAS
public String trama="";
public static String FechaHora="";
public static String bus="000";
public static String nivel="NaN";
public static String tapa="NaN";
public static double lat;
public static double lon;
public static String direccion="";
//VARIABLES LAYOUT
public static EditText et;
public EditText IPText;
public EditText gpsText;
public EditText tramaText;
public Button btnSend;
public Button btnTrama;
//VARIABLES TIMER
public Timer timer;
TimerTask timerTask;
final Handler thandler = new Handler();
///////////////////////////
// ONBACKPRESSED (SALIR)
///////////////////////////
public void onBackPressed()
Toasty("Saliendo");
try
socket.close();
btSocket.close();
catch (IOException e)
e.printStackTrace();
catch(NullPointerException e)
catch(RuntimeException e)
finish();
return;
//////////////////////////
// ONCREATE (MAIN)
//////////////////////////
@Override
public void onCreate(Bundle savedInstanceState)
//DECLARACION COMPONENTES DEL LAYOUT
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.editText1);
gpsText= (EditText) findViewById(R.id.gpsText);
250
IPText= (EditText) findViewById(R.id.IPText);
tramaText= (EditText) findViewById(R.id.tramaText);
btnSend = (Button) findViewById(R.id.btn_Send);
btnTrama= (Button) findViewById(R.id.btn_Trama);
txtString = (TextView) findViewById(R.id.txtString);
IntentFilter filter1 =
new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
IntentFilter filter3 =
new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiver, filter1);
this.registerReceiver(mReceiver, filter3);
//GPS
LocationManager mlocManager =
(LocationManager)
getSystemService(Context.LOCATION_SERVICE);
MyLocationListener mlocListener = new MyLocationListener();
mlocListener.setMainActivity(this);
mlocManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0,
(LocationListener) mlocListener);
//IP
try
IPText.setText(ip());
catch (SocketException e1)
e1.printStackTrace();
catch(NullPointerException e)
//INICIO DEL SOCKET CLIENTE BIDIRECCIONAL IRC
ConectarIRC();
//THREAD QUE GESTIONA LOS MENSAJES DEL SERVIDOR
receiveMsg();
// INICIA EL TIMER
startTimer();
//BLUETOOTH
bluetoothIn = new Handler()
public void handleMessage(android.os.Message msg)
try
// Mensaje leido desde el
//dispositivo BT enviado al Handler
String readMessage = (String) msg.obj;
//Mantiene anexando caracteres
//hasta que se topa con el simbolo ~
recDataString.append(readMessage);
//Indice de Delimitador de fin de linea
int endOfLineIndex =
recDataString.indexOf("~");
// Se asegura que la cadena no
//tiene longitud=0, es decir, es no nula
if (endOfLineIndex > 0)
251
//Extrae la cadena recibida
String dataInPrint =
recDataString.substring(0,
endOfLineIndex);
txtString.setText(
"Datos recibidos = "
+ dataInPrint);
// Si detecta que el
//primer caracter es #,
//realiza la extraccion
//de los datos
if (
recDataString.charAt(0)
== '#')
//Obtiene el valor del
//sensor ubicado entre
//los indices 1-5
nivel =
recDataString
.substring(1, 5);
//Lo mismo con el otro sensor
tapa =
recDataString.
substring(6, 7);
//Vacía todos los
//datos de la cadena
recDataString.delete(0,
recDataString.length());
dataInPrint = " ";
catch(NullPointerException e)
;
// Obtener el objeto que representa el adaptador BT
btAdapter = BluetoothAdapter.getDefaultAdapter();
checkBTState();
////LISTENER DEL BOTON SEND
btnSend.setOnClickListener(new View.OnClickListener()
//LISTENER DEL BOTON TRAMA
btnTrama.setOnClickListener(new
View.OnClickListener()
@Override
public void onClick(View v)
trama="$"+Fecha()+";"+bus+";"+
nivel+";"+tapa+";"+lat+";"+lon+"%";
sendMessageToServer(trama);
tramaText.setText(trama);
Toasty(trama);
if(nivel=="NaN"&&tapa=="NaN")
252
onResume();
);
//////////////////////////////
// CONECTAR IRC
/////////////////////////////
public static void ConectarIRC()
try
socket.close();
catch (Exception e)
try
socket = new Socket(host,6667);
out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())),true);
File tarjeta = Environment.
getExternalStorageDirectory();
File file = new File(tarjeta.
getAbsolutePath(), "bus.txt");
if(file.exists())
//SETEO NOMBRE BUS
String txt1="bus.txt";
nombreBus(txt1);
else
String txt1="bus.txt";
int numero = (int) (Math.random() *1000)
+ 1;
nick="BUS-"+numero;
grabar(txt1, nick);
nombreBus(txt1);
out.println("NICK "+nick+'\n');
out.println(
"USER mynick 0 * :Real Name" + '\n');
out.println("JOIN #mychannel" + '\n');
out.flush();
catch(NullPointerException e)
catch(RuntimeException e)
catch (UnknownHostException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
//////////////////////////////
//MENSAJE EMERGENTE TOAST!!
/////////////////////////////
253
public void Toasty(String s)
Toast.makeText(getApplicationContext(), s,
Toast.LENGTH_SHORT).show();
//////////////////////////
//FUNCIONES TIMER
//////////////////////////
public void startTimer()
timer = new Timer();
initializeTimerTask();
timer.schedule(timerTask, 3000,30000);
public void initializeTimerTask()
timerTask = new TimerTask()
public void run()
thandler.post(new Runnable()
public void run()
try
if(!socket.isConnected())
Toasty("Reconectando");
ConectarIRC();
catch(
NullPointerException e)
if(nivel=="NaN"&&
tapa=="NaN")
onResume();
trama="$"+Fecha()+
";"+bus+";"+nivel
+";"+tapa+";"+lat+
";"+lon+"%";
tramaText.setText(trama,
TextView.
BufferType.EDITABLE);
Toasty(trama);
try
sendMessageToServer(trama);
catch (Exception e)
e.printStackTrace();
//FIN RUN 1
); //FIN HANDLER
//FIN RUN 2
; //FIN TIMERTASK
//////////////////////////
//DETECTAR IP
//////////////////////////
@TargetApi(
Build.VERSION_CODES.GINGERBREAD)
@SuppressLint("NewApi")
254
static String ip() throws
SocketException
Enumeration<NetworkInterface> nis =
NetworkInterface.getNetworkInterfaces();
NetworkInterface ni;
while (nis.hasMoreElements())
ni = nis.nextElement();
if (!ni.isLoopback()/*SI NO ES LOOPBACK*/
&& ni.isUp()/*Y SI ESTÁ FUNCIONANDO*/)
for (InterfaceAddress ia :
ni.getInterfaceAddresses())
//Filtro para detectar
//si la IP es version 4 o 6
if (ia.getAddress().
getAddress().length == 4)
//4 para ipv4, 16 para ipv6
return ia.getAddress()
.toString();
return null;
//////////////////////////////
//FECHA/HORA
/////////////////////////////
public static String Fecha()
FechaHora =(DateFormat.format(
"ddMMyy;HHmmss",
new java.util.Date()).toString());
return FechaHora;
public static void
sendMessageToServer(String str)
final String str1=str;
new Thread(new Runnable()
@Override
public void run()
try
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream()
)),true);
out.println(
"PRIVMSG #mychannel :"+str1);
out.flush();
catch (UnknownHostException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
255
catch(NullPointerException e)
).start();
///////////////////////////////////////////////////
//RECEIVEMSG (MENSAJES PROVENIENTES DEL SERVER IRC)
///////////////////////////////////////////////////
public void receiveMsg()
new Thread(new Runnable()
@Override
public void run()
try
in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
catch (IOException e)
e.printStackTrace();
catch(NullPointerException e)
while(true)
String msg = null;
try
// ACA SE DEFINE EL STRING
//MSG A PARTIR DEL
//BUFFEREDREADER
//QUE APUNTA AL SOCKET
msg = in.readLine();
String comando="";
if(msg.indexOf(
"PRIVMSG")!=-1)
if(msg.indexOf(
":")!=-1)
String[] parts =
msg.split(":");
comando=parts[
parts.length-1];
remitente=
msg.substring(msg.indexOf(":")+1,
msg.indexOf("!"));
//SOLO REACCIONA ANTE EL USUARIO ROOT
if(remitente.equals("root"))
try
Enviar("PRIVMSG "+remitente+" :remitente: *"+remitente+"* comando:
*"+comando+"*");
catch (Exception e)
ProcesarComando(comando);
else if(msg.indexOf("PING")!=-1)
if(msg.indexOf(":")!=-1)
String[] parts = msg.split(":");
256
comando=parts[parts.length-1];
try
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),true);
out.println("PONG :"+comando);
out.println("PRIVMSG #mychannel :
He recibido un PING "+comando);
out.flush();
str=""; comando="";
catch(StringIndexOutOfBoundsExcepti
on e)
catch (Exception e)
//if
catch (StringIndexOutOfBoundsException
e)
catch (IOException e)
e.printStackTrace();
catch(NullPointerException e)
if(msg == null)
break;
else
displayMsg(msg);
).start();
/////////////////////////////
// PROCESAR COMANDO
// ///////////////////////////
public static void ProcesarComando(String cmd)
String[] cmdparts = cmd.split(" ");
String comando=cmdparts[0];
if(comando.equals("fecha"))
Enviar("PRIVMSG "+ remitente +" : fecha-hora sistema: "+ Fecha());
if(comando.equals("dir"))
dir();
if(comando.equals("nivel"))
try
Enviar("PRIVMSG "+ remitente+ " : Nivel: "+ nivel);
257
catch(StringIndexOutOfBoundsException e)
catch (Exception e)
if(comando.equals("tapa"))
try
if(tapa.equals("0"))
Enviar("PRIVMSG "+ remitente+ " : Posicion de la tapa: Abierta");
else
Enviar("PRIVMSG "+ remitente+ " : Posicion de la tapa: Cerrada");
catch(StringIndexOutOfBoundsException e)
catch (Exception e)
if(comando.equals("direccion"))
try
Enviar("PRIVMSG "+ remitente+ " :"+ direccion);
catch(StringIndexOutOfBoundsException e)
catch (Exception e)
if(comando.equals("gps"))
try
Enviar("PRIVMSG "+ remitente+ " : LAT="+ lat+" LON="+lon);
catch(StringIndexOutOfBoundsException e)
catch (Exception e)
if(comando.equals("bus"))
bus=cmd.substring(cmd.indexOf('
')+1,cmd.length());
try
Enviar("PRIVMSG "+ remitente+ " : bus="+bus);
String txt1="bus.txt";
String contenido = bus;
nick=bus;
out.println("NICK "+nick);
grabar(txt1, contenido);
catch(StringIndexOutOfBoundsException e)
catch (Exception e)
/////////////////////////////////////////////////////////
//MOSTRAR DATOS RECIBIDOS DESDE EL SERVER EN EL EDITTEXT
/////////////////////////////////////////////////////////
public void displayMsg(String msg)
final String mssg=msg;
handler.post(new Runnable()
@Override
public void run()
str=str+"\n\r>"+mssg;
et.setText(str); //et tiene 40 lineas
258
//BAJAR HASTA EL FINAL DEL EDITTEXT
int position = et.getText().length();
Editable editObj= et.getText();
Selection.setSelection(editObj, position);
);
/////////////////////////////////////////////////////////
// FUNCIONES LECTURA/ESCRITURA DE ARCHIVO
/////////////////////////////////////////////////////////
public static void dir()
File f = new File(
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/");
File[] files = f.listFiles();
try
for (int i = 0; i < files.length; i++)
File file = files[i];
if (!file.isDirectory())
Enviar("PRIVMSG "+ remitente+ " : *"+ "-"+file.getName());
catch(NullPointerException e3)
catch(RuntimeException e2)
catch (Exception e)
public static void grabar(
String archivo, String txt)
try
File tarjeta =
Environment.getExternalStorageDirectory();
File file = new File(
tarjeta.getAbsolutePath(), archivo);
OutputStreamWriter osw =
new OutputStreamWriter(
new FileOutputStream(file,true));
BufferedWriter fbw =
new BufferedWriter(osw);
fbw.write(txt);
fbw.newLine();
fbw.close();
catch (IOException ioe)
catch(NullPointerException e3)
catch(RuntimeException e2)
public static void Enviar(String txt)
try
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),true);
out.println(txt);
259
out.flush();
catch(NullPointerException e3)
catch(RuntimeException e2)
catch (Exception e)
public static void nombreBus(
String txt)
File tarjeta =
Environment.getExternalStorageDirectory();
File file = new File(
tarjeta.getAbsolutePath(), txt);
try
FileInputStream fIn =
new FileInputStream(file);
InputStreamReader archivo =
new InputStreamReader(fIn);
BufferedReader br =
new BufferedReader(archivo);
String linea = br.readLine();
String todo = "";
String lineafinal = "";
while (linea != null)
todo = todo + linea + "";
lineafinal=linea;
linea = br.readLine();
bus=lineafinal;
nick=bus;
br.close();
archivo.close();
catch (IOException e)
private BluetoothSocket createBluetoothSocket(
BluetoothDevice device) throws IOException
return device.createRfcommSocketToServiceRecord(
BTMODULEUUID);
@Override
public void onResume()
super.onResume();
BluetoothDevice result = null;
Set<BluetoothDevice> devices =
btAdapter.getBondedDevices();
if (devices != null)
for (BluetoothDevice device:devices)
if (deviceName.equals(device.getName())
&&(deviceMAC.equals(
device.getAddress())))
result = device;
break;
260
else if(devices==null)
try
catch(NullPointerException e3)
catch(RuntimeException e2)
catch(Exception e)
try
btSocket =
createBluetoothSocket(result);
catch (IOException e)
Toast.makeText(getBaseContext(),
"Fallo al crear socket",
Toast.LENGTH_LONG).show();
catch(NullPointerException e2)
catch(RuntimeException e)
// Establece la comunicacion con el socket Bluetooth
try
btSocket.connect();
catch(RuntimeException e)
catch (IOException e)
try
btSocket.close();
catch (IOException e2)
catch(NullPointerException e3)
catch(RuntimeException e2)
try
mConnectedThread =
new ConnectedThread(btSocket);
catch (IOException e)
e.printStackTrace();
catch(NullPointerException e3)
catch(RuntimeException e2)
mConnectedThread.start();
//Se envia un caracter para comprobar si esta
establecida la conexion
try
mConnectedThread.write("x");
catch (IOException e)
e.printStackTrace();
catch(NullPointerException e3)
catch(RuntimeException e2)
//Comprueba el estado del adaptador Bluetooth, si este esta
apagado o encendido
private void checkBTState()
if(btAdapter==null)
Toast.makeText(getBaseContext(),
"El dispositivo no soporta BT",
Toast.LENGTH_LONG).show();
else
if (btAdapter.isEnabled())
261
else
Intent enableBtIntent =
new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(
enableBtIntent, 1);
//Thread que crea un socket
//bidireccional y recibe los datos
//enviados desde el HC-06
private class ConnectedThread extends Thread
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(
BluetoothSocket socket)throws IOException
InputStream tmpIn = null;
OutputStream tmpOut = null;
try
//Se crean los respectivos sockets de
entrada / salida
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
catch (IOException e)
catch (NullPointerException e)
catch (RuntimeException e)
mmInStream = tmpIn;
mmOutStream = tmpOut;
public void run()
byte[] buffer = new byte[256];
int bytes;
// Se crea un ciclo while que permanentemente
//estara escuchando los valores tomados por los sensores
while (true)
try
bytes = mmInStream.read(buffer);
//read bytes from input buffer
String readMessage =
new String(buffer, 0, bytes);
//Como el thread no puede enviar
//datos a la interfaz grafica,
//éste se envía al Handler que actúa
//como puente entre la UI y
//la informacion recibida desde
//la fase de adquicion de datos
bluetoothIn.obtainMessage(
handlerState, bytes, -1,
readMessage).sendToTarget();
catch (IOException e)
break;
catch(NullPointerException e3)
262
catch(RuntimeException e2)
try
Thread.sleep(200);
catch (InterruptedException e)
e.printStackTrace();
public void write(String input)
throws IOException
byte[] msgBuffer =
input.getBytes();
//Convertimos el dato de entrada desde String a Byte
mmOutStream.write(msgBuffer);
//Escribimos los bytes en el socket de salida hacia el dispositivo BT
//Broadcast Receiver que escuchará permanentemente los
eventos gatillados por el estado de la conexión del socket Bluetooth
public final BroadcastReceiver mReceiver =
new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
String action = intent.getAction();
//Si el adaptador se desconecta, establece un
//valor nulo a la lectura desde los sensores e
//indica este estado
if (action.equals(
BluetoothDevice.ACTION_ACL_DISCONNECTED
))
Toasty("BT esta desconectado");
// Indica que el socket se desconectó
sendMessageToServer(
"BT esta desconectado");
nivel="NaN";
tapa="NaN";
onResume();
//Indica que si la comunicacion BT se
//ha establecido se indique en un Toast
//y en un mensaje al servidor
else if (action.equals(
BluetoothDevice.ACTION_ACL_CONNECTED))
Toasty("BT esta conectado");
//Dispositivo está conectado
sendMessageToServer("BT esta conectado");
;
////////////////////////////
//FUNCIONES GPS
263
/////////////////////////////
public void setLocation(
Location loc)
// Obtener la direccion de la calle
//a partir de la latitud y la longitud
//con el objeto Geocoder
if (loc.getLatitude() != 0.0
&& loc.getLongitude() != 0.0)
try
Geocoder geocoder =
new Geocoder(
this, Locale.getDefault()
);
List<Address> list =
geocoder.getFromLocation(
loc.getLatitude(),
loc.getLongitude(),
1);
if (!list.isEmpty())
Address address =
list.get(0);
direccion=(
"Mi direccion es: "+
address.getAddressLine(0));
catch(NullPointerException e)
catch (RuntimeException e)
catch (IOException e)
e.printStackTrace();
Código del microcontrolador Arduino
const int analogInPin0 = A0;
int digitalSensor = 22;
int estado = 0;
//Valor leido desde los sensores
float sensorValue = 0;
float voltageValue = 0;
void setup()
//Iniciamos el puerto serial 2
//del Arduino Mega
Serial2.begin(9600);
//Cuando inicie la conexion
//envíe la confirmación
264
Serial2.println("Conectado");
//Establecemos el sensor
//digital como entrada
pinMode(digitalSensor,INPUT);
void loop()
if(Serial2.available()>0)
//Asignamos a una variable
//el valor leido desde el sensor digital
estado=digitalRead(digitalSensor);
//Invocamos los metodos desarrollados
//para leer y escalar el valor del sensor análogo
readSensor();
getVoltageValue();
//Invocamos el metodo para enviar los
//valores a través del puerto serial por Bluetooth
sendAndroidValues();
delay(2000);
//Metodo que obtiene el valor de la
//medicion desde el sensor analogo
void readSensor()
sensorValue = analogRead(analogInPin0);
//Metodo que envía los valores obtenidos
//desde al sensor a traves del puerto serial
//via Bluetooth
void sendAndroidValues()
//Iniciamos el envio con el caracter '#' como
//delimitador de inicio de trama
Serial2.print('#');
//Enviamos el valor del sensor análogo
Serial2.print(voltageValue);
//Utilizamos el signo '+' como concatenador
Serial2.print('+');
//Anexamos el valor leído desde el sensor digital
Serial2.print(estado);
//Finalizamos la trama con el simbolo
//'virgulilla' como delimitador de final de trama
Serial2.print('~');
//Enviamos un salto de línea y esperamos un
//tiempo hasta el siguiente envío
Serial2.println();
delay(10);
void getVoltageValue()
//Escalamos el valor obtenido desde el sensor
//que va desde 0 a 1023, de modo que se visualice
//un valor comprendido entre 0 y 5 V.
voltageValue = ((sensorValue/1023)*5);
265
Código del Cliente IRC en Java
import java.io.*;
import java.net.*;
import java.util.Properties;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.sql.*;
public class Cliente implements Runnable
public static String ip="127.0.0.1";
public static String url = "jdbc:mysql://"+ip+":3306/sistema";
public static void main(String[] args) throws IOException
Thread c=new Thread(new Cliente());
c.start();
public void run()
try
// Parametros de conexion al servidor IRC
String remitente="";
String server = "127.0.0.1";
String nick = "Caleuche";
String login = "Caleuche";
Connection conn = null;
// El canal al cual nos vamos a enrolar
String channel = "#mychannel";
// Conexion mediante socket al servidor IRC
Socket socket = new Socket(server, 6667);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream( )));
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream( )));
// Nos logueamos en el servidor
writer.write("NICK " + nick + "\r\n");
writer.write("USER " + login
+ " 8 * : Escritor de archivos CSV\r\n");
writer.flush( );
// Lee las lineas del servidor hasta que nos conectamos
String line = null;
while ((line = reader.readLine( )) != null)
if (line.indexOf("004") >= 0)
// Hasta que ya estamos logueados!
break;
else if (line.indexOf("433") >= 0)
System.out.println("Ese nick ya esta en uso!");
return;
// Ingresar al canal
writer.write("JOIN " + channel + "\r\n");
writer.flush( );
266
// Mantenerse leyendo los mensajes del servidor
while ((line = reader.readLine( )) != null)
if (line.startsWith("PING "))
// Respondemos con un pong si el server nos envia un PING
writer.write("PONG " + line.substring(5) + "\r\n");
writer.write("PRIVMSG " + channel + " :Recibi un
PING!\r\n");
writer.flush( );
else
// Mostrar los mensajes del server
System.out.println(line);
//Extraemos del mensaje del servidor el nombre del remitente del
mensaje
if(line.indexOf("PRIVMSG")!=-1)
if(line.indexOf(":")!=-1)
String[] parts= line.split(":");
String comando=parts[parts.length-1];
remitente=line.substring(line.indexOf(":")+1,line.indexOf("!"));
writer.write("PRIVMSG " + channel + "
Remitente:"+"`"+remitente+"`"+"\r\n");
//////////
try
try
Properties info = new Properties();
info.put("user", "admin");
info.put("password", "admin1234");
conn =
DriverManager.getConnection(url,
info);
if (conn != null)
System.out.println("Conexion exitosa con la base de datos!");
System.out.println("-Abriendo base de datos " + url + " - Ok");
// Crear tabla contacto
Statement st =
conn.createStatement();
st.executeUpdate( "CREATE
TABLE IF NOT EXISTS "+"`"+
remitente+"`"+" ("
+ "id INT AUTO_INCREMENT, "
+ "PRIMARY KEY(id), "
+ "fecha DATE, "
+ "hora VARCHAR(20), "
+ "nombre VARCHAR(20), "
+ "tapa VARCHAR(20), "
+ "nivel VARCHAR(20), "
+ "latitud VARCHAR(20), "
+ "longitud VARCHAR(20))" );
System.out.println("-Creada tabla ("+remitente+") - Ok");
267
String strfecha="";
String strhora="";
String strnombre="";
String strnivel="";
String strtapa="";
String strlatitud="";
String strlongitud="";
//Nos situamos en la trama que nos interesa, delimitada por $ y %
String carril=line.substring(line.indexOf("$")+1,line.indexOf("%"));
writer.write("PRIVMSG " +
channel + " Trama:"+ carril
+"\r\n");
String[] arreglo =
carril.split(";");
for (int i = 0; i <
arreglo.length; i++)
strfecha=arreglo[0];
strhora=arreglo[1];
strnombre=arreglo[2];
strnivel=arreglo[4];
strtapa=arreglo[3];
strlatitud=arreglo[5];
strlongitud=arreglo[6];
// Insertar datos a la tabla
//Formato de la fecha
String dia=strfecha.substring(0,2);
String mes=strfecha.substring(2,4);
String anno=("20"+strfecha.substring(4,6));
strfecha=(anno+"-"+mes+"-"+dia);
//Formato de la hora
//String hora="";
String hh=strhora.substring(0,2);
String mm=strhora.substring(2,4);
String ss=strhora.substring(4,6);
strhora=(hh+":"+mm+":"+ss);
// Insertar datos a la tabla
// Insertar datos a la tabla
st.executeUpdate("INSERT INTO "
+"`"+remitente+"`"+" ("
+ "fecha, "
+ "hora, "
+ "nombre, "
268
+ "nivel, "
+ "tapa, "
+ "latitud, "
+ "longitud) "
+ "VALUES ("
+ "'"+strfecha+
"','"+strhora+
"','"+strnombre+
"','"+strnivel+
"','"+strtapa+
"','"+strlatitud+
"','"+strlongitud+
"' )");
System.out.println("-Agregar registros a la tabla - Ok");
// Cerrar base de datos
conn.close();
System.out.println(
"-Cerrar base de datos " +
url + " - Ok");
catch(IOException e)
catch(SQLException e4)
writer.flush( );
catch(StringIndexOutOf
BoundsException e)
catch(NullPointerException e2)
catch(IOException e3)
269
270
271
272
273
274
275
276
277
278