Library for the MMA7660 triple axis accelerometer

Dependents:   Websocket_Ethernet_acc app-board-Sprint-WS-Acc app-board-Ethernet-Websocket app-board-Wifly-Websocket ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MMA7660.cpp Source File

MMA7660.cpp

00001 #include "MMA7660.h"
00002 
00003 MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl)
00004 {
00005     setActive(active);
00006     samplerate = 64;
00007 }
00008 
00009 //Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
00010 bool MMA7660::testConnection( void )
00011 {
00012     if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 )
00013         return true;
00014     else
00015         return false;
00016 }
00017 
00018 void MMA7660::setActive(bool state)
00019 {
00020     active = state;
00021     char modereg = read(MMA7660_MODE_R);
00022     modereg &= ~(1<<0);
00023 
00024     //If it somehow was in testmode, disable that
00025     if (modereg && (1<<2)) {
00026         modereg &= ~(1<<2);
00027         write(MMA7660_MODE_R, modereg);
00028     }
00029 
00030     modereg += state;
00031     write(MMA7660_MODE_R, modereg);
00032 }
00033 
00034 void MMA7660::readData(int *data)
00035 {
00036     bool active_old = active;
00037     if (!active) {
00038         setActive(true);
00039         wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
00040     }
00041 
00042     char temp[3];
00043     bool alert;
00044 
00045     do {
00046         alert = false;
00047         read(MMA7660_XOUT_R, temp, 3);
00048         for (int i = 0; i<3; i++) {
00049             if (temp[i] > 63)
00050                 alert = true;
00051             if (temp[i] > 31)
00052                 temp[i] += 128+64;
00053             data[i] = (signed char)temp[i];
00054         }
00055     } while (alert);
00056 
00057     if (!active_old)
00058         setActive(false);
00059 }
00060 
00061 
00062 void MMA7660::readData(float *data)
00063 {
00064     int intdata[3];
00065     readData(intdata);
00066     for (int i = 0; i<3; i++)
00067         data[i] = intdata[i]/MMA7660_SENSITIVITY;
00068 }
00069 
00070 float MMA7660::x( void )
00071 {
00072     return getSingle(0);
00073 }
00074 
00075 float MMA7660::y( void )
00076 {
00077     return getSingle(1);
00078 }
00079 
00080 float MMA7660::z( void )
00081 {
00082     return getSingle(2);
00083 }
00084 
00085 
00086 void MMA7660::setSampleRate(int samplerate)
00087 {
00088     bool active_old = active;
00089     setActive(false);                               //Not allowed to be active to change anything
00090     int rates[] = {120, 64, 32, 16, 8, 4, 2, 1};    //Alowed samplerates (and their number in array is also number required for MMA)
00091     int sampleLoc = 0, sampleError = 10000, temp;
00092     for (int i = 0; i<8; i++) {
00093         temp = abs( rates[i] - samplerate );
00094         if (temp<sampleError) {
00095             sampleLoc = i;
00096             sampleError=temp;
00097         }
00098     }
00099 
00100     //Update the samplerate reg
00101     temp = read(MMA7660_SR_R);
00102     temp &= ~0x07;                                  //Awake sample rate are lowest 3 bit
00103     temp |= sampleLoc;
00104     write(MMA7660_SR_R, temp);
00105     this->samplerate = rates[sampleLoc];
00106     setActive(active_old);                              //Restore previous active state
00107 }
00108 
00109 
00110 MMA7660::Orientation MMA7660::getSide( void )
00111 {
00112     char tiltreg = read(MMA7660_TILT_R);
00113     //We care about 2 LSBs
00114     tiltreg &= 0x03;
00115     if (tiltreg == 0x01)
00116         return MMA7660::Front;
00117     if (tiltreg == 0x02)
00118         return MMA7660::Back;
00119     return MMA7660::Unknown;
00120 }
00121 
00122 MMA7660::Orientation MMA7660::getOrientation( void )
00123 {
00124     char tiltreg = read(MMA7660_TILT_R);
00125 
00126     //We care about bit 2, 3 and 4 (counting from zero)
00127     tiltreg &= 0x07<<2;
00128     tiltreg >>= 2;
00129     if (tiltreg == 0x01)
00130         return MMA7660::Left;
00131     if (tiltreg == 0x02)
00132         return MMA7660::Right;
00133     if (tiltreg == 0x05)
00134         return MMA7660::Down;
00135     if (tiltreg == 0x06)
00136         return MMA7660::Up;
00137     return MMA7660::Unknown;
00138 }
00139 
00140 
00141 
00142 //////////////////////////////////////////////
00143 ///////////////PRIVATE////////////////////////
00144 //////////////////////////////////////////////
00145 
00146 
00147 void MMA7660::write(char address, char data)
00148 {
00149     char temp[2];
00150     temp[0]=address;
00151     temp[1]=data;
00152 
00153     _i2c.write(MMA7660_ADDRESS, temp, 2);
00154 }
00155 
00156 char MMA7660::read(char address)
00157 {
00158     char retval;
00159     _i2c.write(MMA7660_ADDRESS, &address, 1, true);
00160     _i2c.read(MMA7660_ADDRESS, &retval, 1);
00161     return retval;
00162 }
00163 
00164 void MMA7660::read(char address, char *data, int length)
00165 {
00166     _i2c.write(MMA7660_ADDRESS, &address, 1, true);
00167     _i2c.read(MMA7660_ADDRESS, data, length);
00168 }
00169 
00170 float MMA7660::getSingle( int number )
00171 {
00172     bool active_old = active;
00173     if (!active) {
00174         setActive(true);
00175         wait(0.012 + 1/samplerate); //Wait until new sample is ready
00176     }
00177 
00178     signed char temp;
00179     bool alert;
00180 
00181     do {
00182         alert = false;
00183         temp = read(MMA7660_XOUT_R + number);
00184         if (temp > 63)
00185             alert = true;
00186         if (temp > 31)
00187             temp += 128+64;
00188     } while (alert);
00189 
00190     if (!active_old)
00191         setActive(false);
00192 
00193     return temp / MMA7660_SENSITIVITY;
00194 }