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 support@ccsinfo.com

ADXL345 Digital Accelerometer Driver + Processing

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
cleberalbert



Joined: 25 Feb 2014
Posts: 34
Location: Brazil

View user's profile Send private message

ADXL345 Digital Accelerometer Driver + Processing
PostPosted: Wed Mar 26, 2014 2:15 pm     Reply with quote

This driver is for use with ADXL345 Digital Accelerometer using the I2C protocol.
The code was done on CCS 5.018, is commented and is working well, tested by PIC18F4520 and Processing 2.1.1 by serial port on a PC. The code for Processing (.pde) is also below.

This program can give the raw values, the three critical flight dynamics parameters (roll, pitch and yaw=0) and angles of rotation between the vector gravity and each sensor's axis (orthogonal coordinates system).

Code:

#include <18F4520.h>
#case

#FUSES HS
#FUSES PUT
#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 NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(crystal=20MHz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,ERRORS)
#use i2c(master, fast, sda=PIN_C4, scl=PIN_C3)

#include <math.h>

#define ADXL345_Address  0XA6 //0xA6 //0x53//0x3a
#define ACC_READ_ADDR  0XA7//0xA7 //0x53//0x3b
#define ACC_PWRCTRL_ADDR  0x2d
#define ACC_MEASURE_MODE  0x08
#define ACC_DATA_FORMAT  0x31
#define ACC_OUT_LSB_X 0x32
#define ACC_OUT_MSB_X 0x33
#define ACC_OUT_LSB_Y 0x34
#define ACC_OUT_MSB_Y 0x35
#define ACC_OUT_LSB_Z 0x36
#define ACC_OUT_MSB_Z 0x37
#define ACC_ALPHA  0.5

int8 accel_data[6]; // position 0,2 and 4 are respective x,y and z high significant bits. position 1,3 and 5 are respective x,y and z low significant bits.

signed int16 acc_x;
signed int16 acc_y;
signed int16 acc_z;

float acc_x1;
float acc_y1;
float acc_z1;
float acc_R;
float acc_teta=0;
float acc_gama=0;
float acc_fi=0;
float acc_roll=0;
float acc_pitch=0;
float acc_yaw=0;

void initializingADXL345();
void accelerometer();
void acce_cartesian_coordinates();
void acce_spherical_coordinates();
void acce_flight_coordinates();
void writeRegisterI2C(int8 deviceAddress, int8 address, int8 val);
int8 readRegisterI2C(int8 deviceAddress, int8 address);

void main()
{

initializingADXL345();// initialize

   while(TRUE)
   {
  output_high(PIN_A0);

  accelerometer();
  acce_spherical_coordinates();
  acce_flight_coordinates();

  output_low(PIN_A0);
   }
}

void initializingADXL345(){
// Tell the accelerometer to wake up
writeRegisterI2C(ADXL345_Address, ACC_DATA_FORMAT, 0X01);
writeRegisterI2C(ADXL345_Address, ACC_PWRCTRL_ADDR, ACC_MEASURE_MODE);
}

void writeRegisterI2C(int8 deviceAddress, int8 address, int8 val){
   i2c_start();               // start transmission to device
   i2c_write(deviceAddress);  // send device address
   i2c_write(address);        // send register address
   i2c_write(val);            // send value to write
   i2c_stop();                // end transmission
}

int8 readRegisterI2C(int8 deviceAddress, int8 address){
   int v;
   i2c_start();                  // start transmission to device
   i2c_write(deviceAddress);     // This is where you have to _write_ the register number you want
   i2c_write(address);           // register to read
   i2c_start();                  // restart - the bus is now set to _read_
   i2c_write(deviceAddress + 1); // now turn the bus round
   v = i2c_read(0);
   i2c_stop();                   // This will update x, y, and z with new values
   return v;
}

