Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

ADXL345 Interface Pic16f877a

Status
Not open for further replies.
I have tried following code. Works absloutely fine until i see all values of X, Y and Z to be -1. No effect on tilt or anything

VCC = 5V
Chip Select is connected to uC
SDA and SDL are connected to uC
SDO is Connected to VCC.

PHP:
// ADXL345 Register Definition
#define _POWER_CTL      0x2D
#define _DATA_FORMAT    0x31
#define _BW_RATE        0x2C
#define _DATAX0        0x32
#define _DATAX1        0x33
#define _DATAY0        0x34
#define _DATAY1        0x35
#define _DATAZ0        0x36
#define _DATAZ1        0x37
#define _FIFO_CTL      0x38
#define _SPEED          0x0F        // Buffer Speed - 3200Hz

#define _SPI_READ      0x80
#define _SPI_WRITE      0x00

sbit ACCEL_CS    at RC0_bit;
sbit ACCEL_CS_Dir at TRISC0_bit;

unsigned short temp;
char out[16];
int readings[3] = {0, 0, 0}; // X, Y and Z
short address, buffer;
char* codetxt_to_ramtxt(const char* ctxt){
static char txt[20];
char i;
  for(i =0; txt[i] = ctxt[i]; i++);
  return txt;
}
void ADXL345_Write(unsigned short address, unsigned short data1) {

  ACCEL_CS = 0;

  //I2C1_Wr(_ACCEL_ADDRESS|_SPI_WRITE);  // send byte via I2C  (device address + W)

  SPI1_Write((address|_SPI_WRITE));          // send byte (address of the location)
  SPI1_Write(data1);            // send data (data to be written)
  ACCEL_CS = 1;
}

unsigned short ADXL345_Read(unsigned short address) {
  unsigned short tmp = 0;

  ACCEL_CS = 0;
  SPI1_Write((address|_SPI_READ));
  tmp = SPI1_Read(0);          // Read the data (NO acknowledge)
  ACCEL_CS = 1;

  return tmp;
}
char ADXL345_Init(void) {
  // Go into standby mode to configure the device.
  ACCEL_CS = 1;
  ACCEL_CS_Dir = 0;
  ADXL345_Write(_POWER_CTL, 0x00);
  ADXL345_Write(_DATA_FORMAT, 0x0B);      // Full resolution, +/-16g, 4mg/LSB.
  ADXL345_Write(_BW_RATE, _SPEED);          // Set 100 Hz data rate
  ADXL345_Write(_FIFO_CTL, 0x80);          // stream mode
  ADXL345_Write(_POWER_CTL, 0x08);        // POWER_CTL reg: measurement mode
  return 0x00;
}

// Read X Axis
int Accel_ReadX(void) {
  int Out_x;

  Out_x = ADXL345_Read(_DATAX1);
  low_byte = ADXL345_Read(_DATAX0);

  Out_x = (Out_x << 8);
  Out_x = (Out_x | low_byte);

  return Out_x;
}

// Read Y Axis
int Accel_ReadY(void) {
  char low_byte;
  int Out_y;

  Out_y = ADXL345_Read(_DATAY1);
  low_byte = ADXL345_Read(_DATAY0);

  Out_y = (Out_y << 8);
  Out_y = (Out_y | low_byte);

  return Out_y;
}

// Read Z Axis
int Accel_ReadZ(void) {
  char low_byte;
  int Out_z;

  Out_z = ADXL345_Read(_DATAZ1);
  low_byte = ADXL345_Read(_DATAZ0);

  Out_z = (Out_z << 8);
  Out_z = (Out_z | low_byte);

  return Out_z;
}

// Calculate the average values of the X, Y and Z axis reads
void Accel_Average(void) {
  int i, sx, sy, sz;

  // sum
  sx = sy = sz = 0;

  // average accelerometer reading over last 16 samples
  for (i=0; i<16; i++) {
    sx += Accel_ReadX();
    sy += Accel_ReadY();
    sz += Accel_ReadZ();
  }
  // average
  readings[0] = sx >> 4;
  readings[1] = sy >> 4;
  readings[2] = sz >> 4;

}

// Display average X-axis read value on UART
void Display_X_Value(void) {
  UART1_Write_Text("X:");
  IntToStr(readings[0], out);
  UART1_Write_Text(out);
  UART1_Write(0x09);
  Delay_ms(100);
}

// Display average Y-axis read value on UART
void Display_Y_Value(void) {
  UART1_Write_Text("Y:");
  IntToStr(readings[1], out);
  UART1_Write_Text(out);
  UART1_Write(0x09);
  Delay_ms(100);
}

// Display average z-axis read value on UART
void Display_Z_Value(void) {
  UART1_Write_Text("Z:");
  IntToStr(readings[2], out);
  UART1_Write_Text(out);
  UART1_Write(0x0D);
  UART1_Write(0x0A);
  Delay_ms(100);
}
void AccelInit(){
  // Initialize ADXL345 accelerometer

  if (ADXL345_Init() == 0) {
    UART1_Write_Text(codetxt_to_ramtxt("Accel module initialized.\r\n" ));
    Delay_ms(2000);
  }
  else {
    //  UART_Write_Text("Error during Accel module initialization.", 70, 100);
    UART1_Write_Text(codetxt_to_ramtxt("Error during initialization."));
    Delay_ms(2000);
  }
}
void main() {
  Delay_ms(150);

PortB = 0x00;

//  TRISC = 0x10;

  ACCEL_CS_Dir = 0;
  ACCEL_CS = 1;

  UART1_Init(9600);
  Delay_ms(100);                  // Wait for UART module to stabilize

  UART1_Write_Text(codetxt_to_ramtxt("Accel test starting...\r\n"));
  Delay_ms(500);

  SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_LOW_2_HIGH);

  AccelInit();
  Delay_ms(150);

  UART1_Write_Text(codetxt_to_ramtxt("Reading axis values...\r\n\r\n"));
  Delay_ms(2000);

  while(1) {
    Accel_Average();              // Calculate average X, Y and Z reads
    Display_X_Value();
    Display_Y_Value();
    Display_Z_Value();
  }
}
 
I just got a ADXL345 3-axis accelerometer yesterday. Did you find your problem?
 
You might try reading back your initiation bytes.
The device ID at register 0x00 should be 299.
Make sure POWER_CTL is 0x08, that turns things on.
I got mine working on a 16F628a. The program memory is FULL.
I'm trying to get it working on a 16F1827.
After initiation I can read the 229 device ID but BW_RATE and POWER_CTL are still at default settings. Its probably a timing thing.
 
Status
Not open for further replies.

Latest threads

Back
Top