Hiroshi Yamaguchi / MMA7361L

Dependents:   MMA7361L_Example ARLISS2012_Hidaka

Files at this revision

API Documentation at this revision

Comitter:
yamaguch
Date:
Wed Apr 25 02:33:51 2012 +0000
Child:
1:19444721f19a
Commit message:
updated API documentation

Changed in this revision

MMA7361L.cpp Show annotated file Show diff for this revision Revisions of this file
MMA7361L.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA7361L.cpp	Wed Apr 25 02:33:51 2012 +0000
@@ -0,0 +1,174 @@
+#include "MMA7361L.h"
+
+MMA7361L::MMA7361L(PinName xoutPin, PinName youtPin,PinName zoutPin,
+                   PinName zeroGDetectPin, PinName gSelectPin, PinName sleepPin) :
+        xout(xoutPin), yout(youtPin), zout(zoutPin),
+        zeroGDetect(zeroGDetectPin), gSelect(gSelectPin), sleep(sleepPin),
+        flags(-1) {
+    zeroGDetectEnabled = zeroGDetectPin != NC;
+    gSelectEnabled = gSelectPin != NC;
+    sleepEnabled = sleepPin != NC;
+    setSleep(false);
+    setScale(SCALE_1_5G);
+    for (int i = 0; i < 2; i++) {
+        calib[i].minX = -1;
+        calib[i].maxX = 1;
+        calib[i].minY = -1;
+        calib[i].maxY = 1;
+        calib[i].minZ = -1;
+        calib[i].maxZ = 1;
+    }
+}
+
+float MMA7361L::getAccel(bool forceRead) {
+    prepare(ACCEL, forceRead);
+    return sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ);
+}
+
+float MMA7361L::getAccelX(bool forceRead) {
+    prepare(ACCEL_X, forceRead);
+    return accelX;
+}
+
+float MMA7361L::getAccelY(bool forceRead) {
+    prepare(ACCEL_Y, forceRead);
+    return accelY;
+}
+
+float MMA7361L::getAccelZ(bool forceRead) {
+    prepare(ACCEL_Z, forceRead);
+    return accelZ;
+}
+
+float MMA7361L::getTiltX(bool forceRead) {
+    prepare(TILT_X, forceRead);
+    return asin(accelX / sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ));
+}
+
+float MMA7361L::getTiltY(bool forceRead) {
+    prepare(TILT_Y, forceRead);
+    return asin(accelY / sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ));
+}
+
+float MMA7361L::getTiltZ(bool forceRead) {
+    prepare(TILT_Z, forceRead);
+    return asin(accelZ / sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ));
+}
+
+void MMA7361L::setScale(Scale scale) {
+    this->scale = scale;
+    switch (scale) {
+        case SCALE_1_5G:
+            ratio = 0.8;
+            if (gSelectEnabled)
+                gSelect = 0;
+            break;
+        case SCALE_6G:
+            ratio = 0.206;
+            if (gSelectEnabled)
+                gSelect = 1;
+            break;
+    }
+}
+
+void MMA7361L::setSleep(bool on) {
+    if (sleepEnabled)
+        sleep = !on;
+}
+
+bool MMA7361L::zeroGDetected() {
+    if (zeroGDetectEnabled)
+        return zeroGDetect;
+    else
+        return false;
+}
+
+void MMA7361L::setZeroGDetectListener(void (*func)(void)) {
+    if (zeroGDetectEnabled)
+        zeroGDetect.rise(func);
+}
+
+template<typename T> void MMA7361L::setZeroGDetectListener(T* t, void (T::*func)(void)) {
+    if (zeroGDetectEnabled)
+        zeroG.rise(t, func);
+}
+
+void MMA7361L::prepare(int type, bool forceRead) {
+    if (forceRead) {
+        flags = -1;
+        switch (type) {
+            case ACCEL_X:
+                accelX = calibrate((xout - 0.5) * 3.3 / ratio, ACCEL_X, scale);
+                return;
+            case ACCEL_Y:
+                accelY = calibrate((yout - 0.5) * 3.3 / ratio, ACCEL_Y, scale);
+                return;
+            case ACCEL_Z:
+                accelZ = calibrate((zout - 0.5) * 3.3 / ratio, ACCEL_Z, scale);
+                return;
+        }
+    }
+
+    if (flags & type) {
+        if (!forceRead)
+            flags = type;
+        accelX = calibrate((xout - 0.5) * 3.3 / ratio, ACCEL_X, scale);
+        accelY = calibrate((yout - 0.5) * 3.3 / ratio, ACCEL_Y, scale);
+        accelZ = calibrate((zout - 0.5) * 3.3 / ratio, ACCEL_Z, scale);
+    } else
+        flags |= type;
+}
+
+void MMA7361L::printInfo() {
+    ::fprintf(stderr,
+              "zeroGDetectEnabled       = %d\n"
+              "gSelectEnabled           = %d\n"
+              "sleepEnabled             = %d\n"
+              "zeroGDetect(InterruptIn) = %d\n"
+              "gSelect(DigitalOut)      = %d\n"
+              "sleep(DigitalOut)        = %d\n"
+              "scale                    = %d\n"
+              "accelX, accelY, accelZ   = %4.3f, %4.3f, %4.3f\n"
+              "calib (1.5G)             = %4.3f, %4.3f; %4.3f, %4.3f; %4.3f, %4.3f\n"
+              "calib (6.0G)             = %4.3f, %4.3f; %4.3f, %4.3f; %4.3f, %4.3f\n"
+              "flags = %02X\n",
+              zeroGDetectEnabled,
+              gSelectEnabled,
+              sleepEnabled,
+              zeroGDetectEnabled ? zeroGDetect.read() : -1,
+              gSelectEnabled ? gSelect.read() : -1,
+              sleepEnabled ? sleep.read() : -1,
+              scale,
+              accelX, accelY, accelZ,
+              calib[0].minX, calib[0].maxX, calib[0].minY, calib[0].maxY, calib[0].minZ, calib[0].maxZ,
+              calib[1].minX, calib[1].maxX, calib[1].minY, calib[1].maxY, calib[1].minZ, calib[1].maxZ,
+              flags);
+}
+
+void MMA7361L::calibrate(Scale scale, float minX, float maxX, float minY, float maxY, float minZ, float maxZ) {
+    calib[scale].minX = minX;
+    calib[scale].maxX = maxX;
+    calib[scale].minY = minY;
+    calib[scale].maxY = maxY;
+    calib[scale].minZ = minZ;
+    calib[scale].maxZ = maxZ;
+}
+
+float MMA7361L::calibrate(float value, int type, Scale scale) {
+    float r = 1, s = 0;
+    switch (type) {
+        case ACCEL_X:
+            r = (calib[scale].maxX - calib[scale].minX) / 2;
+            s = (calib[scale].minX + calib[scale].maxX) / 2;
+            break;
+        case ACCEL_Y:
+            r = (calib[scale].maxY - calib[scale].minY) / 2;
+            s = (calib[scale].minY + calib[scale].maxY) / 2;
+            break;
+        case ACCEL_Z:
+            r = (calib[scale].maxZ - calib[scale].minZ) / 2;
+            s = (calib[scale].minZ + calib[scale].maxZ) / 2;
+            break;
+    }
+    return (value - s) / r;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA7361L.h	Wed Apr 25 02:33:51 2012 +0000
@@ -0,0 +1,184 @@
+#ifndef MMA7361L_H
+#define MMA7361L_H
+
+#include "mbed.h"
+
+/**
+ * MMA7361L accelerometer
+ */
+class MMA7361L {
+public:
+    /**
+     * Creates an MMA7361L accelerometer interface, connected to the specified pins
+     *
+     * @param xoutPin xout pin
+     * @param youtPin yout pin
+     * @param zoutPin zout pin
+     * @param zeroGDetectPin 0G detect pin
+     * @param gSelectPin select 1.5G/6G pin
+     * @param sleepPin sleep pin
+     *
+     */
+    MMA7361L(PinName xoutPin, PinName youtPin, PinName zoutPin, PinName zeroGDetectPin = NC, PinName gSelectPin = NC, PinName sleepPin = NC);
+
+    /**
+    * Scale enumeration declaration
+    */
+    enum Scale {
+
+        /**
+         * 1.5G mode
+         */
+        SCALE_1_5G,
+
+        /**
+         * 6G mode
+         */
+        SCALE_6G
+    };
+
+    /**
+     * Gets the current total acceleration
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns total acceleration in g
+     */
+    float getAccel(bool forceRead = false);
+
+    /**
+     * Gets the current acceleration along the X axis
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns acceleration along the X axis
+     */
+    float getAccelX(bool forceRead = false);
+
+    /**
+     * Gets the current acceleration along the Y axis
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns acceleration along the Y axis
+     */
+    float getAccelY(bool forceRead = false);
+
+    /**
+     * Gets the current acceleration along the Z axis
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns acceleration along the Z axis
+     */
+    float getAccelZ(bool forceRead = false);
+
+    /**
+     * Computes the inclination of the X axis
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns the inclination of the X axis
+     */
+    float getTiltX(bool forceRead = false);
+
+    /**
+     * Computes the inclination of the Y axis
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns the inclination of the Y axis
+     */
+    float getTiltY(bool forceRead = false);
+
+    /**
+     * Computes the inclination of the Z axis
+     *
+     * @param forceRead true to read the device, false to use cache whenever appropriate
+     * @returns the inclination of the Z axis
+     */
+    float getTiltZ(bool forceRead = false);
+
+    /**
+     * Specifies the scale to use
+     *
+     * @param scale SCALE_1_5G (for 1.5G) or SCALE_6G (for 6G)
+     */
+    void setScale(Scale scale);
+
+    /**
+     * Sets sleep mode
+     *
+     * @param on true to activate sleep mode, false to resume normal operation
+     */
+    void setSleep(bool on);
+
+    /**
+     * Tests whether 0G is detected
+     *
+     * @returns true if 0G is detected, false otherwise
+     */
+    bool zeroGDetected();
+
+    /**
+     * Sets fucntion to be called when 0G is detected
+     *
+     * @param func pointer to a function called when 0G is detected, 0 to reset as none
+     */
+    void setZeroGDetectListener(void (*func)(void));
+
+    /**
+     * Sets member fucntion to be called when 0G is detected
+     *
+     * @param t pointer to the object to call the member function on
+     * @param func pointer to the member function to be called when 0G is detected, 0 to reset as none
+     */
+    template<typename T>
+    void setZeroGDetectListener(T* t, void (T::*func)(void));
+
+    /**
+    * Prints instance info for debugging
+    */
+    void printInfo();
+
+    /**
+     * Sets calibration info
+     *
+     * @param scale scale for calibration
+     * @param minX min X value when the X axis is vertical and stable under 1g
+     * @param maxX max X value when the X axis is vertical and stable under 1g
+     * @param minY min Y value when the Y axis is vertical and stable under 1g
+     * @param maxY max Y value when the Y axis is vertical and stable under 1g
+     * @param minZ min Z value when the Z axis is vertical and stable under 1g
+     * @param maxZ max Z value when the Z axis is vertical and stable under 1g
+     */
+
+    void calibrate(Scale scale, float minX, float maxX, float minY, float maxY, float minZ, float maxZ);
+
+private:
+    enum {
+        ACCEL = 1 << 0,
+        ACCEL_X = 1 << 1,
+        ACCEL_Y = 1 << 2,
+        ACCEL_Z = 1 << 3,
+        TILT_X = 1 << 4,
+        TILT_Y = 1 << 5,
+        TILT_Z = 1 << 6
+    };
+
+    AnalogIn xout, yout, zout;
+    InterruptIn zeroGDetect;
+    DigitalOut gSelect;
+    DigitalOut sleep;
+    bool zeroGDetectEnabled;
+    bool gSelectEnabled;
+    bool sleepEnabled;
+    Scale scale;
+    float ratio;
+    float accelX, accelY, accelZ;
+    int flags;
+    struct Calibration {
+        float minX, maxX;
+        float minY, maxY;
+        float minZ, maxZ;
+    } calib[2];
+
+    void prepare(int type, bool forceRead);
+    float calibrate(float value, int type, Scale scale);
+};
+
+#endif
\ No newline at end of file