Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

26/03/2013 #1


Acelerometro digital adxl345
hola a todos
necesito realizar un sistema que mida los grados de inclinación en los tres ejes, para ello
adquirí un acelerómetro adxl345 que se configura por medio de i2c, como microcontorlador he usado un 16f877a para leer los datos y poder procesarlos, he logrado comunicarlo con el pic, sin embargo no me toma lecturas negativas, la concatenación la estoy realizando como dice en la pagina de fabricante, agradecería cualquier aporte
Código:
#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4M)
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <lcd.c>
#use i2c(MASTER, SDA=PIN_c4, SCL=PIN_c3,FORCE_HW)

#define ACCEL_WRITE_ADDR  0XA6//0xA6 //0x53//0x3a
#define ACCEL_READ_ADDR  0XA7//0xA7  //0x53//0x3b
#define ACCEL_DATA_ADDR 0x32
#define ACCEL_PWRCTRL_ADDR 0x2d
#define ACCEL_MEASURE_MODE 0x08

   unsigned int accel_data[6];
   unsigned int16 x,y,z;
   float x1,y1,z1,R;
  float teta=0, gama=0,fi=0;

void main ()
{
  enable_interrupts(int_rda);
  enable_interrupts(GLOBAL);

   // initialize

   while(true) {
     lcd_init();

      // Tell the accelerometer to wake up
      i2c_start();
      i2c_write(ACCEL_WRITE_ADDR);
      i2c_write(0X31);
      i2c_write(0X01);
      i2c_stop();

     I2C_start();
     i2c_write(ACCEL_WRITE_ADDR);
     i2c_write(ACCEL_PWRCTRL_ADDR);
     i2c_write(ACCEL_MEASURE_MODE);
     I2C_stop();


      // Read data from the accel
      i2c_start();
      i2c_write(ACCEL_WRITE_ADDR);
      i2c_write(ACCEL_DATA_ADDR);
      i2c_start();
      i2c_write(ACCEL_READ_ADDR);
      accel_data[0] = i2c_read(); //x0
      accel_data[1] = i2c_read(); //x1
      accel_data[2] = i2c_read(); //y0
      accel_data[3] = i2c_read(); //y1
      accel_data[4] = i2c_read(); //z0
      accel_data[5] = i2c_read(0); // z1, NACK on last read
      i2c_stop();
      //////////concatenar datos adxl345/////////////
      x=((accel_data[1])<<8)|accel_data[0] ;
      y=((accel_data[3])<<8)|accel_data[2];
      z=((accel_data[5])<<8)|accel_data[4];


      x1=(float)x/256;
      y1=(float)y/256;
      z1=(float)z/256;
      ////////////////////////////////////////////////
      R=sqrt((x1*x1)+(y1*y1)+(z1*z1));


      teta=acos(x1/R);
      teta=teta * 57,296;

      gama=acos(y1/R);
      gama=gama*57,296;

      fi=acos(z1/R);
      fi=fi*57,296;


     printf(lcd_putc,"\f %.2f %.2f %.2f ",x1,y1,z1);
     printf(lcd_putc,"\n %f %f %f ",teta,gama,fi);

   }
}
27/03/2013 #2


Hola, viendo rapidamente te puedo aportar que declaras solo variables unsigned int (accel_data[6],x,y,z) en las cuales almacenas y operas datos recibidos del dispositivo, por lo tanto solo puedes obtener valores positivos.
10/04/2013 #3


correcion codigo
hola de nuevo,
necesito obtener el angulo entre la horizontal y el suelo pero no lo he logrado...agrego el codigo para ver si existe lgun error, lei la AN1057 Y segui sus indicaciones pero no ha funcionado...
de nuevo mil gracias.

Código:
#include <16f877a.h>
#fuses xt,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4M)
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <lcd.c>
#use i2c(MASTER, SDA=PIN_c4, SCL=PIN_c3)


#define ACCEL_WRITE_ADDR  0XA6//0xA6 //0x53//0x3a
#define ACCEL_READ_ADDR  0XA7//0xA7  //0x53//0x3b
#define ACCEL_DATA_ADDR 0x32
#define ACCEL_PWRCTRL_ADDR 0x2d
#define ACCEL_MEASURE_MODE 0x08

   signed int accel_data[6];
   signed int16 x,y,z;
   float x1,y1,z1,R1,R2,R3;
   float teta=0, gama=0, fi=0;
   float teta1=0, gama1=0 , fi1=0 ;
   signed int16 AX,AY,AZ;

