FluxSand 1.0
FluxSand - Interactive Digital Hourglass
Loading...
Searching...
No Matches
Mpu9250 Class Reference

#include <mpu9250.hpp>

Collaboration diagram for Mpu9250:

Public Member Functions

 Mpu9250 (SpiDevice *spi_device, Gpio *gpio_cs, Gpio *gpio_int)
 
void CalibrateThreadTask ()
 
void RegisterDataCallback (const std::function< void(const Type::Vector3 &, const Type::Vector3 &)> &callback)
 Registers a callback function to be called when new data is available.
 
void Initialize ()
 
void ReadData ()
 
void DisplayData ()
 
void WriteMagRegister (uint8_t reg, uint8_t value)
 
void SaveCalibrationData ()
 
void LoadCalibrationData ()
 

Data Fields

SpiDevicespi_device_
 
Gpiogpio_cs_
 
Gpiogpio_int_
 
Type::Vector3 accel_
 
Type::Vector3 gyro_
 
Type::Vector3 mag_
 
Type::Vector3 gyro_delta_
 
Type::Vector3 gyro_bias_ = {0, 0, 0}
 
float temperature_ = 0
 
std::function< void(const Type::Vector3 &accel, const Type::Vector3 &gyro)> data_callback_
 
std::thread calibrate_thread_
 

Static Public Attributes

static constexpr uint8_t WHO_AM_I = 0x75
 
static constexpr uint8_t PWR_MGMT_1 = 0x6B
 
static constexpr uint8_t PWR_MGMT_2 = 0x6C
 
static constexpr uint8_t CONFIG = 0x1A
 
static constexpr uint8_t SMPLRT_DIV = 0x19
 
static constexpr uint8_t GYRO_CONFIG = 0x1B
 
static constexpr uint8_t ACCEL_CONFIG = 0x1C
 
static constexpr uint8_t ACCEL_CONFIG_2 = 0x1D
 
static constexpr uint8_t ACCEL_XOUT_H = 0x3B
 
static constexpr uint8_t GYRO_XOUT_H = 0x43
 
static constexpr uint8_t USER_CTRL = 0x6A
 
static constexpr uint8_t INT_PIN_CFG = 0x37
 
static constexpr uint8_t INT_ENABLE = 0x38
 
static constexpr uint8_t I2C_MST_CTRL = 0x24
 
static constexpr uint8_t I2C_MST_DELAY_CTRL = 0x67
 
static constexpr uint8_t I2C_SLV0_CTRL = 0x27
 
static constexpr uint8_t AK8963_CNTL1_REG = 0x0A
 
static constexpr uint8_t AK8963_CNTL2_REG = 0x0B
 
static constexpr uint8_t AK8963_CNTL2_SRST = 0x01
 

Detailed Description

MPU9250 class

Provides initialization and data retrieval for MPU9250 via SPI.

Definition at line 25 of file mpu9250.hpp.

Constructor & Destructor Documentation

◆ Mpu9250()

Mpu9250::Mpu9250 ( SpiDevice spi_device,
Gpio gpio_cs,
Gpio gpio_int 
)
inline

Constructor

Parameters
spi_devicePointer to an SPI device object
gpio_csPointer to a GPIO object (chip select)

Definition at line 33 of file mpu9250.hpp.

34 : spi_device_(spi_device), gpio_cs_(gpio_cs), gpio_int_(gpio_int) {
35 assert(spi_device_ && gpio_cs_ && gpio_int_);
36
37 Initialize();
39
40 /* Register interrupt callback */
41 gpio_int_->EnableInterruptRisingEdgeWithCallback([this]() { ReadData(); });
42
43 calibrate_thread_ = std::thread(&Mpu9250::CalibrateThreadTask, this);
44 }
void EnableInterruptRisingEdgeWithCallback(Callback cb)
Definition bsp_gpio.hpp:109
void Initialize()
Definition mpu9250.hpp:131
void ReadData()
Definition mpu9250.hpp:197
void LoadCalibrationData()
Definition mpu9250.hpp:291

◆ ~Mpu9250()

Mpu9250::~Mpu9250 ( )
inline

Definition at line 46 of file mpu9250.hpp.

46 {
47 if (calibrate_thread_.joinable()) {
48 calibrate_thread_.join();
49 }
50 }

Member Function Documentation

◆ CalibrateThreadTask()

void Mpu9250::CalibrateThreadTask ( )
inline

Definition at line 52 of file mpu9250.hpp.

52 {
53 while (true) {
54 auto start_time = std::chrono::steady_clock::now();
55 std::chrono::microseconds period_us(1000);
56 std::chrono::steady_clock::time_point next_time =
57 std::chrono::steady_clock::now();
58 uint32_t counter = 0;
59 double gyro_offset_x = 0, gyro_offset_y = 0, gyro_offset_z = 0;
60 static bool cali_done = false;
61
62 if (cali_done) {
63 std::this_thread::sleep_for(std::chrono::seconds(UINT32_MAX));
64 continue;
65 }
66
67 while (true) {
68 if (std::fabsf(gyro_delta_.x) > 0.005 ||
69 std::fabsf(gyro_delta_.y) > 0.005 ||
70 std::fabsf(gyro_delta_.z) > 0.01) {
71 next_time += period_us;
72 std::this_thread::sleep_until(next_time);
73 break;
74 }
75
76 auto now = std::chrono::steady_clock::now();
77 if (now - start_time > std::chrono::seconds(5) &&
78 now - start_time < std::chrono::seconds(30)) {
79 counter++;
80 gyro_offset_x += gyro_.x;
81 gyro_offset_y += gyro_.y;
82 gyro_offset_z += gyro_.z;
83 }
84
85 if (now - start_time > std::chrono::seconds(35) && cali_done == false) {
86 float bias_x =
87 static_cast<float>(gyro_offset_x / static_cast<double>(counter));
88 float bias_y =
89 static_cast<float>(gyro_offset_y / static_cast<double>(counter));
90 float bias_z =
91 static_cast<float>(gyro_offset_z / static_cast<double>(counter));
92
93 if (std::fabsf(bias_x) > 0.005 || std::fabsf(bias_y) > 0.005 ||
94 std::fabsf(bias_z) > 0.005) {
95 gyro_bias_.x += bias_x;
96 gyro_bias_.y += bias_y;
97 gyro_bias_.z += bias_z;
99 std::cout << "Calibration data saved\n";
100 } else {
101 std::cout << "No need to calibrate\n";
102 }
103 cali_done = true;
104 std::cout << "Calibration completed\n";
105 }
106
107 next_time += period_us;
108 std::this_thread::sleep_until(next_time);
109 }
110 }
111 }
void SaveCalibrationData()
Definition mpu9250.hpp:277

◆ DisplayData()

void Mpu9250::DisplayData ( )
inline

Displays the most recently read sensor data.

Definition at line 253 of file mpu9250.hpp.

253 {
254 float accel_intensity = std::sqrt(
255 accel_.x * accel_.x + accel_.y * accel_.y + accel_.z * accel_.z);
256 std::cout << std::format(
257 "Acceleration: [X={:+.4f}, Y={:+.4f}, Z={:+.4f} | Intensity={:+.4f}] | "
258 "Gyroscope: [X={:+.4f}, Y={:+.4f}, Z={:+.4f}] | Temperature: {:+.4f} "
259 "\u00b0C\n",
260 accel_.x, accel_.y, accel_.z, accel_intensity, gyro_.x, gyro_.y,
261 gyro_.z, temperature_);
262 }

◆ Initialize()

void Mpu9250::Initialize ( )
inline

Initializes MPU9250 settings.

Configures power management, digital low-pass filter, sensor ranges, I2C Master mode for the magnetometer, and performs a WHO_AM_I check.

Definition at line 131 of file mpu9250.hpp.

131 {
132 /* Reset and wake up the MPU9250 */
133 spi_device_->WriteRegister(gpio_cs_, PWR_MGMT_1, 0x80);
134 std::this_thread::sleep_for(std::chrono::milliseconds(100));
135
136 /* Read and verify WHO_AM_I register */
137 uint8_t who_am_i = spi_device_->ReadRegister(gpio_cs_, WHO_AM_I);
138 std::cout << std::format("MPU9250 initialized. WHO_AM_I: 0x{:02X}\n",
139 who_am_i);
140
141 if (who_am_i != 0x71 && who_am_i != 0x68 && who_am_i != 0x70) {
142 std::perror(
143 std::format("Error: MPU9250 connection failed (WHO_AM_I: 0x{:02X})",
144 who_am_i)
145 .c_str());
146 }
147
148 /* Gyroscope clock source configuration */
149 spi_device_->WriteRegister(gpio_cs_, PWR_MGMT_1, 0x03);
150
151 /* Enable Accelerometer and Gyroscope */
152 spi_device_->WriteRegister(gpio_cs_, PWR_MGMT_2, 0x00);
153
154 /* INT high level, push-pull */
155 spi_device_->WriteRegister(gpio_cs_, INT_PIN_CFG, 0x10);
156 /* enable data ready interrupt */
157 spi_device_->WriteRegister(gpio_cs_, INT_ENABLE, 0x01);
158
159 spi_device_->WriteRegister(gpio_cs_, I2C_MST_CTRL, 0x4D);
160
161 /* Enable I2C Master mode by setting the I2C_MST_EN bit in USER_CTRL. */
162 spi_device_->WriteRegister(gpio_cs_, USER_CTRL, 0x20);
163
164 /* Enable delay for I2C Slave 0 transfers. */
165 spi_device_->WriteRegister(gpio_cs_, I2C_MST_DELAY_CTRL, 0x01);
166
167 /* Enable I2C communication for external sensors. */
168 spi_device_->WriteRegister(gpio_cs_, I2C_SLV0_CTRL, 0x81);
169
170 /* Configure Digital Low-Pass Filter (DLPF). */
171 spi_device_->WriteRegister(gpio_cs_, CONFIG, 3);
172
173 /* Set the gyroscope sampling rate. */
174 spi_device_->WriteRegister(gpio_cs_, SMPLRT_DIV, 0x00);
175
176 /* Configure gyroscope full-scale range to ±2000°/s. */
177 spi_device_->WriteRegister(gpio_cs_, GYRO_CONFIG, 0x18);
178
179 /* Configure accelerometer full-scale range to ±16g. */
180 spi_device_->WriteRegister(gpio_cs_, ACCEL_CONFIG, 0x18);
181
182 /* Configure accelerometer low-pass filter. */
183 spi_device_->WriteRegister(gpio_cs_, ACCEL_CONFIG_2, 0x00);
184
185 /* Reset the AK8963 magnetometer. */
186 WriteMagRegister(AK8963_CNTL2_REG, AK8963_CNTL2_SRST);
187 std::this_thread::sleep_for(std::chrono::milliseconds(10));
188
189 /* Configure AK8963 magnetometer for continuous measurement mode 1. */
191 std::this_thread::sleep_for(std::chrono::milliseconds(10));
192 }
static constexpr uint8_t WHO_AM_I
Definition mpu9250.hpp:338
void WriteMagRegister(uint8_t reg, uint8_t value)
Definition mpu9250.hpp:270
static constexpr uint8_t AK8963_CNTL1_REG
Definition mpu9250.hpp:356
uint8_t ReadRegister(Gpio *cs, uint8_t reg)
Definition bsp_spi.hpp:58
void WriteRegister(Gpio *cs, uint8_t reg, uint8_t value)
Definition bsp_spi.hpp:88

◆ LoadCalibrationData()

void Mpu9250::LoadCalibrationData ( )
inline

Load the calibration data from a file.

Definition at line 291 of file mpu9250.hpp.

291 {
292 std::ifstream file("cali_data.bin", std::ios::in | std::ios::binary);
293 if (!file) {
294 std::cerr
295 << "MPU9250 calibration file not found. Using default values.\n";
296 return;
297 }
298
299 /* Check file size */
300 file.seekg(0, std::ios::end);
301 std::streamsize file_size = file.tellg();
302 file.seekg(0, std::ios::beg);
303
304 if (file_size != sizeof(gyro_bias_)) {
305 std::cerr
306 << "Error: MPU9250 calibration file size mismatch. Using default "
307 "values.\n";
308 file.close();
309 gyro_bias_ = {0, 0, 0};
310 return;
311 }
312
313 /* Read data */
314 file.read(reinterpret_cast<char*>(&gyro_bias_), sizeof(gyro_bias_));
315 file.close();
316
317 /* Validate data: Ensure gyro_bias values are within a reasonable range */
318 if (std::abs(gyro_bias_.x) > 1.0f || std::abs(gyro_bias_.y) > 1.0f ||
319 std::abs(gyro_bias_.z) > 1.0f || std::isnan(gyro_bias_.x) ||
320 std::isnan(gyro_bias_.y) || std::isnan(gyro_bias_.z) ||
321 std::isinf(gyro_bias_.x) || std::isinf(gyro_bias_.y) ||
322 std::isinf(gyro_bias_.z)) {
323 std::cerr
324 << "Error: MPU9250 invalid calibration data detected. Resetting to "
325 "default values.\n";
326 gyro_bias_ = {0, 0, 0};
327 } else {
328 std::cout << "MPU9250 calibration data loaded successfully: "
329 << "X=" << gyro_bias_.x << ", "
330 << "Y=" << gyro_bias_.y << ", "
331 << "Z=" << gyro_bias_.z << "\n";
332 }
333
334 std::cout << '\n';
335 }

