Skip to content

Commit f789446

Browse files
MPU6050 i2c example expanded into C/C++ library
1 parent da4e50d commit f789446

8 files changed

+675
-128
lines changed

i2c/mpu6050_i2c/CMakeLists.txt

+39-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,39 @@
1-
add_executable(mpu6050_i2c
2-
mpu6050_i2c.c
3-
)
4-
5-
# pull in common dependencies and additional i2c hardware support
6-
target_link_libraries(mpu6050_i2c pico_stdlib hardware_i2c)
7-
8-
# create map/bin/hex file etc.
9-
pico_add_extra_outputs(mpu6050_i2c)
10-
11-
# add url via pico_set_program_url
12-
example_auto_set_url(mpu6050_i2c)
1+
add_library(MPU6050_i2c_pico_lib mpu6050_i2c.c)
2+
target_include_directories(MPU6050_i2c_pico_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
3+
# pull in common dependencies and additional i2c hardware support
4+
target_link_libraries(MPU6050_i2c_pico_lib pico_stdlib hardware_i2c)
5+
6+
add_library(MPU6050_i2c_pico_cpp_lib mpu6050.cpp mpu6050_i2c.c)
7+
target_include_directories(MPU6050_i2c_pico_cpp_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
8+
target_link_libraries(MPU6050_i2c_pico_cpp_lib pico_stdlib hardware_i2c)
9+
10+
11+
add_executable(mpu6050_i2c mpu6050_i2c_main.c)
12+
target_link_libraries(mpu6050_i2c MPU6050_i2c_pico_lib)
13+
14+
# create map/bin/hex file etc.
15+
pico_add_extra_outputs(mpu6050_i2c)
16+
# enable usb and uart output
17+
pico_enable_stdio_usb(mpu6050_i2c 1)
18+
pico_enable_stdio_uart(mpu6050_i2c 1)
19+
20+
# add url via pico_set_program_url
21+
example_auto_set_url(mpu6050_i2c)
22+
23+
24+
add_executable(mpu6050_i2c_scale_test mpu6050_scale_test.cpp)
25+
target_link_libraries(mpu6050_i2c_scale_test MPU6050_i2c_pico_cpp_lib)
26+
27+
# create map/bin/hex file etc.
28+
pico_add_extra_outputs(mpu6050_i2c_scale_test)
29+
pico_enable_stdio_usb(mpu6050_i2c_scale_test 1)
30+
pico_enable_stdio_uart(mpu6050_i2c_scale_test 1)
31+
32+
33+
add_executable(mpu6050_i2c_irq mpu6050_i2c_irq_main.cpp)
34+
target_link_libraries(mpu6050_i2c_irq MPU6050_i2c_pico_cpp_lib)
35+
36+
# create map/bin/hex file etc.
37+
pico_add_extra_outputs(mpu6050_i2c_irq)
38+
pico_enable_stdio_usb(mpu6050_i2c_irq 1)
39+
pico_enable_stdio_uart(mpu6050_i2c_irq 1)

i2c/mpu6050_i2c/mpu6050.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "mpu6050.hpp"
2+
#include "mpu6050_i2c.h"
3+
4+
5+
MPU6050SensorTimingParams::MPU6050SensorTimingParams(int _bandwidth, float _delay, float _sample_rate)
6+
: bandwidth(_bandwidth), delay(_delay), sample_rate(_sample_rate) {}
7+
8+
inline const MPU6050SensorTimingParams convert(mpu6050_timing_params_t *c_struct) { // unfortunate awkwardness of wrapping a C lib
9+
return MPU6050SensorTimingParams(c_struct->bandwidth, c_struct->delay, c_struct->sample_rate);
10+
}
11+
12+
MPU6050TimingParams::MPU6050TimingParams(uint8_t lowpass_filter_cfg, uint8_t sample_rate_div) {
13+
mpu6050_timing_params_t accel_timing_c, gyro_timing_c;
14+
mpu6050_calc_timing(lowpass_filter_cfg, sample_rate_div, &accel_timing_c, &gyro_timing_c);
15+
accel_timing = convert(&accel_timing_c);
16+
gyro_timing = convert(&gyro_timing_c);
17+
}
18+
19+
MPU6050TimingParams::MPU6050TimingParams(const MPU6050SensorTimingParams &_accel_timing,
20+
const MPU6050SensorTimingParams &_gyro_timing)
21+
: accel_timing(_accel_timing), gyro_timing(_gyro_timing) {}
22+
23+
24+
MPU6050::MPU6050(float *accel_out, float *gyro_out, uint8_t addr) :
25+
chip_temp(temp), accel(accel_out), gyro(gyro_out), accel_scale(Scale_0), gyro_scale(Scale_0), bus_addr(addr) {
26+
setup_MPU6050_i2c();
27+
}
28+
29+
void MPU6050::power(uint8_t CLKSEL, bool temp_disable, bool sleep, bool cycle) {
30+
mpu6050_setbusaddr(bus_addr);
31+
mpu6050_power(CLKSEL, temp_disable, sleep, cycle);
32+
}
33+
34+
void MPU6050::reset(void) {
35+
mpu6050_setbusaddr(bus_addr);
36+
mpu6050_reset();
37+
}
38+
39+
void MPU6050::setscale_accel(MPU6050::Scale scale) {
40+
mpu6050_setbusaddr(bus_addr);
41+
mpu6050_setscale_accel((MPU6050_Scale)scale);
42+
accel_scale = scale;
43+
}
44+
45+
void MPU6050::setscale_gyro(MPU6050::Scale scale) {
46+
mpu6050_setbusaddr(bus_addr);
47+
mpu6050_setscale_gyro((MPU6050_Scale)scale);
48+
gyro_scale = scale;
49+
}
50+
51+
void MPU6050::read(void) {
52+
mpu6050_setbusaddr(bus_addr);
53+
mpu6050_read(accel, gyro, &temp, (MPU6050_Scale)accel_scale, (MPU6050_Scale)gyro_scale);
54+
}
55+
56+
void MPU6050::read_accel(void) {
57+
mpu6050_setbusaddr(bus_addr);
58+
mpu6050_read_accel(accel, (MPU6050_Scale)accel_scale);
59+
}
60+
61+
void MPU6050::read_gyro(void) {
62+
mpu6050_setbusaddr(bus_addr);
63+
mpu6050_read_gyro_rad(gyro, (MPU6050_Scale)gyro_scale);
64+
}
65+
66+
bool MPU6050::is_connected() {
67+
mpu6050_setbusaddr(bus_addr);
68+
return mpu6050_is_connected();
69+
}
70+
71+
void MPU6050::set_timing(uint8_t lowpass_filter_cfg, uint8_t sample_rate_div) {
72+
mpu6050_setbusaddr(bus_addr);
73+
mpu6050_set_timing(lowpass_filter_cfg, sample_rate_div);
74+
}
75+
76+
MPU6050TimingParams MPU6050::read_timing(void) {
77+
mpu6050_setbusaddr(bus_addr);
78+
mpu6050_timing_params_t accel_timing_c, gyro_timing_c;
79+
mpu6050_read_timing(&accel_timing_c, &gyro_timing_c);
80+
return MPU6050TimingParams(convert(&accel_timing_c), convert(&gyro_timing_c));
81+
}
82+
83+
void MPU6050::configure_interrupt(bool active_low, bool open_drain, bool latch_pin, bool read_clear, bool enable) {
84+
mpu6050_setbusaddr(bus_addr);
85+
mpu6050_configure_interrupt(active_low, open_drain, latch_pin, read_clear, enable);
86+
}
87+
88+
uint8_t MPU6050::read_interrupt_status() {
89+
mpu6050_setbusaddr(bus_addr);
90+
return mpu6050_read_interrupt_status();
91+
}
92+
93+
94+
float MPU6050_max_accel(MPU6050::Scale scale) {
95+
return accel_scale_vals[(int)scale];
96+
}
97+
float MPU6050_max_gyro_rad(MPU6050::Scale scale) {
98+
return gyro_scale_rad[(int)scale];
99+
}

i2c/mpu6050_i2c/mpu6050.hpp

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* class for using an MPU6050 IMU sensor on pi pico.
2+
A C++ interface to the pico example C code.
3+
*/
4+
#include "stdint.h"
5+
6+
struct MPU6050SensorTimingParams {
7+
MPU6050SensorTimingParams() = default;
8+
MPU6050SensorTimingParams(int _bandwidth, float _delay, float _sample_rate);
9+
int bandwidth; // lowpass filter bandwidth [Hz]
10+
float delay; // lowpass filter delay [ms]
11+
float sample_rate; // rate of new data loading in the register [Hz]
12+
};
13+
struct MPU6050TimingParams {
14+
MPU6050TimingParams(uint8_t lowpass_filter_cfg, uint8_t sample_rate_div);
15+
MPU6050TimingParams(const MPU6050SensorTimingParams &_accel_timing, const MPU6050SensorTimingParams &_gyro_timing);
16+
MPU6050SensorTimingParams accel_timing, gyro_timing;
17+
};
18+
19+
class MPU6050 {
20+
public:
21+
const float &chip_temp; // [C]
22+
23+
MPU6050(float *accel_out, float *gyro_out, uint8_t i2c_addr=0x68); // [m/s^2], [rad/s]
24+
25+
void power(uint8_t CLKSEL, bool temp_disable, bool sleep, bool cycle);
26+
void reset(void);
27+
28+
enum Scale {Scale_0 = 0, Scale_1, Scale_2, Scale_3};
29+
// Warning: The first call to read() after setscale() might not have the updated scaling.
30+
void setscale_accel(Scale scale); //scale 0-3 is 2g, 4g, 8g, or 16g
31+
void setscale_gyro(Scale scale); // scale 0-3 is 250, 500, 1000, or 2000 deg/s
32+
void read(void);
33+
void read_accel(void);
34+
void read_gyro(void);
35+
bool is_connected(void);
36+
void set_timing(uint8_t lowpass_filter_cfg, uint8_t sample_rate_div);
37+
MPU6050TimingParams read_timing(void);
38+
void configure_interrupt(bool active_low, // Whether the INT pin is active low or active high
39+
bool open_drain, // Whether the INT pin is push-pull or open-drain
40+
bool latch_pin, // Whether the INT pin latches or pulses for 50us
41+
bool read_clear, // Whether interrupt status bits are cleared by reading interrupt status (default) or on any read
42+
bool enable); // Turn interrupts on or off
43+
uint8_t read_interrupt_status(); // 0 = no interrupts set, 1 = data ready
44+
private:
45+
float *accel, *gyro, temp;
46+
enum Scale accel_scale, gyro_scale;
47+
uint8_t bus_addr;
48+
};
49+
50+
float MPU6050_max_accel(MPU6050::Scale scale);
51+
float MPU6050_max_gyro_rad(MPU6050::Scale scale);

0 commit comments

Comments
 (0)