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

Committer:
Sissors
Date:
Tue Oct 16 19:42:19 2012 +0000
Revision:
1:8997a1b348dd
Parent:
0:7bc29a9ea016
Child:
2:a8e20db7901e
Tapping doesnt work yet

Who changed what in which revision?

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