為了速度....所以把 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;
};
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;
{
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;
}
=============================================
沒有留言:
張貼留言