当前位置:   article > 正文

【Arduino小车实践】陀螺仪之相关代码分析(可直接搬用)_arduino陀螺仪程序编写教程

arduino陀螺仪程序编写教程

前言

上一篇简单介绍了陀螺仪的基本内容,本篇主要针对陀螺仪的代码使用进行分析。

上一篇关于陀螺仪的基本内容的链接:(58条消息) 【Arduino小车实践】陀螺仪的使用_禾风wyh的博客-CSDN博客

代码分析

1. 相关库函数

Adafruit_MPU6050.h包含了 MPU6050 加速度计的功能,包括初始化、获取数据等
Adafruit_Sensor.h为了支持 MPU6050 加速度计的传感器事件。它提供了一种统一的接口用于获取不同类型传感器(如加速度计、陀螺仪、磁力计等)的数据
Wire.h了支持 MPU6050 加速度计的传感器事件。它提供了一种统一的接口用于获取不同类型传感器(如加速度计、陀螺仪、磁力计等)的数据

2. 对象声明

Adafruit_MPU6050 mpu; //这行代码定义了一个名为 mpu 的对象,其类型为 Adafruit_MPU6050,用于与 MPU6050 加速度计进行通信和操作。

在代码中的其他部分,可以使用这个对象来调用 Adafruit_MPU6050 类中提供的方法,如 begin()getEvent()setAccelerometerRange() 等,以实现对 MPU6050 加速度计的初始化、数据获取和设置等操作。

3. 基础代码

(1)启动MPU6050

  1. void MPU_START(void){//用于启动 MPU6050 传感器
  2. Wire.beginTransmission(0x68); //开启MPU6050的传输
  3. Wire.write(0x6B); //指定寄存器地址,0x68 是 MPU6050 的 I2C 地址
  4. Wire.write(0); //将 MPU6050 的寄存器 0x6B 写入 0,以启动 MPU6050
  5. Wire.endTransmission(true); //结束传输,true表示释放总线
  6. }

(2)配置角速度

  1. void GYRO_CONFIG_SET(int f){ //配置角速度倍率
  2. Wire.beginTransmission(0x68); //开启MPU-6050的传
  3. Wire.write(0x1B); //角速度倍率寄存器的地址
  4. Wire.requestFrom(0x68, 1, true); //从 MPU6050 的寄存器地址 0x1B 请求读取 1 个字节的数据,读出原来的配置
  5. unsigned char acc_conf = Wire.read();//将读取到的数据保存在变量 acc_conf 中。这个变量用于存储原配置的值
  6. acc_conf = ((acc_conf & 0xE7) | (f << 3));//对 acc_conf 进行位运算,以设置新的角速度倍率。通过 f 参数左移 3 位,并和原配置进行按位或操作,从而实现设置新的角速度倍率
  7. Wire.write(acc_conf);//将更新后的角速度倍率配置写入 MPU6050 的寄存器地址 0x1B
  8. Wire.endTransmission(true); //结束传输,true表示释放总线
  9. }

(3)配置加速度

  1. //配置加速度倍率
  2. void ACCEL_CONFIG_SET(int f){
  3. Wire.beginTransmission(0x68); //开启MPU-6050的传输
  4. Wire.write(0x1C); //加速度倍率寄存器的地址
  5. Wire.requestFrom(0x68, 1, true); //先读出原配置
  6. unsigned char acc_conf = Wire.read();
  7. acc_conf = ((acc_conf & 0xE7) | (f << 3));
  8. Wire.write(acc_conf);
  9. Wire.endTransmission(true); //结束传输,true表示释放总线
  10. }

