Mostrando entradas con la etiqueta arduino. Mostrar todas las entradas
Mostrando entradas con la etiqueta arduino. Mostrar todas las entradas

lunes, 26 de enero de 2015

SCADA para Arduino

Un 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.

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.


Más información del proyecto en http://st4makers.com

Os dejo además algunos vídeos que os pueden ser de utilidad sobre su potencial


Utilizando el Arduino Ethernet

Enlazando valores del Arduino con elementos gráficos

miércoles, 3 de julio de 2013

La guía definitiva de comunicaciones Wifi con el Arduino Wireless SD Shield y WiFly RN-XV



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.


El shield Wireless SD 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.

Puedes encontrar este tutorial actualizado en la siguiente dirección:

http://www.ismsolar.com/arduino-wireless-sd-shield-y-wifly-comunicaciones-wifi-con-el-arduino

viernes, 17 de agosto de 2012

Sistema de monitorización OpenSource: Emoncms3


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 openenergymonitor.org y en este post voy a explicar como montar la parte software del sistema de monitorización.



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.

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 VirtualBox 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.

http://www.ubuntu.com/download/server

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.

Bueno, lo primero que haremos será, teniendo el sistema operativo recién instalado, lo siguiente desde el usuario autorizado para actualizar la instalación

$ sudo su
nos preguntará por la clave que hemos indicado durante la instalación

# apt-get update
# apt-get upgrade
esto tardará un poco por lo que paciencia.

Instalando Apache

Una vez actualizado vamos a instalar el servidor web Apache para poder servir las páginas web

# apt-get install apache2
Una vez instalado podemos ir a la ip de nuestra máquina con el navegador para ver si se ha instalado correctamente.

En mi caso la ip es la 192.168.10.26 y la tuya la puedes averiguar con el comando ifconfig


 y usando el navegador lo comprobamos


Instalando PHP5

Una vez instalado el servidor Apache le toca el turno al php5 con:

# apt-get install php5 libapache2-mod-php5 php-gettext
podemos comprobar si todo está correcto creando un fichero en /var/www denominado index.php con el siguiente contenido:

<?php phpinfo(); ?>

y ejecutarlo desde el navegador


Si todo va bien veremos información de php en el navegador.

Instalación de MySQL

El siguiente paso es la instalación del sistema gestor de base de datos MySQL

# apt-get install mysql-server mysql-client
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.

Ahora para dar soporte desde PHP a MySQL instalaremos los siguientes paquetes:

# apt-get install php5-mysql
y reiniciamos Apache con

# /etc/init.d/apache2 restart

Ahora veremos en nuestro index.php que ya tenemos soporte para MySQL desde PHP.


Creación de la base de datos

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.

# mysql -u root -p
nos pedirá el password que hemos indicado cuando instalamos MySQL.

mysql> CREATE USER 'emoncms3user'@'localhost' IDENTIFY BY 'emoncms3userpass'
con esta sentencia creamos el usuario y le asignamos la clave (recordad usar una un poco más compleja ;-)

creamos la base de datos y asignamos como dueño al usuario anteriormente creado.

mysql> CREATE DATABASE emoncms3db;
mysql> GRANT ALL PRIVILEGES ON emoncms3db.* TO emoncms3user@localhost
mysql> \q

ahora podemos probar a conectarnos a la base de datos con el usuario que acabamos de crear

# mysql -u emoncms3user -p emoncms3db
introduciendo la clave de dicho usuario y entrando comprobaremos que todo está correcto.

Instalando Emoncms3 desde el repositorio oficial

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 GitHub en la siguiente dirección:

https://github.com/openenergymonitor/emoncms3

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.

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:

# apt-get install git-core
y clonamos el repositorio emoncms3 con todos los fuentes

# cd /var/www
# git clone git://github.com/openenergymonitor/emoncms3.git

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
# git clone https://github.com/openenergymonitor/emoncms3.git

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.

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.

# git pull
Una vez instalado podemos ir con nuestro navegador al software instalado usando la ip_de_vuestro_servidor/emoncms3


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

# cp Includes/default.settings.php Includes/settings.php
recargamos la página y veremos el siguiente aviso:


ahora editamos el fichero settings.php que se encuentra en Includes/settings.php



y en el fichero setup.php del directorio de instalación descomentamos (quitamos las barras de) la línea donde pone

// $runnable = TRUE

Ahora cambiaremos por cuestiones de seguridad el propietario del proyecto

# chown -R www-data.www-data /var/www/emoncms3
y borraremos el fichero index.php o le cambiaremos el nombre para que nadie conozca los detalles de nuestra instalación

# rm /var/www/index.php
Ahora podemos volver a lanzar la página web del proyecto y veremos como se crean las tablas necesarias.


Pulsaremos sobre "Continue to emoncms" y veremos la página principal de nuestro sistema de monitorización.



Emoncms3 utiliza el modo de reescritura de URL para funcionar por lo que debemos instalarlo antes de continuar


# a2enmod rewrite

y editar el fichero /etc/apache/sites-available/default añadiendo las opciones para el directorio /var/www/emoncms3


y reiniciamos apache de nuevo


# /etc/init.d/apache restart

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.

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:


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
http://emoncms.org/


