2016年2月26日 星期五

using wiringpi to access adxl345 on raspberry



為了速度....所以把 python code 轉成  c code....

但可能bottle-neck 還是在i2c 的protocol 上面


安裝wiringPi 請參考這篇  安裝wiringPi

wiringPi 使用I2C 請參考這篇wiringPi use i2c

 compile 的指令如下:

 gcc -Wall -o adxl345 main.cpp adxl345.cpp -lwiringPi
 sudo ./adxl345 

sample code 如下:
main.cpp
=======================
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiI2C.h>
#include <string.h>
#include "./adxl345.h"


int main (void)
{
int fd_adxl345 ;
struct  acc_dat  gdata ;
 fd_adxl345 = wiringPiI2CSetup(0x53);
  //printf("%d",fd_adxl345);

  ADXL345 adxl345(fd_adxl345);
  gdata = adxl345.getAxes(true);

  printf("x : %f g\n",gdata.x);
  printf("y : %f g\n",gdata.y);
  printf("z : %f g\n",gdata.z);
}

=======================


adxl345.h
==============================
#ifndef  __ADXL345
#define __ADXL345

#include <wiringPiI2C.h>
#include <math.h>
#include <stdio.h>

#define EARTH_GRAVITY_MS2    9.80665
#define SCALE_MULTIPLIER     0.004

#define DATA_FORMAT          0x31
#define BW_RATE              0x2C
#define POWER_CTL            0x2D

#define BW_RATE_1600HZ       0x0F
#define BW_RATE_800HZ        0x0E
#define BW_RATE_400HZ        0x0D
#define BW_RATE_200HZ        0x0C
#define BW_RATE_100HZ        0x0B
#define BW_RATE_50HZ         0x0A
#define BW_RATE_25HZ         0x09

#define RANGE_2G             0x00
#define RANGE_4G             0x01
#define RANGE_8G             0x02
#define RANGE_16G            0x03

#define MEASURE              0x08
#define AXES_DATA            0x32


struct acc_dat{
        double x;
        double y;
        double z;
};

class ADXL345{

public:
    int FD_ADDR;
    ADXL345(int addr);
    void enableMeasurement();
    void setBandwidthRate(int rate_flag);
    void setRange(int range_flag);
    //struct acc_dat getAxes(bool gforce = false);
    struct acc_dat getAxes(bool gforce);
};

#endif
================================================
adxl345.cpp

#include "./adxl345.h"

ADXL345::ADXL345(int addr)
{
    FD_ADDR = addr;
    setBandwidthRate(BW_RATE_100HZ);
    setRange(RANGE_2G);
    enableMeasurement();

}
void ADXL345::enableMeasurement()
{
     wiringPiI2CWriteReg8(FD_ADDR,POWER_CTL,MEASURE);
}

void ADXL345::setBandwidthRate(int rate_flag)
{
     //printf("%d",rate_flag);
     wiringPiI2CWriteReg8(FD_ADDR,BW_RATE,rate_flag);
}

void ADXL345::setRange(int range_flag)
{
        int value;
        value = wiringPiI2CReadReg8(FD_ADDR, DATA_FORMAT);
        value &= ~0x0F;
        value |= range_flag;
        value |= 0x08;

//        printf("set range value : %d",value);
        wiringPiI2CWriteReg8(FD_ADDR, DATA_FORMAT, value);
}

struct acc_dat ADXL345::getAxes(bool gforce = false)
{
        double dx,dy,dz;
        struct acc_dat dat;
        int x,y,z;
        char bytes[6];
        bytes[0] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA);
        bytes[1] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+1);
        bytes[2] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+2);
        bytes[3] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+3);
        bytes[4] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+4);
        bytes[5] = wiringPiI2CReadReg8(FD_ADDR, AXES_DATA+5);

        //printf("%d\n",bytes[0]);
        //printf("%d\n",bytes[1]);
        x = bytes[0] | (bytes[1] << 8);
        if(x & (1<<15))
            x = x - (1<<16);
        //printf("%d\n",x);

        y = bytes[2] | (bytes[3] << 8);
        if(y & (1<<15))
            y = y - (1<<16);

        z = bytes[4] | (bytes[5] << 8);
        if(z & (1<<15))
            z = z - (1<<16);

        dx = (double)x * SCALE_MULTIPLIER;
        dy = (double)y * SCALE_MULTIPLIER;
        dz = (double)z * SCALE_MULTIPLIER;

        if (gforce == false)
        {
            dx = dx * EARTH_GRAVITY_MS2;
            dy = dy * EARTH_GRAVITY_MS2;
            dz = dz * EARTH_GRAVITY_MS2;
        }
        dat.x = (dx);
        dat.y = (dy);
        dat.z = (dz);

        return dat;
}
=============================================

沒有留言:

張貼留言