Búsqueda personalizada

26 diciembre 2006

Tecnodependientes

Qué raro se me hace escribir un post con bolígrafo y papel.

Estoy sentado en un sofá de orejas, en casa de mi abuela, y desde esta perspectiva estoy viendo un televisor, cuatro relojes de pulsera (2 digitales), una cámara de fotos digital, un mp3, las luces del árbol de navidad, un radiador... y, sin embargo, siento que me falta algo. Sí, es el mono tecnológico. Es en un lugar como este, donde realmente te das cuenta de lo enchufado que estamos a la tecnología.

Te levantas y ves que el móvil está apagado debido al frío del pueblo, pero no te molesta pues no tienes que madrugar para ir a la universidad. Sales de la habitación, te vistes y ¡vas a desayunar!, cuando realmente lo que harías en tu casa es encender el ordenador, o ver las descargas y el correo, en caso de que no hayas apagado el ordenador en semanas. Te acuerdas del mando de la televisión cuando estás sentado al calor del brasero y no hay nada que ver en la tele salvo Raphael y su programa navideño... Y hechas algún que otro solitario ¡con cartas de verdad! pues no puedes quedar con Paquito por gtalk o mandar un mail a Luisete para echar una partidilla a la Play.

En fin, voy a ir cerrando el post que si no tengo que pagar otro euro por el puesto informático en el que estoy escribiendo... :-P

23 diciembre 2006

Cena de Navidad Asiática

Lo mejor de la Navidad es que haces cosas que solo haces en esas fechas, como por ejemplo, las Cenas de Navidad. Esto es mucho más divertido si, además, cenas con los amigos. Por eso, para terminar el año, nos juntamos a celebrarlo con un buen plan.
De entrada pudimos deleitarnos con una obra de teatro (espectáculo benéfico a favor de Manos Unidas para prevenir el sida en la juventud urbana de Etiopía) llamada Bulgarian Dream Dancers Legend (Orpheo and Euridyce).

Tras el espectáculo, dejamos el cáucaso para viajar a Asia de manos del restaurante Mandalay.
En él disfrutamos, sobre todo los que estamos poco acostumbrados a este tipo de comida, de sabores, presentaciones y comidas sorprendentes. Además disfrutamos de una atención muy buena por parte de los empleados.
Entre los platos degustados, Rollitos Vietnamitas y Tallarines Fritos Tres Delicias que yo pude saborear, o el típico Shushi o los rollitos de primavera. Uno de los platos fuertes, y no me refiero al jenjibre del Shushi, fue el Arroz Frito y su preparación:




Tan solo quedaba pagar el pato, pero de vez en cuando, se agradece.

21 diciembre 2006

Añadir XMMS al panel de Gnome



La ventaja de tener más de un panel en los escritorios de Ubuntu (sí, en windows también podemos poner más, pero suele venir uno predeterminado, y en ubuntu, como que ya estás más acostumbrado a ver 2) es que tenemos mucho más sitio de añadir miniaplicaciones, applets, y cacharros varios que pueden facilitarnos las tareas, ofrecer información instantánea y hacer nuestro escritorio más personal y llamativo.
Si habéis instalado XMMS como reproductor de audio (esos nostálgicos del Winamp, XD) saber que podéis instalar una miniaplicación básica para el control (avance, pausa, retroceso...).
Para ello, tan sólo hay que ir al Gestor de Paquetes Sinaptic y buscar el módulo gxmms. Después tan sólo hay que ir al panel y "añadir al panel", donde podremos encontrar el módulo a instalar. Aparecerá entonces los controles de XMMS. Indicar que hay una opción (botón derecho sobre la miniaplicación -> Show -> Main Window) que nos permite ocultar la ventana principal de XMMS.

20 diciembre 2006

Fondos de Pantalla - Wallpapers


Es increíble la cantidad de información que podemos obtener al ver el fondo de escritorio de un pc de otra persona (dime que fondo usas y te diré quien eres).
Los hay de todos los tipos, desde las más atrevidas y espectaculares fotos de modelos (o actrices...), hasta los más clásicos e impersonales fondos de Windows, pasando por las fotos de las vacaciones, fiestas o atardeceres de película.
Todo este rollo viene por la necesidad que muchas veces se siente por cambiar de fondo y no encontrar ninguno en condiciones.
Hay una muy buena página (y gratuita), con fondos muy muy buenos, y, lo mejor de todo, con soporte para altas resoluciones (hasta 1600 x 1200).
La página es griega, o eso me parece a mí por la tipografía, pero eso es lo de menos. Aquí podéis encontrar estos wallpapers: Lynder.ru

Principios del Buen Programador














Sacado de un blog que ahora no recuerdo:

  1. Un hombre no necesita el README.txt, ejecuta.
  2. Un hombre no utiliza la desconexión segura de dispositivos USB, lo arranca del puerto. Un macho lo quita cuando todavia parpadea el led.
  3. Un hombre no usa drag&drop, usa el comando cp.
  4. Un hombre no usa delete para borrar un archivo, usa shift+delete y un macho pasa el disco por un campo magnetico.
  5. Un teclado es suficiente para un hombre, el mouse es para niñas que juegan con muñecas.
  6. Para un hombre 56kbps es más que suficiente para conectarse y descargar cualquier cosa que necesite, para un macho 14Kbps es mas que suficiente.
  7. Un hombre no utiliza documentos con formato, texto plano es lo único necesario.
  8. Un hombre programa en ensamblador, un macho en binario, Chuck Norris con niveles de voltaje.
  9. Un verdadero hombre no usa yum, apt-get ni mariconadas parecidas, compila las fuentes.
  10. Para un hombre no existe otro programa de manipulación de imágenes que no sea Paint, cuando más PhotoEditor. Un macho no usa imágenes de ningún tipo.
  11. Un hombre lee su correo conectandose al servidor por el puerto 143 usando ssh, un macho usa telnet.
  12. Un hombre no usa el asistente para particionar un disco duro, usa fdisk.
  13. El único juego de computadora para un hombre es el solitario, cuando quiere variar juega buscaminas, un macho no juega.
  14. Un verdadero hombre, no conoce Dreamweaver. Edit o vi es lo que existe para él.
  15. Un hombre no usa otro browser que no sea Lynx, un macho se conecta al puerto 80 por telnet.
  16. Un hombre no usa antenas wireless comerciales, usa antenas pringles.
  17. Un hombre no pide ayuda en foros ni homosexualidades parecidas, hace ingenieria inversa al programa con softice y deduce el error, un macho hace su propio debugger y desensamblador para corregirlo.
  18. Los hombres de verdad no usan Google, programan su propio webcrawler para que busque el contenido en la red.
  19. MP3 es una mariconada, secuencias midi es lo que escuchan los hombres, los machos no conocen otra música que el sonido de la PC cuando arranca.
  20. Un hombre no hace upgrades de hardware, hace un overclock al procesador, aumenta la memoria swap y comprime los archivos del disco.
  21. Las copias de respaldo son para niñas.
  22. Un hombre no busca parches del kernel, los hace. Un macho escribe su propio kernel.
  23. Las animaciones flash son para niñas del club de Mickey Mouse.
Algunas veces tenemos que ser frikies...