Recordad que podéis ver mucha más información en la página principal del proyecto en http://openenergymonitor.org y si tenéis cualquier problema o duda con la instalación contactad conmigo o utilizad el foro de soporte.

viernes, 18 de mayo de 2012

Actualización del firmware del WiFly de Rovin Networks

En este artículo veremos como actualizar el firmware del módulo WiFly de Rovin Networks a la última versión.

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.

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.


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.

Una vez conectado, con el comando "ver" vemos la versión que tenemos.


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


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.


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.

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".


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.


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 aquí.

miércoles, 16 de mayo de 2012

XBee Shield + WiFly RN-XV + Arduino UNO



Tenía en mente desarrollar algún sistema inalámbrico usando el Arduino y para ello pregunté a la gente de cooking-hacks 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.

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 aquí.

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.

Al principio os aconsejo montarlo y utilizarlo sin el Arduino para ir familiarizándonos con él y para ello debemos seguir unos sencillos pasos.

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 :-)

ACTUALIZACIÓN

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.




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.

Una vez extraido el micro podemos montar el WiFly en el XBee Shield


y montamos el shield en el Arduino sin el microprocesador.


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.

Al conectarlo por primera vez el módulo WiFly intentará conectarse automáticamente a una red pero en nuestro caso lo haremos manualmente.

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 aquí.

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.


Para entrar en modo comandos hay que enviar por el puerto serie la secuencia $$$

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.


Si todo va bien, saldrá el texto CMD y estaréis en modo comando. El manual de usuario que podreís encontrar aquí (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.


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 WPS.

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 ;-)

Tambien podeis ver detalles de la versión del firmware instalado con la orden "ver".

Un comando muy interesante para hacer pruebas es el comando "scan" con el que el módulo WiFly escaneará las redes wifi disponibles.


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.

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"


para el primer comando os dejo en la siguiente tabla las opciones que disponemos:

Mode Protocol
0 DHCP OFF, use stored static IP address
1 DHCP ON, get IP address and gateway from AP
2 Auto-IP, generally used with Adhoc networks
3 DHCP cache mode, Uses previous IP address if lease is not expired (lease survives reboot)
4 Reserved for future use

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

Bit Position Protocol
0 UDP
1 TCP Server & Client (Default)
2 Secure (only receive packets with IP address matches the store host IP)
3 TCP Client only
4 HTTP client mode

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 " y ejecutamos "join ismcasa" para conectarnos a esa red. Si nuestra red es WEP usaremos "set wlan key ".


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.





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.

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.

lunes, 18 de julio de 2011

Aprende el funcionamiento de un transistor gracias al Arduino

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.

Como tenía varios transistores modelo BD-138 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:

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.

La conexión de los componentes en la placa de prototipado es la siguiente:


El transistor se encuentra en la placa de prototipado, en la parte izquierda superior. De abajo a arriba vemos :
  • Un cable amarillo conectado a la base. El cable conecta con el pin digital número 13 de Arduino.
  • Una resistencia conectada a un led une el pin 2 del transistor (colector) con la alimentación de 5V proveniente de Arduino (cable rojo)
  • El pin 3 del transistor (emisor) conecta con tierra (también de Arduino).
Una vista mas cercana del transistor y sus conexiones:


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).

Lectura de voltaje



Lectura de voltaje añadiendo un condensador al conjunto


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.

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.

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:



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.


jueves, 24 de marzo de 2011

Filtro software para suavizar las oscilaciones

La 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.

Podemos utilizar sistemas de filtrado como el filtro Kalman o Filtro de Wiener 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.

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:

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


De esta manera se puede ver la onda sinoidal que se genera y será nuestra señal limpia.


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.


Ahora sumamos el valor de ruido que hemos generado a la señal limpia


Y así tenemos una onda sinoidal con ruido aleatorio


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

Valor Actual = (Valor Anterior)*k + (Valor Actual)*j

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.


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.

En esta gráfica se han utilizado los valores de k=0.6 y j=0.4


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.


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.

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.

domingo, 6 de febrero de 2011

Calculando la inclinación en grados de nuestro acelerómetro MMA7260

Una 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.
Las formulas que he usado son las siguientes:

 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;

el último término es para pasar de radianes a grados.
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.

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.

Aplicando algunas optimizaciones podemos disponer ya de los valores en grados de los tres ejes de nuestro acelerómetro

#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);
}


En esta imagen puede verse, con el acelerómetro inclinado hacia arriba, el eje Y y Z cerca de 90º.

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.

sábado, 5 de febrero de 2011

Midiendo las inclinaciones con el MMA7260

Siguiendo 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.

Existe un documento muy bueno y muy detallado desarrollado por el fabricante con los detalles técnicos que utilizaremos para esta aplicación.

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 post anterior.


Una vez conectadas, programaremos el Arduino para que recoja los valores de esas entradas, las transformaremos y las mostraremos por pantalla.

Para programar con Arduino necesitaremos descargarnos el entorno de desarrollo desde la página web oficial (mejor en inglés ya que dispondrá de la versión más actualizada), podeis seguir las instrucciones para los que nos hayais programado nunca en este entorno.

A continuación os coloco el programa para medir la lectura de la aceleración en Gs:

#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
 {
   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);
} 

Una vez ejecutado el programa podemos ver como se realiza un ajuste del error estando en reposo y se recogen valores del mismo.

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.