ADXL335

Beschleunigungssensoren sind aus unserem Alltag nicht mehr wegzudenken. Sie werden in Smartphones genutzt um die Neigung des Geräts festzustellen. Alarmanlagen nutzen sie um die Bewegung von Gegenständen zu erfassen. Aktive Federungssysteme in Fahrzeugen, Bildstabilisatoren in Kameras und Head-Crash-Schutzverfahren in Festplatten nutzen sie ebenfalls. Wenn man zusätzlich ein Gyroskop verwendet, können Beschleunigungssensoren auch bei der Stabilisierung von Fluggeräten verwendet werden.
Der ADXL335 ist ein einfacher Beschleunigungssensor, der über drei analoge Ausgänge die Beschleunigung in je einer Achse ausgibt. Aus allen drei Werten lässt sich der Beschleunigungsvektor rekonstruieren. Die messbare Beschleunigung liegt dabei zwischen -3g und 3g, wobei die Einheit g für die Erdbeschleunigung steht, also 1g = 9,81 m/s^2 beträgt.
In diesem Tutorial messe ich etwa jede halbe Sekunde den Beschleunigungsvektor und gebe ihn auf der Konsole aus. Es wird das Tutorial für den ADC0804 als Vorwissen vorausgesetzt.

Inhalt


Material

  • ADXL335
  • Drei Optokoppler 4N35
  • Alles für ein ADC0804-Netzwerk
  • Diverse Kabel
  • Steckbrett

Aufbau

Der ADXL335 hat folgende Anschlüsse:

ADXL335
VCC und GND dienen zur Stromversorgung. Dabei muss VCC an eine +3V3-Spannung angeschlossen werden. Die analogen Ausgänge X_OUT, Y_OUT, Z_OUT geben je nach Richtung und Größe der Beschleunigung eine Spannung zwischen 0 und 3,3V aus. Es herrscht dabei ein linearer Zusammenhang. Bei 0g in einer Achse liegt laut Datenblatt eine Spannung von etwa 1,5V an. Eine Änderung von 1g bewirkt laut Datenblatt eine Änderung der Spannung von etwa 300mV. Es wurden Intervalle genannt, in denen sich dieses Werte bewegen. Diese Werte können von Achse zu Achse unterschiedlich sein. Man sollte die Werte vor dem Gebrauch einmal testen.

Um alle drei Achsen auszulesen unter Benutzung von nur einem einzigen AD-Wandler bietet sich folgender Aufbau an:

Gesamtaufbau ohne das ADC0804-Netzwerk
Mit den Optokopplern wählt man die Achse aus, die man auslesen möchte. Das Signal wird dann von einem ADC0804-Netzwerk ausgewertet. Aus Gründen der Übersicht, wird hier nicht das ADC0804-Netzwerk eingezeichnet. Ich verweise dafür auf das entsprechende Tutorial. Es muss lediglich der Anschluss, der hier mit Output gekennzeichnet ist, mit dem Anschluss verbunden werden, der im ADC0804-Tutorial mit Input gekennzeichnet ist.

Mit diesem Netzwerk lässt sich nun jede Achse nacheinander auslesen.

Programm

Es müssen wie immer alle benutzten Anschlüssen initialisiert werden:
#define AXISX 25
#define AXISY 24
#define AXISZ 23

void init() {
/* ... */
    pinMode(AXISX, OUTPUT);
    pinMode(AXISY, OUTPUT);
    pinMode(AXISZ, OUTPUT);

/* ... */
    digitalWrite(AXISX, LOW);
    digitalWrite(AXISY, LOW);
    digitalWrite(AXISZ, LOW);
}
Aus Gründen der Übersicht habe ich teile der Funktion ausgeschnitten und nur die Initialisierung der Optokoppler dargestellt.

Darüber hinaus wird eine Funktion benötigt, die den richtigen Optokoppler auswählt und das entsprechende Signal durchschaltet:
void select_axis(unsigned char axis) {
    digitalWrite(AXISX, LOW);
    digitalWrite(AXISY, LOW);
    digitalWrite(AXISZ, LOW);

    switch(axis) {
        case AXISX:
        case AXISY:
        case AXISZ:
            digitalWrite(axis, HIGH);
        default:
            break;
    }

    delay(20);
}
In der main-Funktion werden für jede Achse die Werte des AD-Wandlers in g umgerechnet. Durch Austesten habe ich herausgefunden, dass bei meinem Exemplar des ADXL335 die AD-Werte für 0g in der x-Achse 76, in der y-Achse 74 und in der z-Achse 80 beträgt. Eine Differenz von 1g entspricht einer Wertänderung von 16. Daraus ergibt sich folgende main-Funktion:
#define ZERO_LEVEL_X 76
#define ZERO_LEVEL_Y 74
#define ZERO_LEVEL_Z 80
#define STEP_SIZE 16

int main() {
    if(wiringPiSetup() == -1) {
        return 0;
    }

    init();

    while(1) {
        delay(500);
        select_axis(AXISX);
        double raw_x = static_cast(analogRead());
        select_axis(AXISY);
        double raw_y = static_cast(analogRead());
        select_axis(AXISZ);
        double raw_z = static_cast(analogRead());
        std::cout << "Measurement:";
        std::cout << " x = " << (raw_x - ZERO_LEVEL_X)/STEP_SIZE << "g";
        std::cout << " y = " << (raw_y - ZERO_LEVEL_Y)/STEP_SIZE << "g";
        std::cout << " z = " << (raw_z - ZERO_LEVEL_Z)/STEP_SIZE << "g";
        std::cout << std::endl << std::endl;
    }
 
    return 0;
}
Hierbei ist die Funktion analogRead() die Lesefunktion aus dem Tutorial ADC0804. Es wird nun etwa alle 500ms der Neigungsvektor des ADXL335 ausgegeben. Möglicherweise müssen bei eurem Exemplar des ADXL335 die 0g-Werte und die Schrittweite angepasst werden. Wenn man für den ADC0804 die Referenzspannung auf 3,3V anpasst, lässt sich die Auflösung der Messung erhöhen. Wenn bei der Anwendung nur Werte zwischen -1g und 1g zu erwarten sind, dann würde eine weitere Anpassung der VIN- die Auflösung noch mehr erhöhen.

Ich hoffe dieses Tutorial hat euch bei der Verwendung des ADXL335 weitergeholfen oder euch seinen Nutzen näher gebracht und euch zum Kauf angeregt. Für weitere Informationen zum ADXL335 siehe:

Keine Kommentare:

Kommentar veröffentlichen

Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.