void main ()
{
    // initialize

   while(true) {
     lcd_init();

      // Tell the accelerometer to wake up
      i2c_start();
      i2c_write(ACCEL_WRITE_ADDR);
      i2c_write(0X31);
      i2c_write(0X0B);////+-16
    //i2c_write(0X01);///+-4g
      i2c_stop();

     I2C_start();
     i2c_write(ACCEL_WRITE_ADDR);
     i2c_write(ACCEL_PWRCTRL_ADDR);
     i2c_write(ACCEL_MEASURE_MODE);
     I2C_stop();


      // Read data from the accel
      i2c_start();
      i2c_write(ACCEL_WRITE_ADDR);
      i2c_write(ACCEL_DATA_ADDR);
      i2c_start();
      i2c_write(ACCEL_READ_ADDR);
      accel_data[0] = i2c_read(); //x0
      accel_data[1] = i2c_read(); //x1
      accel_data[2] = i2c_read(); //y0
      accel_data[3] = i2c_read(); //y1
      accel_data[4] = i2c_read(); //z0
      accel_data[5] = i2c_read(0); // z1, NACK on last read
      i2c_stop();
      //////////concatenar datos adxl345/////////////
      x=((accel_data[1])<<8)|accel_data[0] ;
      y=((accel_data[3])<<8)|accel_data[2];
      z=((accel_data[5])<<8)|accel_data[4];



//////////////////////////multiplicar 16*2/2^13//////////////////
      x1=(float)x * 0.00390625;
      y1=(float)y * 0.00390625;
      z1=(float)z * 0.00390625;
      ////////////////////////////////////////////////
   //   R=sqrt((x1*x1)+(y1*y1)+(z1*z1));


      R1=sqrt((y1*y1)+(z1*z1));
      R2=sqrt((x1*x1)+(z1*z1));
      R1=sqrt((y1*y1)+(x1*x1));


    // teta=acos(x1/R);
     teta=atan(x1/R1);
     teta=teta * 57,296;

//      gama=acos(y1/R);
      gama=atan(y1/R2);
      gama=gama*57,296;

//      fi=acos(z1/R);
        fi= atan(R3/z1);
        fi=fi*57,296;

AX=(TETA*10)*0.1;
AY=(GAMA*10)*0.1;
AZ=(FI*10)*0.1;

 printf(lcd_putc,"\f %ld %ld %ld ",x,y,z);
printf(lcd_putc,"\n %LD %LD %LD ",AX,AY,AZ);
DELAY_MS(100);

   }
}
03/12/2013 #4


Amigo yo tambien estoy interesado en este proyecto del acelerometro ya que yo tengo que mover unos motores con respecto a la posicion del acelerometro.
Desearia tu ayuda
06/12/2013 #5


posible guía...
Hola, curiosamente este acelerometro me fallo dos veces, la primera cuando estaba integrado con un giroscopio(IMU), la segundo como independiente es decir,
poseia el mismo problema, la medida leida en el bus de comunicaciones despues de concatenarla era por ejemplo de -25, de ese valor se saltaba a 220(+-8 bits), no pude entender porque, lo que hice fue usar un acelerómetro que en vez de I2C usara directamente los pines CAD de un microcontrolador, usÉ el MMA7361L, puedes encontrar una muy buena guía buscando en
starlino IMU
vale la pena mencionar que si optas por un sistema I2C y tu sensor funciona a 3.3V y tu microcontrolador funciona a 5v debes realizar un sistema que acople tensiones o podrias averiar el sensor, puedes buscar por la AN97055 DE PHILIPS...
EXITOS...
07/12/2013 #6


¿Tu ya has usado ese AN97055? ¿Y que probabilidad de que ya no haya ese error ahí?
¿Podrías explicarme de que manera lo acoplaría?

Explícame estas expresiones que has puesto.

#define ACCEL_DATA_ADDR 0x32
#define ACCEL_PWRCTRL_ADDR 0x2d
#define ACCEL_MEASURE_MODE 0x08

¿Por qué motivo has puesto estas definiciones con esos determinados valores?
07/12/2013 #7


EL AN97055 SI lo he usado, no es difícil el montaje, buscalo que hay aparece explicado detalladamente el circuito a usar, lo segundo

#define ACCEL_DATA_ADDR 0x32
#define ACCEL_PWRCTRL_ADDR 0x2d
#define ACCEL_MEASURE_MODE 0x08
son las direcciones de los registros del adxl345 para realizar la configuración, es necesario que leas el Datasheet, para entender el proceso de escritura y lectura.
09/12/2013 #8


Con respecto a las conexiones yo he hecho esto:
- sdo y gnd a tierra
- cs y vcc a alimentacion(3.16v)
- cls he puesto una resistencia(1k) a vcc(3.16v)
y tambien del cls a pin_c3
- sda he puesto una resistencia(1k) a vcc(3.16v)
y tambien del sda a pin_c4

¿corrigeme si las conexiones que he hecho esta bien?
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.