2

I have a Kistler type 8921 which produces 1g (10m/s2) RMS (at 159 Hz). The ADXL345/Raspberry Pi 3 setup should produce similar g's, but currently doesn't.

enter image description here

As can be seen, it is not just about a factor of 10 (x10). It should generate 1g rms, and 1.41g Pk. The calibrator has been checked and verified. The offset doesn't matter in this context either (so small that it's negligible).

I guess it is the input for sensitivity of the MEMS sensor, settings in the py-script or Matlab script which is wrong. But what? Is there something I am missing out on? Have obviously spend a lot of time debugging and reading on the internet about this issue.

I use: +/-16g, 10 bit resolution:

bitsresolution=10;
Grange=16; % +/-g
Grange/(2^bitsresolution)

And therefore I believe that the data from the ADXL345 shown be computed in g's as follows:

Gx=x*(Grange/(2^bitsresolution));

See the attached Matlab MWE.

The linked data sheet:

https://www.dropbox.com/s/gath8jtrfi58i2r/10bit16g.csv?dl=0

contains about 20 seconds of x,y,z data which 0g in x-and y-direction, and 1g in z-direction. This script is then imported into the attached Matlab MWE.

Matlab MWE which imports these data and plots calibrated accelerometer data:

clear all; close all; clc

data=csvread('10bit16g.csv');

x=data(:,1);
y=data(:,2);
z=data(:,3);
t=data(:,4);

%% +/-16g

% % % % 2g, 3.9mG/LSB
% % % x=x*0.00390625;
% % % y=y*0.00390625;
% % % z=z*0.00390625;

% 16g, 31.2mG/LSB
x=x*0.0312;
y=y*0.0312;
z=z*0.0312;

figure; hold on
plot(t,x,'k-')
plot(t,y,'b-')
plot(t,z,'r-')
xlabel('Time [s]');
ylabel('Amplitude Pk-Pk [g]');
legend('x','y','z');
grid on;

%% Grange

% Gs = Measurement Value * (G-range/(2^10))
bitsresolution=10;
Grange=16; % +/- g
Grange/(2^bitsresolution)
Gx=x*(Grange/(2^bitsresolution));
Gy=y*(Grange/(2^bitsresolution));
Gz=z*(Grange/(2^bitsresolution));

figure; hold on
plot(t,Gx,'k-')
plot(t,Gy,'b-')
plot(t,Gz,'r-')
xlabel('Time [s]');
ylabel('Amplitude Pk-Pk [g]');
legend('x','y','z');
grid on;

Python MWE:

 from __future__ import division
import spidev, datetime, time

# Setup SPI
spi = spidev.SpiDev()
spi.open(0,0)
spi.mode = 3

# Constants
accres = 16
accrate = 15        

# Initialize the ADXL345
def initadxl345():

    # Set data rate (accrate=15 -> 3200 Hz, 14=1600 Hz, 13=800 Hz, 12=400 Hz, 11=200 Hz, 10=100 Hz etc.)
    spi.xfer2([44, accrate])

    # Enable full range (10 bits resolution) and +/- 16g 4 LSB
    spi.xfer2([49, accres])

# Read the ADXL x-y-z axia
def readadxl345():
    rx = spi.xfer2([242,0,0,0,0,0,0])

    out = [rx[1] | (rx[2] << 8),rx[3] | (rx[4] << 8),rx[5] | (rx[6] << 8)]
    # Format x-axis
    if (out[0] & (1<<16 - 1 )):
        out[0] = out[0] - (1<<16)
    # Format y-axis
    if (out[1] & (1<<16 - 1 )):
        out[1] = out[1] - (1<<16)
    # Format z-axis
    if (out[2] & (1<<16 - 1 )):
        out[2] = out[2] - (1<<16)

    return out

# Initialize the ADXL345 accelerometer
initadxl345()

timeout=0.0003125/2 # timeout=1/samplerate=>not sufficient measurements. Half the time is sufficient (don't know why!)

timetosend = 1

while(1):
   with open('/proc/uptime', 'r') as f: # get uptime
       uptime_start = float(f.readline().split()[0])
   uptime_last = uptime_start
   active_file_first = "10bit" + str(accres) + 'g' + '.csv'
   wStream = open('/var/log/sensor/' + active_file_first,'wb')
   while uptime_last < uptime_start + timetosend:

       time1 = str(datetime.datetime.now().strftime('%S.%f'))
       axia = readadxl345()

       wStream.write(str(axia[0])+','+str(axia[1])+','+str(axia[2])+','+time1+',\n')                   

       # Print data every "timeout" second
       elapsed = time.clock()
       current = 0
       while(current < timeout):
       current = time.clock() - elapsed
  • is this the wrong forum, or should I rephrase? – Stefan Feb 11 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.