# De aceleracion a grados con lis3lv02dq



## trank (Dic 29, 2010)

Antes de nada,presentarme ante esta comunidad.
Pongo el mensaje en este subforo pero no se si sera el mas adecuado.

Dispongo de un sensor lis3lv02dq con el cual tengo un codigo que me muestra la aceleracion de los 3 ejes en cada momento montado sobre un MSP430.
Lo siguiente que quiero hacer a partir del codigo que tengo,usar la aceleracion para que me calcule los grados de inclinacion que va variando los ejes del propio sensor.
Tengo mas o menos un par de ideas en la cabeza,pero quiero ver si me hechais un cable.

Gracias de antemano


----------



## Eduardo (Dic 29, 2010)

trank dijo:


> ...Lo siguiente que quiero hacer a partir del codigo que tengo,usar la aceleracion para que me calcule los grados de inclinacion que va variando los ejes del propio sensor.
> Tengo mas o menos un par de ideas en la cabeza,pero quiero ver si me hechais un cable.


Y cuales son esas ideas?


----------



## trank (Dic 29, 2010)

Mi idea es que,al pulsar un boton,me capture los valores que proporcionan los ejes, y al volver a pulsar,con esa segunda medida,obtendria la posicion que ha variado el sensor.
El problema o duda,es como intentar pasar esa aceleracion a grados.
El codigo que pretendo hacer,es una especie de medidor de angulos,obteniendo mediante las pulsaciones del boton los distintos angulos sobre el sensor.
Quizas no vaya por el buen camino con esa idea


----------



## golumx (Dic 29, 2010)

Puedes pasar a grados la aceleracion facilmente, cuando gira 90º obtendras el valor maximo que te de el acelerometro por lo que con una regla de tres obtendras el angulo. Lo mas correcto es tener en cuenta los tres ejes para obtener un valor mas preciso. Repasa las notas de aplicacion de ST-Microelectronics.


----------



## trank (Dic 30, 2010)

Esa era la idea que tenia desde un principio.
Intentar aplicar una regla de 3,pero no estaba muy seguro de ella o que fuera la mejor manera de plantear el problema.
Gracias por la ayuda


----------



## Eduardo (Dic 30, 2010)

- Primero te recomiendo que repases un poco de cinematica.

- Para conocer la distancia recorrida por el sensor tenes que hacer una doble integracion numerica de la aceleracion.

- Para conocer el angulo girado, tenes que conocer la disposicion del sensor en la estructura para poder relacionar la distancia recorrida con el angulo girado.
Si el eje de giro es el centro del sensor ==> no medis nada.

- Como al hacer una doble integracion de la aceleracion siempre habra deriva --> no sirve para determinar posicion absoluta, solo valores relativos y durante intervalos cortos.


----------



## Beamspot (Dic 30, 2010)

La respuesta es cualquier cosa menos trivial.

Necesitamos más datos. ¿El sensor va a estar quieto, sin aceleraciones, en cualquier caso?¿Hay movimiento en cualquier momento?¿Que mecánica se va a usar?¿Que ángulo necesitas medir?¿Que conocimientos de cinemática tienes?¿Estás absolutamente seguro que lo que necesitas no es un giróscopo?¿Puedes explicar con mayor detalle la aplicación que pretendes hacer?


----------



## trank (Ene 2, 2011)

La idea principal es de hacer una aplicacion para medir la inclinacion de las antenas.
Esta es el dibujo que me dejaron a partir de la cual tengo que trabajar

En principio el sensor estara quieto,y mediante 3 pulsaciones quiero captar los valores que registra dicho sensor para sacar luego la diferencia.
De cinematica no se nada,de hay que este perdido en este mundo.
Quiza con el dibujo (hecho con paint) me podreis orientar mejor para lo que debo hacer.
Un saludo


----------



## golumx (Ene 2, 2011)

Como las antenas solo van a estar sometidas a la aceleracion de la gravedad con la regla de tres vale, si quieres comerte un  poco mas el tarro repasa este documento.


----------



## trank (Ene 2, 2011)

Muchas gracias glumx por ese pdf,me a abierto los ojos y la mente para nuevas cosas.
Lo leere a fondo,pero por lo primero que he visto por encima,me va ayudar mucho.
Gracias de verdad


----------



## Beamspot (Ene 3, 2011)

Aunque a mi corto parecer, los senos y la regla de tres no tienen nada que ver, el documento sí que me parece muy correcto y totalmente aplicable.

Si no me falla la memoria, este tipo de proyectos ya existe por ahí, aunque no se que micro usaban para las mates.


----------



## golumx (Ene 3, 2011)