15 diciembre 2006

Orange "Único" y FON

Según he podido leer, Orange lanzará este Lunes el servicio de telefonía movil y fijo "Único" que ya apareció hace unos meses en Francia y que tuvo gran aceptación.
Y, la verdad, si esto es tan bonito como lo pintan, puede resultar muy interesante.
Se trata de una nueva forma de establecer los enlaces de comunicación clásicos. Gracias a este servicio, podemos llamar a móviles Orange y a fijos nacionales a un precio de 8 Euros. Para ofrecer esta novedad, Orange distribuye un tipo de router, llamado Livebox, que enlaza con el móvil que tendrá soporte WLAN a través de WI-FI. Hasta 5 líneas podrán contratarse, pudiendo realizar hasta 3 llamadas simultáneas y con la ventaja de disponer números móviles particulares.
En fin, todavía no tengo algunos aspectos muy claros, y espero poder resolver esas dudas este Lunes, pues, de ser esto cierto, y de disponer de servicios de calidad a bajo precio (luego todo se queda en letras pequeñas que no se leen), podríamos ver un posible cambio en la línea de negocio de FON.
Recordemos que FON basa su negocio en una movilidad completa y libertad de conexión, pero, qué pasaría si ahora las operadoras se diesen cuenta de ese peligro que amenaza y contraatacan con bajos precios y posibles conexiones libres para sus usuarios. De momento empiezan con tarifas planas entre móviles Orange..., ¿podríamos hablar de una liberación de la red a bajo precio?...
Tan sólo son especulaciones...

Feliz Navidad....

Cómo cambian los gustos, cómo cambiamos.

Hace unos cuantos años, cuando tenía unos siete u ocho años, lo que podía disfrutar de la Navidad. Me acuerdo que estaba deseando poder poner el árbol y el Belén. Sobre todo el Belén. Mi padre y yo nos encargábamos de eso. El árbol era cosa de mis hermanas y de mi madre. Empezábamos a eso de las seis de la tarde, después de merendar, y nos daban las dos de la mañana... Todavía recuerdo cómo sonaba el típico papel de envolver paquetes con el que mi padre creaba las montañas de aquél pueblo en miniatura. A la mañana siguiente, una vez secas las pinturas que daban el toque de color, el serrín y el musgo artificial, poníamos todas las figuras.
Ahora, en cambio, tan sólo el toque de color del árbol de navidad se advierte en el salón. Yo no tomo parte en ese juego. Hemos cambiado, nos hemos hecho mayores. Las cosas ya no nos ilusionan. Todo se vuelve más superficial y las compras más innecesarias. Ahora la Navidad sólo ilusiona a los grandes centros comerciales.

14 diciembre 2006

Iniciando contador de "enumerate" en LaTex









Por algún motivo seguramente hayáis tenido que iniciar una enumeración en LaTex mediante el comando \begin{enumerate}, habéis salido de ella, y habéis vuelto a comenzar otra enumeración, pero el problema es que la enumeración vuelve a comenzar desde 1, cuando lo que realmente queríais hacer era continuar con la enumeración anterior.
La solución más fácil es modificar el contador actual, el cuál se encontrará a 0, y establecerlo en el último número que se quedó. Así, si el último \item fue el 4, habría que establecer el contador a 4. Para ello se usa la sentencia \setcounter{numi}{valor}, siendo "numi" la enumeración del primer nivel de la jerarquía, y "valor" el contador.
Como ejemplo podéis ver el PDF.

13 diciembre 2006

Última actualización de Beryl

Esta mañana me encontré a Santi por la uni y estaba liado con la práctica de Estructura de Computadores. Después de estar un rato comentando el código veo que cierra la ventana y se desvanece dejando un rastro gris. Yo que quedé sorprendido. Le dije: "¿Y eso?!!, es nuevo en Beryl o qué?".
Me dijo que ayer se le actualizó desde los repositorios a la última versión estable, así pues, lo primero que he hecho al llegar esta tarde a casa ha sido actualizar.
Pero antes de eso tuve que añadir la dirección del repositorio a la lista de éstos, pues no la tenía (ya decía yo que no lo había visto).
Como siempre, para añadir una dirección al repositorio, en modo consola como root:

sudo gedit /etc/apt/sources.list

Y añadimos a la lista una de las siguientes líneas (a elegir la que convenga):

deb http://3v1n0.tuxfamily.org dapper beryl-svn (Repositorio para dapper)

deb http://3v1n0.tuxfamily.org edgy beryl-svn (Repositorio para Edgy)

Finalmente, y para obtener la key del repositorio:

wget http://3v1n0.tuxfamily.org/EDD1E155.gpg -O- | sudo apt-key add -

Una vez hecho esto, podremos ir al gestor de paquetes Synaptic y actualizar Beryl.

Y... ¿qué es lo nuevo?

Lo que más sorpende es el nuevo entorno 3D world que permite disponer en capas separadas en profundidad las ventanas que tengamos abiertas.
Otro detalle son nuevos efectos en maximizado, minimizado, cierre... de ventanas.
Para más detalles, enlazar con la página oficial.

Y para verlo in vivo:

10 diciembre 2006

Pobres ricos de la Moraleja, sin FON...

Me puse a mirar los mapas de FON, comencé desde la población donde resido, en Yunquera, y fui pasando por Guadalajara, viendo los portales personalizados que algunos habían editado. Pasé más tarde por Alcalá y finalmente llegué a Madrid.
Ví el centro y me di cuenta de que el número de puntos de acceso en el centro era considerablemente grande.
Entonces me acordé de un post que pegó Martín Varsavsky en su blog sobre los ladrones pijos de la Moraleja, y pensé, mmm... ¿Habrá muchos puntos de acceso en esa zona, la más pija de Madrid?
Al momento tuve la respuesta:

09 diciembre 2006

Firefox y Google Maps




Un nuevo tipo de publicidad está apareciendo, o por lo menos, eso creo yo.
Hace cierto tiempo apareció en Reino Unido la palabra "Fuck" en un campo de cultivo.




Más originales y avispados han sido los chicos de Firefox, que han utilizado el mismo método, más depurado, para colocar el logotipo del navegador en otro campo de labranza.
En Málaga, un centro comercial se sirve de la misma técnica para promocionarse, aunque podían haber pensado un poquito mejor en cómo escribir su mensaje...



Technorati Profile

05 diciembre 2006

Añadir accesos directos desde FAT32

Cuando instalé Ubuntu, una de las cosas que hice fue crear una partición de gran tamaño en formato FAT32 para poder compartir datos con Windows, sobre todo, para poder dejar marchando a la mula. Además, no quería arriesgarme con la partición NTFS, pues he leído por algún sitio que da problemas si damos permisos de escritura a Linux...
Uno de los problemas que tenemos en particiones con formato FAT32 es que si queremos crear un lanzador de alguna carpeta o archivo directamente desde ese sistema de archivos, es que no nos dejará, pues hay una serie de incompatibilidades en ese entorno.
Por ese motivo, debemos crear los enlaces directamente en el destino donde vamos a colocar el acceso directo. Para ello, necesitamos escribir en línea de comandos:

ln -s /origen_a_enlazar /destino_a_emplazar