◆ ReadData()

void Mpu9250::ReadData ( )
inline

Reads sensor data for acceleration and gyroscope.

Definition at line 197 of file mpu9250.hpp.

197 {
198 std::array<uint8_t, 14> data{};
199
200 spi_device_->ReadRegisters(gpio_cs_, ACCEL_XOUT_H, &data[0], 14);
201
202 constexpr float ACCEL_SCALE = 16.0f / 32768.0f * 9.80665f;
203 constexpr float GYRO_SCALE = 2000.0f / 32768.0f * M_PI / 180.0f;
204
205 uint8_t* accel_data = &data[0];
206 uint8_t* temperature_data = &data[6];
207 uint8_t* gyro_data = &data[8];
208
209 accel_.z = static_cast<float>(
210 static_cast<int16_t>((accel_data[0] << 8) | accel_data[1])) *
211 ACCEL_SCALE;
212 accel_.y = -static_cast<float>(
213 static_cast<int16_t>((accel_data[2] << 8) | accel_data[3])) *
214 ACCEL_SCALE;
215 accel_.x = static_cast<float>(
216 static_cast<int16_t>((accel_data[4] << 8) | accel_data[5])) *
217 ACCEL_SCALE;
218
219 temperature_ = static_cast<float>(static_cast<int16_t>(
220 (temperature_data[0] << 8) | temperature_data[1])) /
221 333.87f +
222 21.0f;
223
224 float gyro_z = static_cast<float>(static_cast<int16_t>((gyro_data[0] << 8) |
225 gyro_data[1])) *
226 GYRO_SCALE -
227 gyro_bias_.z;
228 float gyro_y = -static_cast<float>(static_cast<int16_t>(
229 (gyro_data[2] << 8) | gyro_data[3])) *
230 GYRO_SCALE -
231 gyro_bias_.y;
232 float gyro_x = static_cast<float>(static_cast<int16_t>((gyro_data[4] << 8) |
233 gyro_data[5])) *
234 GYRO_SCALE -
235 gyro_bias_.x;
236
237 gyro_delta_.x = gyro_x - gyro_.x;
238 gyro_delta_.y = gyro_y - gyro_.y;
239 gyro_delta_.z = gyro_z - gyro_.z;
240
241 gyro_.x = gyro_x;
242 gyro_.y = gyro_y;
243 gyro_.z = gyro_z;
244
245 if (data_callback_) {
246 data_callback_(accel_, gyro_);
247 }
248 }

◆ RegisterDataCallback()

void Mpu9250::RegisterDataCallback ( const std::function< void(const Type::Vector3 &, const Type::Vector3 &)> &  callback)
inline

Registers a callback function to be called when new data is available.

Parameters
callbackThe callback function

Definition at line 119 of file mpu9250.hpp.

121 {
122 data_callback_ = callback;
123 }

◆ SaveCalibrationData()

void Mpu9250::SaveCalibrationData ( )
inline

Save the calibration data to a file.

Definition at line 277 of file mpu9250.hpp.

277 {
278 std::ofstream file("cali_data.bin", std::ios::binary);
279 if (!file) {
280 std::cerr << "Error: Unable to open cali_data.bin for writing.\n";
281 return;
282 }
283 file.write(reinterpret_cast<const char*>(&gyro_bias_), sizeof(gyro_bias_));
284 file.close();
285 std::cout << "Calibration data saved successfully.\n";
286 }

◆ WriteMagRegister()

void Mpu9250::WriteMagRegister ( uint8_t  reg,
uint8_t  value 
)
inline

Writes a value to the AK8963 magnetometer via I2C.

Parameters
regMagnetometer register address
valueValue to write

Definition at line 270 of file mpu9250.hpp.

270 {
271 spi_device_->WriteRegister(gpio_cs_, reg, value);
272 }

Field Documentation

◆ accel_

Type::Vector3 Mpu9250::accel_

Definition at line 364 of file mpu9250.hpp.

◆ ACCEL_CONFIG

constexpr uint8_t Mpu9250::ACCEL_CONFIG = 0x1C
staticconstexpr

Definition at line 344 of file mpu9250.hpp.

◆ ACCEL_CONFIG_2

constexpr uint8_t Mpu9250::ACCEL_CONFIG_2 = 0x1D
staticconstexpr

Definition at line 345 of file mpu9250.hpp.

◆ ACCEL_XOUT_H

constexpr uint8_t Mpu9250::ACCEL_XOUT_H = 0x3B
staticconstexpr

Definition at line 346 of file mpu9250.hpp.

◆ AK8963_CNTL1_REG

