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();
  }
}
 
Just browsing the datasheet... Register 0x27 "ACT_INACT_CTL" sets the activity of the axies... the default of 0 turns the activity off...
 
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.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…