亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

掌握Arduino I2C通信:实战教程

本教程将讲解I2C通信协议的工作原理,并通过Arduino开发板与一个使用该协议的传感器进行实战演示。您可以观看以下视频或阅读下方文字教程。

概述

I2C通信总线因易于实现,广泛应用于许多电子设备。它可实现主设备与多个从设备(甚至多主设备)之间的通信。实现简易的关键在于仅需两根线:使用7位寻址时最多可连接128(112)个设备,10位寻址时最多1024(1008)个设备。

掌握Arduino I2C通信:实战教程

I2C如何工作

如何仅用两根线实现这么多设备通信?每个设备都有预设的唯一设备地址,主设备可选择与哪个设备通信。

两根线分别称为串行时钟线(SCL)和串行数据线(SDA)。SCL由主设备产生时钟信号,同步总线上设备间的数据传输。SDA传输数据。

两根线均为“开漏”结构,需接上拉电阻使线路保持高电平(设备为低电平有效)。常用电阻值:2KΩ用于高速约400kbps,10KΩ用于低速约100kbps。

掌握Arduino I2C通信:实战教程

I2C协议

掌握Arduino I2C通信:实战教程

数据以8位序列传输。起始条件后,首个8位序列为从设备地址。每8位后跟一个应答位(ACK)。首个ACK后通常跟随从设备内部寄存器地址序列。随后为数据序列,直到数据发送完毕,以停止条件结束。

细看这些事件:起始条件发生在SCL高电平时SDA由高变低。随后时钟开始,每个时钟脉冲传输一位数据。

设备寻址序列从最高有效位(MSB)开始,到最低有效位(LSB)结束,实际由7位组成,第8位用于指示主设备写从设备(低电平)还是读从设备(高电平)。

掌握Arduino I2C通信:实战教程

接下来的ACK/NACK位由从设备用于指示是否成功接收前一个序列。此时主设备将SDA控制权交给从设备,若成功接收,从设备将SDA拉低表示ACK;若不拉低则为NACK,表示未成功接收(可能原因:从设备忙、不理解命令、无法接收更多数据等)。主设备决定后续处理。

掌握Arduino I2C通信:实战教程

随后是内部寄存器寻址。内部寄存器是从设备存储器中包含各种信息或数据的位置。例如ADXL345加速度计有唯一设备地址,以及X、Y、Z轴的内部寄存器地址。若要读取X轴数据,先发送设备地址,再发送X轴对应的内部寄存器地址。这些地址可从传感器数据手册获取。

寻址后开始数据传输序列,方向取决于R/W位选择的模式。数据发送完毕后,以停止条件结束:SCL高电平时SDA由低变高。

实例

示例使用GY-80扩展板(含5个传感器)和GY-521扩展板(含3个传感器),通过I2C总线仅用两根线即可读取8个传感器数据。

掌握Arduino I2C通信:实战教程

所需组件:

  • ADXL345三轴加速度计………………………………………………………
  • 二合一:MPU6050六轴陀螺仪&加速度计…………………
  • 三合一:GY-80九轴磁场加速度陀螺仪……… Amazon
  • 三合一:GY-86十轴MS5611 HMC5883L MPU6050模块……… Banggood / AliExpress

连接方式:Arduino的SCL连接两块扩展板的SCL,SDA同理,GND和5V供电。注意此处未使用上拉电阻,因扩展板已自带。

掌握Arduino I2C通信:实战教程

需要知道各芯片/传感器的唯一地址,可从数据手册获取。GY-80四个地址:加速度计0x53、陀螺仪0x69、磁力计0x1E、气压/温度计0x77。GY-521仅一个地址0x68。也可用Arduino I2C Scanner扫描获取地址(Arduino官网提供)。上传运行该草图可获取I2C总线上连接设备的地址。


传感器型号 | I2C地址

三轴加速度计 ADXL345 | 0x53 | 数据手册

三轴陀螺仪 L3G4200D | 0x69 | 数据手册

三轴磁力计 HMC5883L | 0x1E | 数据手册

气压计+温度计 BMP085 | 0x77 | 数据手册


获取设备地址后,还需内部寄存器地址以读取数据。例如读取GY-80上ADXL345的X轴数据,需找到存储X轴数据的内部寄存器。数据手册显示X轴数据存储在两个寄存器:DATAX0 (0x32) 和 DATAX1 (0x33)。

Arduino I2C代码

编写读取X轴数据的代码。使用Arduino Wire库(需包含)。定义传感器地址和两个内部寄存器地址。Wire.begin()初始化Wire库,同时初始化串口通信以便串口监视器显示数据。

loop()中:Wire.beginTransmission()开始与特定传感器(三轴加速度计)通信。Wire.write()请求X轴两个寄存器的数据。Wire.endTransmission()结束传输并从寄存器传出数据。Wire.requestFrom()请求两字节数据。Wire.available()返回可用字节数,若匹配2字节,用Wire.read()读取两个寄存器字节。最后串口监视器打印数据。注意这是原始数据,需进一步数学处理才能得到正确的X轴值。详细处理请参考我的下一篇加速度计教程,本教程重点讲解I2C通信原理。

/*
 * I2C通信协议工作原理 - Arduino I2C教程
 * by Dejan, www.HowToMechatronics.com
 */
#include <Wire.h>
int ADXLAddress = 0x53; // 设备地址,包含第8位模式选择位(读模式)
#define X_Axis_Register_DATAX0 0x32
#define X_Axis_Register_DATAX1 0x33
#define Power_Register 0x2D // 电源控制寄存器
int X0,X1,X_out;

void setup() {
  Wire.begin(); Serial.begin(9600); delay(100);
  // 启用测量
  Wire.beginTransmission(ADXLAddress);
  Wire.write(Power_Register);
  Wire.write(8); // Bit D3置高 (0000 1000)
  Wire.endTransmission();
}

void loop() {
  Wire.beginTransmission(ADXLAddress);
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission();
  Wire.requestFrom(ADXLAddress,2);
  if(Wire.available()<=2) {
    X0 = Wire.read(); X1 = Wire.read();
  }
  Serial.print("X0= "); Serial.print(X0);
  Serial.print(" X1= "); Serial.println(X1);
}
代码语言: Arduino (arduino)

制造工艺

  1. Arduino 与树莓派 2 I2C 通信集成:打造物联网传感器项目的最佳搭档
  2. 打造可靠的 Arduino 能源监测与数据记录仪——分步指南
  3. Arduino + DHT11 + 以太网盾板温湿度数据记录仪
  4. Python 3 控制 Arduino UNO - 串口通信点亮内置 LED 入门教程
  5. Arduino 连接 NMEA-0183 设备全攻略:从硬件接线到协议解析
  6. Arduino Nano 打造 JARVIS v1 家庭自动化:分步教程
  7. 掌握 Arduino 多任务编程:原型线程分步教程
  8. 掌握nRF24L01:无线通信、Arduino集成、电路与代码全攻略
  9. MPU6050 六轴 IMU 详解:Arduino 姿态解算与 3D 可视化
  10. ADXL345 三轴加速度计 Arduino 姿态追踪教程
  11. 使用 HC-12 模块构建可靠的远距离 Arduino 网络
  12. Arduino RFID 门禁系统:从原理到实战的完整指南