MPU6050.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /*
  2. MPU6050.cpp - Class file for the MPU6050 Triple Axis Gyroscope & Accelerometer Arduino Library.
  3. Version: 1.0.3
  4. (c) 2014-2015 Korneliusz Jarzebski
  5. www.jarzebski.pl
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the version 3 GNU General Public License as
  8. published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #if ARDUINO >= 100
  17. #include "Arduino.h"
  18. #else
  19. #include "WProgram.h"
  20. #endif
  21. #include <Wire.h>
  22. #include <math.h>
  23. #include <MPU6050.h>
  24. bool MPU6050::begin(mpu6050_dps_t scale, mpu6050_range_t range, int mpua)
  25. {
  26. // Set Address
  27. mpuAddress = mpua;
  28. Wire.begin();
  29. // Reset calibrate values
  30. dg.XAxis = 0;
  31. dg.YAxis = 0;
  32. dg.ZAxis = 0;
  33. useCalibrate = false;
  34. // Reset threshold values
  35. tg.XAxis = 0;
  36. tg.YAxis = 0;
  37. tg.ZAxis = 0;
  38. actualThreshold = 0;
  39. // Check MPU6050 Who Am I Register
  40. if (fastRegister8(MPU6050_REG_WHO_AM_I) != 0x68)
  41. {
  42. return false;
  43. }
  44. // Set Clock Source
  45. setClockSource(MPU6050_CLOCK_PLL_XGYRO);
  46. // Set Scale & Range
  47. setScale(scale);
  48. setRange(range);
  49. // Disable Sleep Mode
  50. setSleepEnabled(false);
  51. return true;
  52. }
  53. void MPU6050::setScale(mpu6050_dps_t scale)
  54. {
  55. uint8_t value;
  56. switch (scale)
  57. {
  58. case MPU6050_SCALE_250DPS:
  59. dpsPerDigit = .007633f;
  60. break;
  61. case MPU6050_SCALE_500DPS:
  62. dpsPerDigit = .015267f;
  63. break;
  64. case MPU6050_SCALE_1000DPS:
  65. dpsPerDigit = .030487f;
  66. break;
  67. case MPU6050_SCALE_2000DPS:
  68. dpsPerDigit = .060975f;
  69. break;
  70. default:
  71. break;
  72. }
  73. value = readRegister8(MPU6050_REG_GYRO_CONFIG);
  74. value &= 0b11100111;
  75. value |= (scale << 3);
  76. writeRegister8(MPU6050_REG_GYRO_CONFIG, value);
  77. }
  78. mpu6050_dps_t MPU6050::getScale(void)
  79. {
  80. uint8_t value;
  81. value = readRegister8(MPU6050_REG_GYRO_CONFIG);
  82. value &= 0b00011000;
  83. value >>= 3;
  84. return (mpu6050_dps_t)value;
  85. }
  86. void MPU6050::setRange(mpu6050_range_t range)
  87. {
  88. uint8_t value;
  89. switch (range)
  90. {
  91. case MPU6050_RANGE_2G:
  92. rangePerDigit = .000061f;
  93. break;
  94. case MPU6050_RANGE_4G:
  95. rangePerDigit = .000122f;
  96. break;
  97. case MPU6050_RANGE_8G:
  98. rangePerDigit = .000244f;
  99. break;
  100. case MPU6050_RANGE_16G:
  101. rangePerDigit = .0004882f;
  102. break;
  103. default:
  104. break;
  105. }
  106. value = readRegister8(MPU6050_REG_ACCEL_CONFIG);
  107. value &= 0b11100111;
  108. value |= (range << 3);
  109. writeRegister8(MPU6050_REG_ACCEL_CONFIG, value);
  110. }
  111. mpu6050_range_t MPU6050::getRange(void)
  112. {
  113. uint8_t value;
  114. value = readRegister8(MPU6050_REG_ACCEL_CONFIG);
  115. value &= 0b00011000;
  116. value >>= 3;
  117. return (mpu6050_range_t)value;
  118. }
  119. void MPU6050::setDHPFMode(mpu6050_dhpf_t dhpf)
  120. {
  121. uint8_t value;
  122. value = readRegister8(MPU6050_REG_ACCEL_CONFIG);
  123. value &= 0b11111000;
  124. value |= dhpf;
  125. writeRegister8(MPU6050_REG_ACCEL_CONFIG, value);
  126. }
  127. void MPU6050::setDLPFMode(mpu6050_dlpf_t dlpf)
  128. {
  129. uint8_t value;
  130. value = readRegister8(MPU6050_REG_CONFIG);
  131. value &= 0b11111000;
  132. value |= dlpf;
  133. writeRegister8(MPU6050_REG_CONFIG, value);
  134. }
  135. void MPU6050::setClockSource(mpu6050_clockSource_t source)
  136. {
  137. uint8_t value;
  138. value = readRegister8(MPU6050_REG_PWR_MGMT_1);
  139. value &= 0b11111000;
  140. value |= source;
  141. writeRegister8(MPU6050_REG_PWR_MGMT_1, value);
  142. }
  143. mpu6050_clockSource_t MPU6050::getClockSource(void)
  144. {
  145. uint8_t value;
  146. value = readRegister8(MPU6050_REG_PWR_MGMT_1);
  147. value &= 0b00000111;
  148. return (mpu6050_clockSource_t)value;
  149. }
  150. bool MPU6050::getSleepEnabled(void)
  151. {
  152. return readRegisterBit(MPU6050_REG_PWR_MGMT_1, 6);
  153. }
  154. void MPU6050::setSleepEnabled(bool state)
  155. {
  156. writeRegisterBit(MPU6050_REG_PWR_MGMT_1, 6, state);
  157. }
  158. bool MPU6050::getIntZeroMotionEnabled(void)
  159. {
  160. return readRegisterBit(MPU6050_REG_INT_ENABLE, 5);
  161. }
  162. void MPU6050::setIntZeroMotionEnabled(bool state)
  163. {
  164. writeRegisterBit(MPU6050_REG_INT_ENABLE, 5, state);
  165. }
  166. bool MPU6050::getIntMotionEnabled(void)
  167. {
  168. return readRegisterBit(MPU6050_REG_INT_ENABLE, 6);
  169. }
  170. void MPU6050::setIntMotionEnabled(bool state)
  171. {
  172. writeRegisterBit(MPU6050_REG_INT_ENABLE, 6, state);
  173. }
  174. bool MPU6050::getIntFreeFallEnabled(void)
  175. {
  176. return readRegisterBit(MPU6050_REG_INT_ENABLE, 7);
  177. }
  178. void MPU6050::setIntFreeFallEnabled(bool state)
  179. {
  180. writeRegisterBit(MPU6050_REG_INT_ENABLE, 7, state);
  181. }
  182. uint8_t MPU6050::getMotionDetectionThreshold(void)
  183. {
  184. return readRegister8(MPU6050_REG_MOT_THRESHOLD);
  185. }
  186. void MPU6050::setMotionDetectionThreshold(uint8_t threshold)
  187. {
  188. writeRegister8(MPU6050_REG_MOT_THRESHOLD, threshold);
  189. }
  190. uint8_t MPU6050::getMotionDetectionDuration(void)
  191. {
  192. return readRegister8(MPU6050_REG_MOT_DURATION);
  193. }
  194. void MPU6050::setMotionDetectionDuration(uint8_t duration)
  195. {
  196. writeRegister8(MPU6050_REG_MOT_DURATION, duration);
  197. }
  198. uint8_t MPU6050::getZeroMotionDetectionThreshold(void)
  199. {
  200. return readRegister8(MPU6050_REG_ZMOT_THRESHOLD);
  201. }
  202. void MPU6050::setZeroMotionDetectionThreshold(uint8_t threshold)
  203. {
  204. writeRegister8(MPU6050_REG_ZMOT_THRESHOLD, threshold);
  205. }
  206. uint8_t MPU6050::getZeroMotionDetectionDuration(void)
  207. {
  208. return readRegister8(MPU6050_REG_ZMOT_DURATION);
  209. }
  210. void MPU6050::setZeroMotionDetectionDuration(uint8_t duration)
  211. {
  212. writeRegister8(MPU6050_REG_ZMOT_DURATION, duration);
  213. }
  214. uint8_t MPU6050::getFreeFallDetectionThreshold(void)
  215. {
  216. return readRegister8(MPU6050_REG_FF_THRESHOLD);
  217. }
  218. void MPU6050::setFreeFallDetectionThreshold(uint8_t threshold)
  219. {
  220. writeRegister8(MPU6050_REG_FF_THRESHOLD, threshold);
  221. }
  222. uint8_t MPU6050::getFreeFallDetectionDuration(void)
  223. {
  224. return readRegister8(MPU6050_REG_FF_DURATION);
  225. }
  226. void MPU6050::setFreeFallDetectionDuration(uint8_t duration)
  227. {
  228. writeRegister8(MPU6050_REG_FF_DURATION, duration);
  229. }
  230. bool MPU6050::getI2CMasterModeEnabled(void)
  231. {
  232. return readRegisterBit(MPU6050_REG_USER_CTRL, 5);
  233. }
  234. void MPU6050::setI2CMasterModeEnabled(bool state)
  235. {
  236. writeRegisterBit(MPU6050_REG_USER_CTRL, 5, state);
  237. }
  238. void MPU6050::setI2CBypassEnabled(bool state)
  239. {
  240. return writeRegisterBit(MPU6050_REG_INT_PIN_CFG, 1, state);
  241. }
  242. bool MPU6050::getI2CBypassEnabled(void)
  243. {
  244. return readRegisterBit(MPU6050_REG_INT_PIN_CFG, 1);
  245. }
  246. void MPU6050::setAccelPowerOnDelay(mpu6050_onDelay_t delay)
  247. {
  248. uint8_t value;
  249. value = readRegister8(MPU6050_REG_MOT_DETECT_CTRL);
  250. value &= 0b11001111;
  251. value |= (delay << 4);
  252. writeRegister8(MPU6050_REG_MOT_DETECT_CTRL, value);
  253. }
  254. mpu6050_onDelay_t MPU6050::getAccelPowerOnDelay(void)
  255. {
  256. uint8_t value;
  257. value = readRegister8(MPU6050_REG_MOT_DETECT_CTRL);
  258. value &= 0b00110000;
  259. return (mpu6050_onDelay_t)(value >> 4);
  260. }
  261. uint8_t MPU6050::getIntStatus(void)
  262. {
  263. return readRegister8(MPU6050_REG_INT_STATUS);
  264. }
  265. Activites MPU6050::readActivites(void)
  266. {
  267. uint8_t data = readRegister8(MPU6050_REG_INT_STATUS);
  268. a.isOverflow = ((data >> 4) & 1);
  269. a.isFreeFall = ((data >> 7) & 1);
  270. a.isInactivity = ((data >> 5) & 1);
  271. a.isActivity = ((data >> 6) & 1);
  272. a.isDataReady = ((data >> 0) & 1);
  273. data = readRegister8(MPU6050_REG_MOT_DETECT_STATUS);
  274. a.isNegActivityOnX = ((data >> 7) & 1);
  275. a.isPosActivityOnX = ((data >> 6) & 1);
  276. a.isNegActivityOnY = ((data >> 5) & 1);
  277. a.isPosActivityOnY = ((data >> 4) & 1);
  278. a.isNegActivityOnZ = ((data >> 3) & 1);
  279. a.isPosActivityOnZ = ((data >> 2) & 1);
  280. return a;
  281. }
  282. Vector MPU6050::readRawAccel(void)
  283. {
  284. Wire.beginTransmission(mpuAddress);
  285. #if ARDUINO >= 100
  286. Wire.write(MPU6050_REG_ACCEL_XOUT_H);
  287. #else
  288. Wire.send(MPU6050_REG_ACCEL_XOUT_H);
  289. #endif
  290. Wire.endTransmission();
  291. Wire.beginTransmission(mpuAddress);
  292. Wire.requestFrom(mpuAddress, 6);
  293. while (Wire.available() < 6);
  294. #if ARDUINO >= 100
  295. uint8_t xha = Wire.read();
  296. uint8_t xla = Wire.read();
  297. uint8_t yha = Wire.read();
  298. uint8_t yla = Wire.read();
  299. uint8_t zha = Wire.read();
  300. uint8_t zla = Wire.read();
  301. #else
  302. uint8_t xha = Wire.receive();
  303. uint8_t xla = Wire.receive();
  304. uint8_t yha = Wire.receive();
  305. uint8_t yla = Wire.receive();
  306. uint8_t zha = Wire.receive();
  307. uint8_t zla = Wire.receive();
  308. #endif
  309. ra.XAxis = xha << 8 | xla;
  310. ra.YAxis = yha << 8 | yla;
  311. ra.ZAxis = zha << 8 | zla;
  312. return ra;
  313. }
  314. Vector MPU6050::readNormalizeAccel(void)
  315. {
  316. readRawAccel();
  317. na.XAxis = ra.XAxis * rangePerDigit * 9.80665f;
  318. na.YAxis = ra.YAxis * rangePerDigit * 9.80665f;
  319. na.ZAxis = ra.ZAxis * rangePerDigit * 9.80665f;
  320. return na;
  321. }
  322. Vector MPU6050::readScaledAccel(void)
  323. {
  324. readRawAccel();
  325. na.XAxis = ra.XAxis * rangePerDigit;
  326. na.YAxis = ra.YAxis * rangePerDigit;
  327. na.ZAxis = ra.ZAxis * rangePerDigit;
  328. return na;
  329. }
  330. Vector MPU6050::readRawGyro(void)
  331. {
  332. Wire.beginTransmission(mpuAddress);
  333. #if ARDUINO >= 100
  334. Wire.write(MPU6050_REG_GYRO_XOUT_H);
  335. #else
  336. Wire.send(MPU6050_REG_GYRO_XOUT_H);
  337. #endif
  338. Wire.endTransmission();
  339. Wire.beginTransmission(mpuAddress);
  340. Wire.requestFrom(mpuAddress, 6);
  341. while (Wire.available() < 6);
  342. #if ARDUINO >= 100
  343. uint8_t xha = Wire.read();
  344. uint8_t xla = Wire.read();
  345. uint8_t yha = Wire.read();
  346. uint8_t yla = Wire.read();
  347. uint8_t zha = Wire.read();
  348. uint8_t zla = Wire.read();
  349. #else
  350. uint8_t xha = Wire.receive();
  351. uint8_t xla = Wire.receive();
  352. uint8_t yha = Wire.receive();
  353. uint8_t yla = Wire.receive();
  354. uint8_t zha = Wire.receive();
  355. uint8_t zla = Wire.receive();
  356. #endif
  357. rg.XAxis = xha << 8 | xla;
  358. rg.YAxis = yha << 8 | yla;
  359. rg.ZAxis = zha << 8 | zla;
  360. return rg;
  361. }
  362. Vector MPU6050::readNormalizeGyro(void)
  363. {
  364. readRawGyro();
  365. if (useCalibrate)
  366. {
  367. ng.XAxis = (rg.XAxis - dg.XAxis) * dpsPerDigit;
  368. ng.YAxis = (rg.YAxis - dg.YAxis) * dpsPerDigit;
  369. ng.ZAxis = (rg.ZAxis - dg.ZAxis) * dpsPerDigit;
  370. } else
  371. {
  372. ng.XAxis = rg.XAxis * dpsPerDigit;
  373. ng.YAxis = rg.YAxis * dpsPerDigit;
  374. ng.ZAxis = rg.ZAxis * dpsPerDigit;
  375. }
  376. if (actualThreshold)
  377. {
  378. if (abs(ng.XAxis) < tg.XAxis) ng.XAxis = 0;
  379. if (abs(ng.YAxis) < tg.YAxis) ng.YAxis = 0;
  380. if (abs(ng.ZAxis) < tg.ZAxis) ng.ZAxis = 0;
  381. }
  382. return ng;
  383. }
  384. float MPU6050::readTemperature(void)
  385. {
  386. int16_t T;
  387. T = readRegister16(MPU6050_REG_TEMP_OUT_H);
  388. return (float)T/340 + 36.53;
  389. }
  390. int16_t MPU6050::getGyroOffsetX(void)
  391. {
  392. return readRegister16(MPU6050_REG_GYRO_XOFFS_H);
  393. }
  394. int16_t MPU6050::getGyroOffsetY(void)
  395. {
  396. return readRegister16(MPU6050_REG_GYRO_YOFFS_H);
  397. }
  398. int16_t MPU6050::getGyroOffsetZ(void)
  399. {
  400. return readRegister16(MPU6050_REG_GYRO_ZOFFS_H);
  401. }
  402. void MPU6050::setGyroOffsetX(int16_t offset)
  403. {
  404. writeRegister16(MPU6050_REG_GYRO_XOFFS_H, offset);
  405. }
  406. void MPU6050::setGyroOffsetY(int16_t offset)
  407. {
  408. writeRegister16(MPU6050_REG_GYRO_YOFFS_H, offset);
  409. }
  410. void MPU6050::setGyroOffsetZ(int16_t offset)
  411. {
  412. writeRegister16(MPU6050_REG_GYRO_ZOFFS_H, offset);
  413. }
  414. int16_t MPU6050::getAccelOffsetX(void)
  415. {
  416. return readRegister16(MPU6050_REG_ACCEL_XOFFS_H);
  417. }
  418. int16_t MPU6050::getAccelOffsetY(void)
  419. {
  420. return readRegister16(MPU6050_REG_ACCEL_YOFFS_H);
  421. }
  422. int16_t MPU6050::getAccelOffsetZ(void)
  423. {
  424. return readRegister16(MPU6050_REG_ACCEL_ZOFFS_H);
  425. }
  426. void MPU6050::setAccelOffsetX(int16_t offset)
  427. {
  428. writeRegister16(MPU6050_REG_ACCEL_XOFFS_H, offset);
  429. }
  430. void MPU6050::setAccelOffsetY(int16_t offset)
  431. {
  432. writeRegister16(MPU6050_REG_ACCEL_YOFFS_H, offset);
  433. }
  434. void MPU6050::setAccelOffsetZ(int16_t offset)
  435. {
  436. writeRegister16(MPU6050_REG_ACCEL_ZOFFS_H, offset);
  437. }
  438. // Calibrate algorithm
  439. void MPU6050::calibrateGyro(uint8_t samples)
  440. {
  441. // Set calibrate
  442. useCalibrate = true;
  443. // Reset values
  444. float sumX = 0;
  445. float sumY = 0;
  446. float sumZ = 0;
  447. float sigmaX = 0;
  448. float sigmaY = 0;
  449. float sigmaZ = 0;
  450. // Read n-samples
  451. for (uint8_t i = 0; i < samples; ++i)
  452. {
  453. readRawGyro();
  454. sumX += rg.XAxis;
  455. sumY += rg.YAxis;
  456. sumZ += rg.ZAxis;
  457. sigmaX += rg.XAxis * rg.XAxis;
  458. sigmaY += rg.YAxis * rg.YAxis;
  459. sigmaZ += rg.ZAxis * rg.ZAxis;
  460. delay(5);
  461. }
  462. // Calculate delta vectors
  463. dg.XAxis = sumX / samples;
  464. dg.YAxis = sumY / samples;
  465. dg.ZAxis = sumZ / samples;
  466. // Calculate threshold vectors
  467. th.XAxis = sqrt((sigmaX / 50) - (dg.XAxis * dg.XAxis));
  468. th.YAxis = sqrt((sigmaY / 50) - (dg.YAxis * dg.YAxis));
  469. th.ZAxis = sqrt((sigmaZ / 50) - (dg.ZAxis * dg.ZAxis));
  470. // If already set threshold, recalculate threshold vectors
  471. if (actualThreshold > 0)
  472. {
  473. setThreshold(actualThreshold);
  474. }
  475. }
  476. // Get current threshold value
  477. uint8_t MPU6050::getThreshold(void)
  478. {
  479. return actualThreshold;
  480. }
  481. // Set treshold value
  482. void MPU6050::setThreshold(uint8_t multiple)
  483. {
  484. if (multiple > 0)
  485. {
  486. // If not calibrated, need calibrate
  487. if (!useCalibrate)
  488. {
  489. calibrateGyro();
  490. }
  491. // Calculate threshold vectors
  492. tg.XAxis = th.XAxis * multiple;
  493. tg.YAxis = th.YAxis * multiple;
  494. tg.ZAxis = th.ZAxis * multiple;
  495. } else
  496. {
  497. // No threshold
  498. tg.XAxis = 0;
  499. tg.YAxis = 0;
  500. tg.ZAxis = 0;
  501. }
  502. // Remember old threshold value
  503. actualThreshold = multiple;
  504. }
  505. // Fast read 8-bit from register
  506. uint8_t MPU6050::fastRegister8(uint8_t reg)
  507. {
  508. uint8_t value;
  509. Wire.beginTransmission(mpuAddress);
  510. #if ARDUINO >= 100
  511. Wire.write(reg);
  512. #else
  513. Wire.send(reg);
  514. #endif
  515. Wire.endTransmission();
  516. Wire.beginTransmission(mpuAddress);
  517. Wire.requestFrom(mpuAddress, 1);
  518. #if ARDUINO >= 100
  519. value = Wire.read();
  520. #else
  521. value = Wire.receive();
  522. #endif;
  523. Wire.endTransmission();
  524. return value;
  525. }
  526. // Read 8-bit from register
  527. uint8_t MPU6050::readRegister8(uint8_t reg)
  528. {
  529. uint8_t value;
  530. Wire.beginTransmission(mpuAddress);
  531. #if ARDUINO >= 100
  532. Wire.write(reg);
  533. #else
  534. Wire.send(reg);
  535. #endif
  536. Wire.endTransmission();
  537. Wire.beginTransmission(mpuAddress);
  538. Wire.requestFrom(mpuAddress, 1);
  539. while(!Wire.available()) {};
  540. #if ARDUINO >= 100
  541. value = Wire.read();
  542. #else
  543. value = Wire.receive();
  544. #endif;
  545. Wire.endTransmission();
  546. return value;
  547. }
  548. // Write 8-bit to register
  549. void MPU6050::writeRegister8(uint8_t reg, uint8_t value)
  550. {
  551. Wire.beginTransmission(mpuAddress);
  552. #if ARDUINO >= 100
  553. Wire.write(reg);
  554. Wire.write(value);
  555. #else
  556. Wire.send(reg);
  557. Wire.send(value);
  558. #endif
  559. Wire.endTransmission();
  560. }
  561. int16_t MPU6050::readRegister16(uint8_t reg)
  562. {
  563. int16_t value;
  564. Wire.beginTransmission(mpuAddress);
  565. #if ARDUINO >= 100
  566. Wire.write(reg);
  567. #else
  568. Wire.send(reg);
  569. #endif
  570. Wire.endTransmission();
  571. Wire.beginTransmission(mpuAddress);
  572. Wire.requestFrom(mpuAddress, 2);
  573. while(!Wire.available()) {};
  574. #if ARDUINO >= 100
  575. uint8_t vha = Wire.read();
  576. uint8_t vla = Wire.read();
  577. #else
  578. uint8_t vha = Wire.receive();
  579. uint8_t vla = Wire.receive();
  580. #endif;
  581. Wire.endTransmission();
  582. value = vha << 8 | vla;
  583. return value;
  584. }
  585. void MPU6050::writeRegister16(uint8_t reg, int16_t value)
  586. {
  587. Wire.beginTransmission(mpuAddress);
  588. #if ARDUINO >= 100
  589. Wire.write(reg);
  590. Wire.write((uint8_t)(value >> 8));
  591. Wire.write((uint8_t)value);
  592. #else
  593. Wire.send(reg);
  594. Wire.send((uint8_t)(value >> 8));
  595. Wire.send((uint8_t)value);
  596. #endif
  597. Wire.endTransmission();
  598. }
  599. // Read register bit
  600. bool MPU6050::readRegisterBit(uint8_t reg, uint8_t pos)
  601. {
  602. uint8_t value;
  603. value = readRegister8(reg);
  604. return ((value >> pos) & 1);
  605. }
  606. // Write register bit
  607. void MPU6050::writeRegisterBit(uint8_t reg, uint8_t pos, bool state)
  608. {
  609. uint8_t value;
  610. value = readRegister8(reg);
  611. if (state)
  612. {
  613. value |= (1 << pos);
  614. } else
  615. {
  616. value &= ~(1 << pos);
  617. }
  618. writeRegister8(reg, value);
  619. }