Wie kann ich die x-/y-/z-winkel messen und in grad ausgeben?

Erzeuge ein minimales Projekt mit dem Arduino UnoBoard und dem

und dem

Ja. Beim Arduino Uno + ADXL335 + ADS1115 solltest du die Winkel über den ADS1115 messen. Die ADXL335-Library von codedecaybr nutzt analogRead() und ist daher für den externen ADS1115 nicht direkt der Messpfad; sie kann installiert sein, aber die präzisen Werte kommen vom ADS1115. Die Library bietet u. a. getGX(), getGY(), getGZ() für interne Analogpins. ([GitHub][1])
Die ADS1115_WE-Library unterstützt ADS1115/ADS1015 und stellt die nötigen ADS1115-Funktionen bereit. ([Arduino Docs][2])

Verdrahtung

ADXL335 → ADS1115

ADXL335 ADS1115
X A0
Y A1
Z A2
VCC 3.3 V
GND GND

ADS1115 → Arduino Uno

ADS1115 Arduino Uno
SDA A4
SCL A5
VCC 5 V oder 3.3 V
GND GND
ADDR GND für Adresse 0x48

Wichtig: Den ADXL335 mit 3.3 V versorgen, nicht mit 5 V.

Minimaler Sketch

#include <Wire.h>
#include <ADS1115_WE.h>
#include <ADXL335.h>

#define ADS1115_ADDR 0x48

ADS1115_WE ads = ADS1115_WE(ADS1115_ADDR);

// Die ADXL335-Library wird eingebunden.
// Für Messung über ADS1115 wird sie aber nicht direkt verwendet.
ADXL335 adxl(A0, A1, A2);

const float VCC_ADXL = 3.3;

// Startwerte, später kalibrieren
float zeroX = 1.65;
float zeroY = 1.65;
float zeroZ = 1.65;

// ADXL335: ca. 300 mV/g bei 3.0 V
// bei 3.3 V näherungsweise ca. 330 mV/g
const float sensitivity = 0.330;

float readADS1115(uint8_t channel) {
  switch (channel) {
    case 0:
      ads.setCompareChannels(ADS1115_COMP_0_GND);
      break;
    case 1:
      ads.setCompareChannels(ADS1115_COMP_1_GND);
      break;
    case 2:
      ads.setCompareChannels(ADS1115_COMP_2_GND);
      break;
    case 3:
      ads.setCompareChannels(ADS1115_COMP_3_GND);
      break;
  }

  ads.startSingleMeasurement();

  while (ads.isBusy()) {
    delay(0);
  }

  return ads.getResult_V();
}

void setup() {
  Serial.begin(9600);
  Wire.begin();

  if (!ads.init()) {
    Serial.println("ADS1115 nicht gefunden!");
    while (1);
  }

  ads.setVoltageRange_mV(ADS1115_RANGE_4096);
  ads.setMeasureMode(ADS1115_SINGLE);

  Serial.println("Arduino Uno + ADXL335 + ADS1115_WE gestartet");
}

void loop() {
  float vx = readADS1115(0);
  float vy = readADS1115(1);
  float vz = readADS1115(2);

  float ax = (vx - zeroX) / sensitivity;
  float ay = (vy - zeroY) / sensitivity;
  float az = (vz - zeroZ) / sensitivity;

  float angleX = atan2(ax, sqrt(ay * ay + az * az)) * 180.0 / PI;
  float angleY = atan2(ay, sqrt(ax * ax + az * az)) * 180.0 / PI;
  float angleZ = atan2(az, sqrt(ax * ax + ay * ay)) * 180.0 / PI;

  Serial.print("Vx=");
  Serial.print(vx, 3);
  Serial.print(" V  Vy=");
  Serial.print(vy, 3);
  Serial.print(" V  Vz=");
  Serial.print(vz, 3);

  Serial.print(" V  |  ax=");
  Serial.print(ax, 3);
  Serial.print("g ay=");
  Serial.print(ay, 3);
  Serial.print("g az=");
  Serial.print(az, 3);

  Serial.print("g  |  X=");
  Serial.print(angleX, 1);
  Serial.print(" deg  Y=");
  Serial.print(angleY, 1);
  Serial.print(" deg  Z=");
  Serial.print(angleZ, 1);
  Serial.println(" deg");

  delay(200);
}

Kalibrierung

Sensor flach und ruhig hinlegen. Im seriellen Monitor die Spannungen ablesen.

Beispiel:

Vx = 1.642 V
Vy = 1.658 V
Vz = 1.980 V

Dann im Sketch setzen:

float zeroX = 1.642;
float zeroY = 1.658;
float zeroZ = 1.980 - sensitivity;

Danach stimmen die Neigungswinkel deutlich besser. Der ADXL335 misst nur statische Neigung gegen die Schwerkraft; bei Bewegung sind die Winkel verfälscht.

[1]: "ADXL335/ at master · codedecaybr/ADXL335 · GitHub"
[2]: "ADS1115_WE | Arduino Documentation"