BrickUp API Service for Docker version.

HMC5883L.cpp 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*****************************************************************************/
  2. // Function: Cpp file for HMC5883L
  3. // Hardware: Grove - 3-Axis Digital Compass
  4. // Arduino IDE: Arduino-1.0
  5. // Author: FrankieChu
  6. // Date: Jan 10,2013
  7. // Version: v1.0
  8. // by www.seeedstudio.com
  9. //
  10. // This library is free software; you can redistribute it and/or
  11. // modify it under the terms of the GNU Lesser General Public
  12. // License as published by the Free Software Foundation; either
  13. // version 2.1 of the License, or (at your option) any later version.
  14. //
  15. // This library is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. // Lesser General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU Lesser General Public
  21. // License along with this library; if not, write to the Free Software
  22. // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. //
  24. /*******************************************************************************/
  25. #include <Arduino.h>
  26. #include "HMC5883L.h"
  27. HMC5883L::HMC5883L()
  28. {
  29. m_Scale = 1;
  30. }
  31. void HMC5883L::initCompass()
  32. {
  33. delay(5);
  34. int error = setScale(1.3); // Set the scale of the compass.
  35. if(error != 0) // If there is an error, print it out.
  36. {
  37. Serial.println(getErrorText(error));
  38. }
  39. error = setMeasurementMode(MEASUREMENT_CONTINUOUS); // Set the measurement mode to Continuous
  40. if(error != 0) // If there is an error, print it out.
  41. {
  42. Serial.println(getErrorText(error));
  43. }
  44. #if __Dbg
  45. //cout << "val_origin = " << val_origin << endl;
  46. //cout <<"init ok" << endl;
  47. #endif
  48. }
  49. int HMC5883L::getCompass()
  50. {
  51. MagnetometerRaw raw = readRawAxis();
  52. // Retrived the scaled values from the compass (scaled to the configured scale).
  53. MagnetometerScaled scaled = readScaledAxis();
  54. // Values are accessed like so:
  55. int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)
  56. // Calculate heading when the magnetometer is level, then correct for signs of axis.
  57. float heading = atan2(scaled.YAxis, scaled.XAxis);
  58. // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
  59. // Find yours here: http://www.magnetic-declination.com/
  60. // Mine is: -2??37' which is -2.617 Degrees, or (which we need) -0.0456752665 radians, I will use -0.0457
  61. // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
  62. float declinationAngle = -0.0457;
  63. heading += declinationAngle;
  64. // Correct for when signs are reversed.
  65. if(heading < 0)
  66. heading += 2*PI;
  67. // Check for wrap due to addition of declination.
  68. if(heading > 2*PI)
  69. heading -= 2*PI;
  70. // Convert radians to degrees for readability.
  71. float headingDegrees = heading * 180/M_PI;
  72. // Output the data via the serial port.
  73. int degree = headingDegrees*10;
  74. return degree;
  75. }
  76. MagnetometerRaw HMC5883L::readRawAxis()
  77. {
  78. uint8_t* buffer = read(DATA_REGISTER_BEGIN, 6);
  79. MagnetometerRaw raw = MagnetometerRaw();
  80. raw.XAxis = (buffer[0] << 8) | buffer[1];
  81. raw.ZAxis = (buffer[2] << 8) | buffer[3];
  82. raw.YAxis = (buffer[4] << 8) | buffer[5];
  83. return raw;
  84. }
  85. MagnetometerScaled HMC5883L::readScaledAxis()
  86. {
  87. MagnetometerRaw raw = readRawAxis();
  88. MagnetometerScaled scaled = MagnetometerScaled();
  89. scaled.XAxis = raw.XAxis * m_Scale;
  90. scaled.ZAxis = raw.ZAxis * m_Scale;
  91. scaled.YAxis = raw.YAxis * m_Scale;
  92. return scaled;
  93. }
  94. short HMC5883L::setScale(float gauss)
  95. {
  96. uint8_t regValue = 0x00;
  97. if(gauss == 0.88)
  98. {
  99. regValue = 0x00;
  100. m_Scale = 0.73;
  101. }
  102. else if(gauss == 1.3)
  103. {
  104. regValue = 0x01;
  105. m_Scale = 0.92;
  106. }
  107. else if(gauss == 1.9)
  108. {
  109. regValue = 0x02;
  110. m_Scale = 1.22;
  111. }
  112. else if(gauss == 2.5)
  113. {
  114. regValue = 0x03;
  115. m_Scale = 1.52;
  116. }
  117. else if(gauss == 4.0)
  118. {
  119. regValue = 0x04;
  120. m_Scale = 2.27;
  121. }
  122. else if(gauss == 4.7)
  123. {
  124. regValue = 0x05;
  125. m_Scale = 2.56;
  126. }
  127. else if(gauss == 5.6)
  128. {
  129. regValue = 0x06;
  130. m_Scale = 3.03;
  131. }
  132. else if(gauss == 8.1)
  133. {
  134. regValue = 0x07;
  135. m_Scale = 4.35;
  136. }
  137. else
  138. return ERRORCODE_1_NUM;
  139. // Setting is in the top 3 bits of the register.
  140. regValue = regValue << 5;
  141. write(CONFIGURATION_REGISTERB, regValue);
  142. }
  143. short HMC5883L::setMeasurementMode(uint8_t mode)
  144. {
  145. write(MODE_REGISTER, mode);
  146. }
  147. void HMC5883L::write(short address, short data)
  148. {
  149. Wire.beginTransmission(HMC5883L_ADDRESS);
  150. Wire.write(address);
  151. Wire.write(data);
  152. Wire.endTransmission();
  153. }
  154. uint8_t* HMC5883L::read(short address, short length)
  155. {
  156. Wire.beginTransmission(HMC5883L_ADDRESS);
  157. Wire.write(address);
  158. Wire.endTransmission();
  159. Wire.beginTransmission(HMC5883L_ADDRESS);
  160. Wire.requestFrom(HMC5883L_ADDRESS, length);
  161. uint8_t buffer[length];
  162. if(Wire.available() == length)
  163. {
  164. for(uint8_t i = 0; i < length; i++)
  165. {
  166. buffer[i] = Wire.read();
  167. }
  168. }
  169. Wire.endTransmission();
  170. return buffer;
  171. }
  172. char* HMC5883L::getErrorText(short errorCode)
  173. {
  174. if(ERRORCODE_1_NUM == 1)
  175. return ERRORCODE_1;
  176. return "Error not defined.";
  177. }