3-Assen versnellingsmeter (ADXL345)

De ADXL345 module sensor is een kleine 3-assige versnellingsmeter, ook wel accelerometer genoemd, die gebruikt wordt in elektronische controlesystemen van (mobiele) apparaattoepassingen zoals mobiele handsets, smartphones, spelapparaten, aanwijsapparaten, persoonlijke navigatieapparaten, bescherming van harde schijven, medische en industriële instrumentatie. De meest bekende toepassing is om beelden rechtopstaand weer te geven op tablets en smartphones.

De ADXL345 meet zowel statische versnelling als gevolg van zwaartekracht als dynamische versnelling als gevolg van beweging of schokken. Het kan worden gebruikt om lineaire versnelling in 3 assen, kanteling en vrije val van een object te detecteren. 

De richting van de 3 Assen

De sensor biedt vier meetbereiken: +/-2g, +/-4g, +/-8g en +/-16g. Het standaard meetbereik is +/-2g, wat kan worden gebruikt om versnellingen tot 19,6 m/s 2 in beide richtingen langs elke as te detecteren. De beschikbare resoluties zijn 10-bits voor +/-2g, 11-bits voor +/-4g, 12-bits voor +/-8g en 13-bits voor +/-16g bereik. De standaardresolutie is 10-bits, wat voor een bereik van +/- 2 g (standaard) een gevoeligheid van 3,9 mg/LSB mogelijk maakt. De standaard datasnelheid is 100 Hz. 

Interactie van de ADXL345 met de Raspberry Pi
Interactie van de ADXL345-sensor met de Raspberry Pi is vrij eenvoudig. De digitale sensor communiceert gegevens via I2C- en SPI-interfaces. In elke ADXL345-sensormodule zijn pinnen voor beide interfaces (I2C/TWI en SPI) en onderbrekingspinnen beschikbaar. De sensor ondersteunt zowel 3-draads als 4-draads SPI. Raspberry Pi heeft zowel I2C- als SPI-interfaces en beide kunnen worden gebruikt om met ADXL345 te praten.

In deze tutorial gebruiken we I2C om met ADXL345 te praten. De gebruikers-I2C van Raspberry Pi is beschikbaar op pinnen GPIO2 (pin 3) en GPIO3 (pin 5). GPIO2 is een seriële datalijn (SDA) en GPIO3 is een seriële kloklijn (SCL) van de I2C1. 

De ADXL345 vereist een bedrijfsspanning van 2,5 V die kan variëren van 2,0 V tot 3,6 V. De module kan worden voorzien van 3,3V-voeding met de gemeenschappelijke ground (GND) van de Raspberry Pi zelf, terwijl de I2C-kanalen direct kunnen worden aangesloten zonder dat er een extern pull-up-circuit nodig is.

Aansluittabel om de sensor met de Raspberry Pi te verbinden

Het I2C-adres van de ADXL345-sensor kan worden gevonden door te scannen naar beschikbare I2C-apparaten op Raspberry Pi na het aansluiten van de sensor. Een scan voor I2C-apparaten kan worden uitgevoerd op Raspberry Pi met behulp van i2c-tools. 

Installeer eerst de i2c-tools door het volgende commando uit te voeren in de Raspberry Pi Terminal:

sudo apt-get install -y i2c-tools

Voer nu de volgende opdracht uit om de aangesloten I2C-module te scannen:

sudo i2cdetect -y 1

De tool retourneert een tabel met adressen van aangesloten I2C-slave-apparaten, zoals weergegeven in de onderstaande afbeelding:

Sensor configureren
Ik ga hier niet bespreken hoe je de sensor kunt configureren. Als je wilt weten hoe dit werkt kun je dit uitgebreid op het web vinden. Deze tutorial is gebaseerd op een artikel van de engineersgarage. Hier leggen ze op detail uit hoe het configureren werkt.

De code
Als het goed is heb je een gekoppelde ADXL345-versnellingsmeter met de Raspberry Pi en weet je of het I2C-adres 0x53 of 0x1D is. De ADXL345-sensor die ik voor deze tutorial gebruik heeft een I2C-adres van 0x53

Het Python script hieronder configureert de ADXL345-sensor tot een meetbereik van +/- 2 g en gebruikt een resolutie van 10 bits. Het script leest versnellingsgegevens van alle assen en zet deze om in zwaartekracht eenheden.

import smbus
import time
from time import sleep
import sys
import subprocess as sp

bus = smbus.SMBus(1)

bus.write_byte_data(0x53, 0x2C, 0x0B)
value = bus.read_byte_data(0x53, 0x31)
value &= ~0x0F;
value |= 0x0B;
value |= 0x08;
bus.write_byte_data(0x53, 0x31, value)
bus.write_byte_data(0x53, 0x2D, 0x08)

def getAxes():
    bytes = bus.read_i2c_block_data(0x53, 0x32, 6)

    x = bytes[0] | (bytes[1] << 8)
    if(x & (1 << 16 - 1)):
        x = x - (1<<16)

    y = bytes[2] | (bytes[3] << 8)
    if(y & (1 << 16 - 1)):
        y = y - (1<<16)

    z = bytes[4] | (bytes[5] << 8)
    if(z & (1 << 16 - 1)):
        z = z - (1<<16)

    x = x * 0.004
    y = y * 0.004
    z = z * 0.004

    x = x * 9.80665
    y = y * 9.80665
    z = z * 9.80665

    x = round(x, 4)
    y = round(y, 4)
    z = round(z, 4)

    # Wis scherm
    tmp = sp.call('clear',shell=True)
    print ("\033[1;32m")
    print ("   x = %.3f ms2" %x)
    print ("   y = %.3f ms2" %y)
    print ("   z = %.3f ms2" %z)

    return {"x": x, "y": y, "z": z}

try:
    while True:
        getAxes()
        time.sleep(0.5)
except KeyboardInterrupt:
    sys.exit()

Eenmaal uitgepakt en in een directorie geplaatst, start je het script in de terminal met:

python adxl.py

Het resultaat is een eenvoudige output met x-, y- en z-waarden die sterk variëren als de sensor in alle richtingen gekeerd wordt.

Mocht je nog vragen hebben, stel ze dan hieronder.

Succes met het project!

Have A Nice Day!