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.

1 comentario:

  1. Nice Tutorial! It works like a charm! Just missed a few characters in the for loop
    for (int j=0;j<NADJ;j++)
    Thank you for sharing this!
    Gepp

    ResponderEliminar