多个 arduino 通信(1 个主设备,n 个从设备)

电器工程 Arduino 串行 沟通 i2c 奴隶
2022-01-18 23:33:16

我想开发一个主/从网络,包括:

  • 1 个 Arduino 主机,它读取传感器并根据传感器信号生成速度斜坡曲线,然后将这些斜坡发送到从机

  • 3(或更多)个 Arduino 从机,根据主机发送的斜坡控制 12V 伺服电机的速度

实现此目的的良好通信协议是什么?串行(SPI)?I2C?还有什么?如果是连载的话,新的Arduino Leonardo是不是一个不错的选择?在选择协议时我应该考虑哪些问题?

我在想像:

掌握:

void loop() {
    update_ramps()
    for(int i=0; i< num_slaves; i++) {
        send_to_all(i, ramps[i]);
    }
}

从站 1:

const int id = 1;
int recived_id, recived_value;
void loop() {
    read_data();
    if(recived_id == id) { 
        do_motor_step(recived_value);
    }
}

以及串行通信,其中来自主机的 RX/TX 被发送到所有从机。

这似乎是一个合理的解决方案?

4个回答

据我了解,您想向每个从站发送不同的数据,但从站不必发回数据。

I2C是寻址总线,因此如果为每个从机分配不同的 I2C 地址,则只需两条线即可发送数据。如果需要,您也可以询问数据。Arduino 的 AVR 具有 I2C 兼容的串行总线。并且您可以在不使用额外硬件的情况下扩展到 3 个以上的从站,最多 127 个。

UART没有寻址,因此您需要 3 个 UART(AVR 没有),或者添加外部逻辑以在 UART 线路之间切换(这需要花钱)。每增加一个奴隶就意味着额外的成本。不建议。
编辑
就像克里斯说的,您可以使用 UART 创建多点总线。然后您必须添加寻址,这使您的 UART 工作有点像 I2C,但随后是异步的,并且没有像 I2C 那样的地址匹配硬件。所以仍然不是真正的优势。 编辑结束

SPI还使用共享线来传输数据:单个 MOSI 和 MISO 线相连。要单独寻址每个从站,每个从站需要一条 SS(从站选择)线。所以至少有 5 个 I/O:MOSI、SCK、3 \\$\\times\\$ SS 和 MISO,如果您还想从从站读取数据。每个额外的从设备在主设备上增加 1 个 I/O 引脚。

在此处输入图像描述

我认为 I2C 是最好的解决方案,需要最少的电线。该协议比 UART 或 SPI 稍微复杂一些,但由于 AVR 有硬件,它应该很容易使用。

我假设串行是指UART?请注意,UART、SPI、I2C 都是串行协议。

SPI 或 I2C 会很好,因为它们都使用主/从架构。
不包括地,对于 3 个从机,SPI 需要 6 个引脚(MOSI、MISO、CLK + 3 个 SS 引脚)和 I2C 只需两个(SDA 和 SCK)
我可能会选择 I2C,假设您不需要非常高的数据传输速率(<400kHz)

添加的从机越多,SPI 就越不方便,因为每个新从机都需要另一个 SS(从机选择)。使用 I2C,这不是问题,因为寻址是协议的一部分,因此您仍然只需要 2 条线(加上地线)。

对于 Arduino,应该有一大堆关于 I2C/SPI 库的教程和上面的示例代码,这应该可以让启动和运行变得非常轻松。

类似于 RS485 的共享异步信令方案也应该是可能的。

如果您不使用线路驱动器/接收器(只是裸 ATMEGA 引脚),则必须在轮到您讲话时将 UART TX 设为输入。如果您使用线路驱动器,当轮不到您发言时,您需要使用额外的引脚来控制线路驱动器上的三态启用。

还要注意,当最后一个字节被接收到发送寄存器时,您不能只是三态发送器(您可以发送另一个字符的时间点),相反,您必须确保保持发送器或线路驱动器启用,直到该字已被完全移出。

在您在同一根线(或差分对)上发送和接收的方案中,考虑到您将听到自己的传输。

在您想通过UART连接的特殊情况下,您可以使用UART RS485 MODBUS这是一种具有软件地址、功能、校验和的通信协议。

我认为:由于 RS-485,它比 I²C 或 SPI 更可靠,并且比 SPI 使用更少的电线。

注意:它可以作为标准实现,有一些,但它可能很昂贵,因为每个从站都需要一个 RS485 模块,主站需要一个 RS485 模块,但它与现有网络兼容。但是您可以通过使用旧组件并制作自己的设备来降低成本。MAX 485可以是制作硬件 485 总线或使用软件 RS485的基本组件