Arduino作为具有多个i2c地址的从机

Arduino作为具有多个i2c地址的从机,arduino,i2c,atmega,Arduino,I2c,Atmega,我想使用Arduino作为i2c从机。但我要求Arduino通过使用多个i2c地址注册自身,充当多个设备 这可能不是人们通常会做的事情,但我这样做的原因如下: 我想使用Arduino作为Spektrum遥测的遥测传感器。遥测接收器有几个i2c插头,连接到多个传感器(电流0x02、电压0x03、空速0x11等),每个传感器都有遥测接收器期望的固定i2c地址 我想使用oneArduino作为所有这些设备,使用上述所有地址注册自身,并用读数进行适当响应 我可以在每个传感器上使用一个Arduino,这看

我想使用Arduino作为i2c从机。但我要求Arduino通过使用多个i2c地址注册自身,充当多个设备

这可能不是人们通常会做的事情,但我这样做的原因如下:

我想使用Arduino作为Spektrum遥测的遥测传感器。遥测接收器有几个i2c插头,连接到多个传感器(电流0x02、电压0x03、空速0x11等),每个传感器都有遥测接收器期望的固定i2c地址

我想使用oneArduino作为所有这些设备,使用上述所有地址注册自身,并用读数进行适当响应

我可以在每个传感器上使用一个Arduino,这看起来很愚蠢,因为我可以用一个Arduino pro mini执行所有这些读数

我知道你可以使用

Wire.begin(0x02); 
但我需要类似的东西(伪代码)

当收到请求时,我需要知道询问Arduino的地址

例如(伪代码)

任何建议都将不胜感激。

使用Wire库无法使Arduino侦听多个从机地址,因为它只允许传递单个从机地址


即使是大多数Arduinos所基于的Atmel ATmega微控制器也只允许通过其双线地址寄存器TWAR将其硬件双线串行接口(TWI)设置为单个7位地址。然而,可以通过使用TWI地址屏蔽寄存器
TWAMR
屏蔽一个或多个地址位来解决此限制,如第22.9.6节所述(略为简要):

TWAMR可以加载7位Salve(原文如此!)地址掩码。TWAMR中的每个位都可以屏蔽(禁用)TWI地址寄存器(TWAR)中的相应地址位。如果掩码位设置为1,则地址匹配逻辑将忽略传入地址位与TWAR中相应位之间的比较

因此,我们首先必须根据我们想要响应的所有I2C地址设置掩码位,方法是对它们进行OR运算并向右移位以匹配
TWAMR
寄存器布局(
TWAMR
将掩码保持在位7:1,位0未使用):


TWAMR=(sensor1|addr | sensor2|addr | sensor3|addr)我真的很喜欢vega8的答案,但我还想提一点,如果你的I2C主机的时钟速度不快,那么使用基于软件的I2C实现也是可行的,可以给你想要的自由

如果粗略的计算表明在TWI ISR中花费的时间太高,中断可能会开始重叠,那么您可能需要考虑该方法。p>
void setup()
void setup() 
{
    Wire.begin(0x11 | 0x12);       // Adr 11 and 12 are used for Alt and Speed by Spectrum DX
    Wire.onRequest(requestEvent);  // register callback function
    TWAMR = (0x11 | 0x12) << 1;    // set filter for given adr
}
{ Wire.begin(0x11 | 0x12);//Adr 11和12通过频谱DX用于Alt和Speed onRequest(requestEvent);//注册回调函数 TWAMR=(0x11 | 0x12) 这适用于带有遥测模块的频谱DX8。
频谱接口在Sectrum主页上公开。技术文档。

I2C总线上可能有其他设备,TWAMR应设置为尽可能少的位。因此我认为计算掩码的更好方法是:

AddrOr =  Addr1 | Addr2 | Addr3 | Addr4 ... 
AddrAnd = Addr1 & Addr2 & Addr3 & Addr4 ...
TWAMR = (AddrOr ^ AddrAnd) << 1
AddrOr=Addr1 | Addr2 | Addr3 | Addr4。。。
AddrAnd=Addr1&Addr2&Addr3&Addr4。。。

TWAMR=(AddrOr^AddrAnd)好的评论,thx!这意味着实现硬件中已有的大部分功能(包括增加的程序大小+额外的测试)。当然更灵活,典型的折衷情况。如果使用除原始Arduino之外的平台是一种选择,ATXmega1设备配有4个I2C接口,github上有一个名为Xmegaduino的接口。谢谢@vega8,你的回答非常有描述性!如果可行,我会尝试更新。回答很好。有一个问题;有一些问题吗限制地址数量的因素(除了7位地址外)?是否可以专门处理6个地址?例如:
(0x28 | 0x29 | 0x2A | 0x2B | 0x2C | 0x2D)这个想法确实有效!!这里有一个代码库:我唯一想添加的是,计算掩码的正确方法不是使用and和运算符。欢迎使用SO。请记住在代码中添加4个空格的缩进,以便正确显示。此外,我还建议添加一些注释。欢迎使用SO。请请记住在代码中添加4个空格的缩进,以便正确显示。
void setup() 
{
    Wire.begin(0x11 | 0x12);       // Adr 11 and 12 are used for Alt and Speed by Spectrum DX
    Wire.onRequest(requestEvent);  // register callback function
    TWAMR = (0x11 | 0x12) << 1;    // set filter for given adr
}
void requestEvent() {
    int adr = TWDR >> 1;  // move 1 bit to align I2C adr
    if (adr == 0x12)      // check for altitude request at adr 12
        Wire.write(tmpSpektrumDataAlt, 16); // send buffer
    if (adr == 0x11)      // check for speed request at adr 11
        Wire.write(tmpSpektrumDataSpd, 16); // send buffer
}
AddrOr =  Addr1 | Addr2 | Addr3 | Addr4 ... 
AddrAnd = Addr1 & Addr2 & Addr3 & Addr4 ...
TWAMR = (AddrOr ^ AddrAnd) << 1