Sensors.ino 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /* This file is part of the Razor AHRS Firmware */
  2. // I2C code to read the sensors
  3. // Sensor I2C addresses
  4. #define ACCEL_ADDRESS ((int) 0x53) // 0x53 = 0xA6 / 2
  5. #define MAGN_ADDRESS ((int) 0x1E) // 0x1E = 0x3C / 2
  6. #define GYRO_ADDRESS ((int) 0x68) // 0x68 = 0xD0 / 2
  7. // Arduino backward compatibility macros
  8. #if ARDUINO >= 100
  9. #define WIRE_SEND(b) Wire.write((byte) b)
  10. #define WIRE_RECEIVE() Wire.read()
  11. #else
  12. #define WIRE_SEND(b) Wire.send(b)
  13. #define WIRE_RECEIVE() Wire.receive()
  14. #endif
  15. void I2C_Init()
  16. {
  17. Wire.begin();
  18. }
  19. void Accel_Init()
  20. {
  21. Wire.beginTransmission(ACCEL_ADDRESS);
  22. WIRE_SEND(0x2D); // Power register
  23. WIRE_SEND(0x08); // Measurement mode
  24. Wire.endTransmission();
  25. delay(5);
  26. Wire.beginTransmission(ACCEL_ADDRESS);
  27. WIRE_SEND(0x31); // Data format register
  28. WIRE_SEND(0x08); // Set to full resolution
  29. Wire.endTransmission();
  30. delay(5);
  31. // Because our main loop runs at 50Hz we adjust the output data rate to 50Hz (25Hz bandwidth)
  32. Wire.beginTransmission(ACCEL_ADDRESS);
  33. WIRE_SEND(0x2C); // Rate
  34. WIRE_SEND(0x09); // Set to 50Hz, normal operation
  35. Wire.endTransmission();
  36. delay(5);
  37. }
  38. // Reads x, y and z accelerometer registers
  39. void Read_Accel()
  40. {
  41. int i = 0;
  42. byte buff[6];
  43. Wire.beginTransmission(ACCEL_ADDRESS);
  44. WIRE_SEND(0x32); // Send address to read from
  45. Wire.endTransmission();
  46. Wire.beginTransmission(ACCEL_ADDRESS);
  47. Wire.requestFrom(ACCEL_ADDRESS, 6); // Request 6 bytes
  48. while(Wire.available()) // ((Wire.available())&&(i<6))
  49. {
  50. buff[i] = WIRE_RECEIVE(); // Read one byte
  51. i++;
  52. }
  53. Wire.endTransmission();
  54. if (i == 6) // All bytes received?
  55. {
  56. // No multiply by -1 for coordinate system transformation here, because of double negation:
  57. // We want the gravity vector, which is negated acceleration vector.
  58. accel[0] = (((int) buff[3]) << 8) | buff[2]; // X axis (internal sensor y axis)
  59. accel[1] = (((int) buff[1]) << 8) | buff[0]; // Y axis (internal sensor x axis)
  60. accel[2] = (((int) buff[5]) << 8) | buff[4]; // Z axis (internal sensor z axis)
  61. }
  62. else
  63. {
  64. num_accel_errors++;
  65. if (output_errors) Serial.println("!ERR: reading accelerometer");
  66. }
  67. }
  68. void Magn_Init()
  69. {
  70. Wire.beginTransmission(MAGN_ADDRESS);
  71. WIRE_SEND(0x02);
  72. WIRE_SEND(0x00); // Set continuous mode (default 10Hz)
  73. Wire.endTransmission();
  74. delay(5);
  75. Wire.beginTransmission(MAGN_ADDRESS);
  76. WIRE_SEND(0x00);
  77. WIRE_SEND(0b00011000); // Set 50Hz
  78. Wire.endTransmission();
  79. delay(5);
  80. }
  81. void Read_Magn()
  82. {
  83. int i = 0;
  84. byte buff[6];
  85. Wire.beginTransmission(MAGN_ADDRESS);
  86. WIRE_SEND(0x03); // Send address to read from
  87. Wire.endTransmission();
  88. Wire.beginTransmission(MAGN_ADDRESS);
  89. Wire.requestFrom(MAGN_ADDRESS, 6); // Request 6 bytes
  90. while(Wire.available()) // ((Wire.available())&&(i<6))
  91. {
  92. buff[i] = WIRE_RECEIVE(); // Read one byte
  93. i++;
  94. }
  95. Wire.endTransmission();
  96. if (i == 6) // All bytes received?
  97. {
  98. // 9DOF Razor IMU SEN-10125 using HMC5843 magnetometer
  99. #if HW__VERSION_CODE == 10125
  100. // MSB byte first, then LSB; X, Y, Z
  101. magnetom[0] = -1 * ((((int) buff[2]) << 8) | buff[3]); // X axis (internal sensor -y axis)
  102. magnetom[1] = -1 * ((((int) buff[0]) << 8) | buff[1]); // Y axis (internal sensor -x axis)
  103. magnetom[2] = -1 * ((((int) buff[4]) << 8) | buff[5]); // Z axis (internal sensor -z axis)
  104. // 9DOF Razor IMU SEN-10736 using HMC5883L magnetometer
  105. #elif HW__VERSION_CODE == 10736
  106. // MSB byte first, then LSB; Y and Z reversed: X, Z, Y
  107. magnetom[0] = -1 * ((((int) buff[4]) << 8) | buff[5]); // X axis (internal sensor -y axis)
  108. magnetom[1] = -1 * ((((int) buff[0]) << 8) | buff[1]); // Y axis (internal sensor -x axis)
  109. magnetom[2] = -1 * ((((int) buff[2]) << 8) | buff[3]); // Z axis (internal sensor -z axis)
  110. // 9DOF Sensor Stick SEN-10183 and SEN-10321 using HMC5843 magnetometer
  111. #elif (HW__VERSION_CODE == 10183) || (HW__VERSION_CODE == 10321)
  112. // MSB byte first, then LSB; X, Y, Z
  113. magnetom[0] = (((int) buff[0]) << 8) | buff[1]; // X axis (internal sensor x axis)
  114. magnetom[1] = -1 * ((((int) buff[2]) << 8) | buff[3]); // Y axis (internal sensor -y axis)
  115. magnetom[2] = -1 * ((((int) buff[4]) << 8) | buff[5]); // Z axis (internal sensor -z axis)
  116. // 9DOF Sensor Stick SEN-10724 using HMC5883L magnetometer
  117. #elif HW__VERSION_CODE == 10724
  118. // MSB byte first, then LSB; Y and Z reversed: X, Z, Y
  119. magnetom[0] = (((int) buff[0]) << 8) | buff[1]; // X axis (internal sensor x axis)
  120. magnetom[1] = -1 * ((((int) buff[4]) << 8) | buff[5]); // Y axis (internal sensor -y axis)
  121. magnetom[2] = -1 * ((((int) buff[2]) << 8) | buff[3]); // Z axis (internal sensor -z axis)
  122. #endif
  123. }
  124. else
  125. {
  126. num_magn_errors++;
  127. if (output_errors) Serial.println("!ERR: reading magnetometer");
  128. }
  129. }
  130. void Gyro_Init()
  131. {
  132. // Power up reset defaults
  133. Wire.beginTransmission(GYRO_ADDRESS);
  134. WIRE_SEND(0x3E);
  135. WIRE_SEND(0x80);
  136. Wire.endTransmission();
  137. delay(5);
  138. // Select full-scale range of the gyro sensors
  139. // Set LP filter bandwidth to 42Hz
  140. Wire.beginTransmission(GYRO_ADDRESS);
  141. WIRE_SEND(0x16);
  142. WIRE_SEND(0x1B); // DLPF_CFG = 3, FS_SEL = 3
  143. Wire.endTransmission();
  144. delay(5);
  145. // Set sample rato to 50Hz
  146. Wire.beginTransmission(GYRO_ADDRESS);
  147. WIRE_SEND(0x15);
  148. WIRE_SEND(0x0A); // SMPLRT_DIV = 10 (50Hz)
  149. Wire.endTransmission();
  150. delay(5);
  151. // Set clock to PLL with z gyro reference
  152. Wire.beginTransmission(GYRO_ADDRESS);
  153. WIRE_SEND(0x3E);
  154. WIRE_SEND(0x00);
  155. Wire.endTransmission();
  156. delay(5);
  157. }
  158. // Reads x, y and z gyroscope registers
  159. void Read_Gyro()
  160. {
  161. int i = 0;
  162. byte buff[6];
  163. Wire.beginTransmission(GYRO_ADDRESS);
  164. WIRE_SEND(0x1D); // Sends address to read from
  165. Wire.endTransmission();
  166. Wire.beginTransmission(GYRO_ADDRESS);
  167. Wire.requestFrom(GYRO_ADDRESS, 6); // Request 6 bytes
  168. while(Wire.available()) // ((Wire.available())&&(i<6))
  169. {
  170. buff[i] = WIRE_RECEIVE(); // Read one byte
  171. i++;
  172. }
  173. Wire.endTransmission();
  174. if (i == 6) // All bytes received?
  175. {
  176. gyro[0] = -1 * ((((int) buff[2]) << 8) | buff[3]); // X axis (internal sensor -y axis)
  177. gyro[1] = -1 * ((((int) buff[0]) << 8) | buff[1]); // Y axis (internal sensor -x axis)
  178. gyro[2] = -1 * ((((int) buff[4]) << 8) | buff[5]); // Z axis (internal sensor -z axis)
  179. }
  180. else
  181. {
  182. num_gyro_errors++;
  183. if (output_errors) Serial.println("!ERR: reading gyroscope");
  184. }
  185. }