Es lo que llamamos un enláce débil a un fichero (o zona física del disco).

Para ilustrar mejor y entender la tarea:

04 diciembre 2006

Campeonato de Bádminton


Hoy hemos tenido el campeonato individual de bádminton de la universidad.
Sí, yo también he jugado. Hacía mucho tiempo que no hacíamos deporte, y había que apuntarse a alguno. En verano dije: "nos apuntamos a algo tranquilito ehh, algo que vaya despacito", y pensamos en el bádminton. Pues según tengo entendido, el bádminton es el deporte de raqueta más rápido del mundo (récord de volante en velocidad en 332 km/h por Fu Haifeng). Y hoy me he dado cuenta... ¡Qué paliza!
En fin, al final, quedé como esperaba quedar... jijiij. Mis espectativas eran peores, pero no estuvo mal. A ver qué tal el próximo lunes en la competición por parejas.

Renovatio


Sí, así se llama el barco que ve Lincoln Eco-Seis en sus sueños en la película "La Isla".
Al igual que ese barco, que le sugería una renovación, un renacer, para escapar del centro de internamiento y salir al exterior, acabo de llevar un proceso similar de restauración.
El proceso de renovación del blog ha comenzado migrando el antiguo sistema en el que estaba éste para terminar en beta Blogger. Y, uno de los cambios es poder asignar etiquetas a los post, para poder formar categorías con estos.
El único problema es que las nuevas plantillas, si optas por hacer un cambio total, se encuentran en xml, y yo... como que no estoy muy puesto al día. Me ha costado adaptar un poquitín la página. Espero hacerme pronto con él.

30 noviembre 2006

Winks, capturando tareas en el escritorio


