ADXL345 Accelerometer met Arduino: Oriëntatie Tracking Stap-voor-Stap
In deze handleiding leer je hoe je hoek meet en oriëntatie trackt met Arduino en de ADXL345 Accelerometer. Bekijk de video of lees de handleiding voor details.
Overzicht
Eerst uitleg over sensorwerking en data uitlezen, daarna 3D-visualisatie van de accelerometer-oriëntatie in Processing.

Hoe de ADXL345 Accelerometer Werkt
De ADXL345 is een 3-as accelerometer die statische en dynamische versnellingskrachten meet. Aardzwaartekracht = statische kracht (voorbeeld). Dynamische krachten: trillingen, bewegingen.

Eenheid: m/s². Sensoren drukken uit in "g" (zwaartekracht). 1g = 9.8 m/s².
Sensor vlak, Z-as omhoog (tegenover zwaartekracht) → Z-output = 1g. X en Y = 0g (zwaartekracht loodrecht op deze assen).

Sensor omgekeerd → Z = -1g. Outputs variëren van -1g tot +1g afhankelijk van oriëntatie ten opzichte van zwaartekracht.

Met deze data en trigonometrie bereken je de sensorhoek.
ADXL345 Data Uitlezen met Arduino
I2C-communicatie → 2 datadraden + 2 voedingsdraden.

Componenten: ADXL345 Accelerometer, Arduino Board, Breadboard en Jumper Draden.
ADXL345 Arduino Code
/* Arduino en ADXL345 Accelerometer Tutorial
* by Dejan, https://howtomechatronics.com
*/
#include <Wire.h>
int ADXL345 = 0x53; // I2C adres
float X_out, Y_out, Z_out;
void setup() {
Serial.begin(9600);
Wire.begin();
// ADXL345 in meetmodus zetten
Wire.beginTransmission(ADXL345);
Wire.write(0x2D); // POWER_CTL Register
Wire.write(8); // Bit D3 HIGH (8dec = 00001000b) voor meting enable
Wire.endTransmission();
delay(10);
}
void loop() {
// Accelerometer data lezen
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start register ACCEL_XOUT_H
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // 6 registers
X_out = (Wire.read() | Wire.read() << 8); X_out = X_out / 256; // +/-2g: /256
Y_out = (Wire.read() | Wire.read() << 8); Y_out = Y_out / 256;
Z_out = (Wire.read() | Wire.read() << 8); Z_out = Z_out / 256;
Serial.print("Xa= "); Serial.print(X_out);
Serial.print(" Ya= "); Serial.print(Y_out);
Serial.print(" Za= "); Serial.println(Z_out);
}
Beschrijving: Wire.h voor I2C. I2C-adres uit datasheet. In setup(): Wire init, sensor in meetmodus via POWER_CTL register (0x2D), bit D3 HIGH (waarde 8).

Wire.beginTransmission(ADXL345);
Wire.write(0x2D);
Wire.write(8);
Wire.endTransmission();
In loop(): data uitlezen. Elke as in 2 registers (adressen uit datasheet).

