Open laurentvm opened 5 years ago
4 kHz seems about right. I would recommend running the gyro/accel rates at 500 Hz or even 1 kHz, and the mag at 100 Hz.
I see much less "slowness" on my ESP32. Not sure what you are doing wrong. Are you using 400 kHz I2C bus speed and using the interrupt for data ready?
On Tue, Jan 8, 2019 at 12:59 PM laurentvm notifications@github.com wrote:
Running on ESP32, iteraring 5 times the filter each time I get new data from the sensors I have a very slow convergence:
At start, it takes 60 seconds to converge [image: image] https://user-images.githubusercontent.com/37613497/50858305-50016d80-1390-11e9-89a7-3db3f074ee93.png
If I move it, for unknown reason it seems to be faster to converge, but still slow to me [image: image] https://user-images.githubusercontent.com/37613497/50858346-6b6c7880-1390-11e9-8156-2026c842718c.png
Frequency is 4kHz, does that make sense?
8408 a(x,y,z) 1.65 1.83 1008.00 [mg] g(x,y,z) -0.06 -0.01 -0.02 [dps] m(x,y,z) 124 -126 363 [mG] q(0,x,y,z)0.89 -0.19 0.40 0.09 o(y,p,r) 0.88 47.95 -23.40 rate = 3.85 kHz 8513 a(x,y,z) 1.16 1.59 1009.64 [mg] g(x,y,z) -0.09 0.01 -0.08 [dps] m(x,y,z) 121 -111 357 [mG] q(0,x,y,z)0.90 -0.19 0.39 0.09 o(y,p,r) 1.19 47.48 -22.96 rate = 4.17 kHz
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qoMaxBxu77sYycS5l8w8PoyjS9Tcks5vBQavgaJpZM4Z2Q90 .
Hi, I am using your sketch https://github.com/kriswiner/MPU9250/blob/master/MPU9250BasicAHRS_t3.ino where I modified the call to the filter based on https://github.com/kriswiner/MPU9250/blob/master/AK8963_as_slave/AK8963Slave0_MPU9250_Ladybug.ino to add iteration.
Are you using 400 kHz I2C bus speed and using the interrupt for data ready?
On Wed, Jan 9, 2019 at 3:06 PM laurentvm notifications@github.com wrote:
Hi, I am using your sketch https://github.com/kriswiner/MPU9250/blob/master/MPU9250BasicAHRS_t3.ino http://url where I modified the call to the filter based on https://github.com/kriswiner/MPU9250/blob/master/AK8963_as_slave/AK8963Slave0_MPU9250_Ladybug.ino http://url to add iteration.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-452849684, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qjkASYdtr6Rl-LABynUrCP8ccyB_ks5vBl5hgaJpZM4Z2Q90 .
Yes but I have a modified I2C call compared to you
bool initI2C()
{
i2c_port_t i2c_master_port = I2C_NUM_0;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = (gpio_num_t)21;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = (gpio_num_t)22;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
//conf.master.clk_speed = 100000;
conf.master.clk_speed = 400000L;
//400000L
return i2c_param_config(i2c_master_port, &conf) == ESP_OK &&
i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0) == ESP_OK;
}
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL (i2c_ack_type_t)0x0 /*!< I2C ack value */
#define NACK_VAL (i2c_ack_type_t)0x1 /*!< I2C nack value */
// I2C read/write functions for the MPU9250 and AK8963 sensors
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
/*
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.write(data); // Put data in Tx buffer
Wire.endTransmission(); // Send the Tx buffer
*/
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( address << 1 ) | WRITE_BIT, ACK_CHECK_EN);
// write sub-address and data
uint8_t buf[2] = {subAddress, data};
i2c_master_write(cmd, buf, sizeof(buf), ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
}
uint8_t readByte(uint8_t address, uint8_t subAddress)
{
/*
uint8_t data; // `data` will store the register data
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive
// Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
// Wire.requestFrom(address, 1); // Read one byte from slave register address
Wire.requestFrom(address, (size_t) 1); // Read one byte from slave register address
data = Wire.read(); // Fill Rx buffer with result
return data; // Return data read from slave register
*/
// write sub-address
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( address << 1 ) | WRITE_BIT, ACK_CHECK_DIS);
i2c_master_write_byte(cmd, subAddress, ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
// read data
uint8_t data = 0;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( address << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &data, NACK_VAL);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return data;
}
void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{
/*
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive
// Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
uint8_t i = 0;
// Wire.requestFrom(address, count); // Read bytes from slave register address
Wire.requestFrom(address, (size_t) count); // Read bytes from slave register address
while (Wire.available()) {
dest[i++] = Wire.read(); } // Put read results in the Rx buffer
*/
// write sub-address
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( address << 1 ) | WRITE_BIT, ACK_CHECK_DIS);
i2c_master_write_byte(cmd, subAddress, ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) return ;//false;
// read data
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( address << 1 ) | READ_BIT, ACK_CHECK_EN);
if (count > 1) {
i2c_master_read(cmd, dest, count - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, dest + count - 1, NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
}
This is a timing plot
So you are sending data to the serial terminal at 10 Hz?
On Thu, Jan 10, 2019 at 10:27 AM laurentvm notifications@github.com wrote:
Yes but I have a modified I2C call compared to you
bool initI2C() { i2c_port_t i2c_master_port = I2C_NUM_0; i2c_config_t conf; conf.mode = I2C_MODE_MASTER; conf.sda_io_num = (gpio_num_t)21; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = (gpio_num_t)22; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; //conf.master.clk_speed = 100000; conf.master.clk_speed = 400000L; //400000L return i2c_param_config(i2c_master_port, &conf) == ESP_OK && i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0) == ESP_OK; }
define WRITE_BIT I2C_MASTER_WRITE /!< I2C master write /
define READ_BIT I2C_MASTER_READ /!< I2C master read /
define ACK_CHECK_EN 0x1 /!< I2C master will check ack from slave/
define ACK_CHECK_DIS 0x0 /!< I2C master will not check ack from slave /
define ACK_VAL (i2c_ack_type_t)0x0 /!< I2C ack value /
define NACK_VAL (i2c_ack_type_t)0x1 /!< I2C nack value /
// I2C read/write functions for the MPU9250 and AK8963 sensors
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) { / Wire.beginTransmission(address); // Initialize the Tx buffer Wire.write(subAddress); // Put slave register address in Tx buffer Wire.write(data); // Put data in Tx buffer Wire.endTransmission(); // Send the Tx buffer / i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( address << 1 ) | WRITE_BIT, ACK_CHECK_EN); // write sub-address and data uint8_t buf[2] = {subAddress, data}; i2c_master_write(cmd, buf, sizeof(buf), ACK_CHECK_EN); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); }
uint8_t readByte(uint8_t address, uint8_t subAddress) { / uint8_t data; //
data
will store the register data
Wire.beginTransmission(address); // Initialize the Tx buffer Wire.write(subAddress); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive // Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive // Wire.requestFrom(address, 1); // Read one byte from slave register address Wire.requestFrom(address, (size_t) 1); // Read one byte from slave register address data = Wire.read(); // Fill Rx buffer with result return data; // Return data read from slave register / // write sub-address i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( address << 1 ) | WRITE_BIT, ACK_CHECK_DIS); i2c_master_write_byte(cmd, subAddress, ACK_CHECK_EN); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); // read data uint8_t data = 0; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( address << 1 ) | READ_BIT, ACK_CHECK_EN); i2c_master_read_byte(cmd, &data, NACK_VAL); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return data; }void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t dest) { / Wire.beginTransmission(address); // Initialize the Tx buffer Wire.write(subAddress); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive // Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive uint8_t i = 0; // Wire.requestFrom(address, count); // Read bytes from slave register address Wire.requestFrom(address, (size_t) count); // Read bytes from slave register address while (Wire.available()) { dest[i++] = Wire.read(); } // Put read results in the Rx buffer */
// write sub-address i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( address << 1 ) | WRITE_BIT, ACK_CHECK_DIS); i2c_master_write_byte(cmd, subAddress, ACK_CHECK_EN); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) return ;//false; // read data cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( address << 1 ) | READ_BIT, ACK_CHECK_EN); if (count > 1) { i2c_master_read(cmd, dest, count - 1, ACK_VAL); } i2c_master_read_byte(cmd, dest + count - 1, NACK_VAL); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd);
}
This is a timing plot
[image: image] https://user-images.githubusercontent.com/37613497/50988707-b364da00-150d-11e9-8d83-3d498af92038.png
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-453202156, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qviRQwzmpmj2hnqcgZd31spCYjZMks5vB4YHgaJpZM4Z2Q90 .
Yes
Doesn't this affect the quaternion update rate?
On Thu, Jan 10, 2019 at 10:51 AM laurentvm notifications@github.com wrote:
Yes
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-453210190, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qlrGKUTFd_RbmVfdoR5JYz29GPECks5vB4u_gaJpZM4Z2Q90 .
I'm not sure but I do not think it affects.
It affects for sure how fast we can retrieve a newData from sensor. But the sensor is not moving, so having new data is not helping or at least I do not see why it would help, nothing is changing.
Changing to 1hz or 0.2Hz output does not change:
I'm iterating 5 times the filter on the same newData, should i push this much higher?
If this is heading versus seconds yes this is way too slow. Not sure why, I don't see this kind of behavior....
Are you running the gyro at 200 or 250 Hz. Mybe go to 1 kHz. Accel too. Mag at 100 Hz. You should be able to get the fusion rate at 5 or 10 x the sample rate.
This should provide good results if the sensors are properly calibrated.
On Thu, Jan 10, 2019 at 11:17 AM laurentvm notifications@github.com wrote:
I'm not sure but I do not think it affects.
It affects for sure how fast we can retrieve a newData from sensor. But the sensor is not moving, so having new data is not helping or at least I do not see why it would help, nothing is changing.
Changing to 1hz or 0.2Hz output does not change: [image: image] https://user-images.githubusercontent.com/37613497/50991355-bca57500-1514-11e9-8760-1e11a15a092b.png
I'm iterating 5 times the filter on the same newData, should i push this much higher?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-453218934, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qrV-qM6ayRbKXVTqiokRD04lxICGks5vB5HHgaJpZM4Z2Q90 .
Kris,
I have this in the init
writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x04);
I guess that's wrong, seems to be 200hz?
it should be
writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00);
as in the calibration routine
Where do I change the gyro and Mag rate?
Mag, I have this
uint8_t Mmode = 0x06;
I believe changing SMPLRT_DIV to 0 sets both accel and gyro rates to 1 kHz. Mag at 0x06 is already at 100 Hz.
// Configure Gyro and Thermometer // Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively; // minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot // be higher than 1 / 0.0059 = 170 Hz // DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both // With the MPU9250, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz writeByte(MPU9250_ADDRESS, CONFIG, 0x03); // 41 Hz bandwidth, 5.9 ms delay // writeByte(MPU9250_ADDRESS, CONFIG, 0x02); // 92 Hz bandwidth, 3.9 ms delay
// Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV) writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x05); // Use a 167 Hz rate; a rate consistent with the filter update rate // determined in set in CONFIG above
// Set accelerometer sample rate configuration // It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for // accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2); // get current ACCEL_CONFIG2 register value c = c & ~0x0F; // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0]) c = c | 0x03; // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c); // Write new ACCEL_CONFIG2 register value
On Thu, Jan 10, 2019 at 11:41 AM laurentvm notifications@github.com wrote:
Kris,
I have this in the init writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x04); I guess that's wrong, seems to be 200hz? it should be writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); as in the calibration routine
Where do I change the gyro and Mag rate? Mag, I have this uint8_t Mmode = 0x06;
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-453227007, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qvJB6ECHFBsJ7qFZULUAieD363uBks5vB5dSgaJpZM4Z2Q90 .
It does not change anything. I got approximately the same timings
void initMPU9250()
{
// wake up device
writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x00); // Clear sleep mode bit (6), enable all sensors
delay(100); // Wait for all registers to reset
// get stable time source
writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x01); // Auto select clock source to be PLL gyroscope reference if ready else
delay(200);
// Configure Gyro and Thermometer
// Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively;
// minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot
// be higher than 1 / 0.0059 = 170 Hz
// DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both
// With the MPU9250, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz
writeByte(MPU9250_ADDRESS, CONFIG, 0x03);
// Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV)
writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); // Use a 200 Hz rate; a rate consistent with the filter update rate
// determined inset in CONFIG above
// Set gyroscope full scale range
// Range selects FS_SEL and GFS_SEL are 0 - 3, so 2-bit values are left-shifted into positions 4:3
uint8_t c = readByte(MPU9250_ADDRESS, GYRO_CONFIG); // get current GYRO_CONFIG register value
// c = c & ~0xE0; // Clear self-test bits [7:5]
//c = c & ~0x02; // Clear Fchoice bits [1:0]
c = c & ~0x03; // Clear Fchoice bits [1:0]
c = c & ~0x18; // Clear GFS bits [4:3]
c = c | Gscale << 3; // Set full scale range for the gyro
// c =| 0x00; // Set Fchoice for the gyro to 11 by writing its inverse to bits 1:0 of GYRO_CONFIG
writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c ); // Write new GYRO_CONFIG value to register
// Set accelerometer full-scale range configuration
c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG); // get current ACCEL_CONFIG register value
// c = c & ~0xE0; // Clear self-test bits [7:5]
c = c & ~0x18; // Clear AFS bits [4:3]
c = c | Ascale << 3; // Set full scale range for the accelerometer
writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c); // Write new ACCEL_CONFIG register value
// Set accelerometer sample rate configuration
// It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for
// accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz
c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2); // get current ACCEL_CONFIG2 register value
c = c & ~0x0F; // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0])
c = c | 0x03; // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz
writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c); // Write new ACCEL_CONFIG2 register value
// The accelerometer, gyro, and thermometer are set to 1 kHz sample rates,
// but all these rates are further reduced by a factor of 5 to 200 Hz because of the SMPLRT_DIV setting
// Configure Interrupts and Bypass Enable
// Set interrupt pin active high, push-pull, hold interrupt pin level HIGH until interrupt cleared,
// clear on read of INT_STATUS, and enable I2C_BYPASS_EN so additional chips
// can join the I2C bus and all can be controlled by the Arduino as master
// writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22);
writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x12); // INT is 50 microsecond pulse and any read to clear
writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x01); // Enable data ready (bit 0) interrupt
delay(100);
}
Don't know what to tell you...Maybe try another MCU and/or senor breakout to be sure?
On Thu, Jan 10, 2019 at 12:24 PM laurentvm notifications@github.com wrote:
It does not change anything. I got approximately the same timings
void initMPU9250() { // wake up device writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x00); // Clear sleep mode bit (6), enable all sensors delay(100); // Wait for all registers to reset
// get stable time source writeByte(MPU9250_ADDRESS, PWR_MGMT_1, 0x01); // Auto select clock source to be PLL gyroscope reference if ready else delay(200); // Configure Gyro and Thermometer // Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively; // minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot // be higher than 1 / 0.0059 = 170 Hz // DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both // With the MPU9250, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz writeByte(MPU9250_ADDRESS, CONFIG, 0x03); // Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV) writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x00); // Use a 200 Hz rate; a rate consistent with the filter update rate // determined inset in CONFIG above // Set gyroscope full scale range // Range selects FS_SEL and GFS_SEL are 0 - 3, so 2-bit values are left-shifted into positions 4:3 uint8_t c = readByte(MPU9250_ADDRESS, GYRO_CONFIG); // get current GYRO_CONFIG register value // c = c & ~0xE0; // Clear self-test bits [7:5] //c = c & ~0x02; // Clear Fchoice bits [1:0] c = c & ~0x03; // Clear Fchoice bits [1:0] c = c & ~0x18; // Clear GFS bits [4:3] c = c | Gscale << 3; // Set full scale range for the gyro // c =| 0x00; // Set Fchoice for the gyro to 11 by writing its inverse to bits 1:0 of GYRO_CONFIG writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c ); // Write new GYRO_CONFIG value to register // Set accelerometer full-scale range configuration c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG); // get current ACCEL_CONFIG register value // c = c & ~0xE0; // Clear self-test bits [7:5] c = c & ~0x18; // Clear AFS bits [4:3] c = c | Ascale << 3; // Set full scale range for the accelerometer writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c); // Write new ACCEL_CONFIG register value // Set accelerometer sample rate configuration // It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for // accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2); // get current ACCEL_CONFIG2 register value c = c & ~0x0F; // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0]) c = c | 0x03; // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c); // Write new ACCEL_CONFIG2 register value // The accelerometer, gyro, and thermometer are set to 1 kHz sample rates, // but all these rates are further reduced by a factor of 5 to 200 Hz because of the SMPLRT_DIV setting // Configure Interrupts and Bypass Enable // Set interrupt pin active high, push-pull, hold interrupt pin level HIGH until interrupt cleared, // clear on read of INT_STATUS, and enable I2C_BYPASS_EN so additional chips // can join the I2C bus and all can be controlled by the Arduino as master // writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22); writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x12); // INT is 50 microsecond pulse and any read to clear writeByte(MPU9250_ADDRESS, INT_ENABLE, 0x01); // Enable data ready (bit 0) interrupt delay(100);
}
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-453240848, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qmyW5ACbAhfoRiychfpBVRUYwcFoks5vB6GTgaJpZM4Z2Q90 .
I will try to use the Wire class as you do. There is maybe something wrong.
Could you advise me where to buy a good board (Teensy?). I'm in europe so a european shop would be better and faster.
There still something I do not understand on the concept. If the filter is a gradient based algo, it's higly dependent on the starting point. You get a sensor data point, previous quaternion and iterate a few time to converge the filter from previous quaternion.
When the sensor is not moving at all, I probably start with an initial bad starting point. If you look at previous graph, we see that. It reach very slowly an optimum and then it's faster because you follow a movement from previous points that is not too far from current position.
When you are standing still, basically, the update rate of sensor (if resonnable) does not affect anything because you do not have to follow a movement. You are iterating with an initial point that is the same after the filter.
If the sensor is well calibrated, yes it will take some (short) time (seconds) to converge to a stable absolute orientation when starting from the arbitrary 1 0 0 0 quaternion, but it shouldn;t take 60 seconds.
I recommend this https://www.tindie.com/products/TleraCorp/ladybug-stm32l432-development-board/ device. or this https://www.tindie.com/products/TleraCorp/dragonfly-stm32l47696-development-board/ one.
On Thu, Jan 10, 2019 at 12:56 PM laurentvm notifications@github.com wrote:
I will try to use the Wire class as you do. There is maybe something wrong.
Could you advise me where to buy a good board (Teensy?). I'm in europe so a european should would be better and faster.
There still something I do not understand on the concept. If the filter is a gradient based algo, it's higly dependent on the starting point. You get a sensor data point, previous quaternion and iterate a few time to converge the filter from previous quaternion.
When the sensor is not moving at all, I probably start with an initial bad starting point. If you look at previous graph, we see that. It reach very slowly an optimum and then it's faster because you follow a movement from previous points that is not too far from current position.
When you are standing still, basically, the update rate of sensor (if resonnable) does not affect anything because you do not have to follow a movement. You are iterating with an initial point that is the same after the filter.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/336#issuecomment-453250468, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qrIBGAtpJ4e7uCt1QYqjp4np5fiDks5vB6j1gaJpZM4Z2Q90 .
Running on ESP32, iteraring 5 times the filter each time I get new data from the sensors I have a very slow convergence:
At start, it takes 60 seconds to converge
If I move it, for unknown reason it seems to be faster to converge, but still slow to me
Frequency is 4kHz, does that make sense?