constexpr uint8_t Mpu9250::AK8963_CNTL1_REG = 0x0A
staticconstexpr

AK8963 Magnetometer registers

Definition at line 356 of file mpu9250.hpp.

◆ AK8963_CNTL2_REG

constexpr uint8_t Mpu9250::AK8963_CNTL2_REG = 0x0B
staticconstexpr

Definition at line 357 of file mpu9250.hpp.

◆ AK8963_CNTL2_SRST

constexpr uint8_t Mpu9250::AK8963_CNTL2_SRST = 0x01
staticconstexpr

Definition at line 358 of file mpu9250.hpp.

◆ calibrate_thread_

std::thread Mpu9250::calibrate_thread_

Definition at line 376 of file mpu9250.hpp.

◆ CONFIG

constexpr uint8_t Mpu9250::CONFIG = 0x1A
staticconstexpr

Definition at line 341 of file mpu9250.hpp.

◆ data_callback_

std::function<void(const Type::Vector3& accel, const Type::Vector3& gyro)> Mpu9250::data_callback_

Definition at line 374 of file mpu9250.hpp.

◆ gpio_cs_

Gpio* Mpu9250::gpio_cs_

Definition at line 361 of file mpu9250.hpp.

◆ gpio_int_

Gpio* Mpu9250::gpio_int_

Definition at line 362 of file mpu9250.hpp.

◆ gyro_

Type::Vector3 Mpu9250::gyro_

Definition at line 365 of file mpu9250.hpp.

◆ gyro_bias_

Type::Vector3 Mpu9250::gyro_bias_ = {0, 0, 0}

Definition at line 369 of file mpu9250.hpp.

369{0, 0, 0}; /* Gyroscope calibration data */

◆ GYRO_CONFIG

constexpr uint8_t Mpu9250::GYRO_CONFIG = 0x1B
staticconstexpr

Definition at line 343 of file mpu9250.hpp.

◆ gyro_delta_

Type::Vector3 Mpu9250::gyro_delta_

Definition at line 367 of file mpu9250.hpp.

◆ GYRO_XOUT_H

constexpr uint8_t Mpu9250::GYRO_XOUT_H = 0x43
staticconstexpr

Definition at line 347 of file mpu9250.hpp.

◆ I2C_MST_CTRL

constexpr uint8_t Mpu9250::I2C_MST_CTRL = 0x24
staticconstexpr

Definition at line 351 of file mpu9250.hpp.

◆ I2C_MST_DELAY_CTRL

constexpr uint8_t Mpu9250::I2C_MST_DELAY_CTRL = 0x67
staticconstexpr

Definition at line 352 of file mpu9250.hpp.

◆ I2C_SLV0_CTRL

constexpr uint8_t Mpu9250::I2C_SLV0_CTRL = 0x27
staticconstexpr

Definition at line 353 of file mpu9250.hpp.

◆ INT_ENABLE

constexpr uint8_t Mpu9250::INT_ENABLE = 0x38
staticconstexpr

Definition at line 350 of file mpu9250.hpp.

◆ INT_PIN_CFG

constexpr uint8_t Mpu9250::INT_PIN_CFG = 0x37
staticconstexpr

Definition at line 349 of file mpu9250.hpp.

◆ mag_

Type::Vector3 Mpu9250::mag_

Definition at line 366 of file mpu9250.hpp.

◆ PWR_MGMT_1

constexpr uint8_t Mpu9250::PWR_MGMT_1 = 0x6B
staticconstexpr

Definition at line 339 of file mpu9250.hpp.

◆ PWR_MGMT_2

constexpr uint8_t Mpu9250::PWR_MGMT_2 = 0x6C
staticconstexpr

Definition at line 340 of file mpu9250.hpp.

◆ SMPLRT_DIV

constexpr uint8_t Mpu9250::SMPLRT_DIV = 0x19
staticconstexpr

Definition at line 342 of file mpu9250.hpp.

◆ spi_device_

SpiDevice* Mpu9250::spi_device_

Definition at line 360 of file mpu9250.hpp.

◆ temperature_

float Mpu9250::temperature_ = 0

Definition at line 371 of file mpu9250.hpp.

◆ USER_CTRL

constexpr uint8_t Mpu9250::USER_CTRL = 0x6A
staticconstexpr

Definition at line 348 of file mpu9250.hpp.

◆ WHO_AM_I

constexpr uint8_t Mpu9250::WHO_AM_I = 0x75
staticconstexpr

MPU9250 register addresses

Definition at line 338 of file mpu9250.hpp.


The documentation for this class was generated from the following file: