|
| 1 | +/* |
| 2 | + * MPU6050 I2C example measuring the interrupt pin and lowpass filter. |
| 3 | + */ |
| 4 | + |
| 5 | +#include <stdio.h> |
| 6 | +#include <memory> |
| 7 | +#include "pico/stdlib.h" |
| 8 | +#include "pico/float.h" |
| 9 | +#include "pico/binary_info.h" |
| 10 | +#include "hardware/gpio.h" |
| 11 | +#include "mpu6050.hpp" |
| 12 | + |
| 13 | +const bool USE_READ_CLEAR = true; // true => fewer reads required, eliminates a failure mode (forgetting to clear irq) |
| 14 | +const unsigned READ_TIME_MS = 8000; |
| 15 | +const uint8_t IRQ_PIN = 6; |
| 16 | +const uint8_t SAMPLE_RATE_DIVS[] = {99, 9}; |
| 17 | +const uint8_t LOWPASS_FILTER_CFGS[] = {5, 1}; |
| 18 | +volatile bool got_irq; |
| 19 | + |
| 20 | +static std::unique_ptr<MPU6050> IMU; |
| 21 | +static float accel[3] = {0}, gyro[3] = {0}; // TODO we shouldn't need this |
| 22 | + |
| 23 | +void print_SensorTimingParams(const MPU6050SensorTimingParams ¶ms) { |
| 24 | + printf("Sample Rate: %.2f, Bandwidth: %i, Delay: %.1f\n", params.sample_rate, params.bandwidth, params.delay); |
| 25 | +} |
| 26 | + |
| 27 | +void print_TimingParams(const MPU6050TimingParams ¶ms) { |
| 28 | + printf("Accelerometer "); |
| 29 | + print_SensorTimingParams(params.accel_timing); |
| 30 | + printf("Gyroscope "); |
| 31 | + print_SensorTimingParams(params.gyro_timing); |
| 32 | +} |
| 33 | + |
| 34 | +void irq_callback(uint gpio, uint32_t events) { |
| 35 | + static unsigned num_reads = 0, sample_rate_div_idx = 0, lowpass_filter_cfg_idx = 0; |
| 36 | + static float last_accel[3] = {0}, last_gyro[3] = {0}; |
| 37 | + static uint64_t last_time_us = 0; |
| 38 | + static float avg_change_acc = 0, avg_change_gyro = 0; |
| 39 | + got_irq = true; |
| 40 | + if (!USE_READ_CLEAR) { |
| 41 | + IMU->read_interrupt_status(); |
| 42 | + } |
| 43 | + IMU->read(); |
| 44 | + float change_acc = 0, change_gyro = 0; |
| 45 | + for (int i = 0; i < 3; i++) { |
| 46 | + change_acc += (accel[i] - last_accel[i]) * (accel[i] - last_accel[i]); |
| 47 | + change_gyro += (gyro[i] - last_gyro[i]) * (gyro[i] - last_gyro[i]); |
| 48 | + last_accel[i] = accel[i]; |
| 49 | + last_gyro[i] = gyro[i]; |
| 50 | + } |
| 51 | + avg_change_acc += sqrtf(change_acc); |
| 52 | + avg_change_gyro += sqrtf(change_gyro); |
| 53 | + if (++num_reads > READ_TIME_MS / (SAMPLE_RATE_DIVS[sample_rate_div_idx] + 1)) { |
| 54 | + uint64_t time_us = to_us_since_boot(get_absolute_time()); |
| 55 | + printf("Measured cycle rate: %f Hz\n", (1e6 * num_reads) / (time_us - last_time_us)); |
| 56 | + last_time_us = time_us; |
| 57 | + printf("Average change between readings:\n\t accel: %f mm/s2 gyro: %f mrad/s\n\n", |
| 58 | + 1000 * avg_change_acc / num_reads, 1000 * avg_change_gyro / num_reads); |
| 59 | + avg_change_acc = 0; |
| 60 | + avg_change_gyro = 0; |
| 61 | + num_reads = 0; |
| 62 | + if (lowpass_filter_cfg_idx == 1) |
| 63 | + sample_rate_div_idx = 1 - sample_rate_div_idx; |
| 64 | + lowpass_filter_cfg_idx = 1 - lowpass_filter_cfg_idx; |
| 65 | + IMU->set_timing(LOWPASS_FILTER_CFGS[lowpass_filter_cfg_idx], SAMPLE_RATE_DIVS[sample_rate_div_idx]); |
| 66 | + print_TimingParams(IMU->read_timing()); |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +int main() { |
| 71 | + stdio_init_all(); |
| 72 | + bi_decl(bi_1pin_with_name(IRQ_PIN, "IMU IRQ pin 1")); |
| 73 | + IMU = std::make_unique<MPU6050>(accel, gyro); |
| 74 | + IMU->reset(); |
| 75 | + IMU->power(1, false, false, false); |
| 76 | + // push-pull is faster, latch allows debugging with the INT pin |
| 77 | + IMU->configure_interrupt(false, false, true, USE_READ_CLEAR, true); |
| 78 | + IMU->set_timing(LOWPASS_FILTER_CFGS[0], SAMPLE_RATE_DIVS[0]); |
| 79 | + print_TimingParams(IMU->read_timing()); |
| 80 | + gpio_set_irq_enabled_with_callback(IRQ_PIN, GPIO_IRQ_LEVEL_HIGH, true, &irq_callback); |
| 81 | + while (true) { |
| 82 | + got_irq = false; |
| 83 | + sleep_ms(3000); |
| 84 | + if (!IMU->is_connected()) { |
| 85 | + printf("MPU6050 is not connected...\n"); |
| 86 | + } else if (!got_irq){ |
| 87 | + printf("MPU6050 is connected, but didn't trigger an interrupt\n"); |
| 88 | + } |
| 89 | + } |
| 90 | +} |
0 commit comments