Skip to content

ADXL345 Accelerometer

Alan Yorinks edited this page Mar 2, 2016 · 6 revisions

The ADXL345 class is provided as a library class that allows control and monitoring of ADXL345 Accelerometers. It is a Xideco Universal i2c implementation that will allow simultaneous use of the ADXL345 on Arduino, Raspberry Pi, and BeagleBone MCUs from a single instance of this class. Range is set to 16 g.

This module will report:

  • board number
  • raw x,y,z values
  • accelerometer values for x,y,z expressed in g's
  • normalized value for x,y,z
  • pitch and roll angles

The class may be operated in a polled 'one-shot' mode, or it may be configured for continuous reading of data by providing a user callback function . If running continuously, it may be temporarily halted and restarted at anytime.

Here is some sample code utilizing this class. It is provided at the bottom of the adxl345.py file.

# a sample callback routine
def data_callback(data):
    p = data['pitch'] 
    r = data['roll'] 
    print('Pitch: {0}, Roll: {1}.'.format(p, r))
    # print(data['x_raw'], data['y_raw'], data['z_raw'])
    # print(data['x_a'], data['y_a'], data['z_a'])


# instantiate the device forcing the routing IP address and setting the data publisher
envelope to 'z'

device = ADXL345('192.168.2.192', data_publish_envelope='z')

try:

    # poll data for 10 iterations
    print("polling 10 times")

    # first initialize the device
    device.initialize_device()

    # now poll ten times and print to the console
    for x in range(0, 10):
        device.read_device()
        print(device.get_last_data())
        time.sleep(.1)

    print("continuous callback for 3 seconds")

    # to run continuous, initialize the device specifying a call back function
    device.initialize_device(data_callback)

    # start continuous operation with a delay after data reported of .001 seconds
    device.start_continuous(.001)

    time.sleep(3)

    # we can halt the continuous operation by calling stop_continuous
    print('halting for 3 seconds')
    device.stop_continuous()
    time.sleep(3)

    # We can re-enable by calling start_continuous
    print('enabling continuous for 3 seconds')
    device.start_continuous(.001)
    time.sleep(3)

    # Halt and then read the last data reported
    print('halting and reading the last value reported then wait 2 seconds')
    device.stop_continuous()
    print(device.get_last_data())
    time.sleep(2)

    # we are out of here
    print('exiting')
    device.clean_up()
    sys.exit(0)
except KeyboardInterrupt:
    device.clean_up()
    sys.exit(0)

Here is a simple ZeroMQ subscriber for the 'z' message envelopes published by the code above. Please note that the router IP address is hardcoded for this example.

# adxl345_monitor.py
import umsgpack
import zmq
import time
import sys

# connect to the router's publisher port (we are subscribing to it)
context = zmq.Context()
subscriber = context.socket(zmq.SUB)
connect_string = 'tcp://192.168.2.192:43125'
subscriber.connect(connect_string)

# set a filter for all mesages with the 'z' envelope
env_string = 'z'
envelope = env_string.encode()
subscriber.setsockopt(zmq.SUBSCRIBE, envelope)

# sit in a loop receiving output from the adxl345.
while True:
    try:
        msg = subscriber.recv_multipart(zmq.NOBLOCK)
        payload = umsgpack.unpackb(msg[1])
        print(payload)
    except KeyboardInterrupt:
        subscriber.close()
        context.term()
        sys.exit(0)
    # if no message is available, zeromq will throw this exception
    except zmq.error.Again:
        time.sleep(.001)


Here is some output from the simple subscriber:

{'pitch': 2, 'z_g': 0.096, 'board': 1, 'z_a': 0.9414, 'x_g': -0.004, 'y_a': -0.0785, 'y_raw': -2, 'roll': -4,
 'y_g': -0.008, 'x_a': -0.0392, 'x_raw': -1, 'z_raw': 24}
{'pitch': 2, 'z_g': 0.104, 'board': 1, 'z_a': 1.0199, 'x_g': -0.004, 'y_a': -0.0785, 'y_raw': -2, 'roll': -4,
 'y_g': -0.008, 'x_a': -0.0392, 'x_raw': -1, 'z_raw': 26}
{'pitch': 2, 'z_g': 0.112, 'board': 1, 'z_a': 1.0983, 'x_g': -0.004, 'y_a': -0.1177, 'y_raw': -3, 'roll': -6,
 'y_g': -0.012, 'x_a': -0.0392, 'x_raw': -1, 'z_raw': 28}
{'pitch': 0, 'z_g': 0.108, 'board': 1, 'z_a': 1.0591, 'x_g': 0.0, 'y_a': -0.1569, 'y_raw': -4, 'roll': -8,
 'y_g': -0.016, 'x_a': 0.0, 'x_raw': 0, 'z_raw': 27}
{'pitch': 0, 'z_g': 0.104, 'board': 1, 'z_a': 1.0199, 'x_g': 0.0, 'y_a': -0.1177, 'y_raw': -3, 'roll': -6,
 'y_g': -0.012, 'x_a': 0.0, 'x_raw': 0, 'z_raw': 26}
{'pitch': 0, 'z_g': 0.104, 'board': 1, 'z_a': 1.0199, 'x_g': 0.0, 'y_a': -0.1177, 'y_raw': -3, 'roll': -6,
 'y_g': -0.012, 'x_a': 0.0, 'x_raw': 0, 'z_raw': 26}
{'pitch': 0, 'z_g': 0.104, 'board': 1, 'z_a': 1.0199, 'x_g': 0.0, 'y_a': -0.1569, 'y_raw': -4, 'roll': -8,
 'y_g': -0.016, 'x_a': 0.0, 'x_raw': 0, 'z_raw': 26}