Start register 0x32, requestFrom() voor 6 registers. Bytes combineren (two's complement).
X_out = (Wire.read() | Wire.read() << 8); X_out = X_out / 256;
Y_out = (Wire.read() | Wire.read() << 8); Y_out = Y_out / 256;
Z_out = (Wire.read() | Wire.read() << 8); Z_out = Z_out / 256;
Output hangt af van gevoeligheid (+/-2g tot +/-16g). Standaard +/-2g → delen door 256 (256 LSB/g) voor -1 tot +1g. Andere gevoeligheden via DATA_FORMAT register (bits D1, D0).


ADXL345 Kalibratie
Na uitlezen: waarden controleren op Serial Monitor. Mijn Z-as had fout van 0.1g.

Oplossing: kalibreren via 3 offset registers. Sensor vlak leggen, RAW waarden printen (zonder /256).

Z-output was ~283 (moet 256 zijn). Verschil +27. Delen door 4 = 6.75 → -7 naar Z-offset register schrijven. Na upload: Z = 256 (1g).
// In SETUP sectie
// Offset Kalibratie
// X-as
Wire.beginTransmission(ADXL345); Wire.write(0x1E); Wire.write(1); Wire.endTransmission(); delay(10);
// Y-as
Wire.beginTransmission(ADXL345); Wire.write(0x1F); Wire.write(-2); Wire.endTransmission(); delay(10);
// Z-as
Wire.beginTransmission(ADXL345); Wire.write(0x20); Wire.write(-7); Wire.endTransmission(); delay(10);
Andere assen analoog kalibreren. Let op: kalibratie is niet permanent; bij elke power-up herhalen.
Na kalibratie: Roll en Pitch berekenen (rotatie om X- en Y-as) in graden:
roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;
Details: Freescale Semiconductor application note.
Arduino en ADXL345 – 3D Visualisatie

Arduino stuurt Roll/Pitch via seriële poort. Complete Arduino code:
/* Arduino en ADXL345 Accelerometer - 3D Visualisatie
* by Dejan, https://howtomechatronics.com
*/
#include <Wire.h>
int ADXL345 = 0x53;
float X_out, Y_out, Z_out;
float roll, pitch, rollF, pitchF = 0;
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(ADXL345);
Wire.write(0x2D); Wire.write(8); Wire.endTransmission(); delay(10);
// Offset Kalibratie
Wire.beginTransmission(ADXL345); Wire.write(0x1E); Wire.write(1); Wire.endTransmission(); delay(10);
Wire.beginTransmission(ADXL345); Wire.write(0x1F); Wire.write(-2); Wire.endTransmission(); delay(10);
Wire.beginTransmission(ADXL345); Wire.write(0x20); Wire.write(-9); Wire.endTransmission(); delay(10);
}
void loop() {
Wire.beginTransmission(ADXL345);
Wire.write(0x32);
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true);
X_out = (Wire.read() | Wire.read() << 8); X_out = X_out / 256;
Y_out = (Wire.read() | Wire.read() << 8); Y_out = Y_out / 256;
Z_out = (Wire.read() | Wire.read() << 8); Z_out = Z_out / 256;
roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;
// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
Serial.print(rollF); Serial.print("/"); Serial.println(pitchF);
}
Processing code voor 3D-visualisatie:
/* Arduino en ADXL345 Accelerometer - 3D Visualisatie
* by Dejan, https://howtomechatronics.com
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String data="";
float roll, pitch;
void setup() {
size(960, 640, P3D);
myPort = new Serial(this, "COM8", 9600);
myPort.bufferUntil('\n');
}
void draw() {
translate(width/2, height/2, 0);
background(33);
textSize(22);
text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265);
rotateX(radians(roll));
rotateZ(radians(-pitch));
textSize(30);
fill(0, 76, 153);
box(386, 40, 200);
textSize(25);
fill(255, 255, 255);
text("www.HowToMechatronics.com", -183, 10, 101);
}
void serialEvent(Serial myPort) {
data = myPort.readStringUntil('\n');
if (data != null) {
data = trim(data);
String[] items = split(data, '/');
if (items.length > 1) {
roll = float(items[0]);
pitch = float(items[1]);
}
}
}
Beschrijving: Seriële bibliotheek, poort en baudrate (moet matchen met Arduino). Data ontvangen → roll/pitch variabelen. In draw() 3D-object (box) roteren.
Resultaat: 3D-object trackt accelerometer oriëntatie. Licht trilling (handbewegingen). Low-pass filter voor vloeiender resultaat:
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
Nadeel: langzamere responsiviteit. Yaw (Z-as rotatie) ontbreekt – niet berekenbaar met alleen 3-as accelerometer.

Verbetering: gyroscoop toevoegen en data fuseren → MPU6050 IMU (3-as accel + 3-as gyro op één chip). Zie volgende tutorial.
Vragen? Reacties hieronder. Bekijk mijn Arduino Projecten Collectie.
Productieproces
- Arduino & MPU6050: Precieze Servomotor Besturing met SG90 & MG996R
- u-blox LEA‑6H GPS Module: Arduino & Python Integratie Handleiding
- Temperatuur en Vochtigheid met DHT11 op Blynk - Stap-voor-Stap Arduino Tutorial
- Spraakherkenning & Synthese Meesteren op Arduino Due
- Maak Muzikale Tonen met Arduino: Stapsgewijze Handleiding
- Arduino Verbinden met NMEA‑0183: Stap‑voor‑Stap Handleiding
- Modbus op Arduino onder de knie: Stapsgewijze handleiding
- Arduino-gestuurde slimme koffiezetapparaat met Bluetooth-bediening en temperatuurmonitoring
- Maak een geanimeerde slimme LED-strip die via Alexa wordt bestuurd met Arduino
- Spraakgestuurde LED-project: Arduino Micro + BitVoicer Server voor Spraakherkenning
- Bouw uw eigen AI-assistent robot met Arduino & Python