tag:blogger.com,1999:blog-10514394535224333422024-03-13T21:39:00.020+01:00La navaja del GeekAnotaciones sobre programación y tecnología, algunos trabajos sobre Arduino y cosas por las que vale la pena perder el tiempo.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-1051439453522433342.post-15680214478385398972015-01-26T21:09:00.002+01:002015-01-26T21:10:07.329+01:00SCADA para ArduinoUn sistema SCADA te permite desarrollar tus propias aplicaciones de control y monitorización usando los dispositivos que desees siempre y cuando estos dispongan de un protocolo de comunicaciones apropiado.<br />
<br />
En el siguiente enlace podéis ver una herramienta que estoy desarrollando que permite crear aplicaciones de manera muy rápida y con un acabado vistoso y profesional que permite intercambiar datos con cualquier tipo de Arduino ya sea serie, ethernet o wifi como el YÚN.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Wd0zUR-C4Ek/VMaeIC5fK3I/AAAAAAAAB8U/En2cTLqMics/s1600/vob.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Wd0zUR-C4Ek/VMaeIC5fK3I/AAAAAAAAB8U/En2cTLqMics/s1600/vob.jpg" height="262" width="400" /></a></div>
<br />
Más información del proyecto en <a href="http://st4makers.com/">http://st4makers.com</a><br />
<br />
Os dejo además algunos vídeos que os pueden ser de utilidad sobre su potencial<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/cJOv5ZYGJwk?feature=player_embedded' frameborder='0'></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Utilizando el Arduino Ethernet</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/H2ZM0g3Wq-c?feature=player_embedded' frameborder='0'></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
Enlazando valores del Arduino con elementos gráficos</div>
<br />Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0tag:blogger.com,1999:blog-1051439453522433342.post-64000532918209071432013-07-03T09:52:00.003+02:002013-07-03T09:52:55.381+02:00La guía definitiva de comunicaciones Wifi con el Arduino Wireless SD Shield y WiFly RN-XV<br />
<br />
<span style="background-color: white; color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15.59375px;">En esta ocasión vamos a ver todos los pasos necesarios para poder comunicar el Arduino con Internet por medio de la Wifi usando el módulo de comunicaciones WiFly.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.ismsolar.com/images/blog/wifly_wireless_sd_shield/wifly%20arduino%20uno%20sd%20card.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="http://www.ismsolar.com/images/blog/wifly_wireless_sd_shield/wifly%20arduino%20uno%20sd%20card.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="background-color: white; color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15.59375px;">El </span><a href="http://arduino.cc/en/Main/ArduinoWirelessShield" style="background-color: white; border: 0px; color: #3d5175; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15.59375px; margin: 0px; outline: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;">shield Wireless SD </a><span style="background-color: white; color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15.59375px;">es un módulo para Arduino para proporcionar conectividad con modulos de comunicación variados tipo XBEE pero se le puede colocar cualquier otro que soporte la misma configuración física. En este caso lo usaremos para comunicar el Arduino con un módulo WiFly. Este shield tiene la ventaja de que dispone tambien de un slot para tarjetas SD lo que nos proporciona a su vez capacidad de almacenamiento para nuestros proyectos aunque su utilización no es obligatoria.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="background-color: white; color: #333333; font-family: Tahoma, Helvetica, Arial, sans-serif; font-size: 12px; line-height: 15.59375px;"><br /></span></div>
<span style="color: red; font-size: large;">Puedes encontrar este tutorial actualizado en la siguiente dirección:</span><br />
<br />
<a href="http://www.ismsolar.com/arduino-wireless-sd-shield-y-wifly-comunicaciones-wifi-con-el-arduino">http://www.ismsolar.com/arduino-wireless-sd-shield-y-wifly-comunicaciones-wifi-con-el-arduino</a>Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0tag:blogger.com,1999:blog-1051439453522433342.post-28473044812535083512012-09-12T10:44:00.001+02:002012-09-17T13:06:48.691+02:00Instalación de PostgreSQL 9.2 sobre Ubuntu Server 12.04.1 LTS <br />
acaba de salir recientemente tanto una actualización de Ubuntu Server como de PostgreSQL y me he decidido a probar ambos en una instalación desde cero. Vamos a ver como instalarlo para tener un entorno de pruebas o producción con lo último de lo último.<br />
<br />
Con el Ubuntu Server instalado sin ningún paquete extra realizaremos los siguientes pasos desde una cuenta de usuario sin privilegios:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">sudo apt-get update
sudo apt-get upgrade</span>
<span style="line-height: 1.5em;"><span style="line-height: 1.5em;">sudo apt-get install gcc bison flex libreadline-dev zlib1g-dev make</span>
wget http://ftp.postgresql.org/pub/source/v9.2.0/postgresql-9.2.0.tar.gz
gzip -d postgresql-9.2.0.tar.gz
tar -xvf postgresql-9.2.0.tar
cd postgresql-9.2.0
./configure
make
sudo su</span><span style="line-height: 1.5em;"><span style="line-height: 1.5em;">
make install</span>
adduser postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su - postgres</span></pre>
Inicializamos el sistema de ficheros para la base de datos con los ficheros de configuración de postgresql (en ese directorio encontraréis los ficheros de configuración principales postgresql.conf y pg_hba.conf)<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data</span></pre>
Arrancamos la instancia de PostgreSQL<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 &</span></pre>
Probamos la instalación creando una base de datos de prueba y conectándonos a ella<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test
</span></pre>
Con esto tendremos <a href="http://www.postgresql.org/about/news/1415/" target="_blank">la última versión de PostgresSQL</a> compilada desde los fuentes sobre la última versión de Ubuntu Server 12.04.1 LTS.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com1tag:blogger.com,1999:blog-1051439453522433342.post-59776631963318990922012-08-17T12:39:00.002+02:002013-07-03T09:42:11.547+02:00Sistema de monitorización OpenSource: Emoncms3<div style="text-align: center;">
<a href="http://www.ismsolar.com/monitorizacion-libre"><span style="color: red; font-size: large;">ATENCIÓN: TUTORIAL ACTUALIZADO AQUÍ</span></a></div>
<br />
Desde hace un par de meses llevo trabajando en un proyecto conjunto sobre un sistema de monitorización Open Source. Este proyecto tiene como finalidad que cualquier persona pueda realizar tareas de monitorización usando software y hardware libre. Toda la información del proyecto la podéis encontrar en <a href="http://openenergymonitor.org/">openenergymonitor.org</a> y en este post voy a explicar como montar la parte software del sistema de monitorización.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-TWkd04EYP4c/UC333Xuzn2I/AAAAAAAAARE/TX0CkmCA58g/s1600/OEM_system_emoncms2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://3.bp.blogspot.com/-TWkd04EYP4c/UC333Xuzn2I/AAAAAAAAARE/TX0CkmCA58g/s400/OEM_system_emoncms2.png" width="400" /></a></div>
<br />
<br />
Para ello necesitaremos un servidor con el sistema operativo Linux Ubuntu (podéis usar otra versión adaptando los pasos de instalación a dicha distribución) o si no tenéis ningún servidor disponible podréis usar la aplicación VirtualBox para montarlo virtualizado sobre vuestro sistema operativo con el que trabajáis habitualmentee (Windows, MacOs X o Linux). Por supuesto esta última opción no es recomendable para un despliegue para producción con casos reales por el poco rendimiento que da pero si nos puede venir muy bien para probarlo todo y empezar a trastear.<br />
<br />
Bueno, primeramente necesitaremos instalar el sistema operativo. Tanto como si lo montáis sobre un servidor físico o en una máquina virtual usando <a href="https://www.virtualbox.org/" target="_blank">VirtualBox</a> sobre vuestro escritorio o con alguna otra solución de virtualización como VMWare, Xen, etc... lo haremos instalando el Ubuntu Server 12.04 LTS desde esta dirección.<br />
<br />
<a href="http://www.ubuntu.com/download/server">http://www.ubuntu.com/download/server</a><br />
<br />
Lo instalaremos sin ninguna opción de paquetes para instalarlos a mano después según nos vayan haciendo falta y así tener el sistema operativo lo más limpio posible.<br />
<br />
Bueno, lo primero que haremos será, teniendo el sistema operativo recién instalado, lo siguiente desde el usuario autorizado para actualizar la instalación<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">$ sudo su</span></pre>
<span style="color: #666666; font-size: x-small;">nos preguntará por la clave que hemos indicado durante la instalación</span><br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># apt-get update
# apt-get upgrade</span></pre>
esto tardará un poco por lo que paciencia.<br />
<h2>
</h2>
<h2>
Instalando Apache</h2>
Una vez actualizado vamos a instalar el servidor web Apache para poder servir las páginas web<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># apt-get install apache2</span></pre>
Una vez instalado podemos ir a la ip de nuestra máquina con el navegador para ver si se ha instalado correctamente.<br />
<br />
En mi caso la ip es la 192.168.10.26 y la tuya la puedes averiguar con el comando ifconfig<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-rv7XRITHbU4/UCzFtX8W4OI/AAAAAAAAAQY/OFiDde5G6QI/s1600/screenshoot_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-rv7XRITHbU4/UCzFtX8W4OI/AAAAAAAAAQY/OFiDde5G6QI/s1600/screenshoot_1.jpg" /></a></div>
<br />
y usando el navegador lo comprobamos<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ViXHvLk0J0E/UCzGXrc2tcI/AAAAAAAAAQg/Bwjw1r-Cp6A/s1600/screenshoot_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="218" src="http://1.bp.blogspot.com/-ViXHvLk0J0E/UCzGXrc2tcI/AAAAAAAAAQg/Bwjw1r-Cp6A/s400/screenshoot_2.jpg" width="400" /></a></div>
<br />
<h2>
Instalando PHP5</h2>
Una vez instalado el servidor Apache le toca el turno al php5 con:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># apt-get install php5 libapache2-mod-php5 php-gettext</span></pre>
podemos comprobar si todo está correcto creando un fichero en /var/www denominado index.php con el siguiente contenido:<br />
<br />
<?php phpinfo(); ?><br />
<br />
y ejecutarlo desde el navegador<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-yZ-2DbEg8mI/UCzH0jseKLI/AAAAAAAAAQo/-bHJ-w1CXbA/s1600/screenshoot_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235" src="http://3.bp.blogspot.com/-yZ-2DbEg8mI/UCzH0jseKLI/AAAAAAAAAQo/-bHJ-w1CXbA/s400/screenshoot_3.jpg" width="400" /></a></div>
<br />
Si todo va bien veremos información de php en el navegador.<br />
<h3>
</h3>
<h2>
</h2>
<h2>
Instalación de MySQL</h2>
El siguiente paso es la instalación del sistema gestor de base de datos MySQL<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># apt-get install mysql-server mysql-client</span></pre>
e introducimos la contraseña para el usurio root de mysql que deseemos cuando nos lo pida. Debemos recordarla ya que la necesitaremos más adelante para crear un usuario específico y la base de datos.<br />
<br />
Ahora para dar soporte desde PHP a MySQL instalaremos los siguientes paquetes:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># apt-get install php5-mysql</span></pre>
y reiniciamos Apache con<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># /etc/init.d/apache2 restart</span></pre>
<br />
Ahora veremos en nuestro index.php que ya tenemos soporte para MySQL desde PHP.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-KEEfE9ZH8Mw/UC4Lig3kXEI/AAAAAAAAARY/-htmNWiRbkg/s1600/phpinfomysql.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-KEEfE9ZH8Mw/UC4Lig3kXEI/AAAAAAAAARY/-htmNWiRbkg/s400/phpinfomysql.jpg" width="372" /></a></div>
<br />
<h2>
Creación de la base de datos</h2>
Emoncms3 trabaja sobre una base de datos para almacenar toda la información de los datos monitorizados así como pantallas, usuarios, etc... para ello vamos a crear un usuario específico en MySQL y será este usuario el dueño de dicha base de datos. Esto nos servirá para aumentar la seguridad ya que dicho usuario sólo tendrá permisos sobre esa base de datos y las acciones de Emoncms3 estarán restringidas por los permisos de dicho usuario.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># mysql -u root -p</span></pre>
nos pedirá el password que hemos indicado cuando instalamos MySQL.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">mysql> CREATE USER 'emoncms3user'@'localhost' IDENTIFY BY 'emoncms3userpass'</span></pre>
con esta sentencia creamos el usuario y le asignamos la clave (recordad usar una un poco más compleja ;-)<br />
<br />
creamos la base de datos y asignamos como dueño al usuario anteriormente creado.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;">mysql> CREATE DATABASE emoncms3db;
mysql> GRANT ALL PRIVILEGES ON emoncms3db.* TO emoncms3user@localhost
mysql> \q</span></pre>
<br />
ahora podemos probar a conectarnos a la base de datos con el usuario que acabamos de crear<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># mysql -u emoncms3user -p emoncms3db</span></pre>
introduciendo la clave de dicho usuario y entrando comprobaremos que todo está correcto.<br />
<h2>
</h2>
<h2>
Instalando Emoncms3 desde el repositorio oficial</h2>
Bueno, tenemos ya el servidor web, el PHP y MySQL ahora queda instalar el software de monitorización. Este software se encuentra en un repositorio denominado <a href="https://github.com/" target="_blank">GitHub</a> en la siguiente dirección:<br />
<br />
<a href="https://github.com/openenergymonitor/emoncms3">https://github.com/openenergymonitor/emoncms3</a><br />
<br />
desde ahí se puede ver todo el proyecto OpenSource con las diferentes ramas de desarrollo. Existe una rama DEV que es de pruebas donde desarrollamos nuevas funcionalidades y probamos que todo va bien y una rama principal que es la que usaremos como instalación. Esta rama suele estar actualizada y es la versión más estable de todas por lo que recomiendo que uséis esta última. Luego veremos como ir actualizando el sistema cada vez que haya nuevas actualizaciones.<br />
<br />
Como vamos a instalarlo todo de manera que podamos actualizar facilmente la mejoras que se vayan incorporando, debemos instalarnos el cliente Git (que es un software para gestionar repositorios de desarrollo) de la siguiente manera:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># apt-get install git-core</span></pre>
y clonamos el repositorio emoncms3 con todos los fuentes<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># cd /var/www
# git clone git://github.com/openenergymonitor/emoncms3.git</span></pre>
<br />
o si estáis detrás de un firewall podéis usar la conexión por https que tardará algo más pero os evitará tener problemas con dicho cortafuegos<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># git clone https://github.com/openenergymonitor/emoncms3.git</span></pre>
<br />
cuando acabe tendréis un directorio denominado emoncms3. Nuestro software recién instalado estará en el directorio /var/www/emoncms3 de nuestro servidor. También podéis descargar el fichero comprimido con todos los fuentes y soltarlo en dicho directorio pero perderéis la facilidad de descargar automaticamente las actualizaciones teniendo que realizar las tareas de despliegue de nuevas versiones realizando la misma operación.<br />
<br />
Cada vez que haya una nueva versión podemos actualizar nuestra instalación desde el directorio /var/www/emoncms con el siguiente comando siempre que hayamos instalado el software usando git.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># git pull</span></pre>
Una vez instalado podemos ir con nuestro navegador al software instalado usando la ip_de_vuestro_servidor/emoncms3<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-bOatiXqSb2k/UC4Qq7-l-NI/AAAAAAAAARs/KCkGHcrdHds/s1600/error1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-bOatiXqSb2k/UC4Qq7-l-NI/AAAAAAAAARs/KCkGHcrdHds/s1600/error1.png" /></a></div>
<br />
os saldrá el siguiente mensaje de error. Quiere decir que nos falta crear y configurar el fichero de configuración de la aplicación. Copiamos el que trae de plantilla en el directorio Includes y lo modificamos con nuestro parámetros<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># cp Includes/default.settings.php Includes/settings.php</span></pre>
recargamos la página y veremos el siguiente aviso:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-i9fb7K0ZTFA/UC4ReIXx8uI/AAAAAAAAAR0/QKBEOYd0zv4/s1600/error2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-i9fb7K0ZTFA/UC4ReIXx8uI/AAAAAAAAAR0/QKBEOYd0zv4/s1600/error2.png" /></a></div>
<br />
ahora editamos el fichero settings.php que se encuentra en Includes/settings.php<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Acmu089N00M/UC4Th81pq8I/AAAAAAAAAR8/pZh7rl5GByo/s1600/settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Acmu089N00M/UC4Th81pq8I/AAAAAAAAAR8/pZh7rl5GByo/s1600/settings.png" /></a></div>
<br />
<br />
y en el fichero setup.php del directorio de instalación descomentamos (quitamos las barras de) la línea donde pone <br />
<br />
// $runnable = TRUE<br />
<br />
Ahora cambiaremos por cuestiones de seguridad el propietario del proyecto<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># chown -R www-data.www-data /var/www/emoncms3</span></pre>
y borraremos el fichero index.php o le cambiaremos el nombre para que nadie conozca los detalles de nuestra instalación<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># rm /var/www/index.php</span></pre>
Ahora podemos volver a lanzar la página web del proyecto y veremos como se crean las tablas necesarias.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-aJHppN5JMiA/UC4U6tgUCVI/AAAAAAAAASE/jtZqA69XB9U/s1600/dbinstall.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-aJHppN5JMiA/UC4U6tgUCVI/AAAAAAAAASE/jtZqA69XB9U/s400/dbinstall.png" width="392" /></a></div>
<br />
Pulsaremos sobre "Continue to emoncms" y veremos la página principal de nuestro sistema de monitorización.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-FFJO_pM3YuA/UC4XB_7f2vI/AAAAAAAAASM/PqYLzVBcasc/s1600/login.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://3.bp.blogspot.com/-FFJO_pM3YuA/UC4XB_7f2vI/AAAAAAAAASM/PqYLzVBcasc/s400/login.png" width="338" /></a></div>
<br />
<br />
Emoncms3 utiliza el modo de reescritura de URL para funcionar por lo que debemos instalarlo antes de continuar<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># a2enmod rewrite</span></pre>
<br />
y editar el fichero /etc/apache/sites-available/default añadiendo las opciones para el directorio /var/www/emoncms3<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-LvW92Mjh1Xw/UC4cGiwC7dI/AAAAAAAAASo/CE9UeZl9ImU/s1600/modrewrite.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-LvW92Mjh1Xw/UC4cGiwC7dI/AAAAAAAAASo/CE9UeZl9ImU/s1600/modrewrite.png" /></a></div>
<br />
y reiniciamos apache de nuevo<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"># /etc/init.d/apache restart</span></pre>
<br />
Ya sólo queda volver a comentar la línea $runnable = TRUE; del fichero setup.php para que nadie pueda llamarlo, elegir un nombre de usuario y contraseña y pulsar sobre "Register" para entrar en nuestro software.<br />
<br />
En estos momento ya tendréis vuestro sistema de monitorización propio y podéis generar pantallas y gráficos con datos enviados desde vuestros dispositivos de medición o sensores, como por ejemplo Arduino. En próximos post daré más detalles de como realizar todo esto y crear aplicaciones como esta:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-BJpDPqIAeSY/UC4ZbmjB11I/AAAAAAAAASc/Pxtx8IpJrt0/s1600/dashboard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://2.bp.blogspot.com/-BJpDPqIAeSY/UC4ZbmjB11I/AAAAAAAAASc/Pxtx8IpJrt0/s400/dashboard.png" width="400" /></a></div>
<br />
Existe una opción disponible que os permite monitorizar igualmente vuestros dispositivos sin necesidad de montar el software y es usando una cuenta oficial en la aplicación que hemos desplegado de manera libre en<br />
<a href="http://emoncms.org/">http://emoncms.org/</a>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Wm_tBdTHo-Q/UC4YYv-U-HI/AAAAAAAAASU/_robHxKYbWw/s1600/emoncms.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://2.bp.blogspot.com/-Wm_tBdTHo-Q/UC4YYv-U-HI/AAAAAAAAASU/_robHxKYbWw/s400/emoncms.png" width="398" /></a></div>
<br />
Recordad que podéis ver mucha más información en la página principal del proyecto en <a href="http://openenergymonitor.org/">http://openenergymonitor.org</a> y si tenéis cualquier problema o duda con la instalación contactad conmigo o utilizad el foro de soporte.<br />
<br />Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com1tag:blogger.com,1999:blog-1051439453522433342.post-71939586511703217812012-05-18T19:54:00.000+02:002012-05-18T20:06:02.935+02:00Actualización del firmware del WiFly de Rovin NetworksEn este artículo veremos como actualizar el firmware del módulo WiFly de Rovin Networks a la última versión.<br />
<br />
En el anterior post os contaba como se configuraba y en el mismo me dí cuenta que no tenía la última versión así que investigando ya he averiguado como hacerlo.<br />
<br />
Lo primero que hay que hacer es ver que versión tenemos, en la actualidad está la versión 2.32 del 13 de febrero de 2012.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-C5lkUgeKI8s/T7aHP-NaERI/AAAAAAAAAPM/pq5tjDWOeeE/s1600/p8.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-C5lkUgeKI8s/T7aHP-NaERI/AAAAAAAAAPM/pq5tjDWOeeE/s1600/p8.jpg" /></a></div>
<br />
Lo primero que tenemos que hacer es conectar nuestro módulo a Internet por medio de la wifi. Para ello seguimos las indicaciones del post anterior y hacemos un "join SSID" donde el SSID es el identificativo de tu red inalámbrica.<br />
<br />
Una vez conectado, con el comando "ver" vemos la versión que tenemos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-iBfdbgaFTBk/T7aHkONjp2I/AAAAAAAAAPU/g6OWc_WtLbI/s1600/p9.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-iBfdbgaFTBk/T7aHkONjp2I/AAAAAAAAAPU/g6OWc_WtLbI/s1600/p9.jpg" /></a></div>
<br />
En mi caso la 2.30 del 26 de noviembre de 2011. Si, lo sé, es bastante reciente pero soy algo maniático por tener siempre todo actualizado :-p<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-qgZn4E2GT-4/T7aIAbP-WsI/AAAAAAAAAPc/hmr1D7RwBxY/s1600/p10.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-qgZn4E2GT-4/T7aIAbP-WsI/AAAAAAAAAPc/hmr1D7RwBxY/s1600/p10.jpg" /></a></div>
<br />
Una vez sabemos la versión podemos ver con el comando "ls" que ahí está el firmware que está instalado, en este caso el archivo WiFly_EZX-2.30 que corresponde con la versión que se ve en el prompt.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-I6Zkf8kZOAU/T7aIXO4LtJI/AAAAAAAAAPk/xD3c7ojROzk/s1600/p11.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"> <img border="0" src="http://3.bp.blogspot.com/-I6Zkf8kZOAU/T7aIXO4LtJI/AAAAAAAAAPk/xD3c7ojROzk/s1600/p11.jpg" /></a></div>
<br />
Ahora simplemente hacemos "ftp update" y veremos como se conecta y se descarga la última versión del firmware, el WiFly_EZX-2.32. En caso de algún error puede ser debido a que hemos modificado los parámetros de conexión por defecto del ftp. Si es así con hacer un "factory RESET" y un "reboot" los volveremos a tener pero tendremos que volver a configurar nuestro módulo para que se conecte a Internet y empezar de nuevo.<br />
<br />
Aquí vemos como se ha descargado correctamente el fichero. Ahora toca hacer un "boot image FL#" y listo, donde FL# corresponde al número que tiene el archivo de firmware que queremos usar. Aquí "boot image 33".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-IK3gbxzegMQ/T7aJCr9H24I/AAAAAAAAAPs/KigTeBZ4Vtw/s1600/p12.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-IK3gbxzegMQ/T7aJCr9H24I/AAAAAAAAAPs/KigTeBZ4Vtw/s1600/p12.jpg" /></a></div>
<br />
Ahora sí, hacemos un "factory RESET", "reboot" y si entramos en modo comando con $$$ y ejecutamos "ver" veremos que ya tenemos la nueva versión instalada.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-DFn5SgOP7Sw/T7aJVHFZqAI/AAAAAAAAAP0/L_4KOOZTnJk/s1600/p13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-DFn5SgOP7Sw/T7aJVHFZqAI/AAAAAAAAAP0/L_4KOOZTnJk/s1600/p13.jpg" /></a></div>
<br />
Bueno, no ha sido demasiado difícil y podemos disfrutar de la última versión disponible. Toda esta información la he sacado del manual de referencia del WiFly por lo que si tenéis dudas podéis acudir a mí o al mismo manual pinchando <a href="http://www.rovingnetworks.com/resources/show/ptype:2/dtype:/product:" target="_blank">aquí</a>.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0tag:blogger.com,1999:blog-1051439453522433342.post-79529375473516057322012-05-16T17:59:00.001+02:002013-07-03T09:47:24.864+02:00XBee Shield + WiFly RN-XV + Arduino UNO<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.ismsolar.com/comunicando-el-arduino-por-wifi"><span style="color: red; font-size: large;">ATENCIÓN: </span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.ismsolar.com/comunicando-el-arduino-por-wifi"><span style="color: red; font-size: large;">TUTORIAL ACTUALIZADO AQUÍ</span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-xb-ZJm1ieHY/T7KfXqxJxqI/AAAAAAAAANU/TxrXTezplZY/s1600/DSCN4182.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="356" src="http://2.bp.blogspot.com/-xb-ZJm1ieHY/T7KfXqxJxqI/AAAAAAAAANU/TxrXTezplZY/s400/DSCN4182.JPG" width="400" /></a></div>
<br />
Tenía en mente desarrollar algún sistema inalámbrico usando el Arduino y para ello pregunté a la gente de <a href="http://www.cooking-hacks.com/" target="_blank">cooking-hacks</a> que módulo sería mejor. Adquirí un módulo XBee Shield para poder colocar diferentes módulos de comunicación (wifi, bluetooth, radio, etc..) y para las primeras pruebas adquirí un módulo de Rovin Networks que es totalmente compatible con el shield de XBee.<br />
<br />
Después de las pruebas he podido comprobar que este módulo funciona muy bien, es muy potente y tiene muchas funcionalidades. Os dejo el enlace por si os interesa verlo en detalle <a href="http://www.rovingnetworks.com/products/RN_XV" target="_blank">aquí</a>.<br />
<br />
El módulo se integra muy bien con el Arduino y se puede empezar a trabajar principalmente de dos forma con él. Una de ellas es programarle una configuración y otra es configurarlo en tiempo real desde el propio Arduino.<br />
<br />
Al principio os aconsejo montarlo y utilizarlo sin el Arduino para ir familiarizándonos con él y para ello debemos seguir unos sencillos pasos.<br />
<br />
Lo primero es que no nos podremos comunicar con el módulo WiFly si está por medio el Arduino ya que en este caso comparten el puerto serie. Solución, lo quitaremos de la placa :-)<br />
<br />
<pre style="background-color: #eeeeee; border: 1px solid rgb(221, 221, 221); clear: both; color: #111111; font-family: Consolas, 'Andale Mono', Monaco, Courier, 'Courier New', Verdana, sans-serif; font-size: 12px; line-height: 1.5em; margin-bottom: 1.667em; overflow: auto; padding: 0.583em 0.833em;"><span style="line-height: 1.5em;"><span style="color: #cc0000;"><b>ACTUALIZACIÓN</b></span>
Ya no es necesario quitarlo de la placa ya que he descubierto
que cargando en el Arduino un sketch vacío se puede acceder al WiFly directamente.
El sketch es el siguiente:
void setup() { }
void loop() { }
funciona tanto para este shield como para el Wireless SD Shield.
Puedes saltarte el paso de desmontar el micro de la placa.
</span></pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-X09vU9dObNc/T7KnjjUiQII/AAAAAAAAANg/lnp3Lgsu5No/s1600/DSCN4183.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="http://1.bp.blogspot.com/-X09vU9dObNc/T7KnjjUiQII/AAAAAAAAANg/lnp3Lgsu5No/s400/DSCN4183.JPG" width="400" /></a></div>
<br />
Para ello, primero y muy importante acordarnos de la orientación del microprocesador y luego usando un destornillador plano y de manera muy suave haciendo palanca lo sacamos. En el caso de que el microprocesador venga directamente soldado en placa no podremos hacer las pruebas pero podremos igualmente programar el WiFly desde el propio Arduino.<br />
<br />
Una vez extraido el micro podemos montar el WiFly en el XBee Shield<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-gl_hxmYzWgE/T7KpHam7I0I/AAAAAAAAANo/ZAO2oLzb_kE/s1600/DSCN4184.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="http://2.bp.blogspot.com/-gl_hxmYzWgE/T7KpHam7I0I/AAAAAAAAANo/ZAO2oLzb_kE/s400/DSCN4184.JPG" width="400" /></a></div>
<br />
y montamos el shield en el Arduino sin el microprocesador.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-N3Uwnqpq3Gw/T7KpTOfv6HI/AAAAAAAAANw/Sr1iqlF47JE/s1600/DSCN4180.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="322" src="http://1.bp.blogspot.com/-N3Uwnqpq3Gw/T7KpTOfv6HI/AAAAAAAAANw/Sr1iqlF47JE/s400/DSCN4180.JPG" width="400" /></a></div>
<br />
De esta manera la placa del Arduino y el shield harán la función de puente entre el ordenador y el módulo WiFly aunque nos queda un paso importante. El shield dispone de dos jumpers marcados como XBEE/USB. La posición XBEE es para que el microprocesador y el módulo se comuniquen entre sí, la posición USB hace que el módulo se conecte directamente con el puerto USB pero al compartir el RX/TX con el microprocesador es necesario quitarlo (que es lo que hemos hecho). Colocamos los dos jumpers en la posición USB y ya podemos conectar la placa Arduino con el ordenador.<br />
<br />
Al conectarlo por primera vez el módulo WiFly intentará conectarse automáticamente a una red pero en nuestro caso lo haremos manualmente. <br />
<br />
Para ello desde nuestro ordenador instalaremos el software que el fabricante suministra para la comunicación serie con el módulo WiFly llamado Teraterm (que es parecido al Hyperterminal pero que no recomienda usar el fabricante). Lo podeís descargar desde <a href="http://www.rovingnetworks.com/resources/show/ptype:2/dtype:/product:" target="_blank">aquí</a>. <br />
<br />
Lo arrancamos, establecemos la comunicación por el puerto serie apropiado y debería salir algo así. Esto es el módulo intentando conectarse automaticamente.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-0HyxpxsNEGY/T7KsRaQQ-EI/AAAAAAAAAN8/P-M1OtYJ5Es/s1600/p1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-0HyxpxsNEGY/T7KsRaQQ-EI/AAAAAAAAAN8/P-M1OtYJ5Es/s1600/p1.jpg" /></a></div>
<br />
Para entrar en modo comandos hay que enviar por el puerto serie la secuencia $$$<br />
<br />
Al estar el ECO desactivado no veremos lo que escribimos y hay otro detalle importante. Si entre pulsación y pulsación pasan más de 250 ms el módulo interpretará estas pulsaciones como letras sueltas en lugar de la palabra de control. Ya sabeis, pulsad $ tres veces de manera rápida.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-gnEtsHSz7GM/T7KtVRnNzrI/AAAAAAAAAOE/lM__StshmB0/s1600/p2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-gnEtsHSz7GM/T7KtVRnNzrI/AAAAAAAAAOE/lM__StshmB0/s1600/p2.jpg" /></a></div>
<br />
Si todo va bien, saldrá el texto CMD y estaréis en modo comando. El manual de usuario que podreís encontrar <a href="http://www.rovingnetworks.com/resources/show/ptype:2/dtype:/product:" target="_blank">aquí</a> (WiFly User Manual) dispone de múltitud de comandos para juguetear un rato y os permitirán configurar muchísimos parámetros del módulo Wifi.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-FAA1OU7g0oU/T7KunMfx6mI/AAAAAAAAAOM/7sj9N_0RSLc/s1600/p3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-FAA1OU7g0oU/T7KunMfx6mI/AAAAAAAAAOM/7sj9N_0RSLc/s1600/p3.jpg" /></a></div>
<br />
por ejemplo el comando "ls" muestra algunos ficheros que se encuentran dentro del sistema de archivos del módulo WiFly y podemos por ejemplo ejecutar el "wps" para invocar la aplicación para el modo <a href="http://es.wikipedia.org/wiki/Wi-fi_protected_setup" target="_blank">WPS</a>.<br />
<br />
En el prompt aparece la versión del firmware instalado que en mi caso es la 2.30 (en la documentación hablan de la 2.32 por lo que tendré que destinar otro post para la actualización cuando averigüe como se hace ;-)<br />
<br />
Tambien podeis ver detalles de la versión del firmware instalado con la orden "ver". <br />
<br />
Un comando muy interesante para hacer pruebas es el comando "scan" con el que el módulo WiFly escaneará las redes wifi disponibles.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-02Q4umFGjXo/T7KwdMZYWqI/AAAAAAAAAOU/wEBgTezUJq8/s1600/p4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-02Q4umFGjXo/T7KwdMZYWqI/AAAAAAAAAOU/wEBgTezUJq8/s1600/p4.jpg" /></a></div>
<br />
una vez que vemos nuestra red (en mi caso "ismcasa") vamos a pasar a configurar el WiFly para que se conecte a nuestra red. Para ello existen una serie de comandos para realizar esta tarea que podemos ver en el manual antes comentado aunque explicaré ahora los más importantes.<br />
<br />
Primeramente vamos a configurar el funcionamiento por dhcp para que dispongamos de una dirección ip de manera automática con "set ip dhcp 1" y configuraremos la forma en la que vamos a usar el protocolo IP con "set ip protocol 2"<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-IuHmisA7g3A/T7PHAZIpSBI/AAAAAAAAAOg/28GuiFXyKd4/s1600/p5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-IuHmisA7g3A/T7PHAZIpSBI/AAAAAAAAAOg/28GuiFXyKd4/s1600/p5.jpg" /></a></div>
<br />
para el primer comando os dejo en la siguiente tabla las opciones que disponemos:<br />
<br />
Mode Protocol<br />
0 DHCP OFF, use stored static IP address<br />
1 DHCP ON, get IP address and gateway from AP<br />
2 Auto-IP, generally used with Adhoc networks<br />
3 DHCP cache mode, Uses previous IP address if lease is not expired (lease survives reboot)<br />
4 Reserved for future use<br />
<br />
para elegir el tipo de protocolo ip tenemos que tener en cuenta que lo que se indica es la posición del bit que queremos activar por lo que el comando "set ip protocol 2" indica que activamos la posición 1 (en binario b0010) poniendo el módulo en tipo servidor y cliente TCP<br />
<br />
Bit Position Protocol<br />
0 UDP<br />
1 TCP Server & Client (Default)<br />
2 Secure (only receive packets with IP address matches the store host IP)<br />
3 TCP Client only<br />
4 HTTP client mode<br />
<br />
Una vez establecidos los parámetros ejecutamos "set wlan join 0" para que el WiFly deje de intentar conectarse automaticamente como lo hacía al principio, colocamos la clave WAP o WAP2 en este caso con "set wlan phrase <clave>" y ejecutamos "join ismcasa" para conectarnos a esa red. Si nuestra red es WEP usaremos "set wlan key <clave>".</clave></clave><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-iavNijRdm9Q/T7PMJFDtPvI/AAAAAAAAAO8/3ntzlvM4Bd4/s1600/p6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-iavNijRdm9Q/T7PMJFDtPvI/AAAAAAAAAO8/3ntzlvM4Bd4/s1600/p6.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Si todo va bien veremos los anteriores mensajes que nos informan que todo está bien y cual es nuestra dirección ip. El led verde del WiFly comenzará a pardadear lo que indicará que está asociado a la red. Para comprobar que funciona, desde nuestro equipo podemos hacer un ping a esa ip y veremos como el WiFly nos contesta.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-p6X0baWK4Ow/T7PLbqAtcBI/AAAAAAAAAO0/rlIFNE9rZGo/s1600/p7.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-p6X0baWK4Ow/T7PLbqAtcBI/AAAAAAAAAO0/rlIFNE9rZGo/s1600/p7.jpg" /></a></div>
<br />
<br />
<br />
Si deseamos guardar la configuración podremos ejecutar la orden "save" y quedará ya configurado así la próxima vez con sólo hacer un "join SSID" nos conectaremos a la red Wifi.<br />
<br />
Bueno, ya hemos jugado un poco con nuestro módulo WiFly, ahora toca apagarlo, montar el microprocesador y realizar todos los pasos anteriores pero esta vez desde un programa Arduino y que sea este el que configura el módulo y lo utiliza acordándonos de colocar los jumpers en la posición XBEE, pero esto, para el siguiente post.<br />
<br />Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com14tag:blogger.com,1999:blog-1051439453522433342.post-52426752962120078742011-12-19T19:21:00.001+01:002011-12-20T20:03:45.027+01:00Buenas prácticas con aplicaciones y datos portablesHace no mucho tiempo, cuando queríamos trabajar con nuestro ordenador, nos dirigíamos, en la mayoría de las ocasiones, a la zona de la casa donde disponíamos de nuestro santuario. Ese lugar que con tanto esmero habíamos elegido para ubicar nuestro ordenador. Sin embargo esto está cambiando cada vez más, y sobre todo, los más jóvenes no entienden ya de estar anclados a un mismo lugar/dispositivo. Los que ya llevamos algún tiempo trabajando con estas máquinas nos hemos ido dando cuenta que necesitamos eliminar el binomio lugar/trabajo debido a que posiblemente estemos continuamente moviendonos y necesitamos seguir realizando nuestras tareas en mayor o menor medida.<br />
<br />
Yo mismo estoy sufriendo últimamente este problema, siempre he dispuesto todos mis datos y herramientas en un único ordenador y esto a su vez me ha ido transmitiendo una paranoia sobre el temor al pensar que pasaría si se rompiese el disco duro o un virus acabase con mis datos. ¿No os ha pasado que realizáis una copia de seguridad y al día siguiente ya sentís que está anticuada?.<br />
<br />
Al final he llegado a una solución que, por lo menos a mí, me es de mucha utilidad. Colocar tanto los datos como los programas y herramientas en la nube.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-DoHsWBJPcPs/Tu-IRF_esoI/AAAAAAAAALQ/nr4G67X5UXo/s1600/nube1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-DoHsWBJPcPs/Tu-IRF_esoI/AAAAAAAAALQ/nr4G67X5UXo/s1600/nube1.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">uhm... puedo conectar todos estos dispositivos a Internet. Interesante.</td></tr>
</tbody></table>
<br />
Siguiendo este tipo de filosofía tenemos varias aproximaciones:<br />
<br />
<ol>
<li>La propia nube nos da acceso a los datos y nos proporciona herramientas para gestionarlos. Son principalmente soluciones tipo zimbra o google con google docs y gmail y suele ser muy útil si en nuestro trabajo nos dedicamos a generar documentación (google docs), intercambiar información con otros compañeros (gmail y calendar) y trabajar con redes sociales y blogs.</li>
<li>Almacenar solamente los datos para tenerlos en cualquier sitio y nosotros somos los responsables de disponer de las herramientas para tratarlos. Soluciones que permiten tener los datos en la nube tipo Dropbox, Sugarsync, SkyDrive, iDisk, etc... o usar un disco usb.</li>
<li>Almacenar tanto los datos como las aplicaciones para disponer de todo ello desde cualquier sitio.</li>
</ol>
<div>
Este último caso es el que más interesante me ha parecido para los que solemos trabajar con datos pero también usamos multitud de programas de muy diversa índole (programadores, administradores de sistemas, diseñadores o usuarios avanzados).</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-wNpICT7Nl-4/Tu-MWWqi-qI/AAAAAAAAALY/vdRm9LXnBCg/s1600/nube2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-wNpICT7Nl-4/Tu-MWWqi-qI/AAAAAAAAALY/vdRm9LXnBCg/s1600/nube2.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">¿y si coloco los datos en Internet?, los tendré vaya donde vaya...</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Alguna limitación en este esquema (luego no digas que no te lo avisé) es que los programas que almacenamos en la nube no pueden ser ejecutados en todos los dispositivos desde los que podemos conectarnos pero es una limitación que suele salvarse utilizando servicios online o aplicaciones nativas para ese dispositivo.</div>
<br />
En mi caso utilizo <a href="https://www.dropbox.com/">Dropbox</a> para tener en una carpeta toda la información con la que suelo trabajar. De esta manera no tengo distinción entre el equipo que tengo en el trabajo o tengo en mi casa y siempre tengo todos esos datos desde el móvil y desde la tablet. Podéis usar cualquier otro servicio ya que suelen funcionar igual.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-edLrgJvwMzc/Tu-PSkwMrqI/AAAAAAAAALg/AMCSMGHWDaU/s1600/nube3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-edLrgJvwMzc/Tu-PSkwMrqI/AAAAAAAAALg/AMCSMGHWDaU/s1600/nube3.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ya tengo los datos esté donde esté, ¿y ahora?</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Dopbox está disponible para casi todas las plataformas y dispositivos (Windows, MacOs, Linux, Android, IOs, etc..). Una opción interesante es que podemos seguir usando nuestros datos (los últimos que tengamos desde la última vez que nos conectamos a Internet) para trabajar en modo offline. En el momento de disponer de conectividad se subirán a la nube las últimas versiones y estarán disponibles en el resto de nuestros dispositivos. Si estamos en otro equipo que no es nuestro podemos optar por instalar Dropbox o acceder a nuestros datos a través del portal web que nos ofrece este servicio.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
El siguiente paso es el de llevarnos además nuestras aplicaciones pero sólo sirve en este caso para sistemas Windows ya que, como sabemos, los programas de un sistema operativo no se pueden ejecutar en otro diferente, a menos que estén en Java o en otro lenguaje interpretado, aunque en mi caso no es una limitación.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Los programas instalados en un ordenador no son facilmente portables a otro ordenador a menos que los instalemos y en muchos casos tendremos que hacerlo así. Si optamos por software libre podríamos ir instalándolo sin problema descargándolo de la red o si son programas con licencias llevar las licencias en el dropbox. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table border="0">
<tbody>
<tr>
<td><a href="http://2.bp.blogspot.com/-g5Q-fCRPlgE/TvDIe6NtLAI/AAAAAAAAALo/RrZmH7pojzs/s1600/portable_apps.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-g5Q-fCRPlgE/TvDIe6NtLAI/AAAAAAAAALo/RrZmH7pojzs/s1600/portable_apps.png" /></a> </td>
<td>Otra opción es hacer uso de la tecnología de aplicaciones portables.
Esta tecnología nació con la idea de llevar nuestra aplicaciones en los
discos usb pero nada nos impide usar nuestra carpeta de datos de la nube
para almacenar dichas aplicaciones.</td>
</tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Así, vayamos donde vayamos llevaremos las aplicaciones que solemos usar más a menudo o al menos las que nos permitan realizar esas tareas que casualmente tenemos que hacer con urgencia cuando estamos fuera.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-dmDqel3dUoU/TvDKrDplC_I/AAAAAAAAALw/pm0zJDAeH_g/s1600/nube4.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-dmDqel3dUoU/TvDKrDplC_I/AAAAAAAAALw/pm0zJDAeH_g/s1600/nube4.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Datos y aplicaciones en la nube</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Ahora podemos dirigirnos a la web de <a href="http://portableapps.com/" target="_blank">aplicaciones portables</a> y descargar e instalar dentro de nuestra carpeta compartida aquellas que necesitéis disponer de ellas. Portableapps dispone de una herramienta para tener vuestras aplicaciones ordenadas y clasificadas, aunque yo soy más partidario de instalarlas de manera manual y así ahorrarme el espacio de dicho gestor. Simplemente cuando estemos instalando la aplicación le decimos que lo instale en nuestra carpeta compartida y así la tendremos accesible desde cualquier ubicación y ejecutable desde cualquier Windows XP, Vista o 7.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="http://portableapps.com/apps" target="_blank">Aquí tenéis un enlace directo a la lista de todas las aplicaciones disponibles</a>. Son aplicaciones gratuitas y/o de código libre que suelen dar muchas de las funcionalidades que necesitamos y entre ellas hay desde antivirus, herramientas de desarrollo, de productividad, gráficos y sonidos, etc... en mi caso suelo disponer de herramientas como el <a href="http://portableapps.com/apps/utilities/keepass_portable">KeePass Password Safe Portable</a> para tener mis contraseñas a salvo, <a href="http://portableapps.com/apps/internet/putty_portable">PuTTY Portable</a> para poder conectarme a mis servidores, <a href="http://portableapps.com/apps/utilities/clamwin_portable">ClamWin Portable</a> y <a href="http://portableapps.com/apps/security/spybot_portable">Spybot - Search & Destroy Portable</a> para proteger los equipos donde trabajo y algunas otros.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Si queremos disponer de aplicaciones nuestras o que no aparecen en la lista debemos usar soluciones comerciales como ThinApp que ofrece VMWare. <a href="http://en.kioskea.net/faq/1500-make-a-portable-application-with-thinapp" target="_blank">Os dejo un enlace donde podéis ver como se hace.</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Espero que estos consejos os ayuden a hacer más llevadera las tareas de trabajo o mantenimiento esteis donde esteis y recordad que siempre os quedará la alternativa de decir que no podeis hacer nada al estar fuera y así disfrutar del lugar donde os encontréis.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0tag:blogger.com,1999:blog-1051439453522433342.post-53754258826028475702011-07-18T11:34:00.002+02:002011-07-18T11:38:27.946+02:00Aprende el funcionamiento de un transistor gracias al Arduino<div style="font-family: inherit; text-align: justify;">Cada vez que miramos cualquier circuito no hacemos otra cosa que ver esos pequeños bichos con tres patas que no sabemos muy bien para que valen. En esta ocasión y con ayuda del Arduino vamos a ver como funcionan los transistores.<br />
<br />
</div><div style="text-align: justify;"><div style="font-family: inherit;">Como tenía varios transistores modelo <a href="http://www.datasheetcatalog.org/datasheet2/f/0c695lq7ut3hjriqzff0kfs5i8wy.pdf">BD-138</a> por aquí y quería probarlos con Arduino, he realizado este pequeño post a modo de introducción al funcionamiento de los transistores. Para esta aplicación, emplearemos el transistor como mero interruptor y no como amplificador. ¿No os había dicho que tienen estos dos modos de funcionamiento?. El esquema del transistor es el siguiente:</div><br />
<a href="http://1.bp.blogspot.com/-siGXq2H2Klg/TfpaZZ0DrKI/AAAAAAAAACY/zeK_9HEJU8M/s1600/pines_bd138.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5618902877570575522" src="http://1.bp.blogspot.com/-siGXq2H2Klg/TfpaZZ0DrKI/AAAAAAAAACY/zeK_9HEJU8M/s400/pines_bd138.jpg" style="cursor: hand; cursor: pointer; display: block; height: 400px; margin: 0px auto 10px; text-align: center; width: 335px;" /></a>La base (pin 3) es a través del cual controlaremos el paso de corriente entre los pines 1 y 2. Por tanto, el pin 3 será el que tengamos que controlar desde Arduino para dejar pasar o no la corriente cuando sea necesario. La alimentación de nuestro circuito externo colgará de las pines 1-2.<br />
<br />
La conexión de los componentes en la placa de prototipado es la siguiente:<br />
<br />
<a href="http://2.bp.blogspot.com/-nZQNHfTgYQE/Tf-yQ0mBXwI/AAAAAAAAACg/CGYMt480aI4/s1600/circuito_conexion.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5620406862047436546" src="http://2.bp.blogspot.com/-nZQNHfTgYQE/Tf-yQ0mBXwI/AAAAAAAAACg/CGYMt480aI4/s400/circuito_conexion.jpg" style="cursor: hand; cursor: pointer; display: block; height: 337px; margin: 0px auto 10px; text-align: center; width: 400px;" /></a><br />
El transistor se encuentra en la placa de prototipado, en la parte izquierda superior. De abajo a arriba vemos :<br />
<ul><li>Un cable amarillo conectado a la base. El cable conecta con el pin digital número 13 de Arduino.</li>
<li>Una resistencia conectada a un led une el pin 2 del transistor (colector) con la alimentación de 5V proveniente de Arduino (cable rojo)</li>
<li>El pin 3 del transistor (emisor) conecta con tierra (también de Arduino).</li>
</ul>Una vista mas cercana del transistor y sus conexiones:<br />
<br />
<a href="http://2.bp.blogspot.com/-eyqAy8V34Xc/Tf-0EP4k91I/AAAAAAAAACo/0xn-smFKYeo/s1600/transistor.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5620408845057980242" src="http://2.bp.blogspot.com/-eyqAy8V34Xc/Tf-0EP4k91I/AAAAAAAAACo/0xn-smFKYeo/s400/transistor.jpg" style="cursor: hand; cursor: pointer; display: block; height: 346px; margin: 0px auto 10px; text-align: center; width: 400px;" /></a><br />
Vemos un cable naranja que conecta el colector con la entrada analógica de Arduino. Nos puede servir para leer el voltaje en un punto determinado y contruirnos una curva de voltaje/tiempo y tener más detalle de lo que sucede o realizar gráficas con los datos capturados por el conversor A/D de Arduino (tal y como nos lo mostraría un osciloscopio).<br />
<br />
<div style="text-align: center;"><a href="http://4.bp.blogspot.com/-sj6l9aW1D-M/TgD_p1eunVI/AAAAAAAAADY/Q4Cpvw6fnpw/s1600/Grafica2.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5620773429154061650" src="http://4.bp.blogspot.com/-sj6l9aW1D-M/TgD_p1eunVI/AAAAAAAAADY/Q4Cpvw6fnpw/s320/Grafica2.jpg" style="cursor: hand; cursor: pointer; display: block; height: 150px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><span style="font-size: xx-small;">Lectura de voltaje</span></div><br />
<br />
<div style="text-align: center;"><a href="http://1.bp.blogspot.com/-U-E6QK2UrrM/TgD_vCv-mxI/AAAAAAAAADg/mYppjNw6tnA/s1600/Grafica3.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5620773518615419666" src="http://1.bp.blogspot.com/-U-E6QK2UrrM/TgD_vCv-mxI/AAAAAAAAADg/mYppjNw6tnA/s320/Grafica3.jpg" style="cursor: hand; cursor: pointer; display: block; height: 88px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
<span style="font-size: xx-small;">Lectura de voltaje añadiendo un condensador al conjunto</span></div><br />
<br />
El voltaje a aplicar al transistor en su base para dejar pasar la corriente (o los huecos) dependerá del tipo del mismo. Para el BD-138, la base deja pasar la corriente cuando se conecta a 0V. <br />
<br />
Si nos centramos ya en el funcionamiento del conjunto, cuando lo ponemos en marcha, se observa que cada vez que el led asociado al pin 13 de Arduino está encendido, el led rojo de la placa de prototipado está apagado lo que significa que el circuito externo no está conectado.<br />
<br />
<a href="http://4.bp.blogspot.com/-Z__uwMLx2qg/TgD7u-uWiyI/AAAAAAAAAC4/sjzZCiaCQqo/s1600/off.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5620769119488346914" src="http://4.bp.blogspot.com/-Z__uwMLx2qg/TgD7u-uWiyI/AAAAAAAAAC4/sjzZCiaCQqo/s400/off.jpg" style="cursor: hand; cursor: pointer; display: block; height: 354px; margin: 0px auto 10px; text-align: center; width: 400px;" /></a>En cambio, cuando el pin 13 de Arduino esta apagado, el transistor sí deja pasar la corriente, por lo que el led rojo se enciende:<br />
<br />
<a href="http://4.bp.blogspot.com/-jJKdqanfNFI/TgD8A3p6_8I/AAAAAAAAADA/fCbQlG4Ptyk/s1600/on.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5620769426828361666" src="http://4.bp.blogspot.com/-jJKdqanfNFI/TgD8A3p6_8I/AAAAAAAAADA/fCbQlG4Ptyk/s400/on.jpg" style="cursor: hand; cursor: pointer; display: block; height: 400px; margin: 0px auto 10px; text-align: center; width: 397px;" /></a><br />
<br />
Espero que este pequeño experimento os ayude a comprender un poco mejor como funciona un transistor, aunque todavía no hayamos hecho más que rascar en la superficie de todas las posibilidades que ofrecen estos pequeños ingenios de la electrónica.<br />
<br />
<br />
</div>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1051439453522433342.post-37518088029517816352011-05-30T18:43:00.003+02:002011-05-30T19:09:32.142+02:00Portadas de revistas de videojuegosHace poco encontré en el desván de casa de mis padres una caja con revistas que iba a ser facturada proximamente dirección al contenedor más cercano. Gracias a la rápida acción de mi hermana, que me notificó tal olvidado hallazgo, las pudimos salvar y he podido volver a disfrutar de algunas de las revistas que ojeábamos cuando contaba con pocos años y donde iba destinada la mayor parte de mi paga semanal.<br />
<br />
Una de las cosas que más me ha llamado la atención ahora que las veo es que apenas salen pantallas de los juegos debido a la pobre calidad que ofrecían los equipos de 8 bits de la época. Al contrario, son todo fotos o dibujos los que forman el elenco gráfico de estas portadas que pertenecen a revistas que ya tienen casi 25 años (la primera de ellas es el número 2 y corresponde a 1988). <br />
<br />
<table><tbody>
<tr> <td><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-Xda-KRPSC-o/TeOMt8dt8ZI/AAAAAAAAAFg/TO35KUt8l1g/s1600/002-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-Xda-KRPSC-o/TeOMt8dt8ZI/AAAAAAAAAFg/TO35KUt8l1g/s200/002-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-tjVAP-EeOTE/TeOMuFP9d0I/AAAAAAAAAFk/QoOW1ngJzEQ/s1600/003-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-tjVAP-EeOTE/TeOMuFP9d0I/AAAAAAAAAFk/QoOW1ngJzEQ/s200/003-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-3bt3oF_2doI/TeOMuT6nd-I/AAAAAAAAAFo/FVi0B61sULo/s1600/004-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-3bt3oF_2doI/TeOMuT6nd-I/AAAAAAAAAFo/FVi0B61sULo/s200/004-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-RbXocBfTSZg/TeOMu6jCbOI/AAAAAAAAAFs/0Ipr7gRwB00/s1600/005-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-RbXocBfTSZg/TeOMu6jCbOI/AAAAAAAAAFs/0Ipr7gRwB00/s200/005-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-UveIu5wwa-s/TeOMvYmfx-I/AAAAAAAAAFw/iCx_41sLf70/s1600/006-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-UveIu5wwa-s/TeOMvYmfx-I/AAAAAAAAAFw/iCx_41sLf70/s200/006-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-vOerqAmjNA8/TeOMvzFoZCI/AAAAAAAAAF0/ftzmkl1lE08/s1600/007-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-vOerqAmjNA8/TeOMvzFoZCI/AAAAAAAAAF0/ftzmkl1lE08/s200/007-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-wp7otORE8KQ/TeOMwIwJcKI/AAAAAAAAAF4/FIqMudWp0ek/s1600/008-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-wp7otORE8KQ/TeOMwIwJcKI/AAAAAAAAAF4/FIqMudWp0ek/s200/008-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-Xmb2S4dqmBE/TeOMwopH6XI/AAAAAAAAAF8/wBuxAvjWeTg/s1600/009-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-Xmb2S4dqmBE/TeOMwopH6XI/AAAAAAAAAF8/wBuxAvjWeTg/s200/009-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-7ifRFMU9ItU/TeOMw3ombnI/AAAAAAAAAGA/dRYNXF2OzH8/s1600/010-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-7ifRFMU9ItU/TeOMw3ombnI/AAAAAAAAAGA/dRYNXF2OzH8/s200/010-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-jnKn3cPiYG0/TeOMxFiv2aI/AAAAAAAAAGE/kKSVZTeAwV4/s1600/011-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-jnKn3cPiYG0/TeOMxFiv2aI/AAAAAAAAAGE/kKSVZTeAwV4/s200/011-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-whi0syFaeuU/TeOMxjZtoQI/AAAAAAAAAGI/kpmpdfaSG_o/s1600/012-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-whi0syFaeuU/TeOMxjZtoQI/AAAAAAAAAGI/kpmpdfaSG_o/s200/012-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-evy2XsgBgbM/TeOMx-9fXWI/AAAAAAAAAGM/QUF9Sxazp2s/s1600/013-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-evy2XsgBgbM/TeOMx-9fXWI/AAAAAAAAAGM/QUF9Sxazp2s/s200/013-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-wtjf_q6emDM/TeOMyPDWKMI/AAAAAAAAAGQ/tnmWmif8QEc/s1600/014-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-wtjf_q6emDM/TeOMyPDWKMI/AAAAAAAAAGQ/tnmWmif8QEc/s200/014-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-WessXFiHEOY/TeOMySGSu-I/AAAAAAAAAGU/J-S6wDqauEo/s1600/015-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-WessXFiHEOY/TeOMySGSu-I/AAAAAAAAAGU/J-S6wDqauEo/s200/015-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-g7wlANgxe98/TeOMy7_1lWI/AAAAAAAAAGY/X5iVNqDYu8w/s1600/016-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-g7wlANgxe98/TeOMy7_1lWI/AAAAAAAAAGY/X5iVNqDYu8w/s200/016-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-Olel_SIrgac/TeOMzAmhLVI/AAAAAAAAAGc/O5RXjTPeTHw/s1600/017-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-Olel_SIrgac/TeOMzAmhLVI/AAAAAAAAAGc/O5RXjTPeTHw/s200/017-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-qvfI2gRKtTk/TeOMzfUZLcI/AAAAAAAAAGg/z93_K4Kgi2Q/s1600/018-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-qvfI2gRKtTk/TeOMzfUZLcI/AAAAAAAAAGg/z93_K4Kgi2Q/s200/018-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-6tYc9IoxZbU/TeOMzw6jrMI/AAAAAAAAAGk/VWZztTNRBZ8/s1600/019-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-6tYc9IoxZbU/TeOMzw6jrMI/AAAAAAAAAGk/VWZztTNRBZ8/s200/019-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-h6mQaixfTi0/TeOM0Q1b_QI/AAAAAAAAAGo/IxBMA3GxtCc/s1600/021-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-h6mQaixfTi0/TeOM0Q1b_QI/AAAAAAAAAGo/IxBMA3GxtCc/s200/021-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-DiiunAJbZRY/TeOM0t1jGGI/AAAAAAAAAGs/AjPf8Z6Yb8Y/s1600/022-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-DiiunAJbZRY/TeOM0t1jGGI/AAAAAAAAAGs/AjPf8Z6Yb8Y/s200/022-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-c_3yPiV1Fjw/TeOM0yRepFI/AAAAAAAAAGw/LlvJhB-xwbo/s1600/023-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-c_3yPiV1Fjw/TeOM0yRepFI/AAAAAAAAAGw/LlvJhB-xwbo/s200/023-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-MwSG26-8h4Y/TeOM1IxwX0I/AAAAAAAAAG0/dlYPrbQaRSE/s1600/024-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-MwSG26-8h4Y/TeOM1IxwX0I/AAAAAAAAAG0/dlYPrbQaRSE/s200/024-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-Z4oXHNvmKDU/TeOM1nxrjHI/AAAAAAAAAG4/xulttr3cd4k/s1600/025-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-Z4oXHNvmKDU/TeOM1nxrjHI/AAAAAAAAAG4/xulttr3cd4k/s200/025-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-cl8TP27Lel4/TeOM19J0zPI/AAAAAAAAAG8/lunt1qZzCIw/s1600/026-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-cl8TP27Lel4/TeOM19J0zPI/AAAAAAAAAG8/lunt1qZzCIw/s200/026-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-qNrkThdKT7c/TeOM2ZNJZsI/AAAAAAAAAHA/JEQ4eHfLxqI/s1600/027-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-qNrkThdKT7c/TeOM2ZNJZsI/AAAAAAAAAHA/JEQ4eHfLxqI/s200/027-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-YhbXlUiV00E/TeOM3IjToNI/AAAAAAAAAHE/iFgw6C4FVvQ/s1600/028-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-YhbXlUiV00E/TeOM3IjToNI/AAAAAAAAAHE/iFgw6C4FVvQ/s200/028-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-gXFm1FpM8jw/TeOM3Y-fYeI/AAAAAAAAAHI/95LQ6Tub_FY/s1600/029-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-gXFm1FpM8jw/TeOM3Y-fYeI/AAAAAAAAAHI/95LQ6Tub_FY/s200/029-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-rKC_B1RvH0Y/TeOM3rMa9KI/AAAAAAAAAHM/-_Wc9vywes4/s1600/030-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-rKC_B1RvH0Y/TeOM3rMa9KI/AAAAAAAAAHM/-_Wc9vywes4/s200/030-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-zyTE4SdCeUU/TeOM5jZppaI/AAAAAAAAAHQ/92MikRk1OBc/s1600/031-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-zyTE4SdCeUU/TeOM5jZppaI/AAAAAAAAAHQ/92MikRk1OBc/s200/031-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-_-K147pNMhk/TeOM59xS9DI/AAAAAAAAAHU/W9QnDeHaUwg/s1600/032-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-_-K147pNMhk/TeOM59xS9DI/AAAAAAAAAHU/W9QnDeHaUwg/s200/032-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/--ZfT4RryFFM/TeOM6RJ0O3I/AAAAAAAAAHY/ZMgCd_wc_Mc/s1600/033-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/--ZfT4RryFFM/TeOM6RJ0O3I/AAAAAAAAAHY/ZMgCd_wc_Mc/s200/033-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-7yVGqZvXGYM/TeOM6rYfUbI/AAAAAAAAAHc/bFnL078cQdI/s1600/034-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-7yVGqZvXGYM/TeOM6rYfUbI/AAAAAAAAAHc/bFnL078cQdI/s200/034-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-5lsOBmQ1f4g/TeOM7DqMANI/AAAAAAAAAHg/mUDd8PVkhzA/s1600/035-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-5lsOBmQ1f4g/TeOM7DqMANI/AAAAAAAAAHg/mUDd8PVkhzA/s200/035-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-C0yoiTDQJ9s/TeOM7eGis0I/AAAAAAAAAHk/Xqdz8SGpjpc/s1600/036-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-C0yoiTDQJ9s/TeOM7eGis0I/AAAAAAAAAHk/Xqdz8SGpjpc/s200/036-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-cwWE4A6pACY/TeOM7ltOA6I/AAAAAAAAAHo/70Zw-bEtz28/s1600/037-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-cwWE4A6pACY/TeOM7ltOA6I/AAAAAAAAAHo/70Zw-bEtz28/s200/037-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-4gOvqwqmcHI/TeOM8KGF9yI/AAAAAAAAAHs/UkfYZWWi3gU/s1600/038-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-4gOvqwqmcHI/TeOM8KGF9yI/AAAAAAAAAHs/UkfYZWWi3gU/s200/038-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-1BBbxcXp4qg/TeOM8gUTkcI/AAAAAAAAAHw/gbitdhS9PfE/s1600/039-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-1BBbxcXp4qg/TeOM8gUTkcI/AAAAAAAAAHw/gbitdhS9PfE/s200/039-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-Y9YEdkmwFPA/TeOM87TX5-I/AAAAAAAAAH0/hJukn2M-bks/s1600/040-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-Y9YEdkmwFPA/TeOM87TX5-I/AAAAAAAAAH0/hJukn2M-bks/s200/040-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-yziI4TOVLHk/TeOM9ekgqAI/AAAAAAAAAH4/BqwvnDUvGlg/s1600/041-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-yziI4TOVLHk/TeOM9ekgqAI/AAAAAAAAAH4/BqwvnDUvGlg/s200/041-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-ZXAxS50Cuwk/TeOM9mvkltI/AAAAAAAAAH8/_G0-r5h1ZkA/s1600/042-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-ZXAxS50Cuwk/TeOM9mvkltI/AAAAAAAAAH8/_G0-r5h1ZkA/s200/042-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-nV_NdwrHy1A/TeOM-HEXFjI/AAAAAAAAAIA/-lv17X4OLg0/s1600/043-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-nV_NdwrHy1A/TeOM-HEXFjI/AAAAAAAAAIA/-lv17X4OLg0/s200/043-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-pBtnXysYth8/TeOM-X3x5TI/AAAAAAAAAIE/MFnuGwETwHs/s1600/044-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-pBtnXysYth8/TeOM-X3x5TI/AAAAAAAAAIE/MFnuGwETwHs/s200/044-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-rJjinPziAyg/TeOM-_NMttI/AAAAAAAAAII/YMLlaroGmj8/s1600/045-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-rJjinPziAyg/TeOM-_NMttI/AAAAAAAAAII/YMLlaroGmj8/s200/045-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-74KnB9wOa7A/TeOM_NkBq5I/AAAAAAAAAIM/2gAjrORwqXg/s1600/046-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-74KnB9wOa7A/TeOM_NkBq5I/AAAAAAAAAIM/2gAjrORwqXg/s200/046-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-5liIb2llUBI/TeOM_khRjpI/AAAAAAAAAIQ/W7QKI8iPjJQ/s1600/047-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-5liIb2llUBI/TeOM_khRjpI/AAAAAAAAAIQ/W7QKI8iPjJQ/s200/047-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-f-KV_3Ouajo/TeOM_8cEEnI/AAAAAAAAAIU/yqqXGoI4pYU/s1600/048-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-f-KV_3Ouajo/TeOM_8cEEnI/AAAAAAAAAIU/yqqXGoI4pYU/s200/048-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-tocQUgYHCxE/TeONAOdIqpI/AAAAAAAAAIY/ImbGFard1Os/s1600/049-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-tocQUgYHCxE/TeONAOdIqpI/AAAAAAAAAIY/ImbGFard1Os/s200/049-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-98RL3-RkBfA/TeONATk049I/AAAAAAAAAIc/xVasnlCYRVk/s1600/050-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-98RL3-RkBfA/TeONATk049I/AAAAAAAAAIc/xVasnlCYRVk/s200/050-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-noB1I5IkRgo/TeONAnlxU_I/AAAAAAAAAIg/AYMJhGWKvI4/s1600/051-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-noB1I5IkRgo/TeONAnlxU_I/AAAAAAAAAIg/AYMJhGWKvI4/s200/051-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-mIgJ1TfDB68/TeONBPHzyxI/AAAAAAAAAIk/2YXrZ5th-pc/s1600/052-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-mIgJ1TfDB68/TeONBPHzyxI/AAAAAAAAAIk/2YXrZ5th-pc/s200/052-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-9qq1Bo48BdI/TeONBU98R9I/AAAAAAAAAIo/OYbfPM-SdaM/s1600/054-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-9qq1Bo48BdI/TeONBU98R9I/AAAAAAAAAIo/OYbfPM-SdaM/s200/054-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-SHJfiYbosxQ/TeONBpcMljI/AAAAAAAAAIs/oQa_Ko58dpA/s1600/055-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-SHJfiYbosxQ/TeONBpcMljI/AAAAAAAAAIs/oQa_Ko58dpA/s200/055-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-yAt5PwhPM6A/TeONCLEuWPI/AAAAAAAAAIw/IqG4xkpX4tc/s1600/056-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-yAt5PwhPM6A/TeONCLEuWPI/AAAAAAAAAIw/IqG4xkpX4tc/s200/056-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-1hFWQMhX-lk/TeONCaflmiI/AAAAAAAAAI0/Z3Lw_E--gxo/s1600/057-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-1hFWQMhX-lk/TeONCaflmiI/AAAAAAAAAI0/Z3Lw_E--gxo/s200/057-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-sYDQjb01Oeo/TeONCuNtZhI/AAAAAAAAAI4/FVgIRJCHNlc/s1600/058-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-sYDQjb01Oeo/TeONCuNtZhI/AAAAAAAAAI4/FVgIRJCHNlc/s200/058-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-4Sr4JvFW_BY/TeONDRxwULI/AAAAAAAAAI8/76ccdBRGJr8/s1600/059-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-4Sr4JvFW_BY/TeONDRxwULI/AAAAAAAAAI8/76ccdBRGJr8/s200/059-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-LC3oNy8QcYc/TeOND7vaaEI/AAAAAAAAAJA/9YCdtVdQZKY/s1600/060-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-LC3oNy8QcYc/TeOND7vaaEI/AAAAAAAAAJA/9YCdtVdQZKY/s200/060-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-KxQliyww4WY/TeONEBG4F8I/AAAAAAAAAJE/1WNFMouG7ro/s1600/061-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-KxQliyww4WY/TeONEBG4F8I/AAAAAAAAAJE/1WNFMouG7ro/s200/061-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-dns_OS1L9AE/TeONEu8F-bI/AAAAAAAAAJI/MjNC8pdztXs/s1600/062-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-dns_OS1L9AE/TeONEu8F-bI/AAAAAAAAAJI/MjNC8pdztXs/s200/062-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-C-vyv56AfH4/TeONEzgmOPI/AAAAAAAAAJM/RC7FT_H3VRw/s1600/063-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-C-vyv56AfH4/TeONEzgmOPI/AAAAAAAAAJM/RC7FT_H3VRw/s200/063-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-0hG5-q7GsHQ/TeONFdd-BeI/AAAAAAAAAJQ/TQQuGvJ1mHM/s1600/064-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-0hG5-q7GsHQ/TeONFdd-BeI/AAAAAAAAAJQ/TQQuGvJ1mHM/s200/064-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-n0XVs6obSwU/TeONFkt3tXI/AAAAAAAAAJU/47Rcy_KU_zg/s1600/066-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-n0XVs6obSwU/TeONFkt3tXI/AAAAAAAAAJU/47Rcy_KU_zg/s200/066-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-P_XSDNktcHA/TeONGP7SjCI/AAAAAAAAAJY/oggqxyqaLRw/s1600/067-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-P_XSDNktcHA/TeONGP7SjCI/AAAAAAAAAJY/oggqxyqaLRw/s200/067-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-yZfpNKYe0xQ/TeONGZoV2hI/AAAAAAAAAJc/ixKjQsAFRtw/s1600/068-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-yZfpNKYe0xQ/TeONGZoV2hI/AAAAAAAAAJc/ixKjQsAFRtw/s200/068-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-TGoC8PlGZbs/TeONGoRH1NI/AAAAAAAAAJg/33FWOJqA-OU/s1600/069-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-TGoC8PlGZbs/TeONGoRH1NI/AAAAAAAAAJg/33FWOJqA-OU/s200/069-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-KwbGn9w52mw/TeONHAQ3b_I/AAAAAAAAAJk/qCdSxVCr3ps/s1600/070-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-KwbGn9w52mw/TeONHAQ3b_I/AAAAAAAAAJk/qCdSxVCr3ps/s200/070-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-nFGDwPcdLps/TeONHftoKOI/AAAAAAAAAJo/pSPvt3f6eKA/s1600/071-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-nFGDwPcdLps/TeONHftoKOI/AAAAAAAAAJo/pSPvt3f6eKA/s200/071-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-nyeQzrAXX98/TeONH9_ANdI/AAAAAAAAAJs/epMWnvD5SXc/s1600/072-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-nyeQzrAXX98/TeONH9_ANdI/AAAAAAAAAJs/epMWnvD5SXc/s200/072-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-zAr_2XLum90/TeONIdYk1cI/AAAAAAAAAJw/R3VdOjpl0IY/s1600/073-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-zAr_2XLum90/TeONIdYk1cI/AAAAAAAAAJw/R3VdOjpl0IY/s200/073-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-ddkqnjOy7o4/TeONIkWQKaI/AAAAAAAAAJ0/MX4_2pjhSBs/s1600/074-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-ddkqnjOy7o4/TeONIkWQKaI/AAAAAAAAAJ0/MX4_2pjhSBs/s200/074-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-aurKmRkNmmU/TeONJA3BKZI/AAAAAAAAAJ4/3PStHLrNGa8/s1600/076-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-aurKmRkNmmU/TeONJA3BKZI/AAAAAAAAAJ4/3PStHLrNGa8/s200/076-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-mVjkdkAAjKo/TeONJZWtdiI/AAAAAAAAAJ8/wpTdlcUl07s/s1600/077-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-mVjkdkAAjKo/TeONJZWtdiI/AAAAAAAAAJ8/wpTdlcUl07s/s200/077-1.jpg" width="155" /></a></div><br />
</td> </tr>
<tr> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-hKvmo1zACnk/TeONJ2eYjFI/AAAAAAAAAKA/DPRRM6hDSwQ/s1600/078-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-hKvmo1zACnk/TeONJ2eYjFI/AAAAAAAAAKA/DPRRM6hDSwQ/s200/078-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-85Iu-A3WAdE/TeONKFfkvSI/AAAAAAAAAKE/1PBGFF_tFBU/s1600/079-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-85Iu-A3WAdE/TeONKFfkvSI/AAAAAAAAAKE/1PBGFF_tFBU/s200/079-1.jpg" width="155" /></a></div><br />
</td> <td><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-NbciJFJSsQs/TeONKrWqWHI/AAAAAAAAAKI/OFBqwhVRwpo/s1600/080-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-NbciJFJSsQs/TeONKrWqWHI/AAAAAAAAAKI/OFBqwhVRwpo/s200/080-1.jpg" width="155" /></a></div><br />
</td> </tr>
</tbody></table>Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com2tag:blogger.com,1999:blog-1051439453522433342.post-42352487619963897982011-04-18T23:03:00.128+02:002011-06-11T22:44:22.776+02:00Desnudando a un ZX81<div style="text-align: justify;"><br />
El Sinclair ZX81 fue lanzado en 1981 y fue uno de los primeros ordenadores personales accesibles para gran público. Muchos de los que comenzaron a utilizarlos siguen hoy en día enganchados a la informática y es en gran medida culpa de esta pequeña maravilla.</div><br />
<div style="text-align: justify;">A tan sólo 3.5 Mhz y con la escalofriante cantidad de memoria de 1 kB (1024 bytes) pensareis que poco se podría hacer, pero los programadores de antes estaban hechos de otra pasta y podían meter en esa memoria juegos tan pintorescos como juegos de naves o juegos de ajedrez utilizando tan sólo caracteres ASCII e implementando la lógica con un par de puñados de bytes.</div><br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-9NRxFQyJ8XA/TaykSXWM2EI/AAAAAAAAAEg/6Kv19yqPzB0/s1600/Chess%2528MikroGen%2529.A.screen.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-9NRxFQyJ8XA/TaykSXWM2EI/AAAAAAAAAEg/6Kv19yqPzB0/s1600/Chess%2528MikroGen%2529.A.screen.gif" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Chess Game</td></tr>
</tbody></table><div style="text-align: center;"><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-29dwR6ZIlMQ/TaykStLDPSI/AAAAAAAAAEk/BIhRrCGBJdY/s1600/SpaceInvaders%2528dk%2529.screen.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-29dwR6ZIlMQ/TaykStLDPSI/AAAAAAAAAEk/BIhRrCGBJdY/s1600/SpaceInvaders%2528dk%2529.screen.gif" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Space Invaders</td></tr>
</tbody></table><br />
<div style="text-align: justify;">Por suerte he podido conseguir uno de estos equipos y debido a mi manía de ver como funcionan las cosas os voy a detallar su interior y algunas de sus curiosidades.</div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-IquQRcqTrvY/Ta1qBMU23AI/AAAAAAAAAEo/97sw8QSfSuw/s1600/zx1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="316" src="http://4.bp.blogspot.com/-IquQRcqTrvY/Ta1qBMU23AI/AAAAAAAAAEo/97sw8QSfSuw/s320/zx1.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ZX81 de la época</td></tr>
</tbody></table><div style="text-align: justify;">Lo primero que llama la atención es su tamaño y poco peso. No pasa desapercibido además su teclado de membrana que es posiblemente la parte más frágil del dispositivo ya que si se usa mucho, estas membranas se rompen y era necesario cambiar el teclado entero. Vendían kits para el teclado por si esto tranquiliza a alguien ;-).</div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-o-h1RhuDQZM/Ta1raoBH1dI/AAAAAAAAAEs/XuLB19J-jTI/s1600/zx2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="239" src="http://1.bp.blogspot.com/-o-h1RhuDQZM/Ta1raoBH1dI/AAAAAAAAAEs/XuLB19J-jTI/s320/zx2.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Detalle del teclado de membrana</td></tr>
</tbody></table><div style="text-align: justify;">En su lateral se observan varios conectores correspondientes a la salida de televisión y una salida rudimentaria de audio para grabar en cinta. Dispone de la entrada de micrófono donde conectar una unidad de cintas para cargar los juegos y la entrada de 9V para la alimentación.</div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/--8m8cZA72hA/Ta1sFKhEAJI/AAAAAAAAAEw/IvNd2anuVKE/s1600/zx3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="138" src="http://4.bp.blogspot.com/--8m8cZA72hA/Ta1sFKhEAJI/AAAAAAAAAEw/IvNd2anuVKE/s320/zx3.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Conectores laterales</td></tr>
</tbody></table><br />
En la parte posterior dispone de un bus de expansión para colocar algunos pack de expansión como mayor memoria, impresora, etc....<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-jPV2NU88MhM/Ta1t9LC12pI/AAAAAAAAAE0/WzyDenCRrN4/s1600/zx5.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="135" src="http://1.bp.blogspot.com/-jPV2NU88MhM/Ta1t9LC12pI/AAAAAAAAAE0/WzyDenCRrN4/s320/zx5.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bus de expansión trasero</td></tr>
</tbody></table><br />
<br />
Sólo 4 tornillos nos separan de la intimidad de este equipo. Siendo oseados y despojando al equipo de su carcasa exterior podemos ver algo que en principio nos llama bastante la atención.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-YwlTZqqMoIo/Ta1uPMv9CwI/AAAAAAAAAE4/2JqxaTOH0zk/s1600/zx4.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://1.bp.blogspot.com/-YwlTZqqMoIo/Ta1uPMv9CwI/AAAAAAAAAE4/2JqxaTOH0zk/s320/zx4.jpg" width="313" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Detalle de la placa de circuitos</td><td class="tr-caption" style="text-align: center;"><br />
</td></tr>
</tbody></table><br />
<div style="text-align: justify;">Por un lado la forma de serigrafía de las pistas no parece demasiado normalizada pero bueno, estamos hablando de una placa que tiene dibujado la fecha de 1980.</div><div style="text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-dcuFAFnGCYs/Ta1vEyviBnI/AAAAAAAAAE8/tcBJqqNugzk/s1600/zx6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="http://2.bp.blogspot.com/-dcuFAFnGCYs/Ta1vEyviBnI/AAAAAAAAAE8/tcBJqqNugzk/s320/zx6.jpg" width="320" /></a></div><br />
Como puede verse, el número de microchips puede contarse exactamente con los dedos de una mano.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-sm8GXa0TUCA/Ta1v4SCz3KI/AAAAAAAAAFA/kiEumx2U5HE/s1600/zx07.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="218" src="http://3.bp.blogspot.com/-sm8GXa0TUCA/Ta1v4SCz3KI/AAAAAAAAAFA/kiEumx2U5HE/s320/zx07.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Detalle de la placa</td></tr>
</tbody></table>Abajo a la derecha, puede verse el conversor a señal RF para la sintonización en un televisor por medio de la entrada de la antena analógica y arriba a la izquierda el conector de plástico que trae la señal del teclado de membranas. <br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-mtijS8vtZ0I/Ta2Wnu9wzhI/AAAAAAAAAFQ/X6jzTJqgA1g/s1600/zx11.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="http://1.bp.blogspot.com/-mtijS8vtZ0I/Ta2Wnu9wzhI/AAAAAAAAAFQ/X6jzTJqgA1g/s320/zx11.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Detalle del conector del teclado</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-qUkyXl3r3K0/Ta1w85mQOuI/AAAAAAAAAFE/JjGZlPzfM8g/s1600/zx08.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="310" src="http://4.bp.blogspot.com/-qUkyXl3r3K0/Ta1w85mQOuI/AAAAAAAAAFE/JjGZlPzfM8g/s320/zx08.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Disipador de calor para el regulador de tensión</td></tr>
</tbody></table><div style="text-align: justify;">Nada de ruidosos ventiladores para refrigerar el micro o grandes fuentes de alimentación. El sistema de regulación de alimentación comandado por un <a href="http://www.datasheetcatalog.org/datasheet/stmicroelectronics/2143.pdf">L7805CV</a> dispone de una placa para la disipación del calor y así se soluciona el problema de temperatura debido al trabajo del componente.</div><br />
<div class="separator" style="clear: both; text-align: center;"></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ifwvhT4LQlo/Ta1zLimxHII/AAAAAAAAAFI/RELNyDwxw4g/s1600/zx09.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="152" src="http://1.bp.blogspot.com/-ifwvhT4LQlo/Ta1zLimxHII/AAAAAAAAAFI/RELNyDwxw4g/s320/zx09.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Array Lógico Programable (ULA)</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: justify;">La ULA (uncommitted logic array) cariñosamente nombrada es un chip de lógica programable que se ha reprogramado para las necesidades propias de este equipo y permite a los diseñadores guardar la lógica deseada en un sólo chip que de otras maneras necesitaría varios.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-8PkU-hVmouM/Ta2Ubd9-XMI/AAAAAAAAAFM/p4qYFe976sw/s1600/zx10.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="223" src="http://4.bp.blogspot.com/-8PkU-hVmouM/Ta2Ubd9-XMI/AAAAAAAAAFM/p4qYFe976sw/s320/zx10.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Detalle de los módulos de memoria de 1kb</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: justify;">El <a href="http://www.google.es/search?q=mcm21l14p30&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:es-ES:official&client=firefox-a#sclient=psy&hl=es&client=firefox-a&hs=zxW&rls=org.mozilla:es-ES%3Aofficial&source=hp&q=mcm21l14p30+datasheet&aq=f&aqi=&aql=&oq=&pbx=1&fp=e7d139bec31213f9">MCM21L14P30</a> es un módulo de memoría de 4x1024 bits. Se utilizan dos para poder disponer de 1kB.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: center;">1kB -> 1024 bytes -> 8192 bits = 2 módulos de 4x1024 bits</div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: justify;">Vemos que este ordenador disponía solamente de 1kB de memoria aunque podía ser extendido por medio de su puerto trasero con un pack de 16 kB.</div><div class="separator" style="clear: both; text-align: justify;"><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-ZHYWzqTrKhU/Ta2XGcXAiVI/AAAAAAAAAFU/RXfkuvAeegc/s1600/zx12.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-ZHYWzqTrKhU/Ta2XGcXAiVI/AAAAAAAAAFU/RXfkuvAeegc/s1600/zx12.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ROM de 8kb</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: justify;">Le llega el turno a la <a href="http://www.alldatasheet.com/datasheet-pdf/pdf/125066/NEC/D2364.html">ROM D2364C</a> donde se almacena el interprete de BASIC que es un chip de sólo lectura de 8 kB y finalmente y en el centro se descubre una CPU que para mi sorpresa no es un Z80 de Zilog sino que se trata de una <a href="http://es.wikipedia.org/wiki/NEC_D780C">versión totalmente compatible desarrollada por NEC</a>.</div><div class="separator" style="clear: both; text-align: justify;"><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-ko9CawqxSbE/Ta2aZLHdOiI/AAAAAAAAAFY/rv6BR4sp3pk/s1600/zx13.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="159" src="http://4.bp.blogspot.com/-ko9CawqxSbE/Ta2aZLHdOiI/AAAAAAAAAFY/rv6BR4sp3pk/s320/zx13.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Microprocesador compatible Z80 de NEC</td><td class="tr-caption" style="text-align: center;"><br />
</td><td class="tr-caption" style="text-align: center;"><br />
</td><td class="tr-caption" style="text-align: center;"><br />
</td><td class="tr-caption" style="text-align: center;"><br />
</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: justify;">Y con sólo estos componentes, el pequeño dispositivo de <a href="http://es.wikipedia.org/wiki/Clive_Sinclair">Sir Clive Sinclair</a> se convirtió en uno de los iconos y equipos que cambiaron el curso de la informática y permitieron que esta entrase en las familias y comenzase así una revolución del que algunos todavía seguimos enganchados.</div><div class="separator" style="clear: both; text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: justify;"></div><div style="text-align: justify;">Aunque las comparaciones son odiosas, a veces nos ayudan a darnos cuenta de lo rápido que avanza la tecnología y de como, pronto todo lo que nos rodea, pasará de nuevo a ser tan antiguo como nuestro querido ZX81.</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-3lz7owjnGvQ/Ta2cb9KT4_I/AAAAAAAAAFc/GNV6wQN8SZc/s1600/zx14.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="301" src="http://2.bp.blogspot.com/-3lz7owjnGvQ/Ta2cb9KT4_I/AAAAAAAAAFc/GNV6wQN8SZc/s320/zx14.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ZX81 vs. iPhone</td></tr>
</tbody></table><br />
<div class="separator" style="clear: both; text-align: left;"><br />
</div>Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com17tag:blogger.com,1999:blog-1051439453522433342.post-1526423827150942882011-03-27T19:03:00.001+02:002011-03-27T19:03:33.144+02:00Desenrolle de bucles en optimización software<div style="text-align: justify;"><blockquote><i>Las aplicaciones cada vez demandan mayores recursos a la hora de ejecutarse: mayor velocidad, mas memoria, etc. Y a veces parece que la única solución es la de fabricar máquinas más veloces, sin embargo, ¿podríamos pensar que esto es inevitable?</i></blockquote></div><br />
<div style="text-align: justify;">Cuando los programadores realizan sus programas se centran principalmente en la parte algorítmica de los mismos que, como es normal, es la parte más importante en esta etapa del desarrollo software, ¿qué haríamos nosotros con un programa que no hace lo que queremos?, sin embargo, en este post vamos a preocuparnos menos de esta fase y pasar a transformar nuestros programas, que sabemos que ya funcionan correctamente, para que se ejecuten de una manera mucho más rápida.</div><div style="text-align: justify;">La mayoría de nosotros, cuando nos enfrentamos a la resolución de un problema intentamos hacer el algoritmo con el único fin de que funcione correctamente, utilizando multitud de variables auxiliares y montones de comprobaciones innecesarias. Cuando lo probamos y vemos que funciona, una sonrisa de oreja a oreja recorre nuestra cara, ¿ahora qué?, Lo hemos hecho, pero ¿podríamos haberlo hecho mejor y más rápido?.</div><br />
<span style="font-size: large;">Aceleremos nuestros programas</span><br />
<br />
<div style="text-align: justify;">El primer paso que debemos dar ante todo al implementar un algoritmo es el de comprender el problema, ¿qué es lo que realmente queremos resolver?, ¿cómo lo vamos a resolver? y ¿cuál es la mejor forma de resolverlo?. De nada nos vale realizar una implementación eficiente de la ordenación utilizando <a href="http://es.wikipedia.org/wiki/Ordenamiento_de_burbuja">el método de la burbuja</a>, frente a una implementación mediocre pero correcta del algoritmo de ordenación utilizando el método <a href="http://es.wikipedia.org/wiki/Quicksort">QuickSort</a>. </div><div style="text-align: justify;">Apenas aumentemos el número de elementos de entrada de nuestro eficiente algoritmo, este se verá delegado a segundo puesto por nuestra lenta implementación del famoso QuickSort.</div><br />
<div style="text-align: justify;">Sin embargo la cosa cambia frente a dos implementaciones distintas del mismo algoritmo, el más eficiente será el ganador. ¿Y cuales son esos parámetros que hacen que una implementación sea más eficiente? Principalmente el número de instrucciones que deben ejecutarse para resolver una misma tarea, aunque existen otras como el orden de complejidad del algoritmo, (probablemente la más importante, aunque no entraremos en ello), el aprovechamiento de diversas características del microprocesador, acceso eficiente a la memoria caché y otros parámetros que iremos viendo poco a poco.</div><br />
<div style="text-align: justify;">La idea de este post es la de mostrar pequeñas transformaciones y trucos que podemos aplicar al código de nuestros programas que harán la ejecución de los mismos mucho más rápidos y que pueden ser aplicados tanto por los programadores gurús o avanzados como por los que estéis descubriendo la programación recientemente.</div><div style="text-align: justify;">Antes de empezar me gustaría indicar que los conocimientos que se adquieran en estos artículos no solo son válidos para su aplicación en la programación Delphi (que es el lenguaje que vamos a usar en los ejemplos), sino que son igualmente efectivos aplicados a cualquier lenguaje de programación imperativo.</div><br />
Bueno, después de esta introducción vayamos al lío:<br />
<br />
<span style="font-size: large;">Desenrolle de bucles</span><br />
<br />
<div style="text-align: justify;">Uno des las primeras técnicas que aprendí para acelerar los programas viene como consecuencia de la aparición de las estructuras iterativas en los mismos. Si nos fijamos bien, la mayoría de los algoritmos tienen su cuerpo principal en algún tipo de bucle que se ejecuta interminablemente hasta que se cumple algún tipo de condición y puede deducirse que si aceleramos la ejecución de los bucles, la ejecución del programa completo será mucho más rápida.</div><br />
Veamos el siguiente ejemplo:<br />
<br />
<pre><code>for k := 0 to 10000 do
A[k] := B[k] * C[k]</code></pre><br />
En este sencillo ejemplo pude verse como estamos multiplicando los elementos de dos vectores y guardando sus resultados en un tercero.<br />
¿En qué consiste el desenrolle de bucles?. Veamos el ejemplo anterior al que se le ha aplicado el desenrolle una sola vez:<br />
<br />
<pre><code>for j := 0 to 5000 do // se ha dividido la condición entre numero de desenrolles
begin
A[j*2] := B[j*2] * C[j*2];
A[(j*2)+1] := B[(j*2)+1] * C[(j*2)+1];
end;</code></pre><br />
<div style="text-align: justify;"><blockquote><i>El desenrolle de bucles consiste en hacer que el número de veces que se ejecuta el cuerpo del bucle sea menor, modificando este de tal manera que se ejecuten las mismas operaciones, teniendo especial cuidado con los índices que se manejan.</i></blockquote></div><br />
Veamos unas gráficas de rendimiento.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-fTEM9PVE8kQ/TY8VuLKaH2I/AAAAAAAAAD4/A9hfMGcf0d0/s1600/fig1_ac.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="201" src="http://4.bp.blogspot.com/-fTEM9PVE8kQ/TY8VuLKaH2I/AAAAAAAAAD4/A9hfMGcf0d0/s400/fig1_ac.png" width="274" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: x-small;">Rendimiento de la rutina desenrollada frente a la original</span> </td></tr>
</tbody></table><br />
<div style="text-align: justify;">Como puede verse, si tomamos como referencia lo que tarda en ejecutarse el bucle original, el bucle desenrollado una sola vez, produce un incremento de velocidad de un 224,7 % más. De esta manera hemos hecho que la gestión del bucle for sea menor por un coste adicional de mayor código en el cuerpo del mismo.</div><br />
<div style="text-align: justify;">La implementación interna del bucle for consiste en comprobar si se ha llegado al limite del mismo, y si no, incrementar el contador. Reduciendo el número de veces que se realizan estas comprobaciones hacemos que nuestro algoritmo se ejecute más rápido y además al colocar un cuerpo del bucle más grande hemos dado la posibilidad al microprocesador de planificar mejor las instrucciones para su reordenación y hemos hecho que los cauces de ejecución del mismo estén ocupados durante más tiempo.</div><br />
Desenrollemos ahora el bucle en 4:<br />
<br />
<pre><code>for j := 0 to 2500 do
begin
A[j*4] := B[j*4] * C[j*4];
A[(j*4)+1] := B[(j*4)+1] * C[(j*4)+1];
A[(j*4)+2] := B[(j*4)+2] * C[(j*4)+2];
A[(j*4)+3] := B[(j*4)+3] * C[(j*4)+3];
end;</code></pre><br />
Ahora la condición de finalización e incremento del bucle for se reduce en un cuarto al bucle original, por lo que el tiempo de ejecución de este algoritmo se espera mucho menor.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-05qRsvMVbW4/TY8Y1RY3PpI/AAAAAAAAAEA/9LSjzWeQPJk/s1600/fig2_ac.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-05qRsvMVbW4/TY8Y1RY3PpI/AAAAAAAAAEA/9LSjzWeQPJk/s1600/fig2_ac.png" /></a></div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-KL-ci4Exp-A/TY8Y10mSRGI/AAAAAAAAAEE/o3LRb4m3QKw/s1600/fig2_ve.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-KL-ci4Exp-A/TY8Y10mSRGI/AAAAAAAAAEE/o3LRb4m3QKw/s1600/fig2_ve.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tiempo y rendimiento del bucle desenrollado 4 veces</td></tr>
</tbody></table><br />
Como podemos observar, los tiempos de ejecución de este algoritmo son mucho menores consiguiéndose un incremento de velocidad del 345%.<br />
<br />
Vamos por último a desenrollar el bucle 8 veces.<br />
<br />
<pre><code>for j := 0 to 1250 do
begin
A[j*8] := B[j*8] * C[j*8];
A[(j*8)+1] := B[(j*8)+1] * C[(j*8)+1];
A[(j*8)+2] := B[(j*8)+2] * C[(j*8)+2];
A[(j*8)+3] := B[(j*8)+3] * C[(j*8)+3];
A[(j*8)+4] := B[(j*8)+4] * C[(j*8)+4];
A[(j*8)+5] := B[(j*8)+5] * C[(j*8)+5];
A[(j*8)+6] := B[(j*8)+6] * C[(j*8)+6];
A[(j*8)+7] := B[(j*8)+7] * C[(j*8)+7];
end;</code></pre><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-gDfcshwgrsk/TY8ZXAjZqrI/AAAAAAAAAEI/V-lb1dL2xHY/s1600/fig3_ac.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-gDfcshwgrsk/TY8ZXAjZqrI/AAAAAAAAAEI/V-lb1dL2xHY/s1600/fig3_ac.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tiempo del bucle desenrollado 8 veces</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-kOrjLWXi6ME/TY8ZXw8OtrI/AAAAAAAAAEM/N40j568j8pU/s1600/fig3_ve.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-kOrjLWXi6ME/TY8ZXw8OtrI/AAAAAAAAAEM/N40j568j8pU/s1600/fig3_ve.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Rendimiento del bucle desenrollado 8 veces</td></tr>
</tbody></table><br />
<div style="text-align: justify;">Desenrollando 8 veces el bucle interno del algoritmo original hemos llegado a conseguir un método que realiza lo mismo que el primero pero 4,2 veces más rápido.</div><div style="text-align: justify;">Fijaros en que la condición del bucle se ha dividido por 8 y los índices hacen la función de desplazamiento dentro del bucle, haciendo que el espacio de trabajo dentro de los arrays sea el correcto.</div><div style="text-align: justify;"><br />
</div><span style="font-size: large;">Optimización del índice del bucle</span><br />
<br />
<div style="text-align: justify;">Para optimizar el bucle for debemos estudiar que parámetros entran en juego en su ejecución. El bucle for está formado por el contador, la condición de terminación y el cuerpo del bucle. Hasta ahora hemos realizado operaciones sobre el cuerpo del bucle sin embargo también tenemos que tener en cuenta el índice y la condición. Respecto a la condición, esta deberá ser lo más sencilla posible ya que se evalúa en cada iteración del bucle. Respecto al contador, en los ejemplos anteriores hemos utilizado una variable global, sin embargo, ¿que pasaría si utilizamos una variable local al procedimiento donde se ejecuta el bucle for?.</div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-KAkYPbHgXto/TY8ZqNT0UXI/AAAAAAAAAEQ/VjCkLhgoHu4/s1600/fig4_ac.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-KAkYPbHgXto/TY8ZqNT0UXI/AAAAAAAAAEQ/VjCkLhgoHu4/s1600/fig4_ac.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tiempo de utilizar una variable local al procedimiento frente a los anteriores métodos</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-D_YL5FCni2g/TY8ZqS6lziI/AAAAAAAAAEU/e0zTK9B4tD0/s1600/fig4_ve.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-D_YL5FCni2g/TY8ZqS6lziI/AAAAAAAAAEU/e0zTK9B4tD0/s1600/fig4_ve.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ganancia de rendimiento al utilizar una variable local al procedimiento frente a los anteriores métodos</td></tr>
</tbody></table><div style="text-align: justify;">Si nos fijamos en las dos últimas columnas de las figuras anteriores, podemos ver los tiempos de ejecución del bucle desenrollado 8 veces, pero en el último se ha utilizado una variable local al procedimiento donde se encontraba el bucle for como contador del mismo.</div><br />
<pre><code>Procedure Rutina
var
j : integer;
begin
for j := 0 to 1250 do
begin
A[j*8] := B[j*8] * C[j*8];
A[(j*8)+1] := B[(j*8)+1] * C[(j*8)+1];
A[(j*8)+2] := B[(j*8)+2] * C[(j*8)+2];
A[(j*8)+3] := B[(j*8)+3] * C[(j*8)+3];
A[(j*8)+4] := B[(j*8)+4] * C[(j*8)+4];
A[(j*8)+5] := B[(j*8)+5] * C[(j*8)+5];
A[(j*8)+6] := B[(j*8)+6] * C[(j*8)+6];
A[(j*8)+7] := B[(j*8)+7] * C[(j*8)+7];
end;
end;</code></pre><br />
<div style="text-align: justify;">Para explicar lo que ha ocurrido tenemos que pensar como realiza un compilador la etapa de optimización. Cuando se entra en un procedimiento se almacenan en la pila los registros del microprocesador. Esto implica que se queden libres, para utilizarlos, albergando en ellos variables que se utilizarán dentro del procedimiento, donde en este caso, el índice del bucle for es un candidato en potencia. Ya que el índice se ha colocado dentro de uno de los registros del microprocesador, su manipulación es muchísimo más rápida a la hora de, por ejemplo, multiplicarlo, como vemos en el código anterior. De ahí el incremento de velocidad en la ejecución de este procedimiento en un 625%.</div>¿Y esto es todo?<br />
<div style="text-align: justify;">¡Os parece poco! Bueno, intentaremos mejorarlo. Hemos aprendido a desenrollar los bucles for teniendo especial cuidado con el contador. Sin embargo, el desenrolle de bucles muestra toda su potencia con otra de las estructuras iterativas de la programación imperativa: el bucle while.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Internamente, el for no está diseñado de manera óptima lo que lleva a que el bucle while sea más eficiente para la mayoría de las tareas. Veamos como se construye un bucle for internamente.</div><br />
<pre><code>for i:=n to m do
A[i] := B[i] * C[i]</code></pre><br />
se transforma en:<br />
<br />
<pre><code>PA:=@A[m];
PB:=@B[m];
PC:=@C[m];
contador := m-n+1;
if contador > 0 then
repeat
PA^:=PB^ * PC^;
inc(PA);
inc(PB);
inc(PC);
dec(contador);
until contador = 0;</code></pre><br />
<div style="text-align: justify;">y el problema es que la variable i no aparece por ningún lado dentro de la implementación del bucle, lo que lleva a que en cada iteración tenemos, en este caso, que incrementar los tres punteros de las variables que necesitan el índice del bucle. Podemos ver además, en el ejemplo anterior, la sobrecarga de código que es necesario introducir a la hora de inicializar el bucle for.</div><div style="text-align: justify;"><br />
</div>El código anterior en formato while sería el siguiente:<br />
<br />
<pre><code>i:=n;
while i <= m do
A[i] := B[i] * C[I];</code></pre><br />
Por lo tanto, nuestra rutina podría transformase en:<br />
<br />
<pre><code>Procedure Rutina
var
j : integer;
begin
while j < 10000 do
begin
A[j] := B[j] * C[j];
A[j+1] := B[j+1] * C[j+1];
A[j+2] := B[j+2] * C[j+2];
A[j+3] := B[j+3] * C[j+3];
A[j+4] := B[j+4] * C[j+4];
A[j+5] := B[j+5] * C[j+5];
A[j+6] := B[j+6] * C[j+6];
A[j+7] := B[j+7] * C[j+7];
j := j + 8;
end;
end;</code></pre><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-ZwS9rn3X44U/TY8Z6Y0fEVI/AAAAAAAAAEY/wMVXYzvw9RM/s1600/fig5_ac.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-ZwS9rn3X44U/TY8Z6Y0fEVI/AAAAAAAAAEY/wMVXYzvw9RM/s1600/fig5_ac.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Comparativa de tiempos de todas los métodos implementados</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-2DKp0ahnz1k/TY8Z7K6ppbI/AAAAAAAAAEc/ajbhSLeHBAc/s1600/fig5_ve.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-2DKp0ahnz1k/TY8Z7K6ppbI/AAAAAAAAAEc/ajbhSLeHBAc/s1600/fig5_ve.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ganancia de tiempo de todos los métodos</td></tr>
</tbody></table><div style="text-align: justify;">Como puede verse en las figuras anteriores, la implementación con la estructura while es un 50% más rápida que la misma implementada con el for debido principalmente a que desaparece la multiplicación del índice dentro del cuerpo del bucle y de la transformación más eficiente de la misma a código máquina, siendo finalmente 6,7 veces más rápida que la rutina inicial.</div><blockquote>Debemos recordar que el índice debe ser divisible por el número de veces que queremos desenrollar el cuerpo del bucle.</blockquote><br />
<span style="font-size: large;">Conclusiones</span><br />
<div style="text-align: justify;">Después de ver estos resultados seguramente tendréis una pregunta en vuestra mente, ¿podríamos desenrollar hasta cualquier nivel?. La respuesta es sí; de esta manera aumentará el rendimiento del programa pero también su tamaño aumentará considerablemente y si el cuerpo del bucle es muy complejo habrá que desenrollarlo y modificarlo con cuidado de no equivocarnos (cosa que es muy común que ocurra) y el código pasará a ser menos legible. Es por tanto que deberemos llegar a una situación de compromiso entre espacio, legibilidad y velocidad prestando atención también al contenido y tipo del cuerpo del bucle. Valores comunes de desenrolle son 1,2,4 y 8. Además hay que tener en cuenta que la condición de salida sea múltiple del nivel de desenrolle que queremos aplicar, sino es así deberíamos comprobar con que indice se ha salido y si falta alguna otra iteración implementarla fuera del bucle.<br />
<br />
</div><div style="text-align: justify;">Otro factor a tener en cuenta es el de intentar utilizar siempre, en cualquier estructura iterativa, una variable local como índice para que pueda ser planificada y así ser gestionada para ubicarla en un registro del microprocesador.</div><div style="text-align: justify;">También debemos destacar la utilización de la estructura while frente a la for a menos que manejemos arrays de más de una dimensión ya que sino tendremos que pagar por el hecho de utilizar multiplicaciones a la hora de desplazar los punteros de las matrices.</div><div style="text-align: justify;">Para los más avezados podéis intentar aplicar las técnicas que hemos aprendido en esta ocasión al siguiente fragmento de código, desenrollando el bucle en un factor de 2 (fijaos que no conocemos a priori el valor de k por lo que tendremos que añadir código para controlar esa situación).</div><br />
<pre><code>Randomize;
k := random(1000);
for j:=0 to k do
A[j] := B[j] * C[j];</code></pre><br />
<div style="text-align: justify;">En esta entrega hemos aprendido una de las técnicas más utilizadas entre los programadores y compiladores para acelerar la ejecución de los programas, que consiste en duplicar el código dentro de una estructura iterativa para disminuir el número de veces que se ejecuta el cuerpo de control del bucle, a lo que se denomina desenrolle de bucles.</div>Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com3tag:blogger.com,1999:blog-1051439453522433342.post-23622148428136373152011-03-24T14:08:00.001+01:002011-03-24T14:42:14.969+01:00Filtro software para suavizar las oscilacionesLa mayoría de las veces que disponemos de sistemas de adquisición de datos del exterior, ya sea por la sensibilidad o por tratarse de una señal física muy variable, nos podemos encontrar con que la señal fluctúa demasiado.<br />
<br />
Podemos utilizar sistemas de filtrado como <a href="http://es.wikipedia.org/wiki/Filtro_de_Kalman">el filtro Kalman</a> o <a href="http://es.wikipedia.org/wiki/Filtro_de_Wiener">Filtro de Wiener</a> sin embargo en este post me gustaría explicar un sistema que es muy sencillo de implementar y muy apropiado para incluirlo en dispositivos con no demasiado rendimiento o que queremos que consuma muy pocos recursos en su aplicación.<br />
<br />
Como base de pruebas vamos a utilizar una hoja de cálculo y generar una onda sinoidal y aplicarle una señal aleatoria de ruido, de esta manera podremos ver como actual el filtro al conocer el valor original y compararlo con el esperado. Esto lo podemos hacer siguiendo los siguientes pasos:<br />
<br />
Utilizando nuestra hoja de cálculo preferida podemos generar una señal de pruebas. En este caso he generado una onda sinoidal basada en una columna de valores desde 0 hasta 359 y convirtiendo dichos valores en radianes<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-SmxjRDiDSyg/TYs-vVXtiqI/AAAAAAAAADw/niAhHtnxp9g/s1600/datos.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="169" width="400" src="http://4.bp.blogspot.com/-SmxjRDiDSyg/TYs-vVXtiqI/AAAAAAAAADw/niAhHtnxp9g/s400/datos.jpg" /></a></div><br />
De esta manera se puede ver la onda sinoidal que se genera y será nuestra señal limpia.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-KMKKGibsKqQ/TYssh0DjYkI/AAAAAAAAACg/rtBxhESo3vM/s1600/gfx1.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="223" width="400" src="http://4.bp.blogspot.com/-KMKKGibsKqQ/TYssh0DjYkI/AAAAAAAAACg/rtBxhESo3vM/s400/gfx1.jpg" /></a></div><br />
Podemos generar ruido usando una función aleatoria y añadiendoselo a nuestra señal limpia. El valor aleatorio es entre 0 y 1 por lo que le restamos 0.5 para que sea entre -0.5 y 0.5 y así disponer de valores negativos y lo dividimos entre 6 para que no sea un ruido muy exagerado.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-LmDcw6acLV4/TYs1ihxOr5I/AAAAAAAAADQ/-rJedjmKcUA/s1600/ruido.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="187" width="399" src="http://2.bp.blogspot.com/-LmDcw6acLV4/TYs1ihxOr5I/AAAAAAAAADQ/-rJedjmKcUA/s400/ruido.jpg" /></a></div><br />
Ahora sumamos el valor de ruido que hemos generado a la señal limpia<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-zjwoVc0E-zg/TYs6yoWc5mI/AAAAAAAAADg/aVYBrhrM2IU/s1600/ruidosumado.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="207" width="389" src="http://4.bp.blogspot.com/-zjwoVc0E-zg/TYs6yoWc5mI/AAAAAAAAADg/aVYBrhrM2IU/s400/ruidosumado.jpg" /></a></div><br />
Y así tenemos una onda sinoidal con ruido aleatorio<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-QrGKUeyLGgc/TYswcnBmZwI/AAAAAAAAACo/j_Bvbz3YOIk/s1600/gfx2.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="223" width="400" src="http://2.bp.blogspot.com/-QrGKUeyLGgc/TYswcnBmZwI/AAAAAAAAACo/j_Bvbz3YOIk/s400/gfx2.jpg" /></a></div><br />
El filtro que utilizaremos será muy sencillo y se basará en combinar el valor actual y el anterior para generar el nuevo valor para la señal. De manera que la fórmula se quedará como<br />
<br />
<center>Valor Actual = (Valor Anterior)*k + (Valor Actual)*j</center><br />
donde k y j deben ser entre 0 y 1 y ambos sumar 1. Si usamos k=0 y j=1 no estaríamos aplicando el filtro.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-FNmPiRiKj1k/TYs9OCj-gpI/AAAAAAAAADo/zw80TFqybZk/s1600/filtro.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="169" width="400" src="http://4.bp.blogspot.com/-FNmPiRiKj1k/TYs9OCj-gpI/AAAAAAAAADo/zw80TFqybZk/s400/filtro.jpg" /></a></div><br />
el factor k y j deciden cuanto peso o importancia tiene la señal anterior y actual o cuanto rápido olvida el filtro los valores anteriores.<br />
<br />
En esta gráfica se han utilizado los valores de k=0.6 y j=0.4<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-ucetuWPmKso/TYswnnenRFI/AAAAAAAAACw/b9YtjDoeP6g/s1600/gfx3_0604.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="223" width="400" src="http://3.bp.blogspot.com/-ucetuWPmKso/TYswnnenRFI/AAAAAAAAACw/b9YtjDoeP6g/s400/gfx3_0604.jpg" /></a></div><br />
En esta otra se aplican k=0.8 y j=0.2 viendo que el filtro suaviza más pero desplaza los valores al darle mucha importancia a la señal anterior.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/--HIsIxuBBQA/TYsws4TZ-SI/AAAAAAAAAC4/hbDZCnBka6I/s1600/gfx3_0802.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="223" width="400" src="http://2.bp.blogspot.com/--HIsIxuBBQA/TYsws4TZ-SI/AAAAAAAAAC4/hbDZCnBka6I/s400/gfx3_0802.jpg" /></a></div><br />
Añadiendo otra columna, podríamos restar el valor filtrado con el valor limpio y así averiguar la bondad del sistema a nivel estadístico.<br />
<br />
En este post he intentado mostrar una forma muy sencilla para la implementación de filtros donde, como podeis ver por su sencillez, es fácil transladar a nuestros Arduinos o cualquier otro sistema donde nos sea necesario, además de consumir pocos recursos y ser bastante rápido en su aplicación.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com5tag:blogger.com,1999:blog-1051439453522433342.post-29068398552743468072011-02-06T14:36:00.019+01:002011-06-01T19:41:54.530+02:00Calculando la inclinación en grados de nuestro acelerómetro MMA7260Una vez que disponemos de las aceleraciones estáticas de nuestro dispositivo tan sólo queda aplicar un poco de trigonometría para disponer para cada eje el ángulo.<br />
Las formulas que he usado son las siguientes:<br />
<br />
<pre><code> x=analogRead(xaxis);
y=analogRead(yaxis);
z=analogRead(zaxis);
unsigned long tt = micros();
float aax = (((x*5000.0)/1023.0)-XError)/RESOLUTION;
float aay = (((y*5000.0)/1023.0)-YError)/RESOLUTION;
float aaz = (((z*5000.0)/1023.0)-ZError)/RESOLUTION;
float rho = atan(aax/sqrt(pow(aay,2)+pow(aaz,2)))*(360/2*PI);
float phi = atan(aay/sqrt(pow(aax,2)+pow(aaz,2)))*(360/2*PI);
float theta = atan(sqrt(pow(aay,2)+pow(aax,2))/aaz)*(360/2*PI);
tt = micros() - tt;
</code></pre><br />
el último término es para pasar de radianes a grados.<br />
Como puede verse, el cálculo es bastante costoso debido a la gran cantidad de cálculos que hay que realizar por lo que intentaremos acelerar y simplificar dichas operaciones. Utilizando la función micros() podemos ver los microsegundos que se tardan en resolver todos los cálculos lo que nos será muy útil para ver si vamos mejorando el algoritmo.<br />
<br />
El valor de "tt" es aproximadamente de 980 microsegundos por lo que disponemos ahora de un indicador de lo que tarda en calcularse los grados a partir del voltaje de entrada del acelerómetro.<br />
<br />
Aplicando algunas optimizaciones podemos disponer ya de los valores en grados de los tres ejes de nuestro acelerómetro<br />
<br />
<pre><code>#define DEBUGMODE
#define _360div2xPI 57.29577951
#define _5000div1023 4.887585533
#define MMA7260_RESOLUTION 800 //0.8 v/g -> resolucion de 1.5g -> 800mV/g
#define MMA7260_VOLTAGE 3300.0; //mv voltage al que está conectado el acelerómetro
const float ZOUT1G = 2450; // mv Voltage en Zout a 1G
const float ZOUT0G = 1650; // mv Voltage en Zout a 1G
#define MMA7260_ZOUT_1G 850 // mv Voltage en Zout a 1G
const float XOUT1G = 2450; // mv Voltage en Zout a 1G
const float XOUT0G = 1650; // mv Voltage en Zout a 1G
const float YOUT1G = 2450; // mv Voltage en Zout a 1G
const float YOUT0G = 1650; // mv Voltage en Zout a 1G
#define NADJ 50 // Número de lecturas para calcular el error
// Entradas analógicas donde van los sensores
#define XAXIS_PORT 0
#define YAXIS_PORT 1
#define ZAXIS_PORT 2
// Salida digital del led de la placa
#define LEDPIN_PORT 13
float XError,YError,ZError;
float z,x,y;
float AccelAdjust(int axis)
{
float acc = 0;
for (int j=0;j < NADJ;j++)
{
float lectura=analogRead(axis);
acc = acc + (lectura*_5000div1023);
delay(11); //número primo para evitar ciclos de lectura proporcionales
}
return acc/NADJ;
}
void setup()
{
Serial.begin(9600); // 9600 bps
pinMode(XAXIS_PORT,INPUT);
pinMode(YAXIS_PORT,INPUT);
pinMode(ZAXIS_PORT,INPUT);
pinMode(LEDPIN_PORT, OUTPUT);
digitalWrite(LEDPIN_PORT, HIGH);
XError = AccelAdjust(XAXIS_PORT);
YError = AccelAdjust(YAXIS_PORT);
ZError = AccelAdjust(ZAXIS_PORT);
ZError = ZError - MMA7260_ZOUT_1G;
digitalWrite(LEDPIN_PORT, LOW);
#ifdef DEBUGMODE
Serial.println("Ajustado acelerometro eje X");
Serial.print("Error de X= ");
Serial.println(XError);
Serial.println("Ajustado acelerometro eje Y");
Serial.print("Error de Y= ");
Serial.println(YError);
Serial.println("Ajustado acelerometro eje Z");
Serial.print("Error de Z= ");
Serial.println(ZError);
#endif
}
void loop()
{
x=analogRead(XAXIS_PORT);
y=analogRead(YAXIS_PORT);
z=analogRead(ZAXIS_PORT);
unsigned long tt = micros();
float aax = ((x*_5000div1023)-XError)/MMA7260_RESOLUTION;
float aay = ((y*_5000div1023)-YError)/MMA7260_RESOLUTION;
float aaz = ((z*_5000div1023)-ZError)/MMA7260_RESOLUTION;
float rho = atan(aax/sqrt((aay*aay)+(aaz*aaz)))*_360div2xPI;
float phi = atan(aay/sqrt((aax*aax)+(aaz*aaz)))*_360div2xPI;
float theta = atan(sqrt((aay*aay)+(aax*aax))/aaz)*_360div2xPI;
tt = micros()-tt;
#ifdef DEBUGMODE
Serial.print(aax);
Serial.print(" ");
Serial.print(aay);
Serial.print(" ");
Serial.print(aaz);
Serial.println();
Serial.print(rho);
Serial.print(" ");
Serial.print(phi);
Serial.print(" ");
Serial.print(theta);
Serial.println();
Serial.print(tt);
Serial.println();
#endif
delay(1000);
}
</code></pre><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_4-yYGV2s0BM/TU7i3kfQs4I/AAAAAAAAABk/w0dRexgCua8/s1600/mma7260.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="287" src="http://3.bp.blogspot.com/_4-yYGV2s0BM/TU7i3kfQs4I/AAAAAAAAABk/w0dRexgCua8/s320/mma7260.jpg" width="320" /></a></div><br />
En esta imagen puede verse, con el acelerómetro inclinado hacia arriba, el eje Y y Z cerca de 90º.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_4-yYGV2s0BM/TU7lc2Lb7SI/AAAAAAAAABs/VVAFPXgArTo/s1600/mma7260%2Binclinado.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="http://3.bp.blogspot.com/_4-yYGV2s0BM/TU7lc2Lb7SI/AAAAAAAAABs/VVAFPXgArTo/s320/mma7260%2Binclinado.jpg" width="320" /></a></div><br />
Con este código modificado dispondremos de las inclinaciones en reposo así como un tiempo de alrededor de 930 microsegundos (50 microsegundos más rápido). Se han cambiado algunas variables por #defines así como algunos cálculos se han convertido en constantes. Sin embargo el mayor tiempo se consume en el cálculo de las funciones trigonométricas que espero poder mejorar usando por ejemplo lookup-tables.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com4tag:blogger.com,1999:blog-1051439453522433342.post-42052975716176537832011-02-05T12:50:00.009+01:002011-02-09T12:45:07.431+01:00Midiendo las inclinaciones con el MMA7260Siguiendo con nuestro trabajo con el acelerómetro MMA7260 toca recoger la información que nos suministra. Inicialmente lo utilizaremos para medir la aceleración estática y como en reposo está sometido a la fuerza de la gravedad podremos medir las inclinaciones en los tres ejes.<br />
<br />
Existe<a href="http://cache.freescale.com/files/sensors/doc/app_note/AN3107.pdf?fpsp=1"> un documento muy bueno y muy detallado</a> desarrollado por el fabricante con los detalles técnicos que utilizaremos para esta aplicación.<br />
<br />
Lo primero será conectar al Arduino las señales provenientes de cada eje de aceleración del acelerómetro. Para ello utilizaremos las entradas analógicas A0, A1 y A2 como vimos en el<a href="http://lanavajadelgeek.blogspot.com/2011/02/el-acelerometro-mma-7260.html"> post anterior</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_4-yYGV2s0BM/TU1DagNuO2I/AAAAAAAAABY/wp0aHmWP9X4/s1600/ab.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="http://1.bp.blogspot.com/_4-yYGV2s0BM/TU1DagNuO2I/AAAAAAAAABY/wp0aHmWP9X4/s320/ab.jpg" width="320" /></a></div><br />
Una vez conectadas, programaremos el Arduino para que recoja los valores de esas entradas, las transformaremos y las mostraremos por pantalla.<br />
<br />
Para programar con Arduino necesitaremos descargarnos el entorno de desarrollo desde la página web oficial <a href="http://arduino.cc/en/Main/Software">(mejor en inglés ya que dispondrá de la versión más actualizada)</a>, podeis seguir las instrucciones para los que nos hayais programado nunca en este entorno.<br />
<br />
A continuación os coloco el programa para medir la lectura de la aceleración en Gs:<br />
<br />
<pre><code><b>#define DEBUGMODE
const float RESOLUTION=800; //0.8 v/g -> resolucion de 1.5g -> 800mV/g
const float VOLTAGE=3.3; //voltage al que está conectado el acelerómetro
const float ZOUT1G = 2450; // mv Voltage en Zout a 1G
const float ZOUT0G = 1650; // mv Voltage en Zout a 1G
const float ZOUT_1G = 850; // mv Voltage en Zout a 1G
const float XOUT1G = 2450; // mv Voltage en Zout a 1G
const float XOUT0G = 1650; // mv Voltage en Zout a 1G
const float YOUT1G = 2450; // mv Voltage en Zout a 1G
const float YOUT0G = 1650; // mv Voltage en Zout a 1G
const int NADJ = 50; // Número de lecturas para calcular el error
// Entradas analógicas donde van los sensores
const int xaxis = 0;
const int yaxis = 1;
const int zaxis = 2;
// Salida digital del led de la placa
const int LEDPIN = 13;
float XError,YError,ZError;
float xd,yd,zd,z,x,y;
float AccelAdjust(int axis)
{
float acc = 0;
for (int j=0;j<nadj;j++)>
{
float lectura=analogRead(axis);
acc = acc + ((lectura*5000)/1023.0);
delay(11); //número primo para evitar ciclos de lectura proporcionales
}
return acc/NADJ;
}
void setup()
{
Serial.begin(9600); // 9600 bps
pinMode(xaxis,INPUT);
pinMode(yaxis,INPUT);
pinMode(zaxis,INPUT);
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, HIGH);
XError = AccelAdjust(xaxis);
YError = AccelAdjust(yaxis);
ZError = AccelAdjust(zaxis);
ZError = ZError - ZOUT_1G;
digitalWrite(LEDPIN, LOW);
#ifdef DEBUGMODE
Serial.println("Ajustado acelerometro eje X");
Serial.print("Error de X= ");
Serial.println(XError);
Serial.println("Ajustado acelerometro eje Y");
Serial.print("Error de Y= ");
Serial.println(YError);
Serial.println("Ajustado acelerometro eje Z");
Serial.print("Error de Z= ");
Serial.println(ZError);
#endif
}
void loop()
{
x=analogRead(xaxis);
y=analogRead(yaxis);
z=analogRead(zaxis);
float aax = (((x*5000.0)/1023.0)-XError)/RESOLUTION;
float aay = (((y*5000.0)/1023.0)-YError)/RESOLUTION;
float aaz = (((z*5000.0)/1023.0)-ZError)/RESOLUTION;
#ifdef DEBUGMODE
Serial.print(aax);
Serial.print(" ");
Serial.print(aay);
Serial.print(" ");
Serial.print(aaz);
Serial.println();
#endif
delay(500);
} </nadj;j++)></b></code></pre><br />
Una vez ejecutado el programa podemos ver como se realiza un ajuste del error estando en reposo y se recogen valores del mismo.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_4-yYGV2s0BM/TU1Eh3FdjnI/AAAAAAAAABg/xzRrD0uloKs/s1600/resultado.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="287" src="http://4.bp.blogspot.com/_4-yYGV2s0BM/TU1Eh3FdjnI/AAAAAAAAABg/xzRrD0uloKs/s320/resultado.jpg" width="320" /></a></div><br />
Los ejes X e Y (los dos primeros valores) están próximos a cero y el eje Z debido a la gravedad está en torno a 1. En realidad la oscilación de valores es mucho mayor pero gracias al ajuste del principio podemos disponer de valores mucho más estables y fiables. Si movemos el acelerómetro veremos como la fuerza G se ve aplicada a cada uno de los ejes. A partir de estos valores podremos calcular por ejemplo los grados de inclinación y utilizar el acelerómetro como un inclinómetro pero eso en el siguiente post.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com1tag:blogger.com,1999:blog-1051439453522433342.post-78835674902919216942011-02-05T12:23:00.002+01:002011-02-05T12:37:39.633+01:00Utilidad de identificación de CPU de IntelLos que trabajamos con muchos ordenadores solemos encontrarnos con la duda de que tipo de CPU tenemos en cada máquina y, por que hemos perdido el libro de instrucciones de la placa o no tenemos ganas de quitar el sistema de refrigeración del micro o nuestra bios no nos dá información detallada, nos quedamos con la duda que la mayoría de las veces se soluciona por medio de prueba y error y reinstalación del software.<br />
<br />
En la mayoría de los casos y debido a que cada vez se está extendiendo más las solucionas de virtulización sobre escritorio nos gustaría por ejemplo saber si nuestro micro soporta <a href="http://es.wikipedia.org/wiki/Virtualizaci%C3%B3n_x86">VT</a> o cuanta memoria caché dispone.<br />
<br />
Para ello Intel dispone de una herramienta que en nuestro caso nos puede solucionar muchos problemas y además nos permite informarnos sobre detalles de nuestro micro.<br />
<br />
La herramienta se llama "Intel® Processor Identification Utility" y se puede descargar <a href="http://downloadcenter.intel.com/Detail_Desc.aspx?agr=N&ProductID=1881&DwnldID=7838">desde aquí</a>.<br />
<br />
Una vez instalada podemos ver información sobre nuestra la frecuencia de funcionamiento actual de tu CPU y la memoria caché que dispone<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_4-yYGV2s0BM/TU0x60FhIeI/AAAAAAAAABI/hVtYCxBovBU/s1600/p1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="http://3.bp.blogspot.com/_4-yYGV2s0BM/TU0x60FhIeI/AAAAAAAAABI/hVtYCxBovBU/s320/p1.jpg" width="320" /></a></div>Si dispones de tecnología VT, <a href="http://es.wikipedia.org/wiki/HyperThreading">Hyper-Threading</a> o si es de 64 bits, así como otras tecnologías asociadas<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_4-yYGV2s0BM/TU0x8LWusxI/AAAAAAAAABM/6bNeLaH1edU/s1600/p2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="http://4.bp.blogspot.com/_4-yYGV2s0BM/TU0x8LWusxI/AAAAAAAAABM/6bNeLaH1edU/s320/p2.jpg" width="320" /></a></div> y el tipo, familia, modelo, versión, etc.... de tu microprocesador.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_4-yYGV2s0BM/TU0yOindmZI/AAAAAAAAABU/6uu--axH8Tc/s1600/p3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="http://2.bp.blogspot.com/_4-yYGV2s0BM/TU0yOindmZI/AAAAAAAAABU/6uu--axH8Tc/s320/p3.jpg" width="320" /></a></div><br />
me acabo de dar cuenta que no dispongo de VT y ahora comprendo porque por más que lo intento no puedo virtualizar un MAC en mi pc con <a href="http://www.virtualbox.org/">Virtualbox </a>:-(Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0tag:blogger.com,1999:blog-1051439453522433342.post-46803291144861546592011-02-04T19:29:00.028+01:002011-02-09T12:45:27.150+01:00El acelerómetro MMA7260¿Qué es un acelerómetro y para que sirve?, pues es un dispositivo electrónico que sirve para medir las aceleraciones en uno o varios ejes. Para mis primeras pruebas decidí adquirir el modelo MMA 7260 de <a href="http://www.freescale.com/">Freescale Semiconductor</a> que es ligero, barato (15€) y robusto y permite medir las aceleraciones en los tres ejes. <br />
<br />
Las principales caracteristicas son:<br />
<ul><li>Dispone de sensivilidad ajustable de 1,5G/2G/4G y 6G</li>
<li>Bajo consumo. En torno a 500µA</li>
<li>Modo de reposo con un consumo de 3µA</li>
<li>Alta sensibilidad (800 mV/g para 1,5G) </li>
<li>Incluye filtros paso bajo ideal para no tener que añadir más hardware</li>
</ul><span style="color: red;">Atención:</span> su voltaje de operación es entre 2.2V y 3.6V, esto es importante si lo vamos a conectar al Arduino ya que podemos estar acostumbrados a conectar dispositivos y sensores que funcionan a 5V y podríamos freirlo. <br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_4-yYGV2s0BM/TUxR11X9SmI/AAAAAAAAAAg/5fZHHsdHmaQ/s1600/acel1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://4.bp.blogspot.com/_4-yYGV2s0BM/TUxR11X9SmI/AAAAAAAAAAg/5fZHHsdHmaQ/s320/acel1.jpg" width="282" /></a></div><br />
El acelerómetro viene con una serie de cables para alimentarlo y para recoger las señales que serán un valor analógico en milivoltios para representar el valor de la aceleración.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxTIT09ohI/AAAAAAAAAAk/qG1IXkz8sZE/s1600/acel1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxTIT09ohI/AAAAAAAAAAk/qG1IXkz8sZE/s320/acel1.jpg" width="320" /></a></div>En esta imagen se puede ver con detalle el significado de cada conector, el selector de la sensibilidad del acelerómetro y los tres ejes de medición X,Y y Z.<br />
<br />
Para los más intrépidos os pongo <a href="http://www.cooking-hacks.com/skin/frontend/default/cooking/pdf/MMA7260QT.pdf">aquí el datasheet</a><br />
<br />
Para conectarlo al Arduino y así poder capturar la aceleración del dispositivo tenemos que primero, alimentarlo correctamente y luego conectar las señales procedentes del acelerómetro a entradas analógicas del Arduino.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxXjfu70UI/AAAAAAAAAAo/Zw3-lKX3KFA/s1600/acel3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxXjfu70UI/AAAAAAAAAAo/Zw3-lKX3KFA/s320/acel3.jpg" width="320" /></a></div><br />
Os recuerdo que la alimentación es de 3.3V y para ello conectamos cualquiera de los cables rojos y negro a la alimentación y masa respectivamente.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxYLTwOcRI/AAAAAAAAAAs/aP2AB_MF2OI/s1600/acel4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxYLTwOcRI/AAAAAAAAAAs/aP2AB_MF2OI/s320/acel4.jpg" width="320" /></a></div><br />
En la fotografía anterior puede verse el conexionado del cable de masa y tensión a los conectores correspondientes del Arduino. No me hartaré de repertirlo: <span style="color: red;">3.3V</span>!!! lo digo por experiencia... :-(<br />
La conexión de alimentación se puede conectar a cualquiera de los 3 mazos de cable que trae siempre respetando conectarlo al sitio adecuado.<br />
<br />
A continuación, para conectar las señales de acelaración suministradas por el acelerómetro tendremos que usar las entradas analógicas que trae el Arduino. Para ello usamos el cable azul que viene del acelerómetro<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_4-yYGV2s0BM/TUxZsCqdMWI/AAAAAAAAAAw/Ia23BXHSRDg/s1600/acel5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="http://1.bp.blogspot.com/_4-yYGV2s0BM/TUxZsCqdMWI/AAAAAAAAAAw/Ia23BXHSRDg/s320/acel5.jpg" width="320" /></a></div><br />
en este caso usando un cable verde y lo conectamos a la entrada analógica A2<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxaWPbZDCI/AAAAAAAAAA0/kcTYrKd0j2k/s1600/acel5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="215" src="http://2.bp.blogspot.com/_4-yYGV2s0BM/TUxaWPbZDCI/AAAAAAAAAA0/kcTYrKd0j2k/s320/acel5.jpg" width="320" /></a></div>comprobamos que todo está correctamente conectado, conectamos el arduino al puerto usb para encenderlo y veremos que además de encenderse el Arduino se enciende un pequeño led rojo del acelerómetro<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_4-yYGV2s0BM/TUxbFZoqb_I/AAAAAAAAAA4/65cvia9c8cE/s1600/acel1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="204" src="http://1.bp.blogspot.com/_4-yYGV2s0BM/TUxbFZoqb_I/AAAAAAAAAA4/65cvia9c8cE/s320/acel1.jpg" width="320" /></a></div>si queremos podemos conectar las otras dos señales de los dos ejes de aceleración que faltan (no es necesario conectar más cables de alimentación, sólo el cable azul del resto de mazo de cables)<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_4-yYGV2s0BM/TU1DsN4s5JI/AAAAAAAAABc/13TeueqoVuQ/s1600/aa.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/_4-yYGV2s0BM/TU1DsN4s5JI/AAAAAAAAABc/13TeueqoVuQ/s320/aa.jpg" width="320" /></a></div><br />
y ya podemos proceder a realizar la lectura de las aceleraciones desde el Arduino... pero esto lo dejaré para más adelante.Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com1tag:blogger.com,1999:blog-1051439453522433342.post-74837245568094177462011-02-03T09:31:00.001+01:002012-03-06T12:09:42.413+01:00Problemas con tablas marcadas como corruptas en MySQL<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-xz9WzgUDQe4/T1XwadCOqYI/AAAAAAAAAMI/Kba-WCxEvco/s1600/mysql_logo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-xz9WzgUDQe4/T1XwadCOqYI/AAAAAAAAAMI/Kba-WCxEvco/s1600/mysql_logo.jpg" /></a></div>
Una de las razones por las que migré en todos mis desarrollos a <a href="http://www.postgresql.org/">PostgreSQL</a> ha sido la capacidad de soportar los cortes de corriente que hacen estragos en bases de datos <a href="http://www.mysql.com/">MySQL</a>. En alguno que otro sistema todavia conservo estas bases de datos y es muy común encontrar errores como:<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">
<span style="font-size: small;">Table 'xxx' is marked as crashed and should be repaired .....</span></div>
<span style="font-size: small;"> </span> <br />
para solucionarlo tan sólo debe realizarse la siguiente acción con un usuario con privilegios para gestionar la base de datos correspondiente<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">
<span style="font-size: small;">mysqlcheck -u root -p --auto-repair base_de_datos;</span></div>
<br />
donde el usuario puede ser cualquier otro y el -p fuerza a la petición de la clave. En realidad este comando chequea y repara la base de datos y existen más opciones pero ya os dejo <a href="http://dev.mysql.com/doc/refman/5.0/es/using-mysqlcheck.html">aquí el enlace a la documentación oficial</a>.<br />
<br />
Por desgracia he tenido que realizar este arreglo varias veces pero por suerte siempre me ha sacado del apuro.<br />
<br />
Ante todo espero que no tengais que recurir a él ;-)Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0tag:blogger.com,1999:blog-1051439453522433342.post-85769541901420377942011-02-02T21:19:00.005+01:002011-02-04T20:15:51.664+01:00Arduino - Primer contactoDurante mucho tiempo llevo usando y aplicando el paradigma de fuentes abiertas (que no es lo mismo que software libre pero ya lo contaré en otra entrada) y cuando escuché que se estaba extendiendo hacia el mundo del hardware causó en mí una expectación y curiosidad de como podría ser esto posible.<br />
Indagando un poco descubrí que existe una plataforma de desarrollo abierta denominada <a href="http://www.arduino.cc/">Arduino</a> que pretende compartir desarrollos electrónicos entre todos y además es sencilla de usar y bastante efectiva. Lo primero que me llamó la atención fue pensar si su precio sería muy superior a lo que cuestan los puñados de bytes (sin entrar en el valor de su calidad, por supuesto) de un desarrollo software abierto y realmente me sorprendió. Con un precio de alrededor 20€ se puede disponer de un kit completo para pasar del mundo del soft al mundo del hard, o al menos, tender un puente entre ambos.<br />
<br />
Aprovechando que en fechas señaladas cuando la gente se regala cosas yo puedo permitirme el lujo de orientar "mi regalo sorpresa" decidí que me regalasen uno de ellos. Debido a que la plataforma es abierta encontré multitud de sitios en Internet donde disponían de ellos y me decanté por una tienda simplemente por que me hicieron gracia sus <a href="http://www.cooking-hacks.com/">ositos de colores de caramelo en su página web</a> (alguien que se publicita con tan tierno reclamo no puede darte productos hardware que te amarguen demasiado, sobre todo si estas empezando).<br />
<br />
Después de seleccionar el modelo básico y realizar el correspondiente desembolso forzoso tenía el paquete en casa en 24 horas. Lo primero que me sorprendió fue su diseño respecto la presentación que no hizo más que recordarme cierta empresa de Cupertino dedicada a la fruticultura pomácea mordisqueada. <br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_4-yYGV2s0BM/TUpzzOfd4oI/AAAAAAAAAAM/tlyKfr-6pWg/s1600/ard1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://4.bp.blogspot.com/_4-yYGV2s0BM/TUpzzOfd4oI/AAAAAAAAAAM/tlyKfr-6pWg/s320/ard1.jpg" width="255" /></a></div><br />
Lo siguiente fue su tamaño. Yo me imaginaba una placa con multitud de microchips pero era todo lo contrario. <br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_4-yYGV2s0BM/TUpz4CFnsgI/AAAAAAAAAAQ/3kxkeCeMiSE/s1600/ard2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/_4-yYGV2s0BM/TUpz4CFnsgI/AAAAAAAAAAQ/3kxkeCeMiSE/s320/ard2.jpg" width="307" /></a></div><br />
El conector para el usb, el de la alimentación, las entradas/salidas analógicas y digitales y el procesador programable es lo que abarca la mayor parte del espacio de la placa que tiene una superficie total de tan sólo 6,9x5,3 cms.<br />
<br />
Ahora toca conectarlo al ordenador por medio del cable usb, descargar el software y empezar a probarlo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_4-yYGV2s0BM/TUxQWf1GtaI/AAAAAAAAAAc/rzsgjeaxtvI/s1600/arduinoon.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="http://4.bp.blogspot.com/_4-yYGV2s0BM/TUxQWf1GtaI/AAAAAAAAAAc/rzsgjeaxtvI/s320/arduinoon.jpg" width="320" /></a></div><br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div>Anonymoushttp://www.blogger.com/profile/18276516260054603546noreply@blogger.com0