Uno de los problemas que veo a la hora de instalar muchas aplicaciones en distribuciones linux es que en las documentaciones y explicaciones sobre cómo llevarlas a cabo, muchas veces, o son insuficientes, o nulas, o imprecisas. Siempre se ha dicho que una imagen vale más que mil palabras, y si esas imágenes se suceden dando lugar a un vídeo o presentación, entonces mucho mejor. Lo mismo me ocurre a veces cuando estoy aprendiendo a utilizar un entorno de desarrollo nuevo, como el último que nombré en el post. La verdad que eclipse es una maravilla, y más aún si te explican y muestran ejemplos "in-vivo". Me fijé entonces en la presentación que llevaron a cabo a través de un archivo flash, y pensé... "mmm, no estaría mal probar algún capturador de pantalla para linux". En Windows hay multitud, pero aquí, en linux, la tarea siempre se complica.
Estuve mirando, y encontré bastantes que operan sobre archivos .avi, .wmv, .ogg, o similares, pero quería que fuese en formato flash, para tener mayor integridad y compresión.
Probé vnc2swf, una aplicación que se basa en captura sobre terminales ofrecidas por los servidores de escritorio remoto VNC. Sin embargo, como soy bastante nulo a la hora de llevar a cabo compilaciones y demás, al final desistí... :-(.
De casualidad, entonces, llegué a WINK. Una maravilla.
Ofrece la posibilidad de generar un archivo .swf o .exe. Con configuración sobre el tamaño de captura, refresco de frames, edición de la película con posibilidad de añadir comentarios, botones de navegación, y todo ello bajo una impecable interfaz gráfica que facilita la vida al usuario más negado...
En fin, muy recomendable, sí señor.
Espero poder hacer explicaciones de aplicaciones y demás chuladas desde el nuevo punto de vista que me ofrece esta herramienta.
Y para dar fé de ello, he ahi una presentación.

Entorno WINK:
(Para reducir tamaño del archivo, puede usarse paleta de colores, de ahí que el aspecto de las ventanas tenga ese color amarillo, y los iconos sin color...)

26 noviembre 2006

Eclipse SDK en español

Eclipse SDK en Español
Si habéis probado el entorno de desarrollo Eclipse SDK para java, habréis podido comprobar que se trata de una potente herramienta que cuida bastante bien hasta el último detalle. Y sobre esos detalles, destacar el apoyo que os brinda a la hora de depurar sintácticamente las líneas de código. Si hay algo que no es adecuado o erróneo, os lo indica y os da la oportunidad de corregirlo.

Pero, qué ocurre con Eclipse. Pues que, como toda aplicación, su interfaz viene en inglés, a no ser que uno se encargue de lavarle la cara.
Y ese lavado se lleva a cabo de la siguiente forma.

1. Instalación de Eclipse SDK 3.2.1. (para ubuntu - edgy).
Tan fácil como obtener la versión a través de Synaptic.

2. Una vez instalado (comprobar que funciona en la versión en inglés), tendremos que obtener los plug-in desde: plugin

3. Una vez descargado (el paquete ocupa unos 53 MB), descomprimir y copiar la carpeta al directorio de Eclipse. Desde consola:

kayak@HR24:~$ sudo -s
root@HR24:~# cp -r Desktop/eclipse/plugins/ /usr/lib/eclipse/
root@HR24:~# cp -r Desktop/eclipse/features/ /usr/lib/eclipse/


Finalmente, sólo queda reiniciar la aplicación para poder disfrutar de la versión en español.

24 noviembre 2006

Creatividad por encargo



Y qué quiere decir eso?, "Creatividad por encargo"?, y a qué viene ese animalejo? Pues se trata de eso, de un encargo. Una amiga mía me pidió que le hiciese un dibujo sobre un topo, un vampiro y un elfo. Y yo que dibujo tannnn bien... ¬¬ me puese a hacerlo.
Ya que me topé con Xara Xtreme para dibujo vectorial, no podía hacerle un feo, y usé ese programa. Es muy intuitivo, con herramientas muy muy útiles. En fin, así fue el resultado obtenido. Está claro que el dibujo no es lo mío, de ahí, creatividad por encargo...

19 noviembre 2006

De vectores va la cosa
















Pues sí, de vectores y no de pixels. Y es que, trasteando con los programas de ubuntu te lías a hacer cosas y al final acabas con un programa de tratamiento de imágenes, bueno, mejor dicho, de creación y edición de imágenes vectoriales. Y la verdad que está muy bien. La aplicación se llama Xara Xtreme, y tiene las funcionalidades básicas para crear un buen gráfico. Tan bueno es el programa que me hace parecer profesional, y sino fijaros en el logotipo que he creado, inspirado en el nombre del programa.
Así pues, ya tengo otra cosa que hacer cuando me aburra, ponerme a hacer dibujitos y pegarlos por aquí... XD.

Enga gente, a cuidarse.

16 noviembre 2006

Ya estoy cabreado....

Ke leches..., no se si por obra del destino o qué, pero este post no debería estar aquí.

En lugar de éste debía aparecer uno que hablaba de cómo podíamos aprovechar el día, cómo cundía más un día de biblioteca que tres meses en tu casa haciendo el intento de hacer algo, lo que se suele denominar (hacer que haces algo).
Pero no, en lugar de ese post aparece éste. ¿Por qué? ¿Cuál es el motivo? El motivo es una potencia de luz contratada que no soporta la numerosa cantidad de aparatos eléctricos que conviven en mi casa. Además, Blogger, no se si porque se trata de la versión antigua, no dispone de guardado automático de forma periódica (Googleeee!!!!, oidme!!!!, no me hagáis revisar vuestra nueva versión en busca de esa funcionalidad!!!), y en un fallo de suministro se me fué al garete todo lo que había escrito. Yo que iba con buena voluntad a escribir un buen post..... jarrrrr.
En fin, que acabas hablando de la rabia incontenida que tenías ahí en el fondo, casi sin saber de ella, y de repente, con este hecho, te viene a la mente el momento del apagón, el momento en el que un gilipollas te adelanta en línea contínua y tú te acuerdas de su familia, o cuando has ido a sentarte y te has pegado con la p... pata de la mesa en la rodilla (sí, justo en el canto, de tu rodilla y de la pata), o cuando ....
Bueno, a ver si el siguiente post, si me da tiempo :-(, habla sobre algo interesante.

12 noviembre 2006

Día en SIMO

Tras dejar pasar toda la semana en la que se han dado cita en el IFEMA conferencias, eventos, simposios y demás, al final nos decidimos en acercarnos esta mañana. Craso error. El recinto cierra a las 15:00 h y los stand recogen rápido. Más rápido hemos tenido que realizar la ruta para intentar ver lo más posible.

Tengo que decir que la entrada me vino de FON, y que por allí me pasé, y que lo tenían muy bien montado, de hecho, mucha gente había, con pinchadiscos, y bastante animado.
Sin embargo, y como ya decían, la feria empieza a perder su carácter profesional, y se extiende más hacia un ocio de familia. Un pabellón para los videojuegos lo corrobora.

En fin, que, a no ser por obligaciones profesionales, creo que o me vuelven a invitar, o... ¿me costará volver a ir?

El tiempo lo dirá.

30 octubre 2006

Versión 1.0 Display en Router Linksys - Arduino

Mas proyectos en: http://eduardomarin.es/blog/tag/arduino

Introducción (Documentación actual en http://eduardomarin.es/blog/entry/version-1-0-display-en-router-linksys---arduino)


Bueno, pues empezamos este "tuto" para añadir al router Linksys WRT54GL un display 16x2 de Philips (documentacion) que nos ayudará a visualizar aquellos datos que creamos oportunos.

En mi caso, y de momento, puedo visualizar dos temperaturas (interna y externa), la hora GMT, las redes disponibles, y aquellos mensajes que yo edite.

Pero... cómo he realizado todo esto. Comencemos.

Antecedentes

Desde que adquirí el router y comencé a añadirle componentes (puerto serie, lector tarjeta SD, ...), visité muchas páginas, y en una de ellas, más concretamente en los Hacks de Openwrt, ví que añadían un display de un Nokia. Esa opción me alegró bastante y me amplió las miras hacia las posibilidades que ofrecía. El inconveniente es que, ni yo tenía ese tipo de display, ni lo iba a comprar, y además, la instalación se lleva a cabo a través de las señales GPIO, que no me gusta tocar mucho, además que ya las tengo ocupadas con el lector de SD.
Entonces... qué solución podía darle. Pues bien. En primer lugar, llegó a mis manos una impresora multifunción con escaner en donde venía el display que ahora porta el router.
Se trata del modelo de 16 x 2 de philips, en donde hay una muy buena documentación sobre su control en esta dirección.
Muy bien, ya tenemos el display, pero ahora... dónde lo enchufamos?
Aquí entra en juego el proyecto que desarrollan los chicos de Arduino. Como ya he hablado bastantes veces en posts anteriores, éste microcontrolador nos permite manejar una serie de señales digitales y analógicas, y, además, puede realizar una comunicación por puerto serie. Es este el punto fuerte del enlace.
Así pues, volvemos a la simbiosis Arduino - Linksys que me permiten ampliar el sistema linux que porta Linksys.

Componentes

Router Linksys WRT56GL
Microcontrolador Arduino
Placa microperforada PCB
Tira de conectores
Resistencias de 220 ohm
Cable

Manos a la obra

En primer lugar, buscamos un lugar donde colocar el display. En mi caso, lo centré sobre la parte superior del router, justo donde está perforada la tapa para que ventile. Las medidas del display me permitieron centrarlo perfectamente, con lo cual da un aspecto bastante aproximado a "de fábrica", XD.
El siguiente paso es realizar la conexión entre las 11 entradas del display a Arduino (vease que puede realizarse el control del display con tan sólo 4 bits sobre datos). Así pues, de las 14 salidas digitales de las que dispone Arduino, tan sólo usamos 11. Dos de ellas están reservadas para el puerto serie.
Hay que pensar, además, que Arduino debe ser alimentado de alguna forma. También tenemos que pensar en qué uso le vamos a dar. En mi caso, además de controlar el display, realizará lecturas de diversos sensores, aprovechando las 5 entradas analógicas de las que dispone.
Por lo tanto, el cableado hacia Arduino va a ser algo complejo, y sería conveniente montar una PCB con conectores para facilitar la conexión y desconexión en caso de que se necesite.
Para ello, se monta una tira de conectores para que encaje perfectamente a Arduino. Esta tira irá soldada a cada una de las entradas al display, convenientemente dirigida, y soldada.
Para graduar el contraste del display hacemos uso de una resistencia variable de 10 k. Para la adquisición de datos para los dos termómetros, realizamos un divisor de voltaje mediante dos resistencias de 220 ohmios. Finalmente, la alimentación de Arduino se lleva a cabo directamente de la alimentación del router. Sin embargo, ésta alimentación devuelve unos 20 - 25 voltios que podrían no sentar muy bien a Arduino, pues éste trabaja en un rango de 5 a 12 voltios. Para ello se usa un regulador de tensión, en mi caso, aprovechado de la impresora que recibí.
Una vez establecida la conexión entre Arduino y el display, tan sólo queda realizar la conexión con el router. Esta conexión se lleva a cabo a través del puerto serie que ya buscamos en un post anterior.
Si todo ha salido bien, ahora quedaría meterse con el soft.

-- Software --

A la hora de crear los scripts y código necesario debemos tener en cuenta los siguientes aspectos.
Por un lado, estamos trabajando con Arduino y con Linksys.
Vamos a comenzar hablando del código que correrá en Arduino.
En posts anteriores hablé de la comunicación que podía llevarse a cabo entre Linksys y Arduino. Pues bien, mantendremos esa comunicación tal cual. Esto es, Linksys tendrá que ser capaz de activar y desactivar las señales suficientes para que arduino responda como si las señales las estuviese originando él. Así, de las 13 salidas digitales (mejor dicho, 11, pues dos de ellas son para comunicación serie), el router Linksys debe poder activarlas, tan sólo indicando las salidas que desea activar. Lo mismo ocurre con la entrada analógica. Así pues, si revisáis el post donde se indica veréis cómo para activar la salida 10 y 8 digitales, tan sólo habia que enviar sobre el puerto serie el comando H10H08, esto es echo H10H08 > /dev/cua/1. Una vez llevada a cabo la configuración de Arduino, y dispuesto para funcionar como un "interfaz" de cara al lcd, podemos comenzar con el código del router.

Por un lado tenemos el script que controla el lcd, y por otro el código que nos hace de lanzador de la "aplicación", es decir, la que recoge la información de la temperatura, de la hora, recoge información sobre la ssid actual, recoge los mensajes a imprimir...

Empecemos por el nivel más bajo, esto es, el control del lcd.

Veamos, en primer lugar, el código de ese controlador

#!/bin/ash

iniciar_lcd()
{
echo L06L07H08H09L10L11L12L13L04L03H05D00020L05D00020 > /dev/cua/1
echo H06L07L08L09L10L11L12L13L04L03H05D00020L05D00020 > /dev/cua/1
echo L06L07L08H09H10H11L12L13L04L03H05D00020L05D00020 > /dev/cua/1
}

desplazar_display()
{
L=1
while test $L -le $1
do
echo L06L07L08H09H10L11L12L13L04L03H05D00020L05D00020 > /dev/cua/1
L=`expr $L + 1`
done
}

posicionar_cursor()
{
COCIENTE=$1
COCIENTE=`expr $COCIENTE - 1`
K=6
if test $1 -ge 1
then
if test $1 -le 80
then
while test $K -le 12
do
MOD=`expr $COCIENTE % 2`
COCIENTE=`expr $COCIENTE / 2`
if test $K -le 9
then
case $MOD in
0) echo L0$K >> auxiliar
;;
1) echo H0$K >> auxiliar
;;
esac
else
case $MOD in
0) echo L$K >> auxiliar
;;
1) echo H$K >> auxiliar
;;
esac
fi
K=`expr $K + 1`
done
echo H13L04L03H05D00020L05D00020 >> auxiliar
SALIDA=`sed 's/\n//g' auxiliar`
SALIDA=`echo $SALIDA | sed 's/ //g'`
rm auxiliar
fi
fi
echo $SALIDA > /dev/cua/1
}