(4)获取MPU数据

  1. //获取MPU数据
  2. void Get_Value(void){
  3. //获取各个轴分量数据
  4. Wire.beginTransmission(0x68); //开启MPU-6050的传输
  5. Wire.write(0x3B);
  6. Wire.requestFrom(0x68, 7 * 2, true);
  7. Wire.endTransmission(true);
  8. for (long i = 0; i < 7; ++i) {
  9. val_seven[i] = Wire.read() << 8 | Wire.read();
  10. }
  11. //数据换算
  12. val_seven[0] = (float)(val_seven[0] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_x
  13. val_seven[1] = (float)(val_seven[1] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_y
  14. val_seven[2] = (float)(val_seven[2] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_z
  15. val_seven[3] = (float)(val_seven[3] / 340 + 36.53);//acc_z
  16. val_seven[4] = (float)(val_seven[4] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_x
  17. val_seven[5] = (float)(val_seven[5] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_y
  18. val_seven[6] = (float)(val_seven[6] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_z
  19. }

(5)全部代码汇总

  1. //接线方式:VCC--5V、GND--GND、SCL--A5、SDA--A4、AD0--AD0引脚为地址选择引脚,悬空或者接GND,硬件地址为0x68,接VCC/高电平硬件地址为0x69 INT--中断引脚,如果用到可以接中端口,此处不接
  2. #include <Wire.h>
  3. #define ACCEL_CONFIG 1 //加速度倍率配置选项
  4. #define GYRO_CONFIG 1 //角速度速度倍率配置选项
  5. //(具体的倍率与具体的 MPU6050 模块和应用有关,在使用时需要根据实际情况进行设置和调整)
  6. #define G 9.8 //重力加速度
  7. float val_seven[7];
  8. void MPU_START(void){//用于启动 MPU6050 传感器
  9. Wire.beginTransmission(0x68); //开启MPU6050的传输
  10. Wire.write(0x6B); //指定寄存器地址,0x68 是 MPU6050 的 I2C 地址
  11. Wire.write(0); //将 MPU6050 的寄存器 0x6B 写入 0,以启动 MPU6050
  12. Wire.endTransmission(true); //结束传输,true表示释放总线
  13. }
  14. //配置角速度倍率
  15. void GYRO_CONFIG_SET(int f){
  16. Wire.beginTransmission(0x68); //开启MPU-6050的传
  17. Wire.write(0x1B); //角速度倍率寄存器的地址
  18. Wire.requestFrom(0x68, 1, true); //从 MPU6050 的寄存器地址 0x1B 请求读取 1 个字节的数据,读出原来的配置
  19. unsigned char acc_conf = Wire.read();//将读取到的数据保存在变量 acc_conf 中。这个变量用于存储原配置的值
  20. acc_conf = ((acc_conf & 0xE7) | (f << 3));//对 acc_conf 进行位运算,以设置新的角速度倍率。通过 f 参数左移 3 位,并和原配置进行按位或操作,从而实现设置新的角速度倍率
  21. Wire.write(acc_conf);//将更新后的角速度倍率配置写入 MPU6050 的寄存器地址 0x1B
  22. Wire.endTransmission(true); //结束传输,true表示释放总线
  23. }
  24. //配置加速度倍率
  25. void ACCEL_CONFIG_SET(int f){
  26. Wire.beginTransmission(0x68); //开启MPU-6050的传输
  27. Wire.write(0x1C); //加速度倍率寄存器的地址
  28. Wire.requestFrom(0x68, 1, true); //先读出原配置
  29. unsigned char acc_conf = Wire.read();
  30. acc_conf = ((acc_conf & 0xE7) | (f << 3));
  31. Wire.write(acc_conf);
  32. Wire.endTransmission(true); //结束传输,true表示释放总线
  33. }
  34. //获取MPU数据
  35. void Get_Value(void){
  36. //获取各个轴分量数据
  37. Wire.beginTransmission(0x68); //开启MPU-6050的传输
  38. Wire.write(0x3B);
  39. Wire.requestFrom(0x68, 7 * 2, true);
  40. Wire.endTransmission(true);
  41. for (long i = 0; i < 7; ++i) {
  42. val_seven[i] = Wire.read() << 8 | Wire.read();
  43. }
  44. //数据换算
  45. val_seven[0] = (float)(val_seven[0] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_x
  46. val_seven[1] = (float)(val_seven[1] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_y
  47. val_seven[2] = (float)(val_seven[2] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_z
  48. val_seven[3] = (float)(val_seven[3] / 340 + 36.53);//acc_z
  49. val_seven[4] = (float)(val_seven[4] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_x
  50. val_seven[5] = (float)(val_seven[5] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_y
  51. val_seven[6] = (float)(val_seven[6] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_z
  52. }
  53. // The setup() function runs once each time the micro-controller starts
  54. void setup(){
  55. Serial.begin(9600);
  56. Wire.begin();//以主机模式开启总线
  57. MPU_START();//启动MPU6050
  58. GYRO_CONFIG_SET(0);//配置器件角速度倍率
  59. ACCEL_CONFIG_SET(0);//配置器件加速度倍率
  60. }
  61. // Add the main program code into the continuous loop() function
  62. void loop(){
  63. Get_Value();
  64. Serial.print("acc_x:");
  65. Serial.print('\t');
  66. Serial.println(val_seven[0]);
  67. Serial.print("acc_y:");
  68. Serial.print('\t');
  69. Serial.println(val_seven[1]);
  70. Serial.print("acc_z:");
  71. Serial.print('\t');
  72. Serial.println(val_seven[2]);
  73. Serial.print("gyr_x:");
  74. Serial.print('\t');
  75. Serial.println(val_seven[4]);
  76. Serial.print("gyr_y:");
  77. Serial.print('\t');
  78. Serial.println(val_seven[5]);
  79. Serial.print("gyr_z:");
  80. Serial.print('\t');
  81. Serial.println(val_seven[6]);
  82. Serial.print("TEMP:");
  83. Serial.print('\t');
  84. Serial.println(val_seven[3]);
  85. delay(500);
  86. }

4. 相关示例

(1)basic_readings

设置 MPU6050 加速度计的初始化配置,并在串口终端上输出相关信息

  1. void setup(){
  2. Serial.begin(115200);//初始化串口通信,设置波特率为 115200
  3.   while (!Serial) delay(10);//等待直到串口连接完成,以防止一些板子(如Arduino Zero、Leonardo等)在未连接串口时继续执行
  4.   Serial.println("Adafruit MPU6050 test!"); 
  5.   if (!mpu.begin()) {
  6.     Serial.println("Failed to find MPU6050 chip");
  7.     while (1) delay(10);
  8.   }//尝试初始化 MPU6050 加速度计。如果初始化失败,则在串口终端上输出,并进入无限循环
  9.   Serial.println("MPU6050 Found!");
  10.   mpu.setAccelerometerRange(MPU6050_RANGE_8_G);//设置加速度计的量程为 ±8G
  11.   Serial.print("Accelerometer range set to: ");
  12.   switch (mpu.getAccelerometerRange()){//检查并输出当前加速度计的量程设置
  13.   case MPU6050_RANGE_2_G:
  14.     Serial.println("+-2G");
  15.     break;
  16.   case MPU6050_RANGE_4_G:
  17.     Serial.println("+-4G");
  18.     break;
  19.   case MPU6050_RANGE_8_G:
  20.     Serial.println("+-8G");
  21.     break;
  22.   case MPU6050_RANGE_16_G:
  23.     Serial.println("+-16G");
  24.     break;
  25.   }
  26.   mpu.setGyroRange(MPU6050_RANGE_500_DEG);//设置陀螺仪的量程为 ±500°/s
  27.   Serial.print("Gyro range set to: ");
  28.   switch (mpu.getGyroRange()) {//检查并输出当前陀螺仪的量程设置
  29.   case MPU6050_RANGE_250_DEG:
  30.     Serial.println("+- 250 deg/s");
  31.     break;
  32.   case MPU6050_RANGE_500_DEG:
  33.     Serial.println("+- 500 deg/s");
  34.     break;
  35.   case MPU6050_RANGE_1000_DEG:
  36.     Serial.println("+- 1000 deg/s");
  37.     break;
  38.   case MPU6050_RANGE_2000_DEG:
  39.     Serial.println("+- 2000 deg/s");
  40.     break;
  41.   }
  42.   mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);//设置滤波器的带宽为 21 Hz
  43.   Serial.print("Filter bandwidth set to: ");
  44.   switch (mpu.getFilterBandwidth()) {//检查并输出当前陀螺仪滤波器的带宽设置
  45.   case MPU6050_BAND_260_HZ:
  46.     Serial.println("260 Hz");
  47.     break;
  48.   case MPU6050_BAND_184_HZ:
  49.     Serial.println("184 Hz");
  50.     break;
  51.   case MPU6050_BAND_94_HZ:
  52.     Serial.println("94 Hz");
  53.     break;
  54.   case MPU6050_BAND_44_HZ:
  55.     Serial.println("44 Hz");
  56.     break;
  57.   case MPU6050_BAND_21_HZ:
  58.     Serial.println("21 Hz");
  59.     break;
  60.   case MPU6050_BAND_10_HZ:
  61.     Serial.println("10 Hz");
  62.     break;
  63.   case MPU6050_BAND_5_HZ:
  64.     Serial.println("5 Hz");
  65.     break;
  66.   }
  67.   Serial.println("");
  68.   delay(100);
  69. }
  70. void loop() {
  71. sensors_event_t a, g, temp;//声明三个 sensors_event_t 类型的变量 a、g 和 temp,用于存储加速度、角速度和温度的传感器事件数据
  72. mpu.getEvent(&a, &g, &temp);//通过调用 getEvent() 方法,获取最新的传感器事件数据,并将其保存到对应的变量中。
  73. Serial.print("Acceleration X: ");
  74. Serial.print(a.acceleration.x);
  75. Serial.print(", Y: ");
  76. Serial.print(a.acceleration.y);
  77. Serial.print(", Z: ");
  78. Serial.print(a.acceleration.z);
  79. Serial.println(" m/s^2");
  80. Serial.print("Rotation X: ");
  81. Serial.print(g.gyro.x);
  82. Serial.print(", Y: ");
  83. Serial.print(g.gyro.y);
  84. Serial.print(", Z: ");
  85. Serial.print(g.gyro.z);
  86. Serial.println(" rad/s");
  87. Serial.print("Temperature: ");
  88. Serial.print(temp.temperature);
  89. Serial.println(" degC");
  90. Serial.println("");
  91. delay(500);
  92. }

(2)motion_detection

用于检测 MPU6050 模块的运动中断,并在检测到运动时打印加速度和角速度数据。

  1. void setup(void) {
  2. Serial.begin(115200);
  3. while (!Serial) delay(10); // 等待串口打开,适用于 Zero、Leonardo 等板型
  4. Serial.println("Adafruit MPU6050 test!");
  5. // 尝试初始化 MPU6050
  6. if (!mpu.begin()) {
  7. Serial.println("Failed to find MPU6050 chip");
  8. while (1) delay(10);
  9. }
  10. Serial.println("MPU6050 Found!");
  11. // 设置运动检测
  12. mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
  13. mpu.setMotionDetectionThreshold(1);
  14. mpu.setMotionDetectionDuration(20);
  15. mpu.setInterruptPinLatch(true); // 保持中断触发状态,重新初始化时将关闭
  16. mpu.setInterruptPinPolarity(true);
  17. mpu.setMotionInterrupt(true);
  18. Serial.println("");
  19. delay(100);
  20. }
  21. void loop() {
  22. if (mpu.getMotionInterruptStatus()) {
  23. /* 获取新的传感器事件数据 */
  24. sensors_event_t a, g, temp;
  25. mpu.getEvent(&a, &g, &temp);
  26. /* 打印数值 */
  27. Serial.print("AccelX:");
  28. Serial.print(a.acceleration.x);
  29. Serial.print(",");
  30. Serial.print("AccelY:");
  31. Serial.print(a.acceleration.y);
  32. Serial.print(",");
  33. Serial.print("AccelZ:");
  34. Serial.print(a.acceleration.z);
  35. Serial.print(", ");
  36. Serial.print("GyroX:");
  37. Serial.print(g.gyro.x);
  38. Serial.print(",");
  39. Serial.print("GyroY:");
  40. Serial.print(g.gyro.y);
  41. Serial.print(",");
  42. Serial.print("GyroZ:");
  43. Serial.print(g.gyro.z);
  44. Serial.println("");
  45. }
  46. delay(10);
  47. }

(3)mpu6050_oled

通过 MPU6050 传感器获取加速度和角速度数据,并通过 SSD1306 OLED 显示屏显示数据

  1. //导入库函数
  2. #include <Adafruit_MPU6050.h>
  3. #include <Adafruit_SSD1306.h>
  4. #include <Adafruit_Sensor.h>
  5. //创建对象
  6. Adafruit_MPU6050 mpu;
  7. Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
  8. void setup() {
  9. Serial.begin(115200);
  10. while (!Serial);
  11. Serial.println("MPU6050 OLED demo");
  12. if (!mpu.begin()) {
  13. Serial.println("Sensor init failed");
  14. while (1) yield();
  15. }
  16. Serial.println("Found a MPU-6050 sensor");
  17. //设置 SSD1306 OLED 显示屏的相关参数
  18. if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  19. Serial.println(F("SSD1306 allocation failed"));
  20. for (;;)
  21. ;
  22. }
  23. display.display();
  24. delay(500); // Pause for 2 seconds
  25. display.setTextSize(1);
  26. display.setTextColor(WHITE);
  27. display.setRotation(0);
  28. }
  29. void loop() {
  30. //获取 MPU6050 的加速度和角速度数据,并打印到串口和显示屏上
  31. sensors_event_t a, g, temp;
  32. mpu.getEvent(&a, &g, &temp);
  33. display.clearDisplay();
  34. display.setCursor(0, 0);
  35. Serial.print("Accelerometer ");
  36. Serial.print("X: ");
  37. Serial.print(a.acceleration.x, 1);
  38. Serial.print(" m/s^2, ");
  39. Serial.print("Y: ");
  40. Serial.print(a.acceleration.y, 1);
  41. Serial.print(" m/s^2, ");
  42. Serial.print("Z: ");
  43. Serial.print(a.acceleration.z, 1);
  44. Serial.println(" m/s^2");
  45. display.println("Accelerometer - m/s^2");
  46. display.print(a.acceleration.x, 1);
  47. display.print(", ");
  48. display.print(a.acceleration.y, 1);
  49. display.print(", ");
  50. display.print(a.acceleration.z, 1);
  51. display.println("");
  52. Serial.print("Gyroscope ");
  53. Serial.print("X: ");
  54. Serial.print(g.gyro.x, 1);
  55. Serial.print(" rps, ");
  56. Serial.print("Y: ");
  57. Serial.print(g.gyro.y, 1);
  58. Serial.print(" rps, ");
  59. Serial.print("Z: ");
  60. Serial.print(g.gyro.z, 1);
  61. Serial.println(" rps");
  62. display.println("Gyroscope - rps");
  63. display.print(g.gyro.x, 1);
  64. display.print(", ");
  65. display.print(g.gyro.y, 1);
  66. display.print(", ");
  67. display.print(g.gyro.z, 1);
  68. display.println("");
  69. display.display();
  70. delay(100);
  71. }

(4)mpu6050_unifiedsensors

  1. #include <Adafruit_MPU6050.h>
  2. Adafruit_MPU6050 mpu;
  3. Adafruit_Sensor *mpu_temp, *mpu_accel, *mpu_gyro;
  4. void setup(void) {
  5. Serial.begin(115200);
  6. while (!Serial) delay(10);
  7. Serial.println("Adafruit MPU6050 test!");
  8. if (!mpu.begin()) {
  9. Serial.println("Failed to find MPU6050 chip");
  10. while (1) delay(10);
  11. }
  12. Serial.println("MPU6050 Found!");
  13. mpu_temp = mpu.getTemperatureSensor();
  14. mpu_temp->printSensorDetails();
  15. mpu_accel = mpu.getAccelerometerSensor();
  16. mpu_accel->printSensorDetails();
  17. mpu_gyro = mpu.getGyroSensor();
  18. mpu_gyro->printSensorDetails();
  19. }
  20. void loop() {
  21. sensors_event_t accel;
  22. sensors_event_t gyro;
  23. sensors_event_t temp;
  24. mpu_temp->getEvent(&temp);
  25. mpu_accel->getEvent(&accel);
  26. mpu_gyro->getEvent(&gyro);
  27. Serial.print("\t\tTemperature ");
  28. Serial.print(temp.temperature);
  29. Serial.println(" deg C");
  30. Serial.print("\t\tAccel X: ");
  31. Serial.print(accel.acceleration.x);
  32. Serial.print(" \tY: ");
  33. Serial.print(accel.acceleration.y);
  34. Serial.print(" \tZ: ");
  35. Serial.print(accel.acceleration.z);
  36. Serial.println(" m/s^2 ");
  37. Serial.print("\t\tGyro X: ");
  38. Serial.print(gyro.gyro.x);
  39. Serial.print(" \tY: ");
  40. Serial.print(gyro.gyro.y);
  41. Serial.print(" \tZ: ");
  42. Serial.print(gyro.gyro.z);
  43. Serial.println(" radians/s ");
  44. Serial.println();
  45. delay(100);
  46. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/911480
推荐阅读
相关标签
  

闽ICP备14008679号