CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ADXL345 Problem?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Mucit23



Joined: 10 May 2014
Posts: 8

View user's profile Send private message

ADXL345 Problem?
PostPosted: Sat May 10, 2014 9:03 am     Reply with quote

Hi friends,

I'm using pic16F877 with ADXL345 Accelerometer. I'm running ADXL345 in I2C mode. I can communicate with the sensor.
For example, when I read the registers DEVICE_ID, I'm reading the value 0xe5
When I read the data from the sensor, Every time I get the value 0x00.

This is My ADXL345 library,
Code:
// ADXL345  Registers
#define ADXL345_DEVID                   0x00    // R     Device ID
#define ADXL345_THRESH_TAP              0x1D    // R/W   Tap threshold
#define ADXL345_OFSX                    0x1E    // R/W   X-axis offset
#define ADXL345_OFSY                    0x1F    // R/W   Y-axis offset
#define ADXL345_OFSZ                    0x20    // R/W   Z-axis offset
#define ADXL345_DUR                     0x21    // R/W   Tap duration
#define ADXL345_Latent                  0x22    // R/W   Tap latency
#define ADXL345_Window                  0x23    // R/W   Tap window
#define ADXL345_THRESH_ACT              0x24    // R/W   Activity threshold
#define ADXL345_THRESH_INACT            0x25    // R/W   Inactivity threshold
#define ADXL345_TIME_INACT              0x26    // R/W   Inactivity time
#define ADXL345_ACT_INACT_CTL           0x27    // R/W   Axis enable control for activity and inactivity detection
#define ADXL345_THRESH_FF               0x28    // R/W   Free-fall threshold
#define ADXL345_TIME_FF                 0x29    // R/W   Free-fall time
#define ADXL345_TAP_AXES                0x2A    // R/W   Axis control for single tap/double tap
#define ADXL345_ACT_TAP_STATUS          0x2B    // R     Source of single tap/double tap
#define ADXL345_BW_RATE                 0x2C    // R/W   Data Rate and power mode control
#define ADXL345_POWER_CTL               0x2D    // R/W   Power-saving features control
#define ADXL345_INT_ENABLE              0x2E    // R/W   Interrupt enable control
#define ADXL345_INT_MAP                 0x2F    // R/W   Interrupt mapping control
#define ADXL345_INT_SOURCE              0x30    // R     Source of interrupts
#define ADXL345_DATA_FORMAT             0x31    // R/W   Data format control
#define ADXL345_DATAX0                  0x32    // R     X-Axis Data 0
#define ADXL345_DATAX1                  0x33    // R     X-Axis Data 1
#define ADXL345_DATAY0                  0x34    // R     Y-Axis Data 0
#define ADXL345_DATAY1                  0x35    // R     Y-Axis Data 1
#define ADXL345_DATAZ0                  0x36    // R     Z-Axis Data 0
#define ADXL345_DATAZ1                  0x37    // R     Z-Axis Data 1
#define ADXL345_FIFO_CTL                0x38    // R/W   FIFO control
#define ADXL345_FIFO_STATUS             0x39    // R     FIFO status
#define ADXL345_OUTPUTS                 0x32

void adxl345_init(){
         
         i2c_start();
         i2c_write(0xA6);
         //delay for ack in the slave device
         //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
         i2c_write(ADXL345_DATA_FORMAT);
         i2c_write(0x01);
         i2c_stop();
         
         delay_ms(10);
         i2c_start();
         i2c_write(0xA6);
         i2c_write(ADXL345_FIFO_CTL);
         i2c_write(0x00);//FIFO inactive
         i2c_stop();
         
         //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
         delay_ms(10);
         i2c_start();
         i2c_write(0xA6);
         i2c_write(ADXL345_BW_RATE);
         i2c_write(0x0c);
         i2c_stop();
         
         delay_ms(10);
         i2c_start();
         i2c_write(0xA6);
         i2c_write(ADXL345_POWER_CTL);
         i2c_write(0x08); //Measurement mode
         i2c_stop();
}
     
     
int adxl345_read(int add){
         int retval;
         i2c_start();
         i2c_write(0xA6);
         i2c_write(add);
         i2c_start();
         i2c_write(0xA7);
         retval=i2c_read(0);
         i2c_stop();
         return retval;
}


main code,

Code:

#include <16F877A.h>
#device ADC=10
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES HS

#use delay(crystal=10000000)

#use I2C(master, sda=PIN_C4, scl=PIN_C3, slow)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#include <lcd_driver.c>
#include <ADXL345.c>

int8 accel_data[6];
int16 xaxis=0,yaxis=0,zaxis=0;
unsigned int8 temp=0;

