-1

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)
Fred
  • 4,422
  • 16
  • 29
  • 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 '19 at 10:23
  • Can you please tell me how you do you convert baudrate from bit to Hz ? – MOHAMED KOUBAA Aug 30 '19 at 11:15
  • I checked the datasheet. They are advertising 200Hz data rate with 100 kHz I2C there. – Dmitry Grigoryev Aug 30 '19 at 11:22
  • You are asking us to guess what you are doing. You need to provide detail. – joan Aug 30 '19 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 '19 at 14:02
  • @joan I want to get data from my ADXL 357 with the highest possible ODR. Sadly i haven't been able to get any better than 200 Hz. I tried bumping the baudrate but that didn't help – MOHAMED KOUBAA Aug 30 '19 at 14:02
  • I'll comment one more time. You need to provide detail. Show us the software you are using. Show us what we need to know to provide help. – joan Aug 30 '19 at 14:22

1 Answers1

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

tlfong01
  • 4,384
  • 3
  • 9
  • 23
  • So the only solution I have is to buy the new Rpi 4B ? – MOHAMED KOUBAA Aug 30 '19 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 https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=219675&p=1348991&hilit=i2c+speed+100kHz#p1348848 – tlfong01 Aug 30 '19 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 '19 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 '19 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 '19 at 14:31
  • I just added the code to the post – MOHAMED KOUBAA Aug 30 '19 at 14:35
  • I don't know how you can do that , but it would really be great – MOHAMED KOUBAA Aug 30 '19 at 14:47
  • I must confess that I have been playing with I2C/SPI sensors for one hobbyist year, but I am a MEMS gyro/accelero newbie. You might like to read references (3), (4) – tlfong01 Aug 30 '19 at 15:04
  • Bed time. See you tomorrow. – tlfong01 Aug 30 '19 at 15:10
  • ADXL357 can also do SPI, up to 10MHz. So you can do minor changes to your program and test again, in SPI mode. – tlfong01 Aug 31 '19 at 00:55
  • @MOHAMED KOUBAA, Thank you for your posted code, which I think OK. If your code can do 200sps at I2C speed 100kHz, then of course your code can do higher, WITHOUT changing the code, but just increase I2C speed, to 200kHz, say. So the root cause or limitation is that Rpi3B+ stretch cannot change I2C speed. Switching to Rpi4B buster and your problem should be solved. – tlfong01 Oct 02 '19 at 01:58