void accelerometer(){
// Read data from the accel
accel_data[0] = readRegisterI2C(ADXL345_Address, ACC_OUT_MSB_X); //most significant byte
accel_data[1] = readRegisterI2C(ADXL345_Address, ACC_OUT_LSB_X); //least significant byte
accel_data[2] = readRegisterI2C(ADXL345_Address, ACC_OUT_MSB_Y); //most significant byte
accel_data[3] = readRegisterI2C(ADXL345_Address, ACC_OUT_LSB_Y); //least significant byte
accel_data[4] = readRegisterI2C(ADXL345_Address, ACC_OUT_MSB_Z); //most significant byte
accel_data[5] = readRegisterI2C(ADXL345_Address, ACC_OUT_LSB_Z); //least significant byte

//Concatenate data
acc_x=make16(accel_data[0],accel_data[1]);
acc_y=make16(accel_data[2],accel_data[3]);
acc_z=make16(accel_data[4],accel_data[5]);

//Low Pass Filter
acc_x=acc_x*ACC_ALPHA+(acc_x*(1.0-ACC_ALPHA));
acc_y=acc_y*ACC_ALPHA+(acc_y*(1.0-ACC_ALPHA));
acc_z=acc_z*ACC_ALPHA+(acc_z*(1.0-ACC_ALPHA));

//Convert the values to versors
acc_R=sqrt((float)acc_x*(float)acc_x+(float)acc_y*(float)acc_y+(float)acc_z*(float)acc_z);
acc_x1=acc_x/acc_R;
acc_y1=acc_y/acc_R;
acc_z1=acc_z/acc_R;

printf("%ld %ld %ld\n",acc_x,acc_y,acc_z); //print the raw values
}

void acce_spherical_coordinates(){ //angles of rotation beetwen the vector gravity and each sensor's axis (orthogonal coordinates system).
acc_teta=acos(acc_x1)*180/PI;
acc_gama=acos(acc_y1)*180/PI;
acc_fi=acos(acc_z1)*180/PI;

//printf("%f, %f, %f\n",acc_teta,acc_gama,acc_fi);
}

void acce_flight_coordinates(){ //The three critical flight dynamics parameters are the angles of rotation in three dimensions about the vector gravity
acc_roll=180-(atan2(-acc_y1,acc_z1)*180.0)/PI;
acc_pitch=180-(atan2(acc_x1,sqrt((float)acc_y1*(float)acc_y1+(float)acc_z1*(float)acc_z1))*180.0)/PI;
acc_yaw=0;

if((acc_fi>90)&&(acc_fi<180)) acc_pitch=(acc_pitch-180)*(-1); //está no segundo ou terceiro quadrante. força range de 90 ate 270
if(acc_pitch<0) acc_pitch=acc_pitch+360; //está no quarto quadrante. força range de 270 ate 0

//printf("%f, %f, %f\n",acc_roll,acc_pitch,acc_yaw);
}


Processing code (.pde):

Code:

import processing.opengl.*;
import processing.serial.*;

Serial sp;
byte[] buff;
float[] r;

int SIZE = 150, SIZEX = 200;
int OFFSET_X = -28, OFFSET_Y = 9;    //These offsets are chip specific, and vary.  Play with them to get the best ones for you
long lastTime = 0;
void setup() {
  size(SIZEX, SIZE, P3D);
  sp = new Serial(this, "COM6",  9600);
  buff = new byte[128];
  r = new float[3];
  lastTime = millis();

}

float protz, protx;
void draw() {
  if ( millis() - lastTime > 1500 ) {
  //perspective( 45, 4.0/3.0, 1, 5000 );
  translate(SIZEX/2, SIZE/2, -400);
  background(0);
  buildShape(protz, protx);
 
    int bytes = sp.readBytesUntil((byte)10, buff);
    String mystr = (new String(buff, 0, bytes)).trim();
    if(mystr.split(" ").length != 3) {
      println(mystr);
      return;
    }
    setVals(r, mystr);
   
    float z = r[0], x = r[1];
    if(abs(protz - r[0]) < 0.05)
      z = protz;
     if(abs(protx - r[1]) < 0.05)
     x = protx;
    background(0); 
    buildShape(z, x);
   
     protz = z;     
     protx = x;
    //println(r[0] + ", " + r[1] + ", " + r[2]);
}}

void buildShape(float rotz, float rotx) {
  pushMatrix();
  scale(6,6,14);
  rotateZ(rotz);
  rotateX(rotx);
    fill(255);
     stroke(0);
     box(60, 10, 10);
     fill(0, 255, 0);
     box(10, 9, 40);
     translate(0, -10, 20);
     fill(255, 0, 0);
     box(5, 12, 10); 
  popMatrix();
}

void setVals(float[] r, String s) {
  int i = 0;
  r[0] = -(float)(Integer.parseInt(s.substring(0, i = s.indexOf(" "))) +OFFSET_X)*HALF_PI/256;
  r[1] = -(float)(Integer.parseInt(s.substring(i+1, i = s.indexOf(" ", i+1))) + OFFSET_Y)*HALF_PI/256;
  r[2] = (float) Integer.parseInt(s.substring(i+1));
 
 
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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