0

I've been trying to use a Raspberry Pi 3 B+ to get data from an accelerometer, namely an ADXL 357, via I2C but the problem is that the data rate is about 200 Hz or even less. I tried to set the accelerometer to high speed mode and it didn't help. I also tried to change the baudrate in the Rasberry but I wouldn't go higher than 2.000.000 or something similar.

import smbus
import time
import csv
import RPi.GPIO as GPIO
from datetime import datetime



i2c_ch=1

i2c_adress = 0x1D

acc_range = 0x81 # 0x01->8g, 0x02->20g, 0x03->40g

# I'm putting 0x81 rather than 0x01 to set it to high speed mode rather than fast mode

bus = smbus.SMBus(i2c_ch)



#val = bus.read_i2c_block_data(i2c_adress,reg_range,3)
def configure_raspberry():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(8,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(18,GPIO.OUT)

def configure_adxl() :

    #reset
    bus.write_byte_data(i2c_adress,0x2f,0x52)

    #set filter

    bus.write_byte_data(i2c_adress,0x28,0x01)

    # set i2c speed to normal and acceleration range
    bus.write_byte_data(i2c_adress,0x2c,acc_range)

    #set in measurement mode (not standby)
    bus.write_byte_data(i2c_adress,0x2d,0x00)

def get_temperature() :

    temp1 = bus.read_byte_data(i2c_adress,0x06)
    temp2 = bus.read_byte_data(i2c_adress,0x07)
    temp = (temp1 << 8) | temp2
    temp = (float)(1852 - temp)/9.05 + 25
    return temp

def get_x_accel() :
    x1 = bus.read_byte_data(i2c_adress,0x08)
    x2 = bus.read_byte_data(i2c_adress,0x09)
    x3 = bus.read_byte_data(i2c_adress,0x0A)
    x = (x1 << 12) | (x2 << 4) | (x3 >> 4)
    if(x & 0x80000) :
        x = (x & 0x7ffff) - 0x80000
    return x

def get_y_accel() :
    y1 = bus.read_byte_data(i2c_adress,0x0B)
    y2 = bus.read_byte_data(i2c_adress,0x0C)
    y3 = bus.read_byte_data(i2c_adress,0x0D)
    y = (y1 << 12) | (y2 << 4) | (y3 >> 4)
    if(y & 0x80000) :
        y = (y & 0x7ffff) - 0x80000
    return y

def get_z_accel() :
    z1 = bus.read_byte_data(i2c_adress,0x0E)
    z2 = bus.read_byte_data(i2c_adress,0x0F)
    z3 = bus.read_byte_data(i2c_adress,0x8)
    z = (z1 << 12) | (z2 << 4) | (z3 >> 4)
    if(z & 0x80000) :
        z = (z & 0x7ffff) - 0x80000
    return z

def convert_in_g(accel) :
    if(acc_range == 0x01) :
        accel = (float)(accel)/0x7ffff*8
    if(acc_range == 0x02) :
        accel = (float)(accel)/0x7ffff*20
    if(acc_range == 0x03) :
        accel = (float)(accel)/0x7ffff*40
    return accel



configure_adxl()
configure_raspberry()

while True :
        date = datetime.now()

        timestamp = datetime.timestamp(date)
        dateStr = date.strftime("%d-%b-%Y (%H:%M:%S.%f)")

        name = dateStr +'.csv'


        if GPIO.input(8) == GPIO.HIGH :
            f = open(name,'a',newline = "")
            c = csv.writer(f)

            time.sleep(0.08)
            while GPIO.input(8) == GPIO.HIGH :
                GPIO.output(18,GPIO.HIGH)
                temp = get_temperature()
                print("temperature uncalibrated : ",temp)
                print("_________________________________________________________")
                print("\n")
                x = get_x_accel()
                print("x raw acceleration : ",x)
                x = convert_in_g(x)
                print("x acceleration in g : ",x)
                print("\n")
                y = get_y_accel()
                print("y raw acceleration : ",y)
                y = convert_in_g(y)
                print("y acceleration in g : ",y)
                print("\n")
                z = get_z_accel()
                print("z raw acceleration : ",z)
                z = convert_in_g(z)
                print("z acceleration in g : ",z)
                print("\n\n\n\n")
                date2 = datetime.now()

                timestamp = datetime.timestamp(date2)
                c.writerow([timestamp,x,y,z])
            f.close()
            GPIO.output(18,GPIO.LOW)
  • 1
    200Hz data rate should be possible with 100 kHz I2C, so it's not the baudrate problem. You are likely using inefficient I2C libraries/drivers. – Dmitry Grigoryev Aug 30 at 10:23
  • Can you please tell me how you do you convert baudrate from bit to Hz ? – MOHAMED KOUBAA Aug 30 at 11:15
  • I checked the datasheet. They are advertising 200Hz data rate with 100 kHz I2C there. – Dmitry Grigoryev Aug 30 at 11:22
  • You are asking us to guess what you are doing. You need to provide detail. – joan Aug 30 at 12:09
  • @DmitryGrigoryev but I2C in high speed mode should support up to 3.4 MHz , are the any I2C libraries you can suggest – MOHAMED KOUBAA Aug 30 at 14:02
0

Question

I can only get ADXL357 data rate 200Hz. Can I do better?

Datasheet Spec

(1) ODR (Output Data Rate) is 4kHz. (Table 2, Page 4)

(2) I2C speed standard rate 100kHz, max 3.4MHz. (Page 26)

Reason

Rpi3B+, because of a design bug, has a I2C flat rate of ridiculously low standard 100kHz. Yes, you cannot adjust I2C speed for Rpi3B+ stretch.

IT IS A BUG.

The official instruction tells you how to set to speed to 400kHz or higher. I have checked with scope that it does not work. I have also read about this bug in other forums, as reported by very experienced users.

Solution

Upgrade to Rpi4B, then you can set higher I2C speed, therefore higher ADXL357 output data rate.

References

(1) ADXL356/ADXL357 3 Axis MEMS Accelerometers Data Sheet - Analog Devices

https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL356-357.pdf

(2) ADXL345 3-Axis, Digital Accelerometer Data Sheet - Analog Devices

https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf

(3) Adafruit 9-DOF accelerometer/magnetometer/gyroscope sensor Forum Discussion

Adafruit 9-DOF or other accelerometer/magnetometer/gyroscope sensor for Raspberry PI 2/3 with Windows IoT

(4) Rpi4B Raspbian 10 buster circuit-python-blinka installation problem (BNO0955 9DOF) Forum Discussion

Rpi4B Raspbian 10 buster circuit-python-blinka installation problem

(5) SparkFun Triple Axis Accelerometer Breakout - ADXL345 $19

https://www.sparkfun.com/products/9836

(6) SparkFun ADXL345 Hookup Guide

https://learn.sparkfun.com/tutorials/adxl345-hookup-guide

(7) SparkFun Accelerometer, Gyro and IMU Buying Guide

https://www.sparkfun.com/pages/accel_gyro_guide

(8) SparkFun Accelerometers Catalog

https://www.sparkfun.com/categories/80

AdaFruit ADXL345 - Triple-Axis Accelerometer (+-2g/4g/8g/16g) w/ I2C/SPI - $18

https://www.adafruit.com/product/1231

(10) AdaFruit ADXL345 Digital Accelerometer Learning Notes

https://learn.adafruit.com/adxl345-digital-accelerometer/overview

(11) AdaFruit I2C Addresses List

https://learn.adafruit.com/i2c-addresses/the-list

.END

  • So the only solution I have is to buy the new Rpi 4B ? – MOHAMED KOUBAA Aug 30 at 14:03
  • Well, I would suggest that we first confirm a couple of things. First you might like to read the following post, to make sure you understand and agree on what I complain about the Rpi3 I2C speed no setting bug. RASPBERRY PI3 I2C BAUD RATE SETTING Postby samtal » 2018-Aug-04 Sat 1:45 pm raspberrypi.org/forums/… – tlfong01 Aug 30 at 14:16
  • Second, you might like to read the datasheet to understand and agree on what I am saying about (1) the AXDL357 output data rate maximum of 4k samples per seconds, (2) AXDL can take from 100kHz and higher, to a maximum of 3.4 MHz. – tlfong01 Aug 30 at 14:22
  • Thirdly, you might like to add a listing you working program to your question. I can try to see if there is any way of increasing the sampling rate. If I see your program is OK, and that using Rpi4 to test higher I2C speed is likely to be a good thing to do. Then go to step 4. – tlfong01 Aug 30 at 14:26
  • Right now I am using a Rpi4B to test some I2C devices. I can try to run your Rpi3 AXDL357 program on my Rpi4, with I2C set to a higher speed and see if can at least run (without the ADXL357). – tlfong01 Aug 30 at 14:31

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.