Collects 30 samples from ADXL345 (3 axis Accelerometer, Sprakfun SEN-09836 breakout board) based on interrupt and presents the data.

Dependencies:   mbed

main.cpp

Committer:
GerritPathuis
Date:
2017-09-22
Revision:
3:f12b8859ecb2
Parent:
2:4ed2dd2347f3

File content as of revision 3:f12b8859ecb2:

/* This program collects 30 samples from a Triple Axis
*  Accelerometer Breakout ADXL345 sensor (Sparkfun.com SEN-09836)
*  The program is connected to a mbed via 4-wire spi.
*  The data is collected via DATA_READY interrupt at maximum speed
*  of the sensor.
*/

#include "mbed.h"
#define NOSAMPLES           30
#define DEVID               0x00
#define ADXL345_SPI_READ    0x80
#define ADXL345_SPI_WRITE   0x00
#define ADXL345_MULTI_BYTE  0x60
#define ADXL345_DATAX0_REG  0x32

/////////4-wire SPI///////////
//// Hardware connections ////
// ADXL345
// Signal ---------- mbed pin
// Vcc  ------------ mbed Vout
// Gnd  ------------ mbed Gnd
// SDA  ------------ mbed p5
// SDO  ------------ mbed p6
// SCL  ------------ mbed p7
// CS   ------------ mbed p8
// INTI ------------ mbed p9          // ADXL345 gives a interrupt when ready
//////////////////////////////

SPI spi(p5,p6,p7);      // mosi, miso, sclk
DigitalOut cs(p8);      // cs
InterruptIn event(p9);
Serial pc(USBTX, USBRX);

void int_service(void);
void init_SPI_ADXL345(void);
int oneByteRead(int address);
void oneByteWrite(int address, char data);
void multiByteRead(int startAddress, char* buffer, int size);
void multiByteWrite(int startAddress, char* buffer, int size);

Timer timer;
struct ttstamp {
    int x;
    int y;
    int z;
    short int time;
} data [NOSAMPLES];

int acc[3] = {0, 0, 0};
int interrupt_counter, tstamp;

int main() {
    int i;
    float xx, yy, zz;

    pc.baud(9600);
    pc.format(8,Serial::None,1);

    event.rise(&int_service);   // set the interrupt handling
    init_SPI_ADXL345();         // init the ADXL345 sensor

    ////////////////// get the data //////////////////////
    interrupt_counter= -1;
    timer.start();
    pc.printf("\n\rBussy collecting data\n\r ");
    while (interrupt_counter < (NOSAMPLES-1))
        pc.printf(".");

    ///////////////// present the data ////////////////////
    // Full scale 16g is 1024 positions
    pc.printf("\r");
    for (i=0; i <NOSAMPLES; i++) {
        xx= data[i].x * 0.004;  // Full-res, sign extended values,   4.0 mg/LSB
        yy= data[i].y * 0.004;
        zz= data[i].z * 0.004;

        pc.printf("Sample= %03d, x= %+06.3f, y=%+06.3f, z=%+06.3f, t= %5d us\n\r", i, xx, yy, zz, data[i].time);
        //pc.printf("Sample= %03d, x= %+06d, y=%+06d, z=%+06d \n\r", i, data[i].x, data[i].y, data[i].z);
    }
}

///////////////////// Interrupt service /////////////////////
///////////////////// store data in array ///////////////////
///////////////////// clear interrups ///////////////////////
void int_service(void) {
    char buffer[6];

    interrupt_counter += 1;
    if (interrupt_counter == (NOSAMPLES -1))
        oneByteWrite(0x2E, 0x00);                   // InterruptEnableControl, disable all interrupts

    multiByteRead(ADXL345_DATAX0_REG, buffer, 6);   // read the DATAX,DATZ,DATAY register
    acc[0] = (int)buffer[1] << 8 | (int)buffer[0];
    acc[1] = (int)buffer[3] << 8 | (int)buffer[2];
    acc[2] = (int)buffer[5] << 8 | (int)buffer[4];

    tstamp= timer.read_us();
    // stora data in array
    data[interrupt_counter].x = (int16_t) acc[0];
    data[interrupt_counter].y = (int16_t) acc[1];
    data[interrupt_counter].z = (int16_t) acc[2];
    data[interrupt_counter].time = tstamp;

    oneByteRead(0x30);    // clear interrupt sources
}

