===== Interfaz Gráfica =====
La interfaz gráfica se desarrolló con el fin de facilitar al usuario el acceso a los anuncios que se desplegaran en pantalla, de una forma sencilla y eficiente. Los usuarios que tengan acceso al programa podrán ingresar a la Base de Datos videos y anuncios(texto) con el fin de publicar de una forma más eficiente mensajes y tener un mayor alcance. Dichos datos se desplegarán en pantallas estratégicamente ubicadas alternando con el modulo de GPRS, del cual se hablará más adelante.\\
El actual programa se divide en dos partes. La primera que es la parte encargada de interactuar con el usuario y está se puede encontrar en cualquier computadora siempre y cuando tenga acceso al servidor que contendrá los datos. La segunda es la encargada de manejar los datos, la cual se encontrará en el servidor que reporduzca dichos datos en pantalla. \\
Con el fin de desplegar todos los datos en pantalla de forma ordenada y cíclica se utilizó una librería de Python llamada Pygame, específicamente se utilizaron los módulos de pygame.movie y pygame.image (La documentación respectiva se puede encontrar en la bibilografía). Para su utilización se debe instalar en ambos, tanto el servidor como la computadora del usuario, lo siguiente: \\
sudo apt-get install python-pygame
**¿Qué es Pygame?**
Pygame es un conjunto de módulos que nos ayudan a crear videojuegos o aplicaciones gráficas (no necesariamente videojuegos) en dos dimensiones. Pygame incluye gráficos y bibliotecas de sonido diseñados para ser utilizados directamente bajo Python. Está construido bajo Simple DirectMedia Layer (SDL), que a su vez son un conjunto de bibliotecas desarrolladas en lenguaje C, proporcionando las funciones básicas para realizar operaciones de dibujado 2D, gestión de efectos de sonido y música, y carga y gestión de imágenes. De esta manera, a través de Pygame podemos abstraernos de la lógica del juego (o aplicación) en sí mismo, haciendo posible el uso de un lenguaje de alto nivel como Python para estructurar el juego. \\
Como se mencionó anteriormente para la carga del video se utiliza el comando: \\
pygame.movie.Movie(filename)
Donde "filename" es la dirección del archivo a cargar, luego este comando devuelve un archivo que posteriormente se puede reproduciro, cabe destacar que solo se pueden cargar archivos *.mpeg por convención de Pygame. Posteriormente para la reproducción se utilizan los comandos: \\
Movie.play()
Movie.rewind()
Movie.stop()
Los cuales permiten, reproducir, retornar al inicio y parar los videos respectivamente. Todo esto se despliega en una superficie que se genera por medio de los comandos: \\
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), SCREEN_OPTIONS)
pygame.display.set_caption(WindowName)
movie.set_display(screen, screen.get_rect())
Que genera una pantalla "screen" de dimensiones "SCREEN_WIDTH" y "SCREEN_HEIGHT" y con opciones "SCREEN_OPTIONS" como Fullscreen o widescreen que se especifican de mayor forma en la documentación ofical de Pygame. \\
Para la parte de los anuncios se utilizaron varios comandos de pygame también, con el fin de convertir los caracteres ingresados por el usuario en una imagen que si se pudiera desplegar en la pantalla anteriormente mencionada, se utilizaron:
font = pygame.font.SysFont(Fontname, size, Blod, Italic)
text = font.render(string , 0, color)
pygame.image.save(text, 'text.jpeg')
screen.blit(text, (pos x, pos y))
pygame.image.save(screen, filename.jpeg)
El primer comando se utiliza para cargar los opciones de la fuente del texto que se mostrará en pantalla y se guardan en la variable "font", estas serán escogidas de forma "default" y de acuerdo a los gustos de usuario en proporción la pantalla en la cual se desplegarán dichos datos. Ahora se "renderiza" el texto "string" de acuerdo a las opciones guardas en "font", lo cual significa que el texto "string" que digite el usuario se le aplicará el formato escodigo, esto con el fin de convertirlo en una imagen que se pueda agregar a la pantalla por medio del comando screen.blit()
donde "text" ahora es el texto del usuario convertido en imagen y se coloca en una "pos x" y "pos y" en la pantalla. Por último la imagen completa "screen" se guarda con la dirección y nombre "filename.jpg" que permitirá su fácil reproducción alternada con los videos. \\
Pero, ¿Comó el servidor decide cuales son los datos que se desplieguen y en que orden? Para solucionar esta inquietud se utiliza una base de Datos en MySQL, por su facilidad de programación y además su compatibilidad con Python, para su utilización se puede instalar desde consola: \\
sudo apt-get install mysql-utilities mysql-workbench mysql-server mysql-python
**¿Por qué MySQL?**
\\
MySQL es muy utilizado en aplicaciones web, como Drupal o phpBB, en plataformas (Linux/Windows-Apache-MySQL-PHP/Perl/Python), y por herramientas de seguimiento de errores como Bugzilla. MySQL es una base de datos muy rápida en la lectura. Además es un gestor de base de datos muy potente y completo que permite el correcto almacenamiento de la información, además del hecho de que es gratuito. \\
A partir de esto se logra definir la estructura de la base de datos que se describe a continuación:\\
\\
==== Estructura de la Base de Datos====
=== Tablas de Mysql ===
\\
La base de datos creada en Mysql lleva el nombre de "db_pantalla", el cual contiene las siguientes tablas: \\
=== Usuario: ===
^ Campo ^ Tipo de variable ^ llave ^
| idusuario | varchar (30) | Primaria |
| usu_nombre | varchar (30) | Atributo |
=== Mensaje: ===
^ Campo ^ Tipo de variable ^ llave ^
| idmensaje | int (20) | Primaria |
| fecha_entrada | varchar (30) | Atributo |
| fecha_salida | varchar (30) | Atributo |
| dir_mensaje | varchar (200) | Atributo |
| idprioridad | int (11) | Foránea |
| idusuario | varchar (30) | Foránea |
=== Video: ===
^ Campo ^ Tipo de variable ^ llave ^
| idvideo | int (11) | Primaria |
| dir_video | varchar (200) | Atributo |
| fecha_entrada | varchar (30) | Atributo |
| fecha_salida | varchar (30) | Atributo |
| idprioridad | int (11) | Foránea |
| idusuario | varchar (30) | Foránea |
=== Prioridades: ===
^ Campo ^ Tipo de variable ^ llave ^
| idprioridad | int (11) | Atributo |
\\
Y finalmente para poder el desarrollo de la interfaz gráfica se utilizó PyGTK y Glade, ambas compatibles con Python. Esta herramienta es parte oficial de Gnome. Glade genera archivos xml, que después, de forma simple y sencilla podremos cargar en nuestra aplicación. Estos ficheros pueden tener cualquier nombre y/o extensión. Ambos se pueden instalar desde consola con el siguiente comando: \\
sudo apt-get install python-gtk2 python-glade2 glade
El último no es estrictamente necesario, ya que fue la herramienta que se utilizó para el desarrollo de los mismos, por lo que para la implementación solo se deben instalar los dos primeros, pero se deja la opción en caso de que exista algún interés por parte del lector para el desarrollo de ventanas con estos programas. \\
Como resultado de lo anterior se observan las siguientes ventanas en la utilización del programa: \\
- Ingreso al programa: Solicita al usuario su identificación y contraseña. {{ :ie0117_proyectos:final:infomerciales:login.png?nolink&300 |}}\\
- Ingreso de nuevos Usuarios: Se añade una pestaña para que los administradores del programa puedan agregar usuarios nuevos y estos datos sean almacenados de forma inmediata a la base de datos.{{ :ie0117_proyectos:final:infomerciales:usuario.png?nolink&300 |}}
- Ingreso de Datos: Permite al usuario el ingreso de videos y/o mensajes para desplegarlos más adelante. (Se deben completar todos los datos requeridos) {{ :ie0117_proyectos:final:infomerciales:cargararchivo.png?nolink&300 |}}
- Despliegue de Datos: Finalmente esto es lo que se presenta en las pantallas.{{ :ie0117_proyectos:final:infomerciales:video.png?nolink&300 |}}
===== GPS =====
**¿Cómo funciona?**
El módulo GPS envía el posicionamiento el cual es transmitido a través del módulo GPRS hacia el GGSN (Gateway GPRS Support Node) del operador celular y luego a un servidor remoto sobre una conexión TCP, entonces el servidor TCP almacena la posición entrante en una base de datos mySQL.
**¿Cómo lograrlo?**
En primera instancia se necesita un microcontrolador, en este caso se utilizó un Arduino Uno, además de los módulos GPRS y GPS, para lograr la comunicación entre estos dispositivos, se utilizaron las siguientes librerías.
TinyGPS: is designed to provide most of the NMEA GPS functionality I imagine an Arduino user would want – position, date, time, altitude, speed and course – without the large size that seems to accompany similar bodies of code. To keep resource consumption low, the library avoids any floating point dependency and ignores all but a few key GPS fields.
Link:http://arduiniana.org/libraries/pstring/
/* Procesa la String AT para determinar si el GPRS está registrado y listo */
void ProcessATString() {
if( strstr(at_buffer, "+SIND: 8") != 0 ) {
GPRS_registered = 0;
Serial.println("GPRS Network Not Available");
}
if( strstr(at_buffer, "+SIND: 11") != 0 ) {
GPRS_registered=1;
Serial.println("GPRS Registered");
blinkLed(redLedPin,5,100);
}
if( strstr(at_buffer, "+SIND: 4") != 0 ) {
GPRS_AT_ready=1;
Serial.println("GPRS AT Ready");
}
}
PString:(“Print-to-String”) is a new lightweight Print-derivative string class that renders text into a character buffer. With PStrings, you can use the Print renderer for any device, even those that do not directly support Print-style text formatting, by first “printing” to a string.
Link:http://arduiniana.org/libraries/pstring/
NewSoftSerial: is the latest of three Arduino libraries providing “soft” serial port support. It’s the direct descendant of ladyada’s AFSoftSerial, which introduced interrupt-driven receives – a dramatic improvement over the polling required by the native SoftwareSerial.
Without interrupts, your program’s design is considerably restricted, as it must continually poll the serial port at very short, regular intervals. This makes it nearly impossible, for example, to use SoftwareSerial to receive GPS data and parse it into a usable form. Your program is too busy trying to keep up with NMEA characters as they arrive to actually spend time assembling them into something meaningful. This is where AFSoftSerial’s (and NewSoftSerial‘s) interrupt architecture is a godsend. Using interrupt-driven RX, your program fills its buffer behind the scenes while processing previously received data.
Link:http://arduiniana.org/libraries/newsoftserial/
Además de las librerías mencionadas, que son necesarias para programar el microcontrolador, es necesario un IDE, en este caso se utilizó Eclipse, ya que el IDE de Arduino, es poco práctico cuando se tienen que trabajar con varias librerías externas, por llamarlas de alguna forma.
Para la instalación de Eclipse en Debian o sus derivados, se puede hacer de dos maneras, la primera es mediante la instalación en consola
sudo apt-get install eclipse
o yendo a la página de Eclipse (http://www.eclipse.org/downloads/) descargando e instalándolo.
Una vez que tenemos instalado Eclipse, necesitamos hacer que se logre "conectar" con nuestro microcontrolador, para ello, vamos a seguir los sieguientes pasos.
Instalamos las siguientes librerías
sudo apt-get install gcc-avr avr-libc avrdude
Una vez hecho esto:
Iniciar Eclipse y CDT Plugin (C/C++ Development Tools):
Help -> Install New Software…
Trabaje con la versión de Eclipse instalada:
ej. “Helios – http://download.eclipse.org/releases/helios”
Descargar los paquetes de software “pending”
Escoja “Programming Languages” y seleccione “C/C++ Development Tools”
Acepte y reinicie Eclipse
Instalar AVR Eclipse Plugin:
Help -> Install New Software…
Agregue el nuevo repositorio: http://avr-eclipse.sourceforge.net/updatesite/
Descargue nuevamente los paquetes de software “pending”
Descargue AVR Eclipse Plugin y reincie Eclipse
Para ejemplificar como "cargar" un código de fuente al microcontrolador, tenemos lo siguiente:
Crear un nuevo proyecto de C llamado “BlinkBlink”:
Tipo de proyecto AVR Cross Target Application (Empty Project, AVR-GCC Toolchain)
Desmarque “Debug” (en el modo Debug, no se generan archivos-hex, y AVRDUDE no puede “flashear” el dispositivo)
Click en Advanced settings…
AVR -> AVRDude -> Programmer configuration…
Crear un nuevo programador y nombrarlo “Arduino Uno”. Asegúrese que la recién creada configuración, está seleccionada para el proyecto en curso.
Programmer Hardware: Arduino
Override default port: /dev/ttyACM0 o similar
Override default baudrate: 115200
AVR -> Target Hardware:
MCU Type: ATmega328P (or load from MCU)
MCU Clock Frequency: 16000000
Click Apply y OK para abandonar la ventana de propiedades, y click en Finish, para crear el nuevo proyecto en el espacio de trabajo de eclipse.
Crear un nuevo archivo fuente llamado main.c y copiar el siguiente código ahí . Asegúrese de guardarlo (main.c) antes de continuar(File -> Save).
Project -> Build Project
Click en el AVR Button within Eclipse para cargar el archivo hex generado de BlinkBlink/Release/BlinkBlink.hex.
EL LED de su Arduino Uno debiería estar parpadeando. Si algo no funciona, click derecho a su proyecto, y seleccione Propiedades. Asegúrese de que
todas las configuraciones del AVR and Programador están activas como se mencionó arriba.
**Servidor TCP**
Está escrito en Python, y funciona de una manera muy simple, básicamente apre un puerto TCP, y espera la conexión del módulo GSM con el posicionamiento del GPS, una vez que la recibe, la acepta (la conexión) los paquetes comienzan a llegar, los almacena según sean latitud y/o longitud en una tabla de MySQL.
# Seteando el socket para que escuche
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((TCP_IP, TCP_PUERTO))
print "Escuchando...."
s.listen(1)
conn, addr = s.accept()
print 'Conexión aceptada de la dirección:', addr
except socket.error:
if s:
s.close()
print "No se puedo abrir el socket: "
cursor.close()
conn.close()
db.close()
sys.exit(1)
try:
while 1:
data = conn.recv(BUFFER_SIZE)
if not data:break
str1,str2 = data.split("Long: ")
str1 = str1.split("Lat: ")[1]
latitude = float(str1)
longitude = float(str2)
cursor.execute ("""
INSERT INTO gmaptracker (lat, lon)
VALUES (%s,%s)""", (latitude,longitude))
db.commit()
except KeyboardInterrupt:
ClearDB(cursor,db);
cursor.close()
conn.close()
db.close()
**MySQL**
Creamos una base de datos llamada gmap, dentro de ella creamos la siguiente tabla.
Field Type Null Key Default Extra
id int(8) NO PRI NULL auto_increment
lat double(13,10) NO 0.0000000000
lon double(13,10) NO 0.0000000000
[[ie0117_proyectos:final:infomerciales:|Regresar a Índice]]