2023-08-19 11:25:34 | 人围观 | 评论:
MPU6050是一款 集成 了 IC 3 轴加速度计和 3 轴陀螺仪的 单元。它还包含一个温度传感器和一个 DCM 来执行复杂的任务。MPU6050 常用于构建无人机和其他远程机器人,如自平衡机器人。在这个项目中,我们将使用MPU6050 和 Arduino构建一个数字量角器。
什么是加速度计和陀螺仪传感器?
加速度计用于测量加速度。它实际上感应静态和动态加速度。例如,手机使用加速度传感器来感知手机处于横向模式还是纵向模式。
陀螺仪用于测量角速度,该角速度使用地球重力来确定运动中物体的方向。角速度是旋转体角位置的变化率。
例如,今天的手机使用陀螺仪传感器根据手机的方位来玩手机游戏。此外,VR 耳机使用陀螺仪传感器具有 360 度视图
因此,虽然加速度计可以测量线性加速度,但陀螺仪可以帮助找到旋转加速度。当使用两个传感器作为单独的模块时,很难找到方向、位置和速度。但是通过组合这两个传感器,它可以作为一个惯性测量单元(IMU)。因此,在MPU6050 模块中,加速度计和陀螺仪存在于单个 PCB 上,以查找方向、位置和速度。
应用:
用于无人机方向控制
自平衡机器人
机械臂控制
倾斜传感器
用于手机、视频游戏机
人形机器人
用于飞机、汽车等。
MPU6050 加速度计和陀螺仪传感器模块
MPU6050 是一种微机电系统 ( MEMS ),内部包含一个 3 轴加速度计和 3 轴陀螺仪。它也有温度传感器。
它可以测量:
加速
速度
方向
移位
温度
该模块内部还有一个(DMP)数字运动处理器,其功能强大到足以执行复杂的计算,从而为微控制器腾出工作。
该模块还有两个辅助引脚,可用于连接外部 IIC 模块,如磁力计。由于模块的 IIC 地址是可配置的,因此可以使用 AD0 引脚将多个 MPU6050 传感器 连接到微控制器。
特点和规格:
电源:3-5V
通讯方式:I2C协议
内置 16 位 ADC 提供高精度
内置 DMP 提供高计算能力
可用于连接其他 IIC 设备,如磁力计
可配置的 IIC 地址
内置温度传感器
MPU6050的管脚:
我们之前使用MPU6050 和 Arduino来构建自平衡机器人和测斜仪。
所需组件
Arduino UNO
MPU6050陀螺仪模块
16x2 液晶显示器
电位器 10k
SG90-伺服电机
量角器图像
电路原理图
这个DIY Arduino 量角器的电路图如下所示:
Arduino UNO 和 MPU6050 之间的电路连接:
Arduino UNO 和伺服电机之间的电路连接:
Arduino UNO 和 16x2 LCD 之间的电路连接:
编程说明
这里伺服电机与 Arduino 连接,其轴投影在量角器图像上,指示倾斜 MPU6050 的角度。
首先包括所有必需的库 - 用于使用伺服的伺服电机库、用于使用 LCD 的 LCD 库和用于使用 I2C 通信的 Wire 库。
MPU6050 使用I2C 通信,因此,它只能连接到 Arduino 的 I2C 引脚。因此,Wire.h库用于建立 Arduino UNO 和 MPU6050 之间的通信。我们之前将 MPU6050 与 Arduino 连接,并在 16x2 LCD 上显示 x、y、z 坐标值。
#include#include #include
接下来定义与 Arduino UNO 连接的 LCD 显示引脚 RS、E、D4、D5、D6、D7。
液晶液晶(2,3,4,5,6,7);
接下来定义 MPU6050 的 I2C 地址。
常量 int MPU_addr=0x68;
然后初始化myservo对象以使用 Servo 类和三个变量来存储 X、Y 和 Z 轴值。
伺服myservo; int16_t 轴_X,轴_Y,轴_Z;
下一个最小值和最大值设置为 265 和 402,用于测量从 0 到 360 的角度。
int minVal=265; 诠释 maxVal=402;
无效设置():
在void setup函数中,首先启动 I2C 通信,并使用地址为 0x68 的 MPU6050 开始传输。
Wire.begin(); Wire.beginTransmission(MPU_addr);
通过写入 0x6B 将 MPU6050 置于睡眠模式,然后通过写入 0 唤醒它
Wire.write(0x6B); Wire.write(0);
使MPU6050激活后,结束传输
Wire.endTransmission(true);
此处伺服电机的 PWM 引脚与 Arduino UNO 引脚 9 相连。
myservo.attach(9);
一旦我们给电路加电,液晶显示屏就会显示一条欢迎消息,并在 3 秒后清除它
lcd.开始(16,2);//将 LCD 设置为 16X2 模式 lcd.print("CIRCUIT DIGEST"); 延迟(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("MPU6050"); 延迟(3000); lcd.clear();
无效循环():
同样,I2C 通信是从 MPU6050 开始的。
Wire.beginTransmission(MPU_addr);
然后从寄存器 0x3B (ACCEL_XOUT_H) 开始
Wire.write(0x3B);
现在,通过将结束传输设置为 false 重新启动该过程,但连接处于活动状态。
Wire.endTransmission(false);
之后,现在从 14 个寄存器请求数据。
Wire.requestFrom(MPU_addr,14,true);
现在获得尊重的轴寄存器值(x,y,z)并将其存储在变量axis_X,axis_Y,axis_Z中。
axis_X=Wire.read()<<8|Wire.read(); axis_Y=Wire.read()<<8|Wire.read(); axis_Z=Wire.read()<<8|Wire.read();
然后将这些值从 265 映射到 402 为 -90 到 90。这对所有三个轴都完成了。
int xAng = map(axis_X,minVal,maxVal,-90,90); int yAng = map(axis_Y,minVal,maxVal,-90,90); int zAng = map(axis_Z,minVal,maxVal,-90,90);
下面给出了以度(0 到 360)为单位计算 x 值的公式。这里我们只转换 x,因为伺服电机的旋转是基于 x 值移动的。
x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
X 角度值,从 0 到 360 度,转换为 0 到 180。
int pos = map(x,0,180,0,180);
然后写入角度值以在量角器图像上旋转伺服并将这些值打印在 16x2 LCD 显示器上。
myservo.write(pos); lcd.setCursor(0,0); lcd.print("角度"); lcd.setCursor(0,1); lcd.print(x); 延迟(500); lcd.clear();
#include
#include
#include
液晶液晶(2,3,4,5,6,7); //定义LCD显示引脚RS,E,D4,D5,D6,D7
常量 int MPU_addr=0x68; //I2C MPU6050地址
伺服myservo;//类伺服的myservo对象
int16_t 轴_X,轴_Y,轴_Z;
int minVal=265;
诠释 maxVal=402;
双x;
双 y;
双z;
整数位置 = 0;
void setup()
{
Wire.begin(); //开始 I2C 通信
Wire.beginTransmission(MPU_addr); //使用 MPU6050 开始传输
Wire.write(0x6B); //将 MPU6050 置于睡眠模式
Wire.write(0); //将 MPU6050 置于电源模式
Wire.endTransmission(true); //结束
传输 myservo.attach(9);
//UNO lcd.begin(16,2)中的伺服 PWM 引脚为 9 ;//将 LCD 设置为 16X2 模式
lcd.print("CIRCUIT DIGEST");
延迟(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Arduino");
lcd.setCursor(0,1);
lcd.print("MPU6050");
延迟(2000);
lcd.clear();
}
无效循环()
{
Wire.beginTransmission(MPU_addr);//开始 I2C 传输
Wire.write(0x3B); //从寄存器 0x3B (ACCEL_XOUT_H) 开始
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true); //向MPU6050请求14个寄存器
axis_X=Wire.read()<<8|Wire.read(); //获取0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
axis_Y=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
axis_Z=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)
int xAng = map(axis_X,minVal,maxVal,-90,90);
int yAng = map(axis_Y,minVal,maxVal,-90,90);
int zAng = map(axis_Z,minVal,maxVal,-90,90);
x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI); //计算度数x值的公式
int pos = map(x,0,180,0,180); // 因为 X 值是从 0 到 360 度
myservo.write(pos); // 将获得的角度 0 到 180 写入伺服
lcd.setCursor(0,0);
lcd.print("角度");
lcd.setCursor(0,1);
lcd.print(x);
延迟(500);
lcd.clear();
}
全站搜索