Advertisement
ScottG

Use I2C.h lib with MMA8452 Accelerometer

Jun 13th, 2013
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.43 KB | None | 0 0
  1. /*
  2.  Trying to convert from wire.h library to I2C.lib
  3.  
  4.  The MMA8452 has built in pull-up resistors for I2C so you do not need additional pull-ups.
  5.  Source: http://github.com/sparkfun/MMA8452_Accelerometer/tree/master/Firmware/MMA8452Q_BasicExample
  6.  Sparkfun link: http://www.sparkfun.com/products/10955
  7. */
  8.  
  9. #include <I2C.h>
  10.  
  11. // The SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
  12. const uint8_t MMA8452_ADDRESS = 0x1D;  // 0x1D (29 dec) if SA0 is high, 0x1C if low
  13.  
  14. #define ACCELTHRSHOLD 400    // Accelerometer register value that has to be exceded to assume there is movement
  15. uint32_t getAccelTimer;     // timer to get accelerometer values every GETACCELDELAY milliseconds
  16. uint32_t accel1SecTmr;    // print accelerometer register once a second
  17. #define GETACCELDELAY 100   // get acceleromoter every 100 mS
  18.  
  19.  
  20. //-------------------------------------------------------
  21. void setup()
  22. {
  23.   Serial.begin(9600);
  24.   delay(3000);
  25.   while (!Serial && millis() < 8000) {}
  26.   Serial.println(F("MMA8452 Basic Example"));
  27.   pinMode(PCBLED, OUTPUT);
  28.   digitalWrite(PCBLED, LOW);
  29.  
  30.   I2c.begin();   //Join the bus as a master
  31.   initMMA8452(); // Test and intialize the MMA8452
  32.   getAccelTimer = millis() + GETACCELDELAY;
  33.   accel1SecTmr = millis() + 1000;
  34. }
  35.  
  36. //-------------------------------------------------------
  37. void loop()
  38. {  
  39.   int accelCount[] = {0,0,0};  // Stores the 12-bit signed value
  40.  
  41.   if((long)(millis() - getAccelTimer) > 0)
  42.   {
  43.     readAccelData(accelCount);  // Read the x/y/z adc values
  44.     getAccelTimer = millis() + GETACCELDELAY;
  45.  
  46.     // Is accelerometer moving
  47.     if(abs(accelCount[0]) > ACCELTHRSHOLD || abs(accelCount[1]) > ACCELTHRSHOLD )
  48.     {
  49.       PintAccelValues(accelCount);
  50.       accel1SecTmr = millis() + 1000;  // just printed values, so set printout timer to 1 second
  51.     }
  52.   }
  53.  
  54.   // print every second if it's not moving
  55.   if((long)(millis() - accel1SecTmr) > 0)
  56.   {
  57.     readAccelData(accelCount);  // Read the x/y/z adc values
  58.     accel1SecTmr = millis() + 1000;
  59.     PintAccelValues(accelCount);
  60.   }
  61.  
  62. }  
  63.  
  64.  
  65. //-------------------------------------------------------
  66. void PintAccelValues(int *accelValues)
  67. {
  68.   // Print out values
  69.   Serial.print(accelValues[0]);  
  70.   Serial.print("\t");  
  71.   Serial.print(accelValues[1]);  
  72.   Serial.print("\t");  
  73.   Serial.println(accelValues[2]);  
  74. }
  75.  
  76.  
  77. //-------------------------------------------------------
  78. void readAccelData(int *destination)
  79. {
  80.   uint8_t rawData[6];  // x/y/z accel register data stored here
  81.  
  82.   readRegisters(0x01, 6, rawData);  // Read the six raw data registers into data array
  83.  
  84.   // Loop to calculate 12-bit ADC and g value for each axis
  85.   for(int i = 0; i < 3 ; i++)
  86.   {
  87.     int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
  88.     gCount >>= 4; //The registers are left align, here we right align the 12-bit integer
  89.  
  90.     // If the number is negative, we have to make it so manually (no 12-bit data type)
  91.     if (rawData[i*2] > 0x7F)
  92.     {  
  93.       gCount = ~gCount + 1;
  94.       gCount *= -1;  // Transform into negative 2's complement #
  95.     }
  96.  
  97.     destination[i] = gCount; //Record this gCount into the 3 int array
  98.   }
  99. }
  100.  
  101. //-------------------------------------------------------
  102. // Initialize the MMA8452 registers
  103. // See the many application notes for more info on setting all of these registers:
  104. // http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Q
  105. void initMMA8452()
  106. {
  107.   byte c = readRegister(0x0D);  // Read WHO_AM_I register
  108.   if (c == 0x2A) // WHO_AM_I should always be 0x2A
  109.   {  
  110.     Serial.println("MMA8452Q is online...");
  111.   }
  112.   else
  113.   {
  114.     Serial.print("Could not connect to MMA8452Q: 0x");
  115.     Serial.println(c, HEX);
  116. //    while(1) ; // Loop forever if communication doesn't happen
  117.   }
  118.  
  119.   MMA8452Standby();  // Must be in standby to change registers
  120.  
  121.   // Set up the full scale range to 2, 4, or 8g.
  122.   writeRegister(0x0E, 0);  // 00 for 2G
  123.  
  124.   //The default data rate is 800Hz and we don't modify it in this example code
  125.  
  126.   MMA8452Active();  // Set to active to start reading
  127. }
  128.  
  129. //-------------------------------------------------------
  130. // Sets the MMA8452 to standby mode. It must be in standby to change most register settings
  131. void MMA8452Standby()
  132. {
  133.   byte c = readRegister(0x2A);
  134.   writeRegister(0x2A, c & ~(0x01)); //Clear the active bit to go into standby
  135. }
  136.  
  137. //-------------------------------------------------------
  138. // Sets the MMA8452 to active mode. Needs to be in this mode to output data
  139. void MMA8452Active()
  140. {
  141.   byte c = readRegister(0x2A);
  142.   writeRegister(0x2A, c | 0x01); //Set the active bit to begin detection
  143. }
  144.  
  145. //-------------------------------------------------------
  146. // Read bytesToRead sequentially, starting at addressToRead into the dest byte array
  147. void readRegisters(uint8_t addressToRead, uint8_t bytesToRead, uint8_t * dest)
  148. {
  149. /*
  150.   Wire.beginTransmission(MMA8452_ADDRESS);
  151.   Wire.write(addressToRead);
  152.   Wire.endTransmission(false); //endTransmission but keep the connection active
  153.  
  154.   Wire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default
  155.  
  156.   while(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect
  157.  
  158.   for(int x = 0 ; x < bytesToRead ; x++)
  159.     dest[x] = Wire.read();    
  160. */
  161.   I2c.read(MMA8452_ADDRESS, addressToRead, bytesToRead, dest);
  162.  
  163. }
  164.  
  165. //-------------------------------------------------------
  166. // Read a single byte from addressToRead and return it as a byte
  167. uint8_t readRegister(uint8_t addressToRead)
  168. {
  169. /*  
  170.   Wire.beginTransmission(MMA8452_ADDRESS);
  171.   Wire.write(addressToRead);
  172.   Wire.endTransmission(false); //endTransmission but keep the connection active
  173.   Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default
  174.   while(!Wire.available()) ; //Wait for the data to come back
  175.   return Wire.read(); //Return this one byte
  176. */
  177.  
  178.   uint8_t getByte;
  179.   I2c.read(addressToRead, getByte, getByte);
  180.   return getByte;
  181.  
  182. }
  183.  
  184. //-------------------------------------------------------
  185. // Writes a single byte (dataToWrite) into addressToWrite
  186. void writeRegister(uint8_t addressToWrite, uint8_t dataToWrite)
  187. {
  188. /*
  189.   Wire.beginTransmission(MMA8452_ADDRESS);
  190.   Wire.write(addressToWrite);
  191.   Wire.write(dataToWrite);
  192.   Wire.endTransmission(); //Stop transmitting
  193. */
  194.  
  195.   I2c.write(MMA8452_ADDRESS, addressToWrite, dataToWrite);
  196.  
  197. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement