Skip to content

Commit 7bf6b47

Browse files
add sample rate and filter functions
1 parent 60c24b9 commit 7bf6b47

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

i2c/mpu6050_i2c/mpu6050_i2c.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,20 @@
3333
// By default these devices are on bus address 0x68
3434
static uint8_t bus_addr = 0x68;
3535
// Register addresses in the MPU6050 to read and write data to
36-
const uint8_t REG_PWR_MGMT_1 = 0x6B, REG_ACCEL_OUT = 0x3B, REG_GYRO_OUT = 0x43, REG_TEMP_OUT = 0x41,
37-
REG_SIGNAL_PATH_RESET = 0x68, REG_GYRO_CONFIG = 0x1B, REG_ACCEL_CONFIG = 0x1C, REG_WHO_AM_I = 0x75;
36+
const uint8_t REG_ACCEL_OUT = 0x3B, REG_GYRO_OUT = 0x43, REG_TEMP_OUT = 0x41,
37+
REG_SMPRT_DIV = 0x19, REG_SIGNAL_PATH_RESET = 0x68, REG_PWR_MGMT_1 = 0x6B, REG_WHO_AM_I = 0x75,
38+
REG_CONFIG = 0x1A, REG_GYRO_CONFIG = 0x1B, REG_ACCEL_CONFIG = 0x1C;
3839

3940
const float gyro_scale_deg[] = {250. / 0x7fff, 500. / 0x7fff, 1000. / 0x7fff, 2000. / 0x7fff};
4041
const float gyro_scale_rad[] = {M_PI / 180. * 250. / 0x7fff, M_PI / 180. * 500. / 0x7fff,
4142
M_PI / 180. * 1000. / 0x7fff, M_PI / 180. * 2000. / 0x7fff};
4243
const float accel_scale_vals[] = {2 * 9.81 / 0x7fff, 4 * 9.81 / 0x7fff, 8 * 9.81 / 0x7fff, 16 * 9.81 / 0x7fff};
4344

45+
const int accel_bandwidth_lookup[] = {260, 184, 94, 44, 21, 10, 5};
46+
const float accel_delay_lookup[] = {0, 2.0, 3.0, 4.9, 8.5, 13.8, 19.0};
47+
const int gyro_bandwidth_lookup[] = {256, 188, 98, 42, 20, 10, 5};
48+
const float gyro_delay_lookup[] = {0.98, 1.9, 2.8, 4.8, 8.3, 13.4, 18.6};
49+
4450

4551
////////////////////////////////////////////////////lower level functions for i2c
4652
#ifdef i2c_default
@@ -141,6 +147,31 @@ void mpu6050_accel_selftest_on(void) {
141147
mpu6050_writereg(REG_ACCEL_CONFIG, regdata);
142148
}
143149

150+
void mpu6050_set_timing(uint8_t lowpass_filter_cfg, uint8_t sample_rate_div) {
151+
mpu6050_writereg(REG_SMPRT_DIV, sample_rate_div);
152+
mpu6050_writereg(REG_CONFIG, lowpass_filter_cfg & 7);
153+
}
154+
void mpu6050_read_timing(mpu6050_timing_params_t *accel_timing, mpu6050_timing_params_t *gyro_timing) {
155+
uint8_t reg_data[2];
156+
mpu6050_readreg(REG_SMPRT_DIV, reg_data, 2);
157+
mpu6050_calc_timing(reg_data[1], reg_data[0], accel_timing, gyro_timing);
158+
}
159+
void mpu6050_calc_timing(uint8_t filter_cfg, uint8_t sample_rate_div,
160+
mpu6050_timing_params_t *accel_timing, mpu6050_timing_params_t *gyro_timing) {
161+
int i = filter_cfg > 6 ? 0 : filter_cfg;
162+
float gyro_measure_rate = (i == 0) ? 8000 : 1000;
163+
if (accel_timing) {
164+
accel_timing->bandwidth = accel_bandwidth_lookup[i];
165+
accel_timing->delay = accel_delay_lookup[i];
166+
accel_timing->sample_rate = fmin(1000, gyro_measure_rate / (1 + sample_rate_div));
167+
}
168+
if (gyro_timing) {
169+
gyro_timing->bandwidth = gyro_bandwidth_lookup[i];
170+
gyro_timing->delay = gyro_delay_lookup[i];
171+
gyro_timing->sample_rate = gyro_measure_rate / (1 + sample_rate_div);
172+
}
173+
}
174+
144175
bool mpu6050_is_connected(void) {
145176
uint8_t who_are_you = 0;
146177
mpu6050_readreg(REG_WHO_AM_I, &who_are_you, 1);
@@ -178,6 +209,8 @@ int run_MPU6050_demo() {
178209
//setting CLKSEL = 1 gets better results than 0 if gyro is running and no sleep mode
179210
mpu6050_power(1, false, false, false);
180211

212+
mpu6050_set_timing(5, 99); // 10 Hz
213+
181214
while (1) {
182215
while (!mpu6050_is_connected()) {
183216
printf("MPU6050 is not connected...\n");

i2c/mpu6050_i2c/mpu6050_i2c.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ extern "C" {
88
#include "stdint.h"
99
#include "stddef.h"
1010

11-
typedef enum MPU6050_Scale {MPU_FS_0, MPU_FS_1, MPU_FS_2, MPU_FS_3} MPU6050_Scale;
11+
typedef enum MPU6050_Scale {MPU_FS_0 = 0, MPU_FS_1, MPU_FS_2, MPU_FS_3} MPU6050_Scale;
12+
13+
typedef struct {
14+
int bandwidth; // lowpass filter bandwidth [Hz]
15+
float delay; // lowpass filter delay [ms]
16+
float sample_rate; // rate of new data loading in the register [Hz]
17+
} mpu6050_timing_params_t;
1218

1319
// lower level functions for i2c
1420
void mpu6050_writereg(uint8_t reg, uint8_t value); //write one byte to a register
@@ -23,14 +29,20 @@ void mpu6050_setbusaddr(uint8_t addr); //set the i2c bus address for communicati
2329
CLKSEL is clock source, see docs. Recommended CLKSEL = 1 if gyro is enabled.
2430
temp_disable disables temperature, sleep enables sleep mode, cycle wakes up only when converting. */
2531
void mpu6050_power(uint8_t CLKSEL, bool temp_disable, bool sleep, bool cycle);
26-
// Reset power management and signal path registers. MPU6050 returns to default settings. Includes 200ms of wait.
32+
// MPU6050 returns to default settings and enters sleep mode. Includes 200ms of wait.
2733
void mpu6050_reset();
2834
// Check whether MPU6050 is connected using the read-only WHO_AM_I register, which is always 0x68
2935
bool mpu6050_is_connected();
3036
// turn on the mpu6050's accelerometer self test. Turn it off after a few 100ms with mpu6050_setscale_accel
3137
void mpu6050_accel_selftest_on(); // TODO: find out what "self test" does
3238
// turn on the mpu6050's gyroscope self test. Turn it off after a few 100ms with mpu6050_setscale_gyro
3339
void mpu6050_gyro_selftest_on();
40+
// configure lowpass filter and sample rate. Higher filter_cfg -> slower change, higher sample_rate_div -> slower sampling
41+
void mpu6050_set_timing(uint8_t lowpass_filter_cfg, uint8_t sample_rate_div);
42+
void mpu6050_read_timing(mpu6050_timing_params_t *accel_timing, mpu6050_timing_params_t *gyro_timing);
43+
void mpu6050_calc_timing(uint8_t filter_cfg, uint8_t sample_rate_div,
44+
mpu6050_timing_params_t *accel_timing, mpu6050_timing_params_t *gyro_timing);
45+
3446
//set and use scaling. The first read() after setscale() might not have the updated scaling.
3547
void mpu6050_setscale_accel(MPU6050_Scale accel_scale);
3648
void mpu6050_setscale_gyro(MPU6050_Scale gyro_scale);

0 commit comments

Comments
 (0)