19
19
inbuilt FIFO to make it more useful.
20
20
21
21
NOTE: Ensure the device is capable of being driven at 3.3v NOT 5v. The Pico
22
- GPIO (and therefore I2C) cannot be used at 5v.
23
-
24
- You will need to use a level shifter on the I2C lines if you want to run the
25
- board at 5v.
22
+ GPIO (and therefor I2C) cannot be used at 5v. You will need to use a level
23
+ shifter on the I2C lines if you want to run the board at 5v.
26
24
27
25
Connections on Raspberry Pi Pico board, other boards may vary.
28
26
@@ -41,7 +39,7 @@ const uint8_t REG_PWR_MGMT_1 = 0x6B, REG_ACCEL_OUT = 0x3B, REG_GYRO_OUT = 0x43,
41
39
const float gyro_scale_deg [] = {250. / 0x7fff , 500. / 0x7fff , 1000. / 0x7fff , 2000. / 0x7fff };
42
40
const float gyro_scale_rad [] = {M_PI / 180. * 250. / 0x7fff , M_PI / 180. * 500. / 0x7fff ,
43
41
M_PI / 180. * 1000. / 0x7fff , M_PI / 180. * 2000. / 0x7fff };
44
- const float accel_scale [] = {2 * 9.81 / 0x7fff , 4 * 9.81 / 0x7fff , 8 * 9.81 / 0x7fff , 16 * 9.81 / 0x7fff };
42
+ const float accel_scale_vals [] = {2 * 9.81 / 0x7fff , 4 * 9.81 / 0x7fff , 8 * 9.81 / 0x7fff , 16 * 9.81 / 0x7fff };
45
43
46
44
47
45
////////////////////////////////////////////////////lower level functions for i2c
@@ -53,7 +51,6 @@ void mpu6050_writereg(uint8_t reg, uint8_t value) {
53
51
}
54
52
55
53
void mpu6050_readreg (uint8_t reg , uint8_t * out , size_t length ) {
56
- //read length 8-bit integers from the register at reg, store them in out.
57
54
i2c_write_blocking (i2c_default , bus_addr , & reg , 1 , true); // true to keep master control of bus
58
55
i2c_read_blocking (i2c_default , bus_addr , out , length , false);
59
56
}
@@ -63,7 +60,6 @@ void mpu6050_readreg(uint8_t reg, uint8_t *out, size_t length) {};
63
60
#endif
64
61
65
62
void mpu6050_readreg16 (uint8_t reg , int16_t * out , size_t length ) {
66
- //read length 16-bit from the register at reg, store them in out. Max length 32 (= 64 bytes)
67
63
// For this particular device, we send the device the register we want to read
68
64
// first, then subsequently read from the device. The register is auto incrementing
69
65
// so we don't need to keep sending the register we want, just the first.
@@ -82,16 +78,13 @@ void mpu6050_setbusaddr(uint8_t addr) {
82
78
83
79
////////////////////////////////////////////////////higher level mpu6050 functions
84
80
void mpu6050_power (uint8_t CLKSEL , bool temp_disable , bool sleep , bool cycle ) {
85
- /* Set the power and clock settings. CLKSEL is clock source, see docs. Recommended CLKSEL = 1 if gyro is enabled.
86
- temp_disable disables temperature, sleep enables sleep mode, cycle wakes up only when converting. */
87
81
uint8_t pwrval = (CLKSEL & 7 ) + ((uint8_t )temp_disable << 3 )
88
82
+ ((uint8_t )sleep << 6 ) + ((uint8_t )cycle << 5 );
89
83
mpu6050_writereg (REG_PWR_MGMT_1 , pwrval );
90
84
}
91
85
92
86
void mpu6050_reset () {
93
- // Reset power management and signal path registers. MPU6050 returns to default settings.
94
- // Reset instructions come from register map doc. Includes 200ms of wait.
87
+ // Reset instructions come from register map doc
95
88
mpu6050_writereg (REG_PWR_MGMT_1 , 1 << 7 ); //DEVICE_RESET = 1
96
89
sleep_ms (100 );
97
90
mpu6050_writereg (REG_SIGNAL_PATH_RESET , 7 ); //GYRO_RESET = ACCEL_RESET = TEMP_RESET = 1
@@ -105,14 +98,15 @@ void mpu6050_read_raw(int16_t accel[3], int16_t gyro[3], int16_t *temp) {
105
98
}
106
99
107
100
void mpu6050_read (float accel [3 ], float gyro_rad [3 ], float * temp , MPU6050_Scale accel_scale , MPU6050_Scale gyro_scale ) {
108
- int16_t buffer [7 ];
109
- mpu6050_readreg16 (REG_ACCEL_OUT , buffer , 7 ); //reads all at same time
101
+ // reads acceleration [m/s], gyroscope [rad], and temperature [C] in one i2c interaction
102
+ int16_t buffer [7 ]; // 3 accel + 3 gyro + scalar temp
103
+ mpu6050_readreg16 (REG_ACCEL_OUT , buffer , 7 );
110
104
mpu6050_scale_accel (accel , buffer , accel_scale );
111
105
if (temp ) * temp = mpu6050_scale_temp (buffer [3 ]);
112
106
mpu6050_scale_gyro_rad (gyro_rad , buffer + 4 , gyro_scale );
113
107
}
114
108
115
- // set and use sensitivity
109
+ // functions to set and calculate with sensitivity
116
110
void mpu6050_setscale_gyro (MPU6050_Scale gyro_scale ) {
117
111
mpu6050_writereg (REG_GYRO_CONFIG , (uint8_t )gyro_scale << 3 );
118
112
}
@@ -121,7 +115,7 @@ void mpu6050_setscale_accel(MPU6050_Scale accel_scale) {
121
115
}
122
116
void mpu6050_scale_accel (float accel [3 ], int16_t accel_raw [3 ], MPU6050_Scale scale ) {
123
117
for (int i = 0 ; i < 3 ; i ++ ) {
124
- accel [i ] = accel_raw [i ] * accel_scale [scale ];
118
+ accel [i ] = accel_raw [i ] * accel_scale_vals [scale ];
125
119
}
126
120
}
127
121
void mpu6050_scale_gyro_deg (float gyro [3 ], int16_t gyro_raw [3 ], MPU6050_Scale scale ) {
@@ -137,21 +131,25 @@ void mpu6050_scale_gyro_rad(float gyro[3], int16_t gyro_raw[3], MPU6050_Scale sc
137
131
float mpu6050_scale_temp (float temp_raw ) {
138
132
return (temp_raw / 340.0 ) + 36.53 ;
139
133
}
134
+ void mpu6050_gyro_selftest_on (void ) {
135
+ uint8_t regdata = 0b11100000 & ((uint8_t )MPU_FS_0 << 3 );
136
+ mpu6050_writereg (REG_GYRO_CONFIG , regdata );
137
+ }
138
+ void mpu6050_accel_selftest_on (void ) {
139
+ uint8_t regdata = 0b11100000 & ((uint8_t )MPU_FS_2 << 3 );
140
+ mpu6050_writereg (REG_ACCEL_CONFIG , regdata );
141
+ }
140
142
141
143
//TODO: set timing
142
144
//TODO: set and read filter cutoff
143
- //TODO: read self test
145
+ //TODO: interrupts
144
146
145
- //TODO: functional mpu test
146
- int test () {
147
- stdio_init_all ();
147
+ bool setup_MPU6050_i2c () {
148
148
#if !defined(i2c_default ) || !defined(PICO_DEFAULT_I2C_SDA_PIN ) || !defined(PICO_DEFAULT_I2C_SCL_PIN )
149
149
#warning i2c/mpu6050_i2c example requires a board with I2C pins
150
150
puts ("Default I2C pins were not defined" );
151
- return 0 ;
151
+ return false ;
152
152
#else
153
- printf ("Hello, MPU6050! Reading raw data from registers...\n" );
154
-
155
153
// This example will use I2C0 on the default SDA and SCL pins (4, 5 on a Pico)
156
154
i2c_init (i2c_default , 400 * 1000 ); // Max bus speed 400 kHz
157
155
gpio_set_function (PICO_DEFAULT_I2C_SDA_PIN , GPIO_FUNC_I2C );
@@ -160,33 +158,39 @@ int test() {
160
158
gpio_pull_up (PICO_DEFAULT_I2C_SCL_PIN );
161
159
// Make the I2C pins available to picotool
162
160
bi_decl (bi_2pins_with_func (PICO_DEFAULT_I2C_SDA_PIN , PICO_DEFAULT_I2C_SCL_PIN , GPIO_FUNC_I2C ));
161
+ return true;
162
+ #endif
163
+ }
163
164
164
- mpu6050_reset ();
165
- //setting CLKSEL = 1 gets better results than 0 if gyro is running and no sleep mode
166
- mpu6050_power (1 , false, false, false);
165
+ int run_MPU6050_demo () {
167
166
MPU6050_Scale testscale = MPU_FS_0 ;
168
167
mpu6050_setscale_accel (testscale );
169
168
mpu6050_setscale_gyro (testscale );
170
169
171
170
int16_t accel_raw [3 ], gyro_raw [3 ], temp_raw ;
172
171
float acceleration [3 ], gyro [3 ];
173
172
173
+ mpu6050_reset ();
174
+ //setting CLKSEL = 1 gets better results than 0 if gyro is running and no sleep mode
175
+ mpu6050_power (1 , false, false, false);
176
+
174
177
while (1 ) {
178
+ uint64_t time_us = to_us_since_boot (get_absolute_time ());
175
179
mpu6050_read_raw (accel_raw , gyro_raw , & temp_raw );
176
- //TODO time read function
180
+ time_us = to_us_since_boot ( get_absolute_time ()) - time_us ;
177
181
178
182
// These are the raw numbers from the chip
179
183
printf ("Raw Acc. X = %d, Y = %d, Z = %d\n" , accel_raw [0 ], accel_raw [1 ], accel_raw [2 ]);
180
184
printf ("Raw Gyro. X = %d, Y = %d, Z = %d\n" , gyro_raw [0 ], gyro_raw [1 ], gyro_raw [2 ]);
181
- // Temperature is simple so use the datasheet calculation to get deg C .
182
- // Note this is chip temperature.
183
- printf ("Temp [C] = %f \t\t Scale = %d\n" , mpu6050_scale_temp ( temp_raw ) , testscale );
185
+ // This is chip temperature .
186
+ printf ( "Temp [C] = %f\n" , mpu6050_scale_temp ( temp_raw ));
187
+ printf ("Read time: %d us; \t\t Accel and Gyro Scale = %d\n" , time_us , testscale );
184
188
mpu6050_scale_accel (acceleration , accel_raw , testscale );
185
189
mpu6050_scale_gyro_rad (gyro , gyro_raw , testscale );
186
190
printf ("Acc [m/s^2] X = %f, Y = %f, Z = %f\n" , acceleration [0 ], acceleration [1 ], acceleration [2 ]);
187
191
printf ("Gyro [rad/s] X = %f, Y = %f, Z = %f\n" , gyro [0 ], gyro [1 ], gyro [2 ]);
188
192
189
193
sleep_ms (100 );
190
194
}
191
- #endif
195
+ return 0 ;
192
196
}
0 commit comments