Library for the MMA7660 triple axis accelerometer

Fork of MMA7660 by Erik -

Committer:
co838_rosf2
Date:
Wed Feb 08 11:52:58 2017 +0000
Revision:
5:e69f1571e4ea
Parent:
2:a8e20db7901e
explicitly convert double to float

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:7bc29a9ea016 1 #include "MMA7660.h"
Sissors 0:7bc29a9ea016 2
co838_rosf2 5:e69f1571e4ea 3 /*
co838_rosf2 5:e69f1571e4ea 4 **
co838_rosf2 5:e69f1571e4ea 5 ** fave_r (rosf2) change a bit the library to avoid warning compilation
co838_rosf2 5:e69f1571e4ea 6 ** Change 0.012 to 0.012f
co838_rosf2 5:e69f1571e4ea 7 **
co838_rosf2 5:e69f1571e4ea 8 */
co838_rosf2 5:e69f1571e4ea 9
Sissors 2:a8e20db7901e 10 MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl)
Sissors 0:7bc29a9ea016 11 {
Sissors 2:a8e20db7901e 12 setActive(active);
Sissors 1:8997a1b348dd 13 samplerate = 64;
Sissors 1:8997a1b348dd 14
Sissors 0:7bc29a9ea016 15 }
Sissors 0:7bc29a9ea016 16
Sissors 0:7bc29a9ea016 17 //Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
Sissors 0:7bc29a9ea016 18 bool MMA7660::testConnection( void )
Sissors 0:7bc29a9ea016 19 {
Sissors 0:7bc29a9ea016 20 if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 )
Sissors 0:7bc29a9ea016 21 return true;
Sissors 0:7bc29a9ea016 22 else
Sissors 0:7bc29a9ea016 23 return false;
Sissors 0:7bc29a9ea016 24 }
Sissors 0:7bc29a9ea016 25
Sissors 0:7bc29a9ea016 26 void MMA7660::setActive(bool state)
Sissors 0:7bc29a9ea016 27 {
Sissors 0:7bc29a9ea016 28 char modereg = read(MMA7660_MODE_R);
Sissors 0:7bc29a9ea016 29 modereg &= ~(1<<0);
Sissors 0:7bc29a9ea016 30
Sissors 0:7bc29a9ea016 31 //If it somehow was in testmode, disable that
Sissors 0:7bc29a9ea016 32 if (modereg && (1<<2)) {
Sissors 0:7bc29a9ea016 33 modereg &= ~(1<<2);
Sissors 0:7bc29a9ea016 34 write(MMA7660_MODE_R, modereg);
Sissors 0:7bc29a9ea016 35 }
Sissors 0:7bc29a9ea016 36
Sissors 0:7bc29a9ea016 37 modereg += state;
Sissors 0:7bc29a9ea016 38 write(MMA7660_MODE_R, modereg);
Sissors 0:7bc29a9ea016 39 }
Sissors 0:7bc29a9ea016 40
Sissors 0:7bc29a9ea016 41 void MMA7660::readData(int *data)
Sissors 0:7bc29a9ea016 42 {
Sissors 0:7bc29a9ea016 43 if (!active) {
Sissors 0:7bc29a9ea016 44 setActive(true);
Sissors 0:7bc29a9ea016 45 active = true;
co838_rosf2 5:e69f1571e4ea 46 wait(0.012f + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
Sissors 0:7bc29a9ea016 47 }
Sissors 0:7bc29a9ea016 48
Sissors 0:7bc29a9ea016 49 char temp[3];
Sissors 0:7bc29a9ea016 50 bool alert;
Sissors 0:7bc29a9ea016 51
Sissors 0:7bc29a9ea016 52 do {
Sissors 0:7bc29a9ea016 53 alert = false;
Sissors 0:7bc29a9ea016 54 read(MMA7660_XOUT_R, temp, 3);
Sissors 0:7bc29a9ea016 55 for (int i = 0; i<3; i++) {
Sissors 0:7bc29a9ea016 56 if (temp[i] > 63)
Sissors 0:7bc29a9ea016 57 alert = true;
Sissors 0:7bc29a9ea016 58 if (temp[i] > 31)
Sissors 0:7bc29a9ea016 59 temp[i] += 128+64;
Sissors 0:7bc29a9ea016 60 data[i] = (signed char)temp[i];
Sissors 0:7bc29a9ea016 61 }
Sissors 0:7bc29a9ea016 62 } while (alert);
Sissors 2:a8e20db7901e 63
Sissors 2:a8e20db7901e 64 if (!active)
Sissors 2:a8e20db7901e 65 setActive(false);
Sissors 0:7bc29a9ea016 66 }
Sissors 0:7bc29a9ea016 67
Sissors 1:8997a1b348dd 68
Sissors 0:7bc29a9ea016 69 void MMA7660::readData(float *data)
Sissors 0:7bc29a9ea016 70 {
Sissors 0:7bc29a9ea016 71 int intdata[3];
Sissors 0:7bc29a9ea016 72 readData(intdata);
Sissors 0:7bc29a9ea016 73 for (int i = 0; i<3; i++)
Sissors 0:7bc29a9ea016 74 data[i] = intdata[i]/MMA7660_SENSITIVITY;
Sissors 0:7bc29a9ea016 75 }
Sissors 0:7bc29a9ea016 76
Sissors 2:a8e20db7901e 77 float MMA7660::x( void )
Sissors 1:8997a1b348dd 78 {
Sissors 0:7bc29a9ea016 79 return getSingle(0);
Sissors 1:8997a1b348dd 80 }
Sissors 1:8997a1b348dd 81
Sissors 2:a8e20db7901e 82 float MMA7660::y( void )
Sissors 1:8997a1b348dd 83 {
Sissors 1:8997a1b348dd 84 return getSingle(1);
Sissors 1:8997a1b348dd 85 }
Sissors 1:8997a1b348dd 86
Sissors 2:a8e20db7901e 87 float MMA7660::z( void )
Sissors 1:8997a1b348dd 88 {
Sissors 1:8997a1b348dd 89 return getSingle(2);
Sissors 1:8997a1b348dd 90 }
Sissors 1:8997a1b348dd 91
Sissors 1:8997a1b348dd 92
Sissors 1:8997a1b348dd 93 void MMA7660::setSampleRate(int samplerate)
Sissors 1:8997a1b348dd 94 {
Sissors 1:8997a1b348dd 95 setActive(false); //Not allowed to be active to change anything
Sissors 1:8997a1b348dd 96 int rates[] = {120, 64, 32, 16, 8, 4, 2, 1}; //Alowed samplerates (and their number in array is also number required for MMA)
Sissors 1:8997a1b348dd 97 int sampleLoc = 0, sampleError = 10000, temp;
Sissors 1:8997a1b348dd 98 for (int i = 0; i<8; i++) {
Sissors 1:8997a1b348dd 99 temp = abs( rates[i] - samplerate );
Sissors 1:8997a1b348dd 100 if (temp<sampleError) {
Sissors 1:8997a1b348dd 101 sampleLoc = i;
Sissors 1:8997a1b348dd 102 sampleError=temp;
Sissors 1:8997a1b348dd 103 }
Sissors 0:7bc29a9ea016 104 }
Sissors 0:7bc29a9ea016 105
Sissors 1:8997a1b348dd 106 //Update the samplerate reg
Sissors 1:8997a1b348dd 107 temp = read(MMA7660_SR_R);
Sissors 2:a8e20db7901e 108 temp &= ~0x07; //Awake sample rate are lowest 3 bit
Sissors 1:8997a1b348dd 109 temp |= sampleLoc;
Sissors 1:8997a1b348dd 110 write(MMA7660_SR_R, temp);
Sissors 1:8997a1b348dd 111 this->samplerate = rates[sampleLoc];
Sissors 1:8997a1b348dd 112 setActive(active); //Restore previous active state
Sissors 1:8997a1b348dd 113 }
Sissors 1:8997a1b348dd 114
Sissors 1:8997a1b348dd 115
Sissors 1:8997a1b348dd 116 MMA7660::Orientation MMA7660::getSide( void )
Sissors 1:8997a1b348dd 117 {
Sissors 1:8997a1b348dd 118 char tiltreg = read(MMA7660_TILT_R);
Sissors 1:8997a1b348dd 119
Sissors 1:8997a1b348dd 120 //We care about 2 LSBs
Sissors 1:8997a1b348dd 121 tiltreg &= 0x03;
Sissors 1:8997a1b348dd 122 if (tiltreg == 0x01)
Sissors 1:8997a1b348dd 123 return MMA7660::Front;
Sissors 1:8997a1b348dd 124 if (tiltreg == 0x02)
Sissors 1:8997a1b348dd 125 return MMA7660::Back;
Sissors 1:8997a1b348dd 126 return MMA7660::Unknown;
Sissors 1:8997a1b348dd 127 }
Sissors 1:8997a1b348dd 128
Sissors 1:8997a1b348dd 129 MMA7660::Orientation MMA7660::getOrientation( void )
Sissors 1:8997a1b348dd 130 {
Sissors 1:8997a1b348dd 131 char tiltreg = read(MMA7660_TILT_R);
Sissors 1:8997a1b348dd 132
Sissors 1:8997a1b348dd 133 //We care about bit 2, 3 and 4 (counting from zero)
Sissors 1:8997a1b348dd 134 tiltreg &= 0x07<<2;
Sissors 1:8997a1b348dd 135 tiltreg >>= 2;
Sissors 1:8997a1b348dd 136 if (tiltreg == 0x01)
Sissors 1:8997a1b348dd 137 return MMA7660::Left;
Sissors 1:8997a1b348dd 138 if (tiltreg == 0x02)
Sissors 1:8997a1b348dd 139 return MMA7660::Right;
Sissors 1:8997a1b348dd 140 if (tiltreg == 0x05)
Sissors 1:8997a1b348dd 141 return MMA7660::Down;
Sissors 1:8997a1b348dd 142 if (tiltreg == 0x06)
Sissors 1:8997a1b348dd 143 return MMA7660::Up;
Sissors 1:8997a1b348dd 144 return MMA7660::Unknown;
Sissors 1:8997a1b348dd 145 }
Sissors 1:8997a1b348dd 146
Sissors 2:a8e20db7901e 147
Sissors 1:8997a1b348dd 148
Sissors 1:8997a1b348dd 149 //////////////////////////////////////////////
Sissors 1:8997a1b348dd 150 ///////////////PRIVATE////////////////////////
Sissors 1:8997a1b348dd 151 //////////////////////////////////////////////
Sissors 1:8997a1b348dd 152
Sissors 0:7bc29a9ea016 153
Sissors 0:7bc29a9ea016 154 void MMA7660::write(char address, char data)
Sissors 0:7bc29a9ea016 155 {
Sissors 0:7bc29a9ea016 156 char temp[2];
Sissors 0:7bc29a9ea016 157 temp[0]=address;
Sissors 0:7bc29a9ea016 158 temp[1]=data;
Sissors 0:7bc29a9ea016 159
Sissors 0:7bc29a9ea016 160 _i2c.write(MMA7660_ADDRESS, temp, 2);
Sissors 0:7bc29a9ea016 161 }
Sissors 0:7bc29a9ea016 162
Sissors 0:7bc29a9ea016 163 char MMA7660::read(char address)
Sissors 0:7bc29a9ea016 164 {
Sissors 0:7bc29a9ea016 165 char retval;
Sissors 0:7bc29a9ea016 166 _i2c.write(MMA7660_ADDRESS, &address, 1, true);
Sissors 0:7bc29a9ea016 167 _i2c.read(MMA7660_ADDRESS, &retval, 1);
Sissors 0:7bc29a9ea016 168 return retval;
Sissors 0:7bc29a9ea016 169 }
Sissors 0:7bc29a9ea016 170
Sissors 0:7bc29a9ea016 171 void MMA7660::read(char address, char *data, int length)
Sissors 0:7bc29a9ea016 172 {
Sissors 0:7bc29a9ea016 173 _i2c.write(MMA7660_ADDRESS, &address, 1, true);
Sissors 0:7bc29a9ea016 174 _i2c.read(MMA7660_ADDRESS, data, length);
Sissors 0:7bc29a9ea016 175 }
Sissors 0:7bc29a9ea016 176
Sissors 0:7bc29a9ea016 177 float MMA7660::getSingle( int number )
Sissors 0:7bc29a9ea016 178 {
Sissors 0:7bc29a9ea016 179 if (!active) {
Sissors 0:7bc29a9ea016 180 setActive(true);
co838_rosf2 5:e69f1571e4ea 181 wait(0.012f + 1/samplerate); //Wait until new sample is ready
Sissors 0:7bc29a9ea016 182 }
Sissors 0:7bc29a9ea016 183
Sissors 0:7bc29a9ea016 184 signed char temp;
Sissors 0:7bc29a9ea016 185 bool alert;
Sissors 0:7bc29a9ea016 186
Sissors 0:7bc29a9ea016 187 do {
Sissors 0:7bc29a9ea016 188 alert = false;
Sissors 0:7bc29a9ea016 189 temp = read(MMA7660_XOUT_R + number);
Sissors 0:7bc29a9ea016 190 if (temp > 63)
Sissors 0:7bc29a9ea016 191 alert = true;
Sissors 0:7bc29a9ea016 192 if (temp > 31)
Sissors 0:7bc29a9ea016 193 temp += 128+64;
Sissors 2:a8e20db7901e 194 } while (alert);
Sissors 0:7bc29a9ea016 195
Sissors 2:a8e20db7901e 196 if (!active)
Sissors 2:a8e20db7901e 197 setActive(false);
Sissors 0:7bc29a9ea016 198
Sissors 0:7bc29a9ea016 199 return temp / MMA7660_SENSITIVITY;
Sissors 0:7bc29a9ea016 200 }