imprimir_caracter()
{
CARACTER=$1
case $CARACTER in
0)echo L06L07L08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
1)echo H06L07L08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
2)echo L06H07L08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
3)echo H06H07L08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
4)echo L06L07H08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
5)echo H06L07H08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
6)echo L06H07H08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
7)echo H06H07H08L09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
8)echo L06L07L08H09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
9)echo H06L07L08H09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
:)echo L06H07L08H09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
=)echo H06L07H08H09H10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
A)echo H06L07L08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
B)echo L06H07L08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
C)echo H06H07L08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
D)echo L06L07H08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
E)echo H06L07H08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
F)echo L06H07H08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
G)echo H06H07H08L09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
H)echo L06L07L08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
I)echo H06L07L08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
J)echo L06H07L08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
K)echo H06H07L08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
L)echo L06L07H08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
M)echo H06L07H08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
N)echo L06H07H08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
O)echo H06H07H08H09L10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
P)echo L06L07L08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
Q)echo H06L07L08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
R)echo L06H07L08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
S)echo H06H07L08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
T)echo L06L07H08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
U)echo H06L07H08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
V)echo L06H07H08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
W)echo H06H07H08L09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
X)echo L06L07L08H09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
Y)echo H06L07L08H09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
Z)echo L06H07L08H09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
Z)echo H06H07L08H09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
Z)echo H06H07L08H09H10L11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
a)echo H06L07L08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
b)echo L06H07L08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
c)echo H06H07L08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
d)echo L06L07H08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
e)echo H06L07H08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
f)echo L06H07H08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
g)echo H06H07H08L09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
h)echo L06L07L08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
i)echo H06L07L08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
j)echo L06H07L08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
k)echo H06H07L08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
l)echo L06L07H08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
m)echo H06L07H08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
n)echo L06H07H08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
o)echo H06H07H08H09L10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
p)echo L06L07L08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
q)echo H06L07L08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
r)echo L06H07L08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
s)echo H06H07L08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
t)echo L06L07H08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
u)echo H06L07H08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
v)echo L06H07H08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
w)echo H06H07H08L09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
x)echo L06L07L08H09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
y)echo H06L07L08H09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
z)echo L06H07L08H09H10H11H12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
�)echo L06H07L08H09H10H11L12H13L04H03H05D00020L05D00020 > /dev/cua/1
;;
_)echo L06L07L08L09L10H11L12L13L04H03H05D00020L05D00020 > /dev/cua/1
;;
esac
}

imprimir_cadena()
{
# Elimino todos los espacios en blanco de la cadena, para que
# no entre en conflicto con los espacios que no se escriben
# y el n�mero de car�cter que lleva en bucle
# Despu�s, si no hay nada que escribir , no hago nada, en caso
# contrario, distingo entre mensajes que entran en display y
# los que no. Los primeros los escribo a dos renglones.
# Los segundos, mediante desplazamiento de display (tipo banner).
# Finalmente, para cada car�cter, llamo a la funci�n imprimir_caracter.


CADENA=`echo $* | sed 's/ //g' | cat`
LONGITUD_CADENA=`echo $CADENA | wc -c`
LONGITUD_CADENA=`expr $LONGITUD_CADENA - 1`
if test $LONGITUD_CADENA -ne 0
then
I=1
while test $I -le $LONGITUD_CADENA
do
if test $I -ge 17
then
if test $LONGITUD_CADENA -le 32
then
if test $I -eq 17
then
posicionar_cursor 41
fi
else
if test $I -eq 41
then
posicionar_cursor 1
else
desplazar_display 1
II=`expr $I + 1`
if test $II -eq $LONGITUD_CADENA
then
desplazar_display 1
fi
fi
fi
fi
CARACTER=`echo $CADENA | cut -c $I`
imprimir_caracter $CARACTER
I=`expr $I + 1`
done
fi
}

imprimir_cadena $*


