- 物联网ESP32教程
- 首页
- 物联网简述
- ESP32介绍
- 在Arduino IDE中安装ESP32开发板
- 设置RTOS进行双核和多线程操作
- ESP32与MPU6050接口连接
- ESP32与模拟传感器的接口连接
- ESP32参数设置
- ESP32 SPIFFS存储器(芯片内置迷你SD卡)
- ESP32与OLED显示屏接口连接
- ESP32上的WiFi
- 使用HTTP通过WiFi传输数据
- 使用HTTPS通过WiFi传输数据
- 使用MQTT通过WiFi传输数据
- 通过蓝牙传输数据
- 使用NTP客户端获取当前时间
- 执行ESP32固件的(OTA)更新
- ESP32的应用
- 开发者后续步骤
- 物联网ESP32实用资源
- 快速指南
- 实用资源
- 讨论
ESP32与MPU6050接口连接
加速度计和陀螺仪广泛应用于工业物联网,用于测量各种机器的健康状况和运行参数。MPU6050是一款流行的六轴加速度计+陀螺仪。它是一种MEMS(微机电系统)传感器,这意味着它非常紧凑(从下图可以看出),并且在很宽的频率范围内也非常精确。
在本教程中,我们将学习如何将ESP32与MPU6050连接。在这个过程中,您将学习I2C(集成电路间通信)协议的使用,这将使您能够将ESP32与使用I2C协议进行通信的多个传感器和外围设备连接。本教程需要您的ESP32、一个MPU6050和几根跳线。
MPU6050与ESP32的连接
如下图所示,您需要将MPU6050的SDA线连接到ESP32的21引脚,SCL线连接到22引脚,GND连接到GND,VCC连接到3V3引脚。MPU6050的其他引脚无需连接。
代码详解
GitHub链接 − https://github.com/
ESP32和Arduino通常将I2C协议称为“Wire”。因此,所需的库导入是Wire.h
#include<Wire.h>
接下来,我们定义常量和全局变量。
const int MPU_ADDR = 0x68; // I2C address of the MPU-6050 int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
每个I2C设备都有一个固定的地址,其他设备使用该地址识别它并与其通信。对于MPU6050,该地址为0x68。我们稍后将在初始化与MPU6050的I2C通信时使用它。接下来我们进入设置代码。
void setup() { Serial.begin(115200); Wire.begin(21, 22, 100000); // sda, scl, clock speed Wire.beginTransmission(MPU_ADDR); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU−6050) Wire.endTransmission(true); Serial.println("Setup complete"); }
第一行很简单。我们正在以115200波特率启动与串行监视器的通信。接下来,我们开始I2C通信。为此,我们向Wire.begin()函数提供3个参数。
这些是SDA和SCL引脚以及时钟速度。现在,I2C通信需要两条线:数据线(SDA)和时钟线(SCL)。在ESP32上,引脚21和22通常保留用于I2C,其中21为SDA,22为SCL。为了与MPU6050通信,我们有两个速度选项:100kbit/s和400kbit/s。我们在这里选择了100kHz。如果您的用例需要,您也可以选择更高的速度选项。
接下来,我们使用Wire.beginTransmission()命令指示ESP32我们想要与地址等于MPU_ADDR的芯片通信。此时,您可能已经猜到一个ESP32芯片可以与多个I2C外设通信。事实上,共有128个唯一的地址(地址字段为7位长),因此ESP32可以使用I2C与128个不同的外设通信,前提是它们都具有不同的地址。
在接下来的几行中,我们将MPU6050的PWR_MGMT_1寄存器设置为0。这用于唤醒MPU6050。PWR_MGMT_1寄存器的地址0x6B是MPU6050内存中的地址。
它与MPU6050的I2C地址无关。MPU唤醒后,我们结束这段I2C传输,设置完成,并在串行监视器上使用打印语句进行指示。现在让我们跳到循环中。您会注意到我们将布尔值true作为参数传递给Wire.endTransmission。这告诉ESP32发送停止命令并释放I2C线路。如果我们将true替换为false,则ESP32将发送重启而不是停止,保持连接活动。
void loop() { Wire.beginTransmission(MPU_ADDR); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(true); Wire.beginTransmission(MPU_ADDR); Wire.requestFrom(MPU_ADDR, 14, true); // request a total of 14 registers AcX = Wire.read() −− 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY = Wire.read() −− 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ = Wire.read() −− 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp = Wire.read() −− 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX = Wire.read() −− 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) GyY = Wire.read() −− 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) GyZ = Wire.read() −− 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Serial.print(AcX); Serial.print(" , "); Serial.print(AcY); Serial.print(" , "); Serial.print(AcZ); Serial.print(" , "); Serial.print(GyX); Serial.print(" , "); Serial.print(GyY); Serial.print(" , "); Serial.print(GyZ); Serial.print("\n"); }
在循环中,如果您扫描上面的代码片段,您会看到我们总共执行了两次传输。在第一次传输中,我们指示MPU6050我们想要从中开始读取数据的地址,或者更确切地说,将MPU6050的内部指针设置为这个特定地址。在第二次传输中,我们告诉MPU我们请求从前面发送的地址开始的14个字节。然后我们逐个读取字节。您可能会注意到我们没有在读取结束时使用Wire.endTransmission(true)命令。这是因为Wire.requestFrom(MPU,14,true)的第三个参数指示ESP32在读取所需数量的字节后发送停止命令。如果我们传递false而不是true,ESP32将发送重启命令而不是停止命令。
现在,您可能想知道如何确定哪个寄存器对应于哪个读数。答案是MPU6050寄存器映射。顾名思义,它提供了可以从哪个寄存器获取哪个值的信息。根据此映射,我们意识到0x3B和0x3C对应于16位X方向加速度值的较高和较低字节。接下来的两个寄存器(0x3D和0x3E)包含16位Y方向加速度值的较高和较低字节,依此类推。在加速度计和陀螺仪读数之间,有两个字节包含温度读数,我们读取并忽略它们,因为我们不需要它们。这样,您就可以成功地在ESP32上获取MPU6050的数据。恭喜!!继续下一个教程,学习如何在ESP32上获取模拟传感器的数据。