Martin Werluschnig / Mbed 2 deprecated ProcVisDemo_Accelerator

Dependencies:   Serial_HL mbed

Files at this revision

API Documentation at this revision

Comitter:
martwerl
Date:
Thu Nov 15 18:08:43 2018 +0000
Parent:
1:e88b745f2ca2
Commit message:
ProcVisDemo_Accelerator

Changed in this revision

MMA7660.cpp Show annotated file Show diff for this revision Revisions of this file
MMA7660.h Show annotated file Show diff for this revision Revisions of this file
ProcVisDemo.cpp Show diff for this revision Revisions of this file
ProcVisDemo_Accelerator.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA7660.cpp	Thu Nov 15 18:08:43 2018 +0000
@@ -0,0 +1,194 @@
+#include "MMA7660.h"
+
+MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl)
+{
+    setActive(active);
+    samplerate = 64;
+}
+
+//Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
+bool MMA7660::testConnection( void )
+{
+    if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 )
+        return true;
+    else
+        return false;
+}
+
+void MMA7660::setActive(bool state)
+{
+    active = state;
+    char modereg = read(MMA7660_MODE_R);
+    modereg &= ~(1<<0);
+
+    //If it somehow was in testmode, disable that
+    if (modereg && (1<<2)) {
+        modereg &= ~(1<<2);
+        write(MMA7660_MODE_R, modereg);
+    }
+
+    modereg += state;
+    write(MMA7660_MODE_R, modereg);
+}
+
+void MMA7660::readData(int *data)
+{
+    bool active_old = active;
+    if (!active) {
+        setActive(true);
+        wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
+    }
+
+    char temp[3];
+    bool alert;
+
+    do {
+        alert = false;
+        read(MMA7660_XOUT_R, temp, 3);
+        for (int i = 0; i<3; i++) {
+            if (temp[i] > 63)
+                alert = true;
+            if (temp[i] > 31)
+                temp[i] += 128+64;
+            data[i] = (signed char)temp[i];
+        }
+    } while (alert);
+
+    if (!active_old)
+        setActive(false);
+}
+
+
+void MMA7660::readData(float *data)
+{
+    int intdata[3];
+    readData(intdata);
+    for (int i = 0; i<3; i++)
+        data[i] = intdata[i]/MMA7660_SENSITIVITY;
+}
+
+float MMA7660::x( void )
+{
+    return getSingle(0);
+}
+
+float MMA7660::y( void )
+{
+    return getSingle(1);
+}
+
+float MMA7660::z( void )
+{
+    return getSingle(2);
+}
+
+
+void MMA7660::setSampleRate(int samplerate)
+{
+    bool active_old = active;
+    setActive(false);                               //Not allowed to be active to change anything
+    int rates[] = {120, 64, 32, 16, 8, 4, 2, 1};    //Alowed samplerates (and their number in array is also number required for MMA)
+    int sampleLoc = 0, sampleError = 10000, temp;
+    for (int i = 0; i<8; i++) {
+        temp = abs( rates[i] - samplerate );
+        if (temp<sampleError) {
+            sampleLoc = i;
+            sampleError=temp;
+        }
+    }
+
+    //Update the samplerate reg
+    temp = read(MMA7660_SR_R);
+    temp &= ~0x07;                                  //Awake sample rate are lowest 3 bit
+    temp |= sampleLoc;
+    write(MMA7660_SR_R, temp);
+    this->samplerate = rates[sampleLoc];
+    setActive(active_old);                              //Restore previous active state
+}
+
+
+MMA7660::Orientation MMA7660::getSide( void )
+{
+    char tiltreg = read(MMA7660_TILT_R);
+    //We care about 2 LSBs
+    tiltreg &= 0x03;
+    if (tiltreg == 0x01)
+        return MMA7660::Front;
+    if (tiltreg == 0x02)
+        return MMA7660::Back;
+    return MMA7660::Unknown;
+}
+
+MMA7660::Orientation MMA7660::getOrientation( void )
+{
+    char tiltreg = read(MMA7660_TILT_R);
+
+    //We care about bit 2, 3 and 4 (counting from zero)
+    tiltreg &= 0x07<<2;
+    tiltreg >>= 2;
+    if (tiltreg == 0x01)
+        return MMA7660::Left;
+    if (tiltreg == 0x02)
+        return MMA7660::Right;
+    if (tiltreg == 0x05)
+        return MMA7660::Down;
+    if (tiltreg == 0x06)
+        return MMA7660::Up;
+    return MMA7660::Unknown;
+}
+
+
+
+//////////////////////////////////////////////
+///////////////PRIVATE////////////////////////
+//////////////////////////////////////////////
+
+
+void MMA7660::write(char address, char data)
+{
+    char temp[2];
+    temp[0]=address;
+    temp[1]=data;
+
+    _i2c.write(MMA7660_ADDRESS, temp, 2);
+}
+
+char MMA7660::read(char address)
+{
+    char retval;
+    _i2c.write(MMA7660_ADDRESS, &address, 1, true);
+    _i2c.read(MMA7660_ADDRESS, &retval, 1);
+    return retval;
+}
+
+void MMA7660::read(char address, char *data, int length)
+{
+    _i2c.write(MMA7660_ADDRESS, &address, 1, true);
+    _i2c.read(MMA7660_ADDRESS, data, length);
+}
+
+float MMA7660::getSingle( int number )
+{
+    bool active_old = active;
+    if (!active) {
+        setActive(true);
+        wait(0.012 + 1/samplerate); //Wait until new sample is ready
+    }
+
+    signed char temp;
+    bool alert;
+
+    do {
+        alert = false;
+        temp = read(MMA7660_XOUT_R + number);
+        if (temp > 63)
+            alert = true;
+        if (temp > 31)
+            temp += 128+64;
+    } while (alert);
+
+    if (!active_old)
+        setActive(false);
+
+    return temp / MMA7660_SENSITIVITY;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA7660.h	Thu Nov 15 18:08:43 2018 +0000
@@ -0,0 +1,207 @@
+/* Copyright (c) <year> <copyright holders>, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+
+
+#ifndef MMA7660_H
+#define MMA7660_H
+
+#define MMA7660_ADDRESS     0x98
+#define MMA7660_SENSITIVITY 21.33
+
+#define MMA7660_XOUT_R      0x00
+#define MMA7660_YOUT_R      0x01
+#define MMA7660_ZOUT_R      0x02
+#define MMA7660_TILT_R      0x03
+#define MMA7660_INT_R       0x06
+#define MMA7660_MODE_R      0x07
+#define MMA7660_SR_R        0x08
+
+
+/** An interface for the MMA7660 triple axis accelerometer
+ *
+ * @code
+ * //Uses the measured z-acceleration to drive leds 2 and 3 of the mbed
+ *
+ * #include "mbed.h"
+ * #include "MMA7660.h"
+ *
+ * MMA7660 MMA(p28, p27);
+ *
+ * DigitalOut connectionLed(LED1);
+ * PwmOut Zaxis_p(LED2);
+ * PwmOut Zaxis_n(LED3);
+ *
+ * int main() {
+ *     if (MMA.testConnection())
+ *         connectionLed = 1;
+ *
+ *     while(1) {
+ *         Zaxis_p = MMA.z();
+ *         Zaxis_n = -MMA.z();
+ *     }
+ *
+ * }
+ * @endcode
+ */
+class MMA7660
+{
+public:
+    /**
+    * The 6 different orientations and unknown
+    *
+    * Up & Down = X-axis
+    * Right & Left = Y-axis
+    * Back & Front = Z-axis
+    *
+    */
+    enum Orientation {Up, Down,
+                      Right, Left,
+                      Back, Front,
+                      Unknown
+                     };
+
+    /**
+    * Creates a new MMA7660 object
+    *
+    * @param sda - I2C data pin
+    * @param scl - I2C clock pin
+    * @param active - true (default) to enable the device, false to keep it standby
+    */
+    MMA7660(PinName sda, PinName scl, bool active = true);
+
+    /**
+    * Tests if communication is possible with the MMA7660
+    *
+    * Because the MMA7660 lacks a WHO_AM_I register, this function can only check
+    * if there is an I2C device that responds to the MMA7660 address
+    *
+    * @param return - true for successfull connection, false for no connection
+    */
+    bool testConnection( void );
+
+    /**
+    * Sets the active state of the MMA7660
+    *
+    * Note: This is unrelated to awake/sleep mode
+    *
+    * @param state - true for active, false for standby
+    */
+    void setActive( bool state);
+
+    /**
+    * Reads acceleration data from the sensor
+    *
+    * When the parameter is a pointer to an integer array it will be the raw data.
+    * When it is a pointer to a float array it will be the acceleration in g's
+    *
+    * @param data - pointer to array with length 3 where the acceleration data will be stored, X-Y-Z
+    */
+    void readData( int *data);
+    void readData( float *data);
+
+    /**
+    * Get X-data
+    *
+    * @param return - X-acceleration in g's
+    */
+    float x( void );
+
+    /**
+    * Get Y-data
+    *
+    * @param return - Y-acceleration in g's
+    */
+    float y( void );
+
+    /**
+    * Get Z-data
+    *
+    * @param return - Z-acceleration in g's
+    */
+    float z( void );
+
+    /**
+    * Sets the active samplerate
+    *
+    * The entered samplerate will be rounded to nearest supported samplerate.
+    * Supported samplerates are: 120 - 64 - 32 - 16 - 8 - 4 - 2 - 1 samples/second.
+    *
+    * @param samplerate - the samplerate that will be set
+    */
+    void setSampleRate(int samplerate);
+
+    /**
+    * Returns if it is on its front, back, or unknown side
+    *
+    * This is read from MMA7760s registers, page 12 of datasheet
+    *
+    * @param return - Front, Back or Unknown orientation
+    */
+    Orientation getSide( void );
+
+    /**
+    * Returns if it is on it left, right, down or up side
+    *
+    * This is read from MMA7760s registers, page 12 of datasheet
+    *
+    * @param return - Left, Right, Down, Up or Unknown orientation
+    */
+    Orientation getOrientation ( void );
+
+
+private:
+
+    /**
+    * Writes data to the device
+    *
+    * @param adress - register address to write to
+    * @param data - data to write
+    */
+    void write( char address, char data);
+
+    /**
+    * Read data from the device
+    *
+    * @param adress - register address to write to
+    * @return - data from the register specified by RA
+    */
+    char read( char adress);
+
+    /**
+     * Read multiple regigsters from the device, more efficient than using multiple normal reads.
+     *
+     * @param adress - register address to write to
+     * @param length - number of bytes to read
+     * @param data - pointer where the data needs to be written to
+     */
+    void read( char adress, char *data, int length);
+
+    /**
+    * Reads single axis
+    */
+    float getSingle(int number);
+
+    I2C _i2c;
+    bool active;
+    float samplerate;
+};
+
+
+#endif
--- a/ProcVisDemo.cpp	Fri Oct 09 07:58:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#include "mbed.h"
-#include "Serial_HL.h"
-
-SerialBLK pc(USBTX, USBRX);
-SvProtocol ua0(&pc);
-
-// V2.0
-// BusOut leds(LED1,LED2,LED3,LED4); Bertl14
-// M0-Board
-BusOut leds(P1_13,P1_12,P1_7,P1_6,P1_4,P1_3,P1_1,P1_0,LED4,LED3,LED2,LED1);
-
-
-void CommandHandler();
-
-int main(void)
-{
-    pc.format(8,SerialBLK::None,1);
-    pc.baud(115200);
-    leds = 9;
-
-    ua0.SvMessage("SvTest_Serial_HL"); // Meldung zum PC senden
-
-    int16_t sv1=0, sv2=100;
-    Timer stw;
-    stw.start();
-    while(1) {
-        CommandHandler();
-        if( ua0.acqON && (stw.read_ms()>100) ) { // 10Hz
-            // dieser Teil wird mit 10Hz aufgerufen
-            stw.reset();
-            sv1++;
-            sv2++;
-            if( ua0.acqON ) {
-                // nur wenn vom PC aus das Senden eingeschaltet wurde
-                // wird auch etwas gesendet
-                ua0.WriteSvI16(1, sv1);
-                ua0.WriteSvI16(2, sv2);
-            }
-        }
-    }
-    return 1;
-}
-
-void CommandHandler()
-{
-    uint8_t cmd;
-    int16_t idata1, idata2;
-
-    // Fragen ob überhaupt etwas im RX-Reg steht
-    if( !pc.IsDataAvail() )
-        return;
-
-    // wenn etwas im RX-Reg steht
-    // Kommando lesen
-    cmd = ua0.GetCommand();
-
-    if( cmd==2 ) {
-        // cmd2 hat 2 int16 Parameter
-        idata1 = ua0.ReadI16();
-        idata2 = ua0.ReadI16();
-        // für die Analyse den Wert einfach nur zum PC zurücksenden
-        ua0.SvPrintf("Command2 %d %d", idata1, idata2);
-    }
-}
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProcVisDemo_Accelerator.cpp	Thu Nov 15 18:08:43 2018 +0000
@@ -0,0 +1,72 @@
+#include "mbed.h"
+#include "Serial_HL.h"
+#include "MMA7660.h"
+
+SerialBLK pc(USBTX, USBRX);
+SvProtocol ua0(&pc);
+
+// V2.0
+// BusOut leds(LED1,LED2,LED3,LED4); Bertl14
+// M0-Board
+//BusOut leds(P1_13,P1_12,P1_7,P1_6,P1_4,P1_3,P1_1,P1_0,LED4,LED3,LED2,LED1);
+MMA7660 accel (p28, p27);
+
+
+void CommandHandler();
+
+int main(void)
+{
+    pc.format(8,SerialBLK::None,1);
+    pc.baud(115200);
+
+    ua0.SvMessage("Accelerator Test"); // Meldung zum PC senden
+    
+    accel.setSampleRate(120);
+    int val2[3];
+    Timer stw;
+    stw.start();
+    
+    while(1) {
+        CommandHandler();
+        if( ua0.acqON && (stw.read_ms()>100) )  // 10Hz
+        {
+            // dieser Teil wird mit 10Hz aufgerufen
+            stw.reset();
+            accel.readData(val2);//X,Y,Z vom PC lesen
+            ua0.WriteSvI16(1, val2[0]);//X,Y,Z zum PC senden
+            ua0.WriteSvI16(2, val2[1]);
+            ua0.WriteSvI16(3, val2[2]);
+        }
+    return 1;
+    }
+}
+
+void CommandHandler()
+{
+    uint8_t cmd;
+    int16_t idata1, idata2;
+
+    // Fragen ob überhaupt etwas im RX-Reg steht
+    if( !pc.IsDataAvail() )
+        return;
+
+    // wenn etwas im RX-Reg steht
+    // Kommando lesen
+    cmd = ua0.GetCommand();
+
+    if( cmd==2 ) {
+        // cmd2 hat 2 int16 Parameter
+        idata1 = ua0.ReadI16();
+        idata2 = ua0.ReadI16();
+        // für die Analyse den Wert einfach nur zum PC zurücksenden
+        ua0.SvPrintf("Command2 %d %d", idata1, idata2);
+    }   
+    
+    if( cmd==3 )  //leds schalten
+    {
+           
+        ua0.SvMessage("SetLeds Awa pronto!");
+    }
+}
+
+