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

Erzeuge ein minimales Projekt mit dem Arduino UnoBoard und dem

- ADXL335 mit Library https://github.com/codedecaybr/ADXL335

und dem

- ADS1115 mit Library https://github.com/wollewald/ADS1115_WE

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"