void init_SPI_ADXL345() {
    char readID;
    int ox, oy, oz;     

    spi.frequency(5000000);        // max 5 mHz page 8 of the ADXL345 datasheet
    spi.format(8,3);
    wait(0.1);

    readID = oneByteRead(DEVID);
    if (readID == 0xE5)
        pc.printf("\n\rConnected to ADXL345\n\r");
    else
        pc.printf("Sorry not connected to ADXL345 !!!(readID= %d)\n\r", readID);

    // set up ADXL345
    ox = 13;    // Offset X direction, not yet two's complement, (15.6 mg/LSB)
    oy = 2;     // Offset Y direction, not yet two's complement, (15.6 mg/LSB)
    oz = 3;     // Offset Z direction, not yet two's complement, (15.6 mg/LSB)
      
    oneByteWrite(0x1E, -ox);   // Offset X in two's complement 
    oneByteWrite(0x1F, -oy);   // Offset Y in two's complement
    oneByteWrite(0x20, -oz);   // Offset Z in two's complement

    oneByteWrite(0x2D, 0x00);   // PowerControl, Go into standby mode to configure the device.
    oneByteWrite(0x2E, 0x00);   // InterruptEnableControl, disable all interrupts

    oneByteWrite(0x1D, 0x01);   // TRESH_TAP is set to 1
    oneByteWrite(0x21, 0x00);   // DUR disable
    oneByteWrite(0x22, 0x00);   // LATENT disable
    oneByteWrite(0x23, 0x00);   // WINDOW disable
    oneByteWrite(0x24, 0x01);   // TRESH_ACT is set to 1
    oneByteWrite(0x25, 0x01);   // TRESH_INACT is set to 1
    oneByteWrite(0x26, 0x01);   // TIME_INACT is set to 1
    oneByteWrite(0x27, 0x00);   // ACT_INACT_CTL disable
    oneByteWrite(0x28, 0x01);   // TRESF_FF is set to 1
    oneByteWrite(0x29, 0x01);   // TIME_FF is set to 1
    oneByteWrite(0x2A, 0x00);   // TAP_AXES disable

    oneByteWrite(0x31, 0x0B);   // setDataFormatControl, 4-wire SPI, Full res, Right justify, +/-16g, 4 mg/LSB.
    oneByteWrite(0x2F, 0x00);   // setInterruptMappingControl, send ALL interrupt to pin INT1
    oneByteWrite(0x38, 0x01);   // setFifoControl, Bypass, Int pin 1, 1 sample
    oneByteWrite(0x2C, 0x0F);   // setDataRate, 3.2kHz data rate
    oneByteWrite(0x2D, 0x00);   // setPowerControl, measurement mode (start measuring) (se page 17 sleep bit)
    oneByteWrite(0x2D, 0x08);   // setPowerControl, measurement mode (start measuring)
    oneByteWrite(0x2E, 0x80);   // setInterruptEnableControl, enable interrupt DATA_READY
}

int oneByteRead(int address) {
    int tx = (ADXL345_SPI_READ | (address & 0x3F));
    int rx = 0;

    cs = 0;             //Send address to read from.
    spi.write(tx);      //Read back contents of address.
    rx = spi.write(0x00);
    cs = 1;
    return rx;
}

void oneByteWrite(int address, char data) {
    int tx = (ADXL345_SPI_WRITE | (address & 0x3F));

    cs = 0;             //Send address to write to.
    spi.write(tx);      //Send data to be written.
    spi.write(data);
    cs = 1;
}

void multiByteRead(int startAddress, char* buffer, int size) {
    int tx = (ADXL345_SPI_READ | ADXL345_MULTI_BYTE | (startAddress & 0x3F));

    cs = 0;             //Send address to start reading from.
    spi.write(tx);
    for (int i = 0; i < size; i++) {
        buffer[i] = spi.write(0x00);
    }
    cs = 1;
}

void multiByteWrite(int startAddress, char* buffer, int size) {
    int tx = (ADXL345_SPI_WRITE | ADXL345_MULTI_BYTE | (startAddress & 0x3F));

    cs = 0;             //Send address to start reading from.
    spi.write(tx);
    for (int i = 0; i < size; i++) {
        buffer[i] = spi.write(0x00);
    }
    cs = 1;
}