简介
Fermion: I2C 地址转换器是一款直接硬件修改I2C传感器从机地址的模块。在控制器和传感器之间加入这个模块,主控就可以以新的地址来访问您的传感器。
通过板载拨钮的组合,至多可以将传感器修改为四个不同的新地址。通过焊接电阻,将另外获得至少20个新的从机地址
在I2C从机的研发过程中,开发者往往需要在一个I2C总线上集成多个相同的传感器。比如想要使用多个红外距离传感器组成阵列做避障小车,或者使用多个光照传感器测量多株植物收到不同光照的影响,亦或是想要使用多个加速度传感器捕捉人体动作来制作可穿戴设备。
以往,如果I2C传感器本身不支持地址修改的话,我们只能通过I2C级联器来实现这个效果。但是I2C级联器需要使用专门的驱动库,并且在代码中需要进行各个端口的切换,进一步拉长程序的时序,对于一个有高性能软件需求的开发者来说,想必这是不能忍受的。
而这款Fermion: I2C地址转换器提供了一个纯硬件的解决方案,无需使用任何软件库,也不会对I2C总线造成任何的时序影响,大大简化了开发流程,提升了软件性能。
虽然I2C地址转换器的功能强大,但是在使用前,您还需要注意以下两个问题:
- 这款转换器并不支持I2C时钟延长,所以它并不支持类似BNO055这类特殊的I2C传感器。
- I2C地址转换器仅负责硬件地址转换,您需要检查被转换的I2C传感器驱动库,以确保您知道如何在代码中将其改写为新的地址。
产品特性
- 纯硬件解决方案,无需额外软件库
- 板载拨钮,可以将I2C传感器变为四个不同的地址
- 尺寸小巧,邮票孔设计,方便批量集成
规格参数
- 供电电压:2.25V-5.5V
- 工作温度:0~70℃
- 工作电流:2mA @3.3V
- 尺寸:19*19mm
- 安装孔尺寸:φ2.0mm
引脚说明
Controller端引脚 | 功能描述 |
---|---|
VCC | DC2.25V-5.5V输入 |
GND | 接地 |
SCL | I2C时钟线(连接I2C主机) |
SDA | I2C数据线(连接I2C主机) |
RDY | I2C从机地址转换完成后输出高电平 I2C从机地址转换未完成输出低电平 |
Sensor端引脚 | 功能描述 |
---|---|
VCC | DC2.25-5.5V输出 |
GND | 接地 |
SCL | I2C时钟线(连接I2C从机) |
SDA | I2C数据线(连接I2C从机) |
板载拨钮 | 功能描述 |
---|---|
A5 | 控制I2C地址第五位是否翻转(1为翻转,0为不翻转) |
A4 | 控制I2C地址第四位是否翻转(1为翻转,0为不翻转) |
I2C地址计算
I2C地址具有7bit,我们定义A6为最高位,A0为最低位。
地址转换器默认将A6固定翻转(从0变为1,从1变为0)。您也可以通过板载拨钮控制A5或者A4位是否翻转。
假设传感器默认地址为0x69,换算为二进制则为0b1101001,将其接入地址转换器后:
原始地址(bin) | A5拨钮 | A4拨钮 | 新地址(bin) | 新地址(hex) |
---|---|---|---|---|
1101001 | 0 | 0 | 0101001 | 0x29 |
1101001 | 1 | 0 | 0001001 | 0x09 |
1101001 | 0 | 1 | 0111001 | 0x39 |
1101001 | 1 | 1 | 0011001 | 0x19 |
同时,您需要注意以下几点,
- Fermion: I2C地址转换器在调整完板载拨钮后,需要重新上电才能设置新地址。
- 如果您使用Windows电脑,您可以使用电脑自带计算器的程序员功能来进行十六进制(HEX)到二进制(BIN)的转换
- 以上地址说明中:0b为二进制数的前缀,代表后面的数据为二进制;0x为十六进制数的前缀,代表后面数据为十六进制。
使用教程
软硬件准备
硬件准备
- DFRduino UNO+IO扩展板 (SKU:DFR0216-2) ×1
- Gravity: BMI160 6轴惯性运动传感器(SKU:SEN0250)×2
- [Fermion: I2C 地址转换器](SKU:DFR1185)×1
- 杜邦线(F/F) 若干
软件准备
- 下载Arduino IDE: 点击下载Arduino IDE
- 下载BMI160库:DFRobot BMI160库
- Arduino IDE V1.8.19(或以下)安装库文件: 如何加载库文件
- Arduino IDE V2.0.0(或以上)可直接在库管理中搜索"DFRobot_BMI160"库并安装
接线图
示例代码
-
确认Fermion: I2C地址转换器板载拨钮设置为A5=0,A4=0后,按照上述接线图进行连接。
-
烧录以下示例程序
/* @file accelGyroscope.ino @brief Obtain accelerometer data in both BMIs. @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) @license The MIT License (MIT) @author [thdyyl](yuanlong.yu@dfrobot.com) @version V0.1 @date 2024-08-05 */ #include "DFRobot_BMI160.h" DFRobot_BMI160 bmi160_1, bmi160_2; const int8_t i2c_addr_1 = 0x69, i2c_addr_2 = 0x29; void setup(){ Serial.begin(115200); delay(100); //init the default bmi160 if(bmi160_1.softReset() != BMI160_OK){ Serial.println("bmi160_1 reset false"); while(1); } if(bmi160_2.softReset() != BMI160_OK){ Serial.println("bmi160_2 reset false"); while(1); } //set and init the bmi160 i2c address if(bmi160_1.I2cInit(i2c_addr_1) != BMI160_OK){ Serial.println("bmi160_1 init false"); while(1); } if(bmi160_2.I2cInit(i2c_addr_2) != BMI160_OK){ Serial.println("bmi160_2 init false"); while(1); } } void showAccelGyroData(DFRobot_BMI160 bmi160){ int i = 0; int rslt; int16_t accelGyro[6] = {0}; //get both accel and gyro data from bmi160 //parameter accelGyro is the pointer to store the data rslt = bmi160.getAccelGyroData(accelGyro); if(rslt == 0){ for(i = 0; i < 6; ++i){ if(i < 3){ //the first three are gyro datas Serial.print(accelGyro[i] * 3.14 / 180); Serial.print("\t"); }else{ //the following three data accel datas Serial.print(accelGyro[i] / 16384.0); Serial.print("\t"); } } Serial.println(); } else{ Serial.println("err"); } } void loop(){ Serial.print("bmi160_1:\t"); showAccelGyroData(bmi160_1); Serial.print("bmi160_2:\t"); showAccelGyroData(bmi160_2); Serial.println(); delay(500); }
结果
串口监视器输出两个Gravity: BMI160 6轴惯性运动传感器的数据。
进阶教程
Fermion: I2C地址转换器可以通过板载拨钮切换,将传感器设置为四个不同的地址。
如果这还无法满足您的需求。我们在模块上预留出了一个0805电阻焊盘(R2),您可以参考本文档最下方的原理图,以及LTC4316的数据手册中第九页,自行焊接电阻来控制其余的I2C地址位是否翻转。
该焊盘直连XORL引脚,可控制I2C地址低四位是否翻转,我们将RLB(在我们原理图中为R1)固定为100kΩ,您可以自行计算RLT(在我们原理图中为R2)的阻值并焊接。
以下是我们确定一个R2的过程:
-
首先从数据手册可得,该模块是通过XORH或XORL引脚的电压,即VXORH或VORL相对于VCC的比值来确定I2C地址某一位是否翻转的。在数据手册的table 2和table 3中,bit下的1代表翻转,0代表不翻转。
-
假设我们现在给模块供电VCC为5V,我们想要将A3-A0设置为1 0 0 0的模式,即A3翻转,A2~A0不翻转。那就意味着VOXRL/VCC的比值应该为0.53125 ±0.015
-
为了帮助您快速计算电阻,我们的工程师团队总结了一个通用公式:
[VCC/(R1+R2)]R1=VXORL
其中VCC在我们假设中已经规定为5V,R1已知为100kΩ,目标VXORL应该为0.53125*5V=2.65625V
将已知参数全部代入上述通用公式后,我们得出R2≈88.23529kΩ -
鉴于算出的R2并不是个常见阻值,我们需要将其匹配到最接近的常见阻值,并且将这个常见阻值代回通用公式进行验证。
在我们的样例中,最接近88.23529kΩ的常见阻值为86.6kΩ,代入计算后可得VXORL≈2.67953V,即VXORL/VCC≈0.53906。这个比值落在0.53125 ±0.015之间,所以我们可以使用86.6kΩ作为R2的阻值。
为了帮助您省去繁琐的计算,我们帮您列出了经过我们验证的几个R2阻值:
R2 | A3 | A2 | A1 | A0 |
---|---|---|---|---|
91kΩ/86.6kΩ | 1 | 0 | 0 | 0 |
68kΩ | 1 | 0 | 0 | 1 |
51kΩ | 1 | 0 | 1 | 0 |
39kΩ | 1 | 0 | 1 | 1 |
27kΩ | 1 | 1 | 0 | 0 |
如果您焊接电阻后不确定新的地址,我们推荐您使用Arduino或者ESP32,并且上传I2C scanner来确定您的新地址。
常见问题
Q1:在更改拨钮或者焊接电阻后,如何快速确认新的I2C从机地址
A1:您可以将传感器通过地址转换器连接到Arduino或者ESP32,上传下面的I2C Scanner代码。串口监视器会输出新的I2C地址。
/*
@file i2cScanner.ino
@brief The i2c_scanner see if a device did acknowledge to the address.
@copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
@license The MIT License (MIT)
@author [thdyyl](yuanlong.yu@dfrobot.com)
@version V0.1
@date 2024-08-05
*/
#include <Wire.h>
void setup(){
Wire.begin();
Serial.begin(115200);
Serial.println();
Serial.println("I2C Scanner");
}
void loop(){
uint8_t error, address;
int numDevices;
Serial.println("Scanning...");
numDevices = 0;
for (address = 1; address < 127; address++ ){
// The i2c_scanner uses the return value of the
// Write.endTransmisstion to see if a device
// did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0){
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
numDevices++;
}else if (error == 4){
Serial.print("Unknow error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (numDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(2000); // wait 2 seconds for next scan
}