Closed brightproject closed 1 year ago
Have you tried running an I2C scanner program on the microcontroller to verify that it can see the MPU-9250 on the I2C bus and check the I2C address?
Have you tried running an I2C scanner program
Answered above
Why in the example, the bus config I2C
is done like this
imu.Config(&Wire, bfs::Mpu9250::I2C_ADDR_PRIM);
And in the library in the class mpu9250.h
like this
Mpu9250(TwoWire *i2c, const I2cAddr addr
...&Wire...TwoWire
TwoWire is the object type that Arduino defines for I2C. Somewhere in the core software for the board, there is some declaration like: TwoWire Wire(...); TwoWire Wire1(...);
For the library, we're just grabbing a pointer to the I2C bus in use, especially since many boards have multiple I2C buses.
I would also check the I2C address using the scanner to verify whether you should be using I2C_ADDR_PRIM or I2C_ADDR_SEC.
Again checked the I2C address with a scanner.
I am using this core for adruino IDE.
It has a
wire.h
library, and I had to remove the folder from the ARDUINO folder so that there is no conflict, using two libraries.
Later, I returned the folder with the wire.h
library to the ARDUINO folder, and prescribed the use of the library
#include <Wire.h>
and
#include "Wire.h>"
But the result is the same.
It seems to me that the STM32 compiler does not understand instructions...
static_cast
I think problem in here
#if defined(ARDUINO)
#include <Arduino.h>
#include <Wire.h>
#include "SPI.h"
#else
#include <cstddef>
#include <cstdint>
#include "core/core.h"
#endif
#include "invensense_imu.h" // NOLINT
Was this library tested on STM32? What core does this library use? Perhaps there is no correlation with initialization I2C? https://github.com/stm32duino/Arduino_Core_STM32/wiki/API#i2C
@flybrianfly If commented section while
in code
if (!imu.Begin()) {
Serial.println("Error initializing communication with IMU");
//while (1) {}
}
/* Set the sample rate divider */
if (!imu.ConfigSrd(19)) {
Serial.println("Error configured SRD");
//while (1) {}
}
I see a partial execution of the library code
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.58
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.39
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.39
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.63
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.63
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.63
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.58
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.58
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.73
Unit, apparently
Serial.print(imu.new_imu_data());
And the numbers changing at the end, this is apparently Serial.print(imu.die_temp_c());
If disconnect MPU-9250
from SDA/SCL
.
Then the output stops and lines appear.
Error initializing communication with IMU
Error configured SRD
I don't understand what is happening and why the library cannot configure i2c
.
Somehow, magically, the library reads the temperature values die_temp_c()
and new data new_imu_data()
These values are obtained from MPU-9250
by i2c
or not?
The only library that we managed to launch for STM32
and arduino IDE.
I2C
did not even specify contacts, the library itself determined them.
Accel: -0.01, 0.09, 1.01 g
Gyro: -4.57, 4.51, 1.65 dps
Mag: 0.00, 0.00, 0.00 uT
Time: 118769 ms
Accel: -0.02, 0.12, 1.01 g
Gyro: -4.70, 2.99, 2.01 dps
Mag: 0.00, 0.00, 0.00 uT
Time: 120776 ms
Accel: -0.02, 0.14, 1.01 g
Gyro: -4.45, 3.54, 2.01 dps
Mag: 0.00, 0.00, 0.00 uT
Time: 122785 ms
Accel: -0.04, 0.17, 1.00 g
Gyro: -4.76, 2.99, 2.01 dps
Mag: 0.00, 0.00, 0.00 uT
Time: 124796 ms
Questions only to your library - apparently it is not optimized for stm32f401ccu6
.
And in this library added compatibility Mode with a ESP32
.
Could you change the library to work with stm32 or tell me what could be the reason for initializing(problems with initialization) i2c
?
I also ger Quaternion from mpu9250
by using this sketch
Q: 0.9695, -0.0162, 0.1011, 0.2225
R/P/Y: 4.46, 338.23, 333.72
Time: 1852857 ms
Q: 0.9696, -0.0173, 0.1005, 0.2224
R/P/Y: 4.57, 338.42, 333.73
Time: 1852957 ms
I just don’t understand yet, it seems like the quaternion cannot be calculated without a magnetometer, but I couldn’t read it from the mpu9250
module ... or in the quaternion example, it somehow magically pulled out of the module.
I connected the I2C
bus to logic analyzer and began to see what was happening.
When I uploaded the sketch to the stm32f401ccu6
board, I connect it to port com 6
.
Nothing happens until you hit reset on board.
Packet signals appear on the I2C
bus.
The first three messages begin with writing the address of the sensor
0x69
to the mpu9250
sensor and receiving two responses 0x6B
and 0x01
These are the registers of the
mpu9250
sensor
PWR_MGMNT_1_ = 0x6B;
CLKSEL_PLL_ = 0x01;
Then 7 parcels follow.
Write [0x69] + ACK
0x6B + ACK
PWR_MGMNT_1_ = 0x6B;
Read [0x69] + ACK
0x01 + NAK
INT_RAW_RDY_EN_ = 0x01;
Write [0x69] + ACK
0x6A + ACK
0x20 + ACK
USER_CTRL_ = 0x6A;
I2C_MST_EN_ = 0x20;
This is also followed by parcels, as I understand it, setting up the mpu9250
registers for work.
But everywhere the reading Write [0x69]
from the sensor ends with NAK
The package ends with such parcels.
Well, in the port monitor there is a traditional inscription that the sensor has not been initialized.
Each line is a separate pressing of the RESET button on the BlackPill board and, accordingly, sending those packets that I described above.
Strange ... the library SparkFun is written generally for
SAMD
boards, even when compiling it, a warning appears that the library may not work ... but it works and works fine.
WARNING: The SparkFun_MPU-9250-DMP_Arduino_Library-master library must run on SAMD architectures and may not be compatible with your stm32 board.
The library invensense-imu does not issue any warnings, it compiles perfectly, communicates with the mpu9250
sensor via I2C
and does not work ... a paradox!
I want to deal with the problem, but so far my knowledge is not enough ...
I continue experiments, since the author of the library does not want to figure it out.
I tried to connect the MPU9260
module to the ESP32
via I2C
.
The situation is the same as with stm32f401ccu6
.
As I already wrote, the MPU9260
module works fine with the SparkFun library, and even gives out a quaternion - therefore, the library in some way can "get through" to the magnetometer, because, without a magnetometer signal, the quaternion cannot be calculated ... I could be wrong.
After 3 days of torment with I2C
, which for MPU9260
is generally an "experimental" interface, it was decided to connect via SPI
.
Connecting to stm32
did this:
PA7 - SDA(MOSI)
PA6 - AD0(MISO)
PA5 - SCL(SCK)
PA4 - NCS(CS)
BY RESISTOR 10 kOm TO GND - FSYNC
The SPI protocol starts from command 0x6B
, 0x01
- WriteRegister(PWR_MGMNT_1_, CLKSEL_PLL_)
...Further, there are also parcels on the SPI bus, but there is no normal operation.
bool Mpu9250::Begin() {
imu_.Begin();
/* 1 MHz for config */
spi_clock_ = SPI_CFG_CLOCK_;
/* Select clock source to gyro */
if (!WriteRegister(PWR_MGMNT_1_, CLKSEL_PLL_)) {
return false;
}
/* Enable I2C master mode */
if (!WriteRegister(USER_CTRL_, I2C_MST_EN_)) {
return false;
}
/* Set the I2C bus speed to 400 kHz */
if (!WriteRegister(I2C_MST_CTRL_, I2C_MST_CLK_)) {
return false;
}
/* Set AK8963 to power down */
WriteAk8963Register(AK8963_CNTL1_, AK8963_PWR_DOWN_);
/* Reset the MPU9250 */
WriteRegister(PWR_MGMNT_1_, H_RESET_);
/* Wait for MPU-9250 to come back up */
delay(1);
/* Reset the AK8963 */
WriteAk8963Register(AK8963_CNTL2_, AK8963_RESET_);
/* Select clock source to gyro */
if (!WriteRegister(PWR_MGMNT_1_, CLKSEL_PLL_)) {
return false;
}
/* Check the WHO AM I byte */
if (!ReadRegisters(WHOAMI_, sizeof(who_am_i_), &who_am_i_)) {
return false;
}
if ((who_am_i_ != WHOAMI_MPU9250_) && (who_am_i_ != WHOAMI_MPU9255_)) {
return false;
}
/* Enable I2C master mode */
if (!WriteRegister(USER_CTRL_, I2C_MST_EN_)) {
return false;
}
/* Set the I2C bus speed to 400 kHz */
if (!WriteRegister(I2C_MST_CTRL_, I2C_MST_CLK_)) {
return false;
}
/* Check the AK8963 WHOAMI */
if (!ReadAk8963Registers(AK8963_WHOAMI_, sizeof(who_am_i_), &who_am_i_)) {
return false;
}
if (who_am_i_ != WHOAMI_AK8963_) {
return false;
}
/* Get the magnetometer calibration */
/* Set AK8963 to power down */
if (!WriteAk8963Register(AK8963_CNTL1_, AK8963_PWR_DOWN_)) {
return false;
}
delay(100); // long wait between AK8963 mode changes
/* Set AK8963 to FUSE ROM access */
if (!WriteAk8963Register(AK8963_CNTL1_, AK8963_FUSE_ROM_)) {
return false;
}
delay(100); // long wait between AK8963 mode changes
/* Read the AK8963 ASA registers and compute magnetometer scale factors */
if (!ReadAk8963Registers(AK8963_ASA_, sizeof(asa_buff_), asa_buff_)) {
return false;
}
mag_scale_[0] = ((static_cast<float>(asa_buff_[0]) - 128.0f)
/ 256.0f + 1.0f) * 4912.0f / 32760.0f;
mag_scale_[1] = ((static_cast<float>(asa_buff_[1]) - 128.0f)
/ 256.0f + 1.0f) * 4912.0f / 32760.0f;
mag_scale_[2] = ((static_cast<float>(asa_buff_[2]) - 128.0f)
/ 256.0f + 1.0f) * 4912.0f / 32760.0f;
/* Set AK8963 to power down */
if (!WriteAk8963Register(AK8963_CNTL1_, AK8963_PWR_DOWN_)) {
return false;
}
/* Set AK8963 to 16 bit resolution, 100 Hz update rate */
if (!WriteAk8963Register(AK8963_CNTL1_, AK8963_CNT_MEAS2_)) {
return false;
}
delay(100); // long wait between AK8963 mode changes
/* Select clock source to gyro */
if (!WriteRegister(PWR_MGMNT_1_, CLKSEL_PLL_)) {
return false;
}
/* Set the accel range to 16G by default */
if (!ConfigAccelRange(ACCEL_RANGE_16G)) {
return false;
}
/* Set the gyro range to 2000DPS by default*/
if (!ConfigGyroRange(GYRO_RANGE_2000DPS)) {
return false;
}
/* Set the DLPF to 184HZ by default */
if (!ConfigDlpfBandwidth(DLPF_BANDWIDTH_184HZ)) {
return false;
}
/* Set the SRD to 0 by default */
if (!ConfigSrd(0)) {
return false;
}
return true;
}
Played around with SPI modes in file invensense_imu.cpp
spi_->beginTransaction(SPISettings(spi_clock, MSBFIRST, SPI_MODE3));
//spi_->beginTransaction(SPISettings(spi_clock, MSBFIRST, SPI_MODE2));
//spi_->beginTransaction(SPISettings(spi_clock, MSBFIRST, SPI_MODE1));
//spi_->beginTransaction(SPISettings(spi_clock, MSBFIRST, SPI_MODE0));
\
Changed
CPOL
and CPHA
into logic analizer also.
I study the datasheet, but there are no results yet.
Commented out code while(1) {}
in section SETUP
the lines again
if (!imu.Begin()) {
Serial.println("Error initializing communication with IMU");
//while(1) {}
}
/* Set the sample rate divider */
if (!imu.ConfigSrd(19)) {
Serial.println("Error configured SRD");
//while(1) {}
}
In order for the MPU9250
module to start outputting data and get zeros again, except for the temperature sensor.
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.01
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 31.91
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.01
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 31.91
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 31.86
1 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.10
For the sake of interest, to make sure that the temperature data is fake, I cooled the MPU9250
chip with cold spray, and the temperature dropped to minus 28 degrees Celsius
and then returned to room temperature.
Now the thought does not leave me - why does the
MPU9250
module transmit data on the temperature of its chip in the I2C
bus and via SPI
, but does not give out data on the accelerometer, gyroscope and magnetometer?
It's all about the library and the @flybrianfly can't help.
Or just write that the library was created only for the Tinsy microcontroller and will not work anywhere else...
Although where does the microcontroller Tinsy
?
The library does not work on ESP32 either.
It seems to me that the case is in incorrect registers and calls in writeRegister
and readRegisters
into library.
And also in the bfs namespace
.
Perhaps in the library it is necessary to perform a bit shift
for addresses?
0x69<<1
or 0x68<<1
I have seen this in other libraries.
Confusion with the 7-bit address
for I2C
.
My head is completely confused with these codes ...
But I don't have enough knowledge in programming to finalize the library code.
Can I somehow use this library for the sensor GY-LSM6DS3
?
Because these torments with the
MPU9250
chip, which has already been discontinued, are not worth the time spent.
Which IMU
module is currently modern and can be adapted for this library?
Hi, rudeness will not be tolerated. I was traveling over the weekend to visit family and, always, my order of priority is to satisfy family and work obligations before working on open-source projects. Currently, we have a lot of work projects that are due soon - I've already triaged this issue and it's not something that can be easily fixed, since we don't even know what's wrong yet, so it will have to wait until I have a chance to dive deeper into the potential issue. This will likely be later this fall. I welcome a PR if you are able to solve the issue before then.
We use Teensy boards for development because they are well supported and follow the Arduino core guidelines; so I know that if I use a TwoWire method, it is working as intended. We've been working with these IMUs since they were released and the libraries have been working well for years now. Most issues with the library are due to:
In addition to the Teensy boards, this library has bee used on the STM32L4 boards, ESP32, and AVR. I'm sure there are others that I haven't personally tested, but in general it should work well across Arduino boards.
Still doesn't work on the ESP32 😒. Arduino ESP32 Core: v2.0.13 ESP32 by Espressif Core: v2.0.11
@enoch-prince, can you give more information on the exact processor you're trying to use, the sensor, and the communication method? It should work if it's wired correctly and using a support chip that isn't counterfeit.
Microcontroller![STM32-STM32F4-STM32F401-STM32F401CCU6-pinout-low-resolution](https://github.com/bolderflight/invensense-imu/assets/1788098/9615b9e7-84cc-44e3-9a02-99425d882490)
stm32f401ccu6
Connecting by I2c
SDA-PB7
,SCL-PB6
IMUMPU-9250
I get the following in the port monitor:
I check the presence of the module on the bus I2C using the code:
I receive an address
I2C device found at address 0x68 !