Pues bien, comenzamos haciendo que el script pueda ser interpretado por ash. A continuación creamos una serie de funciones que nos ayudarán a modularizar la aplicación y a reutilizar el código. En primer luga r, debemos mandar a Arduino la secuencia de bits necesaria para que éste, a su vez, lo envíe al lcd. Si miramos la documentación del lcd vemos cómo se lleva a cabo esa inicialización, dependiendo de si deseamos mostrar el cursor, en modo parpadeo, en formato 16 x 2 o 16 x 1...
La siguiente función nos realiza el desplazamiento del display teniendo en cuenta que sólo puede mostrar 16 de los 40 caracteres disponibles. Vuelvo a instar a que se lea con detenimiento la documentación del display. Ahí veremos cómo el display dispone de una zona de memoria de 40 posiciones por 2 filas. Al poder mostrar tan sólo 16 x 2 de esas 80 posiciones, es útil tener una función que nos permita mover esa pequeña "ventana" sobre toda la zona de memoria. Para ello, lo único que hacemos es pasarle como parámetro el número de desplazamientos (en este caso he optado hacia la derecha, por ser más útil) a la función desplazar_display y realizar mediante un bucle la iteración de desplazamientos individuales mediante la correspondiente serie de bits. No he dicho que el envío de esos bits en alta o baja sólo corresponden a una decisión propia. Todo depende de a qué pines hemos conectado el lcd a Arduino.
Otra función de movimiento en el lcd afecta esta vez al cursor. Imaginemos que tenemos una palabra de 16 letras. En este caso, esa palabra entra exáctamente en la primera fila del lcd, y, por tanto, no va a haber problemas, pero... qué ocurre si la palabra es de 17. En ese caso, no puede escribirse en la posición 18 de la primera fila, pues no aparecería en la "ventana" del lcd. Para ello, tendría que posicionarse en la posición 1 de la 2ª fila. Bien, esto parece bastante sencillo, pero ¿qué ocurre si tenemos en cuenta que el cursor se desplaza de forma secuencial (ya sea escribiendo carácteres o espacios en blanco), y tendrá que recorrer 40-16 posiciones hasta "bajar" a la segunda fila?, pues que a la vista de alguien, queda bastante mal que transcurra un tiempo notable sin que se escriba nada en el lcd. Para ello debe implementarse la función que posiciona automáticamente el cursor en la posición. Para ello se revisa de nuevo la documentación del lcd y se comprueba cómo el lcd dispone de una zona de memoria, correspondiente con cada posición de carácter a escribir, a la que se puede acceder mediante un comando donde se le indica tal posición (jo ke lío). El problema es que, cuando llamamos a la función posicionar_cursor con un entero, por ejemplo, el 42, la función tiene que comprobar, en primer lugar, que se encuentra entre el 1 y el 80, para, después, indicar en los 7 bits de datos, el entero 42. Para ello debe convertirse el 42 a binario, operación que se lleva a cabo en las líneas sucesivas. En ellas, se va insertando temporalmente cada uno de los bits de datos (del 06 al 12 para Arduino) en su formato en alta o baja (H06H07L08 ...). Finalmente se añade a ese archivo los bits en alta y baja correspondientes a la configuración de la señal que se envía, correspondiente al desplazamiento en el lcd (H13L04L03H05D00020L05D00020 >> auxiliar . ¿y... qué significa esas líneas siguientes? (SALIDA=`sed 's/\n//g' auxiliar` SALIDA=`echo $SALIDA | sed 's/ //g'`) Tan sólo eliminan los saltos de línea que hemos ido creando al añadir elementos al archivo auxiliar, además de los espacios en blanco, para que puedan ser interpretados correctamante al hacer echo. Finalmente enviamos los bits a Arduino.

Otro paso importante es la propia escritura de un carácter. Cuando llamemos finalmente a la función lcd mi_nombre_es_edu tenemos que ser capaces de escribir cada uno de esos carácteres. Para ello necesitamos hacer algo tan tedioso como representar el abecedario más básico con el que podemos trabajar asociándolo a su código binario en "pseudoASCII" (ver códigos del lcd) junto a los bits de control para enviarlo por el puerto serie a Arduino. La función consiste en un simple case sobre todo el conjunto de valores.

Finalmente nos queda tratar la cadena tal cual nos la dan a la función principal. Pero, un problema grave es cómo poder escribir espacios en blanco, y tratar además posibles variables a la entrada de la función. Es decir, imaginemos que tenemos la cadena "Tengo 20 monedas". Si pasamos la cadena en cuestión a la función, tenemos ./lcd Tengo 20 monedas entonces estaríamos dando por parámetros a $1 = Tengo, a $2 = 20 y a $3= monedas. Tratarlas por separados cada uno de los parámetros es difícil. Para ello debemos reunir todos los parámetros. Además, necesitamos contar cuantos caracteres tiene la cadena. Para ello eliminamos los posibles espacios en blanco que haya y guardamos la cadena en la variable CADENA (CADENA=`echo $* | sed 's/ //g' | cat`), y después contamos los carácteres que tiene la cadena (eliminando el salto de línea). Finalmente, y tras comprobar que la cadena tiene al menos 1 carácter, vemos cuál sería la mejor representación de la cadena. Esto es, ya vimos qué ocurriría si la cadena tenía 17 caracteres. Tan sólo había que posicionarse en la posicion 1 de la 2ª fila. pero ¿Qué ocurriría si la palabra tuviese (2 x 16) + 1 carácteres? En ese caso, ni aún pasando por la segunda fila entraría la palabra. En este último caso es mejor dejar la palabra en la primera fila y desplazar toda la "ventana" haciendo "banner" a la derecha, siempre y cuando no supere la longitud de (2x40). De esto es, esencialmente, de lo que se encarga la última parte, de comprobar qué representación y qué movimientos debe hacer la función para que quede "más bonito". Por último, se imprime la cadena.

Una vez "creado" el controlador del lcd, nos queda bastante simplificada la representación de información en el lcd. Tan sólo tenemos que aplicar la expresión ./lcd La_cadena_que_quiero_escribir, para que me muestre la información de la forma más conveniente para que entre en el lcd.

Ahora crearemos la aplicación para monitorear la temperatura exterior, interior, la hora y diversos mensajes útiles que nos permiten sacar la funcionalidad al lcd.

Veamos el código:

#!/bin/ash

imprimir_temperatura()
{
/www/arduino/adquisitor $1 &
sleep 1
ps > procesos
cat procesos | grep adquisitor | cut -b 1,2,3,4,5 > proceso
PROCESO=`cat proceso`
kill -9 $PROCESO
VARIABLE=`cat nivel | cut -b 1,2,3,4`
AUX=`expr 870 - $VARIABLE`
TEMPERATURA=`expr $AUX / 5`
if test $1 -eq 0
then
TEMPERATURA=`expr $TEMPERATURA - 7`
else
if test $1 -eq 2
then
TEMPERATURA=`expr $TEMPERATURA + 2`
fi
fi
echo $TEMPERATURA
}

imprimir_temperaturas()
{
TEMPERATURA0=`imprimir_temperatura 0`
TEMPERATURA1=`imprimir_temperatura 2`
/tmp/mmc/Display/iniciar_lcd
/tmp/mmc/Display/lcd Temp._Int:_ $TEMPERATURA0 _C
/tmp/mmc/Display/posicionar 41
/tmp/mmc/Display/lcd Temp._Ext:_ $TEMPERATURA1 _C
}


J=1
while test $J -le 2
do
imprimir_temperaturas
sleep 3
/tmp/mmc/Display/iniciar_lcd
/tmp/mmc/Display/lcd ==_ROUTER_FON_==
sleep 3
imprimir_temperaturas
sleep 3
/tmp/mmc/Display/iniciar_lcd
/tmp/mmc/Display/lcd By_Eduardo_Marin
sleep 3
imprimir_temperaturas
sleep 3
/tmp/mmc/Display/iniciar_lcd
HORA=`date |cut -c 12-19`
/tmp/mmc/Display/lcd  ===_ $HORA _===
sleep 3
#/tmp/mmc/wifi_sd/escaner
done


Habíamos visto en otro post anterior cómo adquirir un valor numérico que nos daba la temperatura de un sensor conectado a una de las entradas analógicas.
Pues bien, en la aplicación descrita mostraremos 2 temperaturas, la hora local, y mensajes escritos en el lcd.
Las primeras líneas, correspondientes a la función imprimir_temperatura llaman al script adquisitor en modo background. Para terminar el proceso, pues hace uso de la función cat sobre la entrada serie, y ésta no muere a no ser que se la mate, se lleva a cabo esa operación. Para ello se caza su id de ejecución haciendo uso de ps para más tarde, matarlo.
Una vez matado, leemos la información que ha volcado la aplicación anterior sobre el archivo nivel. Después se hace una conversión de los 1024 niveles disponibles a la temperatura adecuada (para ello se hace un "calibrado" manual). Esta parte se aplica a las dos temperaturas. La siguiente función, imprimir_temperaturas lleva a cabo la impresión sobre el lcd, mostrando un mensaje de indicación Temp. Int. Cabe destacar cómo se lleva a cabo el posicionamiento del cursor para imprimir la siguiente línea (posicionar), que, aunque no corresponde a la función interna del script lcd, se trata de la misma idea, pues está en otra función llamada así.

Por último, quedaría la parte principal (main) del script. Esta parte se ejecuta indefinidamente, de ahí el while infinito, en el que se imprimen las temperaturas, se muestra mensaje de FON, se vuelven a imprimir temperaturas...

Para que éste script se lance de forma automática hay que insertar un enlace a éste en /etc/init.d/.

Pues bien, ya sé que pueden quedar bastante confusas algunas ideas. Puede que algunos puntos no estén lo suficientemente desarrollados o que, simplemente, haya cosas que no tengan sentido, pero tampoque tenía la necesidad de crear este tutorial si no fuese porque, de no ser así, a mí se me olvidaría todo el proceso (de hecho ya hay cosas que no recuerdo muy bien porqué las hice), y sería una lástima para mí.

De todas formas, espero que le pueda servir a alguno.

Byes byes.




24 octubre 2006

Atemos cabos


Esos cabos los ato, para que no se me vaya muy lejos el blog.

Y esque, hace mucho que no escribo. No tengo mucho tiempo, y cuando lo tengo, la pereza puede más.

Estas líneas me obligarán a escribir más adelante, de forma más detallada, los pasos que he llevado a cabo para dotar al router de pantalla LCD.

Pero, de momento, mostrar tan sólo el resultado.

23 septiembre 2006

Version 1.1 control Linksys - Arduino

Mas proyectos en: http://eduardomarin.es/node/2


GUÍA: CONTROL ARDUINO - LINKSYS WRT45GL




En las siguientes líneas intento exponer con cierto detalle cómo conseguir una comunicación entre el router Linksys WRT45GL y la placa Arduino a través de una conexión sobre puerto serie, todo ello controlado desde un pc con conexión wifi sobre el router Linksys.

INTRODUCCIÓN

El propósito de la conexión entre estos dos dispositivos nos permite, en cierto modo, ampliar los límites tanto de la placa Arduino como del router Linksys. En combinación mútua, sus posiblidades abarcan, desde una relativa ampliación de memoria de Arduino, como una adquisición de datos de forma remota usando como puente el router Linksys. Podemos, así, mover brazos de robot (que portan webcams), hacer lecturas de diferentes tipos de sensores (temperatura, presión, movimiento), etc; todo ello a través de una red de conexión, ya sea local mediante ethernet o wifi, o a través de WLAN.
PARTICULARIZANDO...

Para mostrar la idea atrás esbozada, vamos a realizar el montaje para poder controlar hasta 12 leds, y llevar a cabo una lectura de un NTC (resistencia variable con la temperatura).
Implementaremos una interfaz gráfica, sobre HTML para hacerlo más intuitivo y atractivo.
La conexión con el router se basará en la comunicación sobre el puerto serie. Este aspecto requiere llevar a cabo una modificación física del router, pues no viene con dicho puerto implantado de fábrica, aunque sí su circuitería impresa.


COMPONENTES

Como decíamos, usaremos una placa Arduino, un router Linksys WRT45GL, una termorresistencia (NTC), dos conectores DB-9 (hembra y macho), un conector para cable plano de 10 pines con cable, y una resistencia de 330 ohm.



PROCESO








En primer lugar, instalaremos el puerto serie en el router.
Para ello, debemos abrir el aparato sin romperlo :-P . Desenrroscamos las antenas, ponemos el router boca abajo y empujamos hacia afuera, sobre las dos patas delanteras. En ese momento, el router pierde toda garantía, de lo cual, yo no me hago responsable :-)
Una vez abierto, debemos buscar dos puertos serigrafiados en la placa, fijándonos en el que tiene 10 perforaciones. Ese es el nuestro. Insertamos el conector de cable plano y soldamos con cuidado. En este momento es donde debemos identificar cada uno de los pines, para llevarlos al conector DB-9.









El router, al usar como sistema embebido Linux, en concreto ejecuta como intérprete de órdenes busybox, el cual mantiene las antiguas callout para comunicarse sobre el puerto serie. Más tarde estas salidas fueron sustituidas por las ttyS0 y ttyS1. No es nuestro caso. Así pues, cuando trabajemos con el puerto serie, debemos prestar atención a cua0 y cua1. Pero para ser más precisos, tan sólo nos fijaremos en cua1, pues, por algún motivo que no entiendo, el device cua0 no está operativo (is busy). Volviendo al puerto, debemos fijarnos en los pines 3, 5, 9 y 10, que son, tx, rx, gnd y gnd respectivamente (el puerto 1, 2, 4, y 6 son Vcc, Vcc, tx y rx de cua0, respectivamente).
Finalmente, y una vez hecha la identificación de los tres pines (gnd, tx, rx), soldamos, del cable plano, los tres cables al conector DB-9. La elección de los tres pines en el conector es a gusto de cada cual, pues no podremos usar ese conector para comunicarnos con un dispositivo corriente mediante puerto serie. Para ello deberíamos trabajar la señal para convertirla al estándar 232 (estamos trabajando en ttl).
Para fijar el conector, podemos realizar una apertura en la carcasa y así no tener que trastear demasiado con el router.










El siguiente paso sería comprobar que las conexiones las hemos realizado correctamente. Para ello, podemos hacer uso de Arduino, monitorizando lo que ocurre en el puerto serie. Así pues, conectamos al puerto serie y entramos mediante SSH (usando Putty por ejemplo) y lanzamos, o bien el entorno de desarrollo de Arduino, o bien un terminal para ver comunicación en COMx.

Desde la consola SSH, y una vez logeados en el router, probamos a enviar un cierto mensaje hacia Arduino. Ésto se lleva a cabo de la siguiente manera: la comunicación en Linux a través del puerto serie se lleva a cabo como una escritura en un fichero cualquiera, salvo que, en este caso, se trata del archivo de dispositivo localizado en /dev/cua/1. Así pues, si tecleamos echo Hola Mundo! > /dev/cua/1, el terminal del ordenador nos mostraría el mensaje por pantalla (siempre y cuando se encuentre a 9600 bps).

¿Cuál es el siguiente paso? El siguiente paso se va a dar sobre la programación de Arduino. Para ello debemos, en primer lugar, señalar la estructura de los diferentes módulos que van a componer la comunicación.
Por un lado, un código en Arduino se encargará de recibir datos codificados (made in yo) y generar las diferentes señales.
En el router, shell scripts (cgi) se encargarán de enviar y recibir datos y lanzar páginas HTML al navegador.
Por último, para hacer presentable la información, se crea la página Web que hará de interfaz al usuario.

Así pues, comencemos con el código en Arduino.

CÓDIGO EN ARDUINO


La idea es, básicamente, dejar la programación más compleja al router, que dispone de un sistema operativo empotrado, con más capacidad de memoria, y liberar a Arduino de esa carga, para, tan sólo, responder a códigos básicos que debe traducir, interpretar y generar las diferentes señales.


Así, podemos ver que tenemos 12 puertos digitales (0 y 1 reservadas para RX y TX), y 5 analógicas. Los digitales vamos a tomarlos sólo como salidas. De esta forma, cuando desde el router queramos activar una señal, sería lógico indicar, tanto que vamos a activar, como el número de puerto de que se trate. Con esta regla, podemos determinar que para activar un determinado puerto, debemos escribir echo H03 > /dev/cua/1. Es decir, para referirnos a la activación de un puerto usaremos "Hx", siendo x el número de puerto (3 <= x <= 13). De la misma forma, para desactivar o pasar a un estado Low "Lx". Finalmente, los puertos analógicos sólo serán de lectura, así pues, los nombraremos como "Ax" (0 <= x <= 5). El código debe leer iterativamente del puerto serie en busca de un byte "H", "L" ó "A", y, o bien activar o desactivar el puerto o bien leer el puerto. Todo ello se detalla en el siguiente código:
/* Adquisición de datos y control de salidas para 

linksys WRT45GL a través de puerto serie */



//Definimos las variables necesarias

int i,valor,valoraux,digito,pin;

byte dato,decenas,unidades;



void setup(){

for (i=2;i<=13;i++){
pinMode(i,OUTPUT);
}
Serial.begin(9600);
}

void loop(){
//A la hora de codificar cada una de las salidas digitales
//mediante el router, estableceremos como norma, codificar
//el estado HIGH para el pin 2 como: "H02". Y para un estado
//LOW: "L02". Para referirnos a las entradas analógicas, 
//lo indicaremos anteponiendo la A:  "A5".
//Dado que la comunicación serie, se lleva a cabo, como la 
//propia palabra indica, mediante secuencia de bytes, entonces
//tendremos que llevar un control de los "paquetes" de datos
//para identificar correctamente los 3 bytes de una codificacion
//del estilo "H02"

//Comprobamos si llega señal del router:
if (Serial.available()){
dato=Serial.read();
//En caso de que el primer byte sea una H o una L, nos 
//preparamos para decodificar el pin, leyendo, previamente
//el número de dicho pin. Para ello transformamos su nº
//a entero, restando al código ascii, 48
if (dato=='H' || dato=='L'){
//leemos primero las decenas, esperando en bucle hasta
//que se detecte el byte entrante.
while(! Serial.available()){
}
decenas=Serial.read();
//eco de comprobacion serialWrite(decenas);
pin=(decenas-48)*10;
//y después las unidades, para obtener el nº del pin
while(! Serial.available()){
}
unidades=Serial.read();
//eco de comprobacion serialWrite(unidades);
pin=pin+(unidades-48);
if(dato=='H'){
digitalWrite(pin,HIGH);
}
else{
digitalWrite(pin,LOW);
}
}
//En caso de que fuese A, entonces es un
//puerto analógico (por supuesto que todo esto debe
//controlarse desde el router), y necesitamos enviar
//los datos analógicos que pueda haber en dicho pin.
//Para ello codificamos el entero que nos devuelve una
//lectura de los 1024 posibles niveles, enviándolos como
//cadena de 4 dígitos.
if (dato=='A'){
//primero hacemos la lectura del pin en cuestión:
while(! Serial.available()){
}
dato=Serial.read();
//A continuación enviamos los datos byte a byte
//a través del puerto serie hacia el router.
//para ello debemos descomponer las unidades, decenas...
pin=dato-48;
delay(1000);
valor=analogRead(pin);
valoraux = valor;
digito = valoraux/1000;
serialWrite(digito+48);
valoraux = (valoraux - (digito * 1000));
digito = valoraux/100;
serialWrite(digito+48);
valoraux = (valoraux - (digito * 100));
digito = valoraux/10;
serialWrite(digito+48);
valoraux = (valoraux - (digito * 10));
digito = valoraux;
serialWrite(digito+48);
Serial.println();
}
}
}





CÓDIGO EN ROUTER

Cuando una página es accedida en internet, los servidores deben buscar información en sus bases de datos, y devolver las consultas oportunas. Se dice entonces que un código cgi (common gateway interface) está creando una página dinámica. El código cgi o lenguaje cgi puede implementarse mediante perl, javascript, ... En nuestro caso usaremos un shell script basado en comandos Unix.
Cuál será la organizacion? Pues bien, como yo no soy un gurú de Unix, y menos de HTML, me baso en ideas que creo que funcionarán (de hecho, podían funcionar mejor :-P ).
Es importante indicar que el código que se cree como interfaz cgi debe ir localizado en el directorio /www/cgi- bin/, que será, en cierta medida, la parte visible a la red (todo /www, de hecho). En ese directorio, crearemos el archivo shell script principal, el cuál creará la página HTML, y llevará a cabo la consulta de la entrada analógica 5 (del NTC).
Su código:

#!/bin/sh
../arduino/adquisitor &
VARIABLE=`cat nivel | cut -b 1,2,3,4`
AUX=`expr 870 - $VARIABLE`
TEMPERATURA=`expr $AUX / 5`
head -n 149 ../arduino/principal.html
echo "
MONITORIZACIÓN DE SENSOR DE TEMPERATURA:  $TEMPERATURA      º
tail -n 4 ../arduino/principal.html


Donde la segunda línea ejecuta otro shell script que es el que hace la llamada a través del puerto serie y lee los datos de Arduino. Las líneas 3, 4 y 5 hacen una conversión de los 1024 niveles analógicos recibidos de Arduino para "amoldarlos" a una presentación de temperatura en ºC. y finalmente se crea la página, ayudándonos de la impresión de un archivo HTML (principal.html) e inclyuendo, entre medias del archivo (fijarse que se imprime parte de principal.html y luego el final, mediante head y tail), la temperatura consultada. Este código se repite para cada uno de los botones que se crean. Es decir, al igual que existe el shell script principal, existe el H03, L04, H05, L05, ... cada uno activa su p uerto correspondiente, además de cargar la página HTML.

El código del script adquisitor es:

#!/bin
/sh
variable=0
echo A5 > /dev/cua/1
cat < /dev/cua/1 > nivel &
until test $variable -ge 300
do
variable=$(($variable + 1))
done
kill $$


En el cual, la tercera línea hace la consulta, como dijimos, mediante la codificación "A5" a través del puerto /cua/1 y se espera la respuesta, redirigiendo la entrada hacia un archivo auxiliar llamado "nivel". La lectura del puerto serie es un proceso que queda ejecutándose hasta que se mate. Por lo tanto, debemos, en primer lugar mandarlo a bacground (&) y finalmente asesinarlo :-) (kill $$). Un aspecto importante es que debemos esperar un cierto tiempo hasta que Arduino haga una lectura y retorne los datos. Para ello se hace uso de un bucle "tonto" (no se si habrá un comando tipo delay en ash).



Final me nte se g uarda la página web principal.html que es la que hace de presentación al usuario.

Debo destacar que hay muchos aspectos mejorables, pues hay algún problemilla con el control de procesos en bacground, con el código HTML, y con el acceso al router desde internet. Pero para una idea más o menos general, la creación de este montaje, creo que es acertada.