Ese pdf lo tenia guardado por que a mi tambien me abrio los ojos. La diferencia entre la regla de tres y el calculo del arcoseno es que le regla de tres es mas aproximada, solo trabaja un eje y suponen completamente lineal la respuesta del acelerometro, mientras que por el metodo que menciona el documento, se tiene en cuenta la composicion de los tres ejes, de todas formas es importante repasar la trigonometria basica para trabajar con acelerometros de forma estatica, si hay una aceleracion externa ya hay que recurrir a calculos integrales y giroscopos para conocer la posicion del sistema.


----------



## trank (Ene 18, 2011)

Hola de nuevo.
He intentado aplicar las formulas trigonometricas en la funcion que hace que muestre por el display la aceleracion.
Estoy intentando capturar cada vez que pulso el boton B3,los valores de los 3 ejes,para luego guardarlos y poder trabajar con las reglas trigonometricas.
Estoy trabajando con un MSP430 en lenguaje C.
No consigo que capture bien las variables,para luego mostrarlas en el display una vez hemos pulsado las 3 veces.
Me podeis ayudar a encontrar el error,llevo ya un par de dias locos!

void sensor_test()
{
 draw_array32_to_lcd("                                ");
 //Endlosschleife
int acc_x;
int acc_y;
int acc_z;
double acc_x_g;
double acc_y_g;
double acc_z_g;
char char_array[]=".01  1.23  4.56";
double ini_x = 0, end_x = 0, dif_x = 0;
double ini_y = 0, end_y = 0, dif_y = 0 ;
double ini_z = 0, end_z = 0, dif_z = 0;
double root_pitch = 0, root_roll = 0, root_theta = 0;



   unsigned int status_reg_val = 0;
 while(1)
 {
   status_reg_val = Sensor_RX(STATUS_REG);
   if(status_reg_val && BIT3)
   {
     if(status_reg_val && BIT7)
     {
 acc_x = Acc_RX('x');
 acc_y = Acc_RX('y');
 acc_z = Acc_RX('z');
 acc_x_g =  (double)acc_x/ 1024;
 acc_y_g =  (double)acc_y/ 1024;
 acc_z_g =  (double)acc_z/ 1024;
     }
   }
//    sprintf(char_array, "X:%1.4f Y:%1.4f     Z:%1.4f

       sprintf(char_array, "%1.4f  %1.4f       %1.4f  ", acc_x_g, acc_y_g, acc_z_g);
 draw_array32_to_lcd(char_array);
//    write_value_to_display('x', DD_RAM_ADDR, acc_z);
//    write_value_to_display('y', DD_RAM_ADDR, acc_y);
//    write_value_to_display('z', DD_RAM_ADDR, acc_x);

for(i=0; i<4;i++) Delayx100us(250);//.


   //----------BUTTON 1

   if ((B1) == 0 && b1_flag == 0)          //if B1 pressed
     {
           b1_flag = 1;
     }
   if ((B1) != 0 && b1_flag != 0)          //if B1 released
     {
           b1_flag = 0;
           return;
     }

   //----------BUTTON 3
 if ((B3) == 0 && b3_flag==0)                //if B3 is pressed
     {
             b3_flag = 1;
     }
   if ((B3) != 0 && b3_flag != 0)            //if B3 is released
     {
             b3_flag = 0;
                   ini_x=acc_x_g;
                   ini_y=acc_y_g;
                   ini_z=acc_z_g; 



     }

   if ((B3) == 0 && b3_flag==0)                //if B3 is pressed
     {
             b3_flag = 1;
     }
   if ((B3) != 0 && b3_flag != 0)            //if B3 is released
     {
             b3_flag = 0;
             end_x=acc_x_g;
             end_y=acc_y_g;
             end_z=acc_z_g;
             dif_x=end_x - ini_x;
             dif_y=end_y - ini_y;
             dif_z=end_z - ini_z;
             root_pitch = sqrt ((dif_y*dif_y)+(dif_z*dif_z));
             root_roll = sqrt ((dif_x*dif_x)+(dif_z*dif_z));
             root_theta = sqrt ((dif_y*dif_y)+(dif_x*dif_x));



     }



   if ((B3) == 0 && b3_flag==0)                //if B3 show results
     {
             b3_flag = 1;
     }
   if ((B3) != 0 && b3_flag != 0)            //if B3 is released
     {
             b3_flag = 0;

       sprintf(char_array,"atan2( %f, %f ) = %f\n", dif_x, root_pitch, atan2(ini_x,root_pitch));
       draw_array32_to_lcd(char_array);
       sprintf(char_array,"atan2( %f, %f ) = %f\n", dif_x, root_roll, atan2(end_x,root_roll));
       draw_array32_to_lcd(char_array);
       sprintf(char_array,"atan2( %f, %f ) = %f\n", root_theta, dif_z, atan2(root_theta,dif_z));
       draw_array32_to_lcd(char_array);


     }



 }
};


----------