void main()
{
   set_tris_a(0x00);
   set_tris_b(0x00);
   set_tris_c(0x00);
   set_tris_d(0x00);
   set_tris_e(0x00);
   output_a(0x00);
   output_b(0x00);
   output_c(0x00);
   output_d(0x00);
   output_e(0x00);
   
   output_float(pin_c3);
   output_float(pin_c4);
   
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);
   setup_spi(SPI_DISABLED);
   
   delay_ms(500);
   lcd_init();
   adxl345_init();   
   
   printf(lcd_putc,"\f");
   lcd_gotoxy(1,1);
   temp=adxl345_read(ADXL345_DEVID );
   printf(lcd_putc,"ADXL345_ID=%02X",temp);

   while(TRUE)
   {
     accel_data[0]=adxl345_read(32); //Read X axis(LSB)
     accel_data[1]=adxl345_read(33); //Read X axis(MSB)
     accel_data[2]=adxl345_read(34); //Read Y axis(LSB)
     accel_data[3]=adxl345_read(35); //Read Y axis(MSB)
     accel_data[4]=adxl345_read(36); //Read Z axis(LSB)
     accel_data[5]=adxl345_read(37); //Read Z axis(MSB)

     xaxis=(int16)((accel_data[1]<<8)|accel_data[0]);
     yaxis=(int16)((accel_data[3]<<8)|accel_data[2]);
     zaxis=(int16)((accel_data[5]<<8)|accel_data[4]);
     
     lcd_gotoxy(1,2);
     printf(lcd_putc,"X%03ld Y%03ld Z%03ld",xaxis, yaxis, zaxis);

     delay_ms(100);
     output_toggle(pin_a0);
 
   }
}


Result


What could be the problem?
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat May 10, 2014 4:33 pm     Reply with quote

you should printout the 'raw data'( to confirm you're actually reading it.

so after reading the high byte ,low byte data.. print out those valuse _before_ you create the 16bit data(xaxis,yaxis,zaxis).

you have 2 possible errors
1) NOT reading the actual data
2) a 'math' error (hint you can use make16())

You're using a 5 volt PIC and a 3 volt sensor, what interface are you using ?

hth
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Sun May 11, 2014 12:50 am     Reply with quote

The basic 'read' for the data is not being done the way that they recommend.

For the 8 bytes from the data registers, you should send the address of the first register, and then read all eight bytes in one sequence. As it stands, it ought probably to work (if the interface is correctly buffering the 3v levels to 5v....), but has the risk that parts of the registers will change between one read and the next. So potentially garbage.

Then the data pairs should be combined with make16 as temtronic says, but doesn't want to be combined into an int16. It wants to be a _signed_ int16.

Then you are running without the FIFO. You have the chip set to update at 8Hz. Unbuffered. You therefore need to wait for the chip to say it has done a reading, before taking the data. Much better to enable the interrupt output, and take the reading when this says that data is available, but as it stands, you need to wait 1/8th second after setting the register, and then read at 1/8th second intervals.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun May 11, 2014 3:24 am     Reply with quote

At quick glance I noted this:
Code:
#define ADXL345_DATAX0                  0x32    // R     X-Axis Data 0
#define ADXL345_DATAX1                  0x33    // R     X-Axis Data 1
#define ADXL345_DATAY0                  0x34    // R     Y-Axis Data 0
#define ADXL345_DATAY1                  0x35    // R     Y-Axis Data 1
#define ADXL345_DATAZ0                  0x36    // R     Z-Axis Data 0
#define ADXL345_DATAZ1                  0x37    // R     Z-Axis Data 1

     accel_data[0]=adxl345_read(32); //Read X axis(LSB)
     accel_data[1]=adxl345_read(33); //Read X axis(MSB)
     accel_data[2]=adxl345_read(34); //Read Y axis(LSB)
     accel_data[3]=adxl345_read(35); //Read Y axis(MSB)
     accel_data[4]=adxl345_read(36); //Read Z axis(LSB)
     accel_data[5]=adxl345_read(37); //Read Z axis(MSB)
Why are you using the hard coded values 32, 33, etc. instead of the defines? It would make the code 'self documenting', but even more important: 0x32 != 32
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Sun May 11, 2014 3:38 am     Reply with quote

Brilliant spot....

Register 32, is the user offset adjustment, so will be zero.

Suggest:
Code:

#define ADXL_read_addr 0xA7;
#define ADXL_write_addr 0xA6;

struct data_block
{
    signed int16 x;
    signed int16 y;
    signed int16 z;
};

union
{
    int8 registers[6];
    struct data_block axes;
} data;

void read_xyz(void)
{
    int8 ctr;
    i2c_start();
    i2c_write(ADXL_write_addr);
    i2c_write(ADXL345_DATAX0);
    i2c_start();
    i2c_write(ADXL_read_addr);
    for (ctr=0;ctr<6;ctr++)
    {
        data.registers[ctr]=i2c_read(ctr==5); //NACK on 5
    }
    i2c_stop();
    return;
}

//you then call 'read_xyz', and have the values in data.axes.x to
//data.axes.z - Signed int16 values.


Best Wishes
Mucit23



Joined: 10 May 2014
Posts: 8

View user's profile Send private message

PostPosted: Sun May 11, 2014 3:30 pm     Reply with quote

Thank you for your answers